init
This commit is contained in:
109
org/jesse/AlligatorAi.go
Normal file
109
org/jesse/AlligatorAi.go
Normal file
@@ -0,0 +1,109 @@
|
||||
package jesse
|
||||
|
||||
import (
|
||||
"github.com/banbox/banbot/config"
|
||||
"github.com/banbox/banbot/strat"
|
||||
ta "github.com/banbox/banta"
|
||||
"gonum.org/v1/gonum/floats"
|
||||
"math"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
/*
|
||||
https://jesse.trade/strategies/alligatorai-by-o1-preview-model
|
||||
原始版本:
|
||||
BTC/USDT 30m
|
||||
仅对BTC有较好的表现,略小回撤。对48个品种收益很不稳定
|
||||
*/
|
||||
|
||||
func smma(obj *ta.Series, period int) *ta.Series {
|
||||
res := obj.To("_smma", period)
|
||||
if res.Cached() {
|
||||
return res
|
||||
}
|
||||
val := obj.Get(0)
|
||||
alpha := 1 / float64(period)
|
||||
old := res.Get(0)
|
||||
if !math.IsNaN(val) && !math.IsNaN(old) {
|
||||
return res.Append(alpha*val + old*(1-alpha))
|
||||
}
|
||||
old = floats.Sum(obj.Range(0, period)) * alpha
|
||||
if math.IsNaN(old) {
|
||||
return res.Append(math.NaN())
|
||||
}
|
||||
for i := period - 1; i >= 0; i-- {
|
||||
val = obj.Get(i)
|
||||
old = alpha*val + old*(1-alpha)
|
||||
}
|
||||
return res.Append(old)
|
||||
}
|
||||
|
||||
func alligatorTrend(e *ta.BarEnv, c float64) int {
|
||||
obj := ta.HL2(e.High, e.Low)
|
||||
jaw := smma(obj, 13).Back(8)
|
||||
teeth := smma(obj, 8).Back(5)
|
||||
lips := smma(obj, 5).Back(3)
|
||||
jawV, teethV, lipsV := jaw.Get(0), teeth.Get(0), lips.Get(0)
|
||||
trend := 0
|
||||
if c > lipsV && lipsV > teethV && teethV > jawV {
|
||||
trend = 1
|
||||
} else if c < lipsV && lipsV < teethV && teethV < jawV {
|
||||
trend = -1
|
||||
}
|
||||
return trend
|
||||
}
|
||||
|
||||
type alliga struct {
|
||||
bigMALong bool
|
||||
bigTrend int
|
||||
}
|
||||
|
||||
func AlligatorAI(p *config.RunPolicyConfig) *strat.TradeStrat {
|
||||
return &strat.TradeStrat{
|
||||
WarmupNum: 200,
|
||||
OnPairInfos: func(s *strat.StratJob) []*strat.PairSub {
|
||||
bigTf := "4h"
|
||||
if s.TimeFrame == "4h" {
|
||||
bigTf = "8h"
|
||||
}
|
||||
return []*strat.PairSub{
|
||||
{"_cur_", bigTf, 200},
|
||||
}
|
||||
},
|
||||
OnStartUp: func(s *strat.StratJob) {
|
||||
s.More = &alliga{}
|
||||
},
|
||||
OnBar: func(s *strat.StratJob) {
|
||||
e := s.Env
|
||||
m, _ := s.More.(*alliga)
|
||||
c := e.Close.Get(0)
|
||||
atr := ta.ATR(e.High, e.Low, e.Close, 14).Get(0)
|
||||
trend := alligatorTrend(e, c)
|
||||
adxVal := ta.ADX(e.High, e.Low, e.Close, 14).Get(0)
|
||||
adx := adxVal > 30
|
||||
cmo := ta.CMO(e.Close, 14).Get(0)
|
||||
srsiC, _ := ta.StochRSI(e.Close, 14, 14, 3, 3)
|
||||
srsi := srsiC.Get(0)
|
||||
dirt := 0
|
||||
if trend == 1 && adx && m.bigTrend == 1 && m.bigMALong && cmo > 20 && srsi < 20 {
|
||||
dirt = 1
|
||||
} else if trend == -1 && adx && m.bigTrend == -1 && !m.bigMALong && cmo < -20 && srsi > 80 {
|
||||
dirt = -1
|
||||
}
|
||||
if dirt != 0 {
|
||||
s.OpenOrder(&strat.EnterReq{
|
||||
Tag: strconv.Itoa(dirt),
|
||||
Short: dirt < 0,
|
||||
StopLossVal: atr * 2,
|
||||
TakeProfitVal: atr * 2,
|
||||
})
|
||||
}
|
||||
},
|
||||
OnInfoBar: func(s *strat.StratJob, e *ta.BarEnv, pair, tf string) {
|
||||
m, _ := s.More.(*alliga)
|
||||
c := e.Close.Get(0)
|
||||
m.bigTrend = alligatorTrend(e, c)
|
||||
m.bigMALong = e.Close.Get(0) > ta.EMA(e.Close, 100).Get(0)
|
||||
},
|
||||
}
|
||||
}
|
||||
20
org/jesse/IFR2.go
Normal file
20
org/jesse/IFR2.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package jesse
|
||||
|
||||
import (
|
||||
"github.com/banbox/banbot/config"
|
||||
"github.com/banbox/banbot/strat"
|
||||
)
|
||||
|
||||
/*
|
||||
使用了talib.HT_TRENDMODE指标,太复杂,暂不实现
|
||||
*/
|
||||
|
||||
func IFR2(p *config.RunPolicyConfig) *strat.TradeStrat {
|
||||
return &strat.TradeStrat{
|
||||
WarmupNum: 100,
|
||||
OnBar: func(s *strat.StratJob) {
|
||||
//e := s.Env
|
||||
|
||||
},
|
||||
}
|
||||
}
|
||||
53
org/jesse/IchimokuCloud.go
Normal file
53
org/jesse/IchimokuCloud.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package jesse
|
||||
|
||||
import (
|
||||
"github.com/banbox/banbot/config"
|
||||
"github.com/banbox/banbot/strat"
|
||||
"github.com/banbox/banstagy/com"
|
||||
ta "github.com/banbox/banta"
|
||||
)
|
||||
|
||||
/*
|
||||
https://jesse.trade/strategies/ichimokucloud
|
||||
在48个品种上表现很不稳定
|
||||
*/
|
||||
|
||||
func IchimokuCloud(p *config.RunPolicyConfig) *strat.TradeStrat {
|
||||
return &strat.TradeStrat{
|
||||
WarmupNum: 100,
|
||||
OnBar: func(s *strat.StratJob) {
|
||||
e := s.Env
|
||||
atr := ta.ATR(e.High, e.Low, e.Close, 14).Get(0)
|
||||
ichi := com.IchimokuCloud(e, 9, 26, 52, 26).Cols
|
||||
adx := ta.ADX(e.High, e.Low, e.Close, 14).Get(0) > 50
|
||||
chop := ta.CHOP(e, 14).Get(0) < 50
|
||||
ichiSub1 := ichi[0].Get(0) - ichi[1].Get(0)
|
||||
ichiSub2 := ichi[2].Get(0) - ichi[3].Get(0)
|
||||
doClose := false
|
||||
if len(s.LongOrders) > 0 {
|
||||
if ichiSub1 < 0 {
|
||||
doClose = true
|
||||
}
|
||||
} else if len(s.ShortOrders) > 0 {
|
||||
if ichiSub1 > 0 {
|
||||
doClose = true
|
||||
}
|
||||
} else if ichiSub1*ichiSub2 > 0 && adx && chop {
|
||||
dirt := float64(1)
|
||||
tag := "long"
|
||||
if ichiSub1 < 0 {
|
||||
dirt = -1
|
||||
tag = "short"
|
||||
}
|
||||
s.OpenOrder(&strat.EnterReq{
|
||||
Tag: tag,
|
||||
Short: dirt < 0,
|
||||
StopLossVal: atr * 2.5 * dirt,
|
||||
})
|
||||
}
|
||||
if doClose {
|
||||
s.CloseOrders(&strat.ExitReq{Tag: "exit"})
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
72
org/jesse/KAMATrendFollow.go
Normal file
72
org/jesse/KAMATrendFollow.go
Normal file
@@ -0,0 +1,72 @@
|
||||
package jesse
|
||||
|
||||
import (
|
||||
"github.com/banbox/banbot/config"
|
||||
"github.com/banbox/banbot/orm/ormo"
|
||||
"github.com/banbox/banbot/strat"
|
||||
ta "github.com/banbox/banta"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
/*
|
||||
https://jesse.trade/strategies/kama-trendfollowing
|
||||
只适合btc,在15m上回测表现良好。
|
||||
其他品种表现很不稳定。
|
||||
*/
|
||||
|
||||
type KamaTrdSta struct {
|
||||
bigKama float64
|
||||
lastExit int
|
||||
}
|
||||
|
||||
func KamaTrendFollow(p *config.RunPolicyConfig) *strat.TradeStrat {
|
||||
return &strat.TradeStrat{
|
||||
WarmupNum: 100,
|
||||
OnPairInfos: func(s *strat.StratJob) []*strat.PairSub {
|
||||
return []*strat.PairSub{
|
||||
{"_cur_", "4h", 100},
|
||||
}
|
||||
},
|
||||
OnStartUp: func(s *strat.StratJob) {
|
||||
s.More = &KamaTrdSta{}
|
||||
},
|
||||
OnBar: func(s *strat.StratJob) {
|
||||
e := s.Env
|
||||
m, _ := s.More.(*KamaTrdSta)
|
||||
c := e.Close.Get(0)
|
||||
kama := ta.KAMA(e.Close, 30).Get(0)
|
||||
bbUp, bbMid, bbDn := ta.BBANDS(e.Close, 20, 2, 2)
|
||||
bbWidth := (bbUp.Get(0) - bbDn.Get(0)) * 100 / bbMid.Get(0)
|
||||
adx := ta.ADX(e.High, e.Low, e.Close, 14).Get(0)
|
||||
chop := ta.CHOP(e, 14).Get(0)
|
||||
atr := ta.ATR(e.High, e.Low, e.Close, 14).Get(0)
|
||||
|
||||
if adx > 50 && chop < 50 && bbWidth < 7 && e.BarNum-m.lastExit >= 10 && s.OrderNum == 0 {
|
||||
dirt := 0
|
||||
if c > max(kama, m.bigKama) {
|
||||
dirt = 1
|
||||
} else if c < min(kama, m.bigKama) {
|
||||
dirt = -1
|
||||
}
|
||||
if dirt != 0 {
|
||||
s.OpenOrder(&strat.EnterReq{
|
||||
Tag: strconv.Itoa(dirt),
|
||||
Short: dirt < 0,
|
||||
StopLossVal: atr * 2.5,
|
||||
TakeProfitVal: atr * 2.5,
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
OnInfoBar: func(s *strat.StratJob, e *ta.BarEnv, pair, tf string) {
|
||||
m, _ := s.More.(*KamaTrdSta)
|
||||
m.bigKama = ta.KAMA(e.Close, 30).Get(0)
|
||||
},
|
||||
OnOrderChange: func(s *strat.StratJob, od *ormo.InOutOrder, chgType int) {
|
||||
m, _ := s.More.(*KamaTrdSta)
|
||||
if chgType == strat.OdChgExitFill && od.Enter.Filled > 0 {
|
||||
m.lastExit = s.Env.BarNum
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
37
org/jesse/MACDEMA.go
Normal file
37
org/jesse/MACDEMA.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package jesse
|
||||
|
||||
import (
|
||||
"github.com/banbox/banbot/config"
|
||||
"github.com/banbox/banbot/strat"
|
||||
ta "github.com/banbox/banta"
|
||||
)
|
||||
|
||||
/*
|
||||
https://jesse.trade/strategies/macd-ema
|
||||
适合4h,在1h级别震荡严重
|
||||
21年到241101,累计收益1555%,回撤28.4%
|
||||
TODO: 考虑加入做空,提高夏普比率
|
||||
*/
|
||||
|
||||
func MACDEMA(p *config.RunPolicyConfig) *strat.TradeStrat {
|
||||
return &strat.TradeStrat{
|
||||
WarmupNum: 200,
|
||||
EachMaxLong: 1,
|
||||
OnBar: func(s *strat.StratJob) {
|
||||
e := s.Env
|
||||
c := e.Close.Get(0)
|
||||
ema := ta.EMA(e.Close, 100).Get(0)
|
||||
macdC, signalC := ta.MACD(e.Close, 12, 26, 9)
|
||||
macd, signal := macdC.Get(0), signalC.Get(0)
|
||||
if s.OrderNum > 0 {
|
||||
if macd < signal && c < ema {
|
||||
s.CloseOrders(&strat.ExitReq{Tag: "close"})
|
||||
}
|
||||
} else if c > ema && macd > signal {
|
||||
s.OpenOrder(&strat.EnterReq{
|
||||
Tag: "long",
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
42
org/jesse/RSITrend.go
Normal file
42
org/jesse/RSITrend.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package jesse
|
||||
|
||||
import (
|
||||
"github.com/banbox/banbot/config"
|
||||
"github.com/banbox/banbot/strat"
|
||||
ta "github.com/banbox/banta"
|
||||
)
|
||||
|
||||
/*
|
||||
https://jesse.trade/strategies/rsi-trend
|
||||
过于简单,无法盈利
|
||||
*/
|
||||
|
||||
func RSITrend(p *config.RunPolicyConfig) *strat.TradeStrat {
|
||||
//lenAtr := int(p.Def("atr", 14, core.PNorm(7, 40)))
|
||||
//baseAtrLen := int(float64(lenAtr) * 4.3)
|
||||
return &strat.TradeStrat{
|
||||
WarmupNum: 100,
|
||||
EachMaxLong: 1,
|
||||
OnBar: func(s *strat.StratJob) {
|
||||
e := s.Env
|
||||
rsi := ta.RSI(e.Close, 5)
|
||||
rsiX35 := rsi.Cross(35)
|
||||
rsiX75 := rsi.Cross(75)
|
||||
rsiX10 := rsi.Cross(10)
|
||||
//atr := ta.ATR(e.High, e.Low, e.Close, lenAtr)
|
||||
//atrBase := ta.Lowest(ta.Highest(atr, lenAtr), baseAtrLen).Get(0)
|
||||
if s.OrderNum > 0 {
|
||||
if rsiX75 == -1 || rsiX10 == -1 {
|
||||
s.CloseOrders(&strat.ExitReq{Tag: "exit"})
|
||||
}
|
||||
} else if rsiX35 == 1 {
|
||||
c := e.Close.Get(0)
|
||||
s.OpenOrder(&strat.EnterReq{
|
||||
Tag: "long",
|
||||
StopLossVal: c * 0.95,
|
||||
TakeProfitVal: c * 1.1,
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
36
org/jesse/SimpleBollinger.go
Normal file
36
org/jesse/SimpleBollinger.go
Normal file
@@ -0,0 +1,36 @@
|
||||
package jesse
|
||||
|
||||
import (
|
||||
"github.com/banbox/banbot/config"
|
||||
"github.com/banbox/banbot/strat"
|
||||
"github.com/banbox/banstagy/com"
|
||||
ta "github.com/banbox/banta"
|
||||
)
|
||||
|
||||
/*
|
||||
https://jesse.trade/strategies/simple-bollinger-bands-strategy
|
||||
适合4h,在1h级别收益很不稳定
|
||||
21年到241101,收益804%,回撤13%
|
||||
22年到241101,收益364%,回撤36%
|
||||
*/
|
||||
|
||||
func SimpleBollinger(p *config.RunPolicyConfig) *strat.TradeStrat {
|
||||
return &strat.TradeStrat{
|
||||
WarmupNum: 100,
|
||||
EachMaxLong: 1,
|
||||
OnBar: func(s *strat.StratJob) {
|
||||
e := s.Env
|
||||
c := e.Close.Get(0)
|
||||
hl2 := ta.HL2(e.High, e.Low)
|
||||
bbUp, bbMid, _ := ta.BBANDS(hl2, 20, 2, 2)
|
||||
ichiCols := com.IchimokuCloud(e, 9, 26, 52, 26).Cols
|
||||
if c < bbMid.Get(0) {
|
||||
s.CloseOrders(&strat.ExitReq{Tag: "exit"})
|
||||
} else if c > max(bbUp.Get(0), ichiCols[2].Get(0), ichiCols[3].Get(0)) {
|
||||
s.OpenOrder(&strat.EnterReq{
|
||||
Tag: "long",
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
52
org/jesse/TTMSqueezeWithAlma.go
Normal file
52
org/jesse/TTMSqueezeWithAlma.go
Normal file
@@ -0,0 +1,52 @@
|
||||
package jesse
|
||||
|
||||
import (
|
||||
"github.com/banbox/banbot/config"
|
||||
"github.com/banbox/banbot/strat"
|
||||
ta "github.com/banbox/banta"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
/*
|
||||
https://jesse.trade/strategies/ttmsqueezewithalma
|
||||
alma实现和jesse中不完全一致,在48个品种,4h级别上震荡严重。
|
||||
*/
|
||||
|
||||
func ttmSqueeze(e *ta.BarEnv, period int, bbMul, kcMul float64) bool {
|
||||
bbUp, _, bbDn := ta.BBANDS(e.Close, period, bbMul, bbMul)
|
||||
ma := ta.SMA(e.Close, period).Get(0)
|
||||
atr := ta.SMA(ta.TR(e.High, e.Low, e.Close), period).Get(0)
|
||||
thres := atr * kcMul
|
||||
return bbDn.Get(0) < ma-thres || bbUp.Get(0) > ma+thres
|
||||
}
|
||||
|
||||
func TTMSqueezeWithAlma(p *config.RunPolicyConfig) *strat.TradeStrat {
|
||||
return &strat.TradeStrat{
|
||||
WarmupNum: 100,
|
||||
EachMaxLong: 1,
|
||||
OnBar: func(s *strat.StratJob) {
|
||||
e := s.Env
|
||||
c := e.Close.Get(0)
|
||||
alma := ta.ALMA(e.Close, 50, 6, 0.85).Get(0)
|
||||
stiff := ta.Stiffness(e.Close, 100, 60, 3).Get(0) > 25
|
||||
ttms := ttmSqueeze(e, 20, 2, 2)
|
||||
atr := ta.ATR(e.High, e.Low, e.Close, 14).Get(0)
|
||||
|
||||
if s.OrderNum > 0 {
|
||||
return
|
||||
}
|
||||
if stiff && ttms {
|
||||
dirt := 1
|
||||
if c < alma {
|
||||
dirt = -1
|
||||
}
|
||||
s.OpenOrder(&strat.EnterReq{
|
||||
Tag: strconv.Itoa(dirt),
|
||||
Short: dirt < 0,
|
||||
StopLossVal: atr * 2,
|
||||
TakeProfitVal: atr * 2.5,
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
73
org/jesse/TrendSwingV1.go
Normal file
73
org/jesse/TrendSwingV1.go
Normal file
@@ -0,0 +1,73 @@
|
||||
package jesse
|
||||
|
||||
import (
|
||||
"github.com/banbox/banbot/config"
|
||||
"github.com/banbox/banbot/orm/ormo"
|
||||
"github.com/banbox/banbot/strat"
|
||||
ta "github.com/banbox/banta"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
/*
|
||||
https://jesse.trade/strategies/trendswingtrader-v1
|
||||
多均线结合ADX。
|
||||
原始版本基于4h市价单入场
|
||||
改为0.5倍atr限价入场后1h略好于4h
|
||||
在48个交易对20210101-20241101
|
||||
4h, 收益442%回撤20%
|
||||
1h, 收益404%回撤19%
|
||||
*/
|
||||
|
||||
func TrendSwingV1(p *config.RunPolicyConfig) *strat.TradeStrat {
|
||||
return &strat.TradeStrat{
|
||||
WarmupNum: 300,
|
||||
EachMaxShort: 1,
|
||||
EachMaxLong: 1,
|
||||
OnBar: func(s *strat.StratJob) {
|
||||
e := s.Env
|
||||
c := e.Close.Get(0)
|
||||
adx := ta.ADX(e.High, e.Low, e.Close, 14).Get(0)
|
||||
maSml := ta.EMA(e.Close, 21).Get(0)
|
||||
maMid := ta.EMA(e.Close, 50).Get(0)
|
||||
maBig := ta.EMA(e.Close, 100).Get(0)
|
||||
atr := ta.ATR(e.High, e.Low, e.Close, 14).Get(0)
|
||||
trend := 0
|
||||
if maBig < maMid && maMid < maSml && maSml < c {
|
||||
trend = 1
|
||||
} else if maBig > maMid && maMid > maSml && maSml > c {
|
||||
trend = -1
|
||||
}
|
||||
if len(s.LongOrders) > 0 {
|
||||
for _, od := range s.LongOrders {
|
||||
tp := od.GetTakeProfit()
|
||||
if tp == nil {
|
||||
// 止盈为nil表示已部分止盈退出
|
||||
od.SetStopLoss(&ormo.ExitTrigger{
|
||||
Price: max(c-atr*2, od.InitPrice),
|
||||
})
|
||||
}
|
||||
}
|
||||
} else if len(s.ShortOrders) > 0 {
|
||||
for _, od := range s.ShortOrders {
|
||||
tp := od.GetTakeProfit()
|
||||
if tp == nil {
|
||||
// 止盈为nil表示已部分止盈退出
|
||||
od.SetStopLoss(&ormo.ExitTrigger{
|
||||
Price: min(c+atr*2, od.InitPrice),
|
||||
})
|
||||
}
|
||||
}
|
||||
} else if adx > 25 && trend != 0 {
|
||||
s.OpenOrder(&strat.EnterReq{
|
||||
Tag: strconv.Itoa(trend),
|
||||
Limit: c - atr*float64(trend)*0.5,
|
||||
StopLossVal: atr * 2,
|
||||
Short: trend < 0,
|
||||
TakeProfitVal: atr * 3,
|
||||
TakeProfitRate: 0.5,
|
||||
StopBars: 4,
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
82
org/jesse/TurtleAI.go
Normal file
82
org/jesse/TurtleAI.go
Normal file
@@ -0,0 +1,82 @@
|
||||
package jesse
|
||||
|
||||
import (
|
||||
"github.com/banbox/banbot/config"
|
||||
"github.com/banbox/banbot/orm/ormo"
|
||||
"github.com/banbox/banbot/strat"
|
||||
ta "github.com/banbox/banta"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
/*
|
||||
https://jesse.trade/strategies/turtleai-by-o1-preview-model
|
||||
初始版本基于btcusdt 1h
|
||||
测试在48个品种上表现很不稳定
|
||||
*/
|
||||
|
||||
func TurtleAI(p *config.RunPolicyConfig) *strat.TradeStrat {
|
||||
return &strat.TradeStrat{
|
||||
WarmupNum: 200,
|
||||
EachMaxLong: 1,
|
||||
EachMaxShort: 1,
|
||||
OnPairInfos: func(s *strat.StratJob) []*strat.PairSub {
|
||||
return []*strat.PairSub{
|
||||
{"_cur_", "12h", 200},
|
||||
}
|
||||
},
|
||||
OnStartUp: func(s *strat.StratJob) {
|
||||
s.More = float64(0)
|
||||
},
|
||||
OnBar: func(s *strat.StratJob) {
|
||||
e := s.Env
|
||||
c := e.Close.Get(0)
|
||||
bigMa, _ := s.More.(float64)
|
||||
hh := ta.Highest(e.High, 20).Get(1)
|
||||
ll := ta.Lowest(e.Low, 20).Get(1)
|
||||
//ma := ta.SMA(e.Close, 200).Get(0)
|
||||
adx := ta.ADX(e.High, e.Low, e.Close, 14).Get(0) > 30
|
||||
atr := ta.ATR(e.High, e.Low, e.Close, 14).Get(0)
|
||||
chopVal := ta.CHOP(e, 14).Get(0)
|
||||
chop := chopVal < 40
|
||||
|
||||
if len(s.LongOrders) > 0 {
|
||||
newSL := c - atr*2.5
|
||||
for _, od := range s.LongOrders {
|
||||
sl := od.GetStopLoss()
|
||||
if newSL > sl.Price {
|
||||
od.SetStopLoss(&ormo.ExitTrigger{
|
||||
Price: newSL,
|
||||
})
|
||||
}
|
||||
}
|
||||
} else if len(s.ShortOrders) > 0 {
|
||||
newSL := c + atr*2.5
|
||||
for _, od := range s.LongOrders {
|
||||
sl := od.GetStopLoss()
|
||||
if newSL < sl.Price {
|
||||
od.SetStopLoss(&ormo.ExitTrigger{
|
||||
Price: newSL,
|
||||
})
|
||||
}
|
||||
}
|
||||
} else if adx && chop {
|
||||
dirt := 0
|
||||
if c > max(bigMa, hh) {
|
||||
dirt = 1
|
||||
} else if c < min(bigMa, ll) {
|
||||
dirt = -1
|
||||
}
|
||||
if dirt != 0 {
|
||||
s.OpenOrder(&strat.EnterReq{
|
||||
Tag: strconv.Itoa(dirt),
|
||||
Short: dirt < 0,
|
||||
StopLossVal: atr * 2.5,
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
OnInfoBar: func(s *strat.StratJob, e *ta.BarEnv, pair, tf string) {
|
||||
s.More = ta.SMA(e.Close, 200).Get(0)
|
||||
},
|
||||
}
|
||||
}
|
||||
18
org/jesse/common.go
Normal file
18
org/jesse/common.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package jesse
|
||||
|
||||
import "github.com/banbox/banbot/strat"
|
||||
|
||||
func init() {
|
||||
strat.AddStratGroup("jesse", map[string]strat.FuncMakeStrat{
|
||||
"TrendSwingV1": TrendSwingV1,
|
||||
"donchian": donchian,
|
||||
"AlligatorAI": AlligatorAI,
|
||||
"TurtleAI": TurtleAI,
|
||||
"SimpleBollinger": SimpleBollinger,
|
||||
"MACDEMA": MACDEMA,
|
||||
"RSITrend": RSITrend,
|
||||
"IchimokuCloud": IchimokuCloud,
|
||||
"TTMSqueezeWithAlma": TTMSqueezeWithAlma,
|
||||
"KamaTrendFollow": KamaTrendFollow,
|
||||
})
|
||||
}
|
||||
39
org/jesse/donchian.go
Normal file
39
org/jesse/donchian.go
Normal file
@@ -0,0 +1,39 @@
|
||||
package jesse
|
||||
|
||||
import (
|
||||
"github.com/banbox/banbot/config"
|
||||
"github.com/banbox/banbot/strat"
|
||||
ta "github.com/banbox/banta"
|
||||
)
|
||||
|
||||
/*
|
||||
https://jesse.trade/strategies/simple-donchian-strategy
|
||||
唐安奇通道,默认周期20
|
||||
适用周期:2h,4h
|
||||
*/
|
||||
func donchian(p *config.RunPolicyConfig) *strat.TradeStrat {
|
||||
return &strat.TradeStrat{
|
||||
WarmupNum: 200,
|
||||
EachMaxLong: 1,
|
||||
OnBar: func(s *strat.StratJob) {
|
||||
e := s.Env
|
||||
c := e.Close.Get(0)
|
||||
hh := ta.Highest(e.High, 25).Get(1)
|
||||
ll := ta.Lowest(e.Low, 25).Get(1)
|
||||
ma := ta.SMA(e.Close, 200).Get(0)
|
||||
//atr := ta.ATR(e.High, e.Low, e.Close, 14).Get(0)
|
||||
|
||||
if len(s.LongOrders) > 0 {
|
||||
if c < ll {
|
||||
s.CloseOrders(&strat.ExitReq{Tag: "exit"})
|
||||
}
|
||||
} else if c > max(ma, hh) {
|
||||
s.OpenOrder(&strat.EnterReq{
|
||||
Tag: "long",
|
||||
//TakeProfitVal: atr * 20,
|
||||
//TakeProfitRate: 0.5,
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
40
org/jesse/jesse_test.go
Normal file
40
org/jesse/jesse_test.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package jesse
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/banbox/banta"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var env = &banta.BarEnv{
|
||||
TimeFrame: "1d",
|
||||
TFMSecs: 86400000,
|
||||
Exchange: "binance",
|
||||
MarketType: "future",
|
||||
}
|
||||
|
||||
var DataKline = []banta.Kline{
|
||||
{1688169600000, 1, 1, 1, 1, 1, 0},
|
||||
{1688256000000, 2, 2, 2, 2, 2, 0},
|
||||
{1688342400000, 3, 3, 3, 3, 3, 0},
|
||||
{1688428800000, 4, 4, 4, 4, 4, 0},
|
||||
{1688515200000, 5, 5, 5, 5, 5, 0},
|
||||
{1688601600000, 6, 6, 6, 6, 6, 0},
|
||||
{1688688000000, 7, 7, 7, 7, 7, 0},
|
||||
{1688774400000, 8, 8, 8, 8, 8, 0},
|
||||
{1688860800000, 9, 9, 9, 9, 9, 0},
|
||||
{1688947200000, 10, 10, 10, 10, 10, 0},
|
||||
{1689033600000, 11, 11, 11, 11, 11, 0},
|
||||
{1689120000000, 12, 12, 12, 12, 12, 0},
|
||||
}
|
||||
|
||||
func TestSMMA(t *testing.T) {
|
||||
env.Reset()
|
||||
var res []float64
|
||||
for _, bar := range DataKline {
|
||||
env.OnBar(bar.Time, bar.Open, bar.High, bar.Low, bar.Close, bar.Volume, bar.Info)
|
||||
ma := smma(env.Close, 4)
|
||||
res = append(res, ma.Get(0))
|
||||
}
|
||||
fmt.Printf("%v", res)
|
||||
}
|
||||
Reference in New Issue
Block a user