init
This commit is contained in:
177
org/ft/BBMod2.go
Normal file
177
org/ft/BBMod2.go
Normal file
@@ -0,0 +1,177 @@
|
||||
package ft
|
||||
|
||||
import (
|
||||
"github.com/banbox/banbot/orm/ormo"
|
||||
"math"
|
||||
|
||||
"github.com/banbox/banbot/config"
|
||||
"github.com/banbox/banbot/core"
|
||||
"github.com/banbox/banbot/strat"
|
||||
ta "github.com/banbox/banta"
|
||||
"gonum.org/v1/gonum/floats"
|
||||
)
|
||||
|
||||
/*
|
||||
https://strat.ninja/overview.php?strategy=BBMod_2
|
||||
BBMod1 modified from BB_RPB_TSL ( https://github.com/jilv220/BB_RPB_TSL )
|
||||
@author jilv220
|
||||
|
||||
210101-241101 48品种 5m 收益570%,回撤9.3%
|
||||
*/
|
||||
|
||||
type BBModSta struct {
|
||||
bigEmaUp bool
|
||||
atrBase float64
|
||||
tmpHolds map[int64]bool
|
||||
}
|
||||
|
||||
func BBMod2(pol *config.RunPolicyConfig) *strat.TradeStrat {
|
||||
//emaDfRate := pol.Def("emaDf", 4, core.PNorm(1.5, 6))
|
||||
lenAtr := int(pol.Def("atr", 29, core.PNorm(7, 40)))
|
||||
baseAtrLen := int(float64(lenAtr) * 4.3)
|
||||
return &strat.TradeStrat{
|
||||
WarmupNum: 100,
|
||||
DrawDownExit: true,
|
||||
OnPairInfos: func(s *strat.StratJob) []*strat.PairSub {
|
||||
return []*strat.PairSub{
|
||||
{"_cur_", "1h", 100},
|
||||
}
|
||||
},
|
||||
OnStartUp: func(s *strat.StratJob) {
|
||||
s.More = &BBModSta{
|
||||
tmpHolds: make(map[int64]bool),
|
||||
}
|
||||
},
|
||||
OnBar: func(s *strat.StratJob) {
|
||||
e := s.Env
|
||||
m, _ := s.More.(*BBModSta)
|
||||
c, c1 := e.Close.Get(0), e.Close.Get(1)
|
||||
atr := ta.ATR(e.High, e.Low, e.Close, lenAtr)
|
||||
atrBase := ta.Lowest(ta.Highest(atr, lenAtr), baseAtrLen).Get(0)
|
||||
m.atrBase = atrBase
|
||||
closeDelta := math.Abs(c - e.Close.Get(1))
|
||||
hlc3 := ta.AvgPrice(e)
|
||||
_, bbMidC, bbLowC := ta.BBANDS(hlc3, 20, 2, 2)
|
||||
bbMid, bbLow := bbMidC.Get(0), bbLowC.Get(0)
|
||||
sma9 := ta.SMA(e.Close, 9).Get(0)
|
||||
//sma15 := ta.SMA(e.Close, 15).Get(0)
|
||||
//
|
||||
//cti := ta.CTI(e.Close, 20).Get(0)
|
||||
|
||||
ema8 := ta.EMA(e.Close, 8).Get(0)
|
||||
ema12S := ta.EMA(e.Close, 12)
|
||||
ema12 := ema12S.Get(0)
|
||||
ema16 := ta.EMA(e.Close, 16).Get(0)
|
||||
//ema20 := ta.EMA(e.Close, 20).Get(0)
|
||||
ema24 := ta.EMA(e.Close, 24).Get(0)
|
||||
ema26S := ta.EMA(e.Close, 26)
|
||||
ema26 := ema26S.Get(0)
|
||||
ema50 := ta.EMA(e.Close, 50).Get(0)
|
||||
ema200 := ta.EMA(e.Close, 200).Get(0)
|
||||
ewo := (ema50 - ema200) / atrBase
|
||||
|
||||
rsi := ta.RSI(e.Close, 14).Get(0)
|
||||
rsiFast := ta.RSI(e.Close, 4).Get(0)
|
||||
rsiSlowS := ta.RSI(e.Close, 20)
|
||||
rsiSlow := rsiSlowS.Get(0)
|
||||
//rsi84 := ta.RSI(e.Close, 84).Get(0)
|
||||
//rsi112 := ta.RSI(e.Close, 112).Get(0)
|
||||
//crsi := ta.CRSIBy(e.Close, 3, 2, 100, 1).Get(0)
|
||||
|
||||
//heiKA := ta.HeikinAshi(e).Cols
|
||||
//heiHlc3 := ta.HLC3(heiKA[1], heiKA[2], heiKA[3])
|
||||
//bb40Cols := ta.BBANDS(heiHlc3, 40, 2, 2).Cols
|
||||
//bb40Mid, bb40Low := bb40Cols[1].Get(0), bb40Cols[2].Get(0)
|
||||
//bb40Low1 := bb40Cols[2].Get(1)
|
||||
//bb40Delta := bb40Mid - bb40Low
|
||||
//tail := math.Abs(heiKA[3].Get(0) - heiKA[2].Get(0))
|
||||
|
||||
//_, vwapLow := vwapB(hlc3, e.Volume, 20, 1)
|
||||
//tcpPct4 := ta.Highest(e.Open, 4).Get(0)/c - 1
|
||||
|
||||
tryTmpHold := c > max(sma9, ema24-atrBase*0.2, bbMid) && rsi > 50 && rsiFast > rsiSlow
|
||||
holdTags := make(map[string]bool)
|
||||
for _, od := range s.LongOrders {
|
||||
holdTags[od.EnterTag] = true
|
||||
if od.ProfitRate < atrBase*4 {
|
||||
if tryTmpHold {
|
||||
m.tmpHolds[od.ID] = true
|
||||
}
|
||||
} else if _, ok := m.tmpHolds[od.ID]; ok {
|
||||
delete(m.tmpHolds, od.ID)
|
||||
}
|
||||
}
|
||||
if len(m.tmpHolds) > 0 && c < floats.Min(e.Low.Range(1, 4)) {
|
||||
for oid := range m.tmpHolds {
|
||||
s.CloseOrders(&strat.ExitReq{Tag: "sellDrop", OrderID: oid})
|
||||
}
|
||||
m.tmpHolds = make(map[int64]bool)
|
||||
}
|
||||
|
||||
_ = c1
|
||||
|
||||
tag := ""
|
||||
ema26_12rate := (ema26 - ema12) / atrBase
|
||||
ema26_12rateP := (ema26S.Get(1) - ema12S.Get(1)) / atrBase
|
||||
closeDeltaRate := closeDelta / atrBase
|
||||
if ema26_12rateP > 2 && c < bbLow-atrBase*0.2 {
|
||||
if ema26_12rate > 5 && closeDeltaRate > 3.5 {
|
||||
//use origin bb_rpb_tsl value
|
||||
tag = "up2"
|
||||
}
|
||||
// 略不稳定
|
||||
//else if ema26_12rate > emaDfRate && closeDeltaRate > 2.4 {
|
||||
// // from NFI next gen, credit goes to @iterativ
|
||||
// tag = "up1"
|
||||
//}
|
||||
}
|
||||
if rsiFast < 44 && ewo > -10 && c < min(ema8-atrBase*13, ema16-atrBase*6.4) && rsi < 23 {
|
||||
// from sma offset
|
||||
//tag = "ewo"
|
||||
tag = "smo"
|
||||
}
|
||||
// 下面的要么不稳定,要么几乎没有订单
|
||||
//} else if ema26_12rate > 4.8 && ema26_12rateP > 2 && c < ema20+atrBase*2.6 && rsi < 21 && crsi > 10 && closeDeltaRate > 2.4 {
|
||||
// tag = "localDip"
|
||||
//} else if rsiSlow < rsiSlowS.Get(1) && rsiFast < 46 && rsi > 19 && c < sma15-atrBase*11 && cti < -0.86 {
|
||||
// tag = "nfi32"
|
||||
//} else if m.bigEmaUp && bb40Delta > atrBase*11 && closeDeltaRate > 2 && tail < bb40Delta*0.5 &&
|
||||
// c < bb40Low1 && c <= c1 && c > ema12-atrBase*17 {
|
||||
// tag = "nfix39"
|
||||
//}
|
||||
//else if c < vwapLow.Get(0) && tcpPct4 > atrBase*8 && cti < -0.8 && rsi < 35 && rsi84 < 60 && rsi112 < 60 {
|
||||
// tag = "vwap"
|
||||
//}
|
||||
|
||||
if _, hasOld := holdTags[tag]; tag != "" && !hasOld {
|
||||
s.OpenOrder(&strat.EnterReq{Tag: tag})
|
||||
}
|
||||
},
|
||||
OnInfoBar: func(s *strat.StratJob, e *ta.BarEnv, pair, tf string) {
|
||||
m, _ := s.More.(*BBModSta)
|
||||
ema200 := ta.EMA(e.Close, 200)
|
||||
cur, p12, p24 := ema200.Get(0), ema200.Get(12), ema200.Get(24)
|
||||
m.bigEmaUp = cur > p12 && p12 > p24
|
||||
},
|
||||
GetDrawDownExitRate: func(s *strat.StratJob, od *ormo.InOutOrder, maxChg float64) float64 {
|
||||
m, _ := s.More.(*BBModSta)
|
||||
if maxChg > m.atrBase*10 {
|
||||
return 0.15
|
||||
} else if maxChg > m.atrBase*4 {
|
||||
return 0.2
|
||||
}
|
||||
return 0
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
vwapB 应传入hlc3和qtpylib.rolling_vwap中保持一致
|
||||
|
||||
return [vwap, low]
|
||||
*/
|
||||
func vwapB(p, v *ta.Series, period int, rate float64) (*ta.Series, *ta.Series) {
|
||||
vwap := ta.VWMA(p, v, period)
|
||||
dev := ta.StdDev(vwap, period)
|
||||
return vwap, vwap.Add(dev.Mul(-rate))
|
||||
}
|
||||
224
org/ft/BBMod7.go
Normal file
224
org/ft/BBMod7.go
Normal file
@@ -0,0 +1,224 @@
|
||||
package ft
|
||||
|
||||
import (
|
||||
"math"
|
||||
|
||||
"github.com/banbox/banbot/config"
|
||||
"github.com/banbox/banbot/core"
|
||||
"github.com/banbox/banbot/strat"
|
||||
ta "github.com/banbox/banta"
|
||||
)
|
||||
|
||||
/*
|
||||
https://strat.ninja/overview.php?strategy=BBMod_7
|
||||
48品种,210101-241101,盈利327%,回撤8.83%
|
||||
*/
|
||||
|
||||
type BBMod7Sta struct {
|
||||
bigEma200 *ta.Series
|
||||
bigRoc float64
|
||||
atrBase float64
|
||||
bigBBWid2 float64
|
||||
bigBBMid float64
|
||||
bigT3 float64
|
||||
}
|
||||
|
||||
func BBMod7(p *config.RunPolicyConfig) *strat.TradeStrat {
|
||||
//lowRate := p.Def("lowRate", 6, core.PNorm(1, 3.5))
|
||||
//highRate := p.Def("highRate", 15, core.PNorm(0.5, 2.5))
|
||||
lenAtr := int(p.Def("atr", 13.35, core.PNorm(7, 25)))
|
||||
baseAtrLen := int(float64(lenAtr) * 4.3)
|
||||
return &strat.TradeStrat{
|
||||
WarmupNum: 100,
|
||||
OnPairInfos: func(s *strat.StratJob) []*strat.PairSub {
|
||||
return []*strat.PairSub{
|
||||
{"_cur_", "1h", 300},
|
||||
}
|
||||
},
|
||||
OnStartUp: func(s *strat.StratJob) {
|
||||
s.More = &BBMod7Sta{}
|
||||
},
|
||||
OnBar: func(s *strat.StratJob) {
|
||||
e := s.Env
|
||||
m, _ := s.More.(*BBMod7Sta)
|
||||
o, c := e.Open.Get(0), e.Close.Get(0)
|
||||
atr := ta.ATR(e.High, e.Low, e.Close, lenAtr)
|
||||
atrBase := ta.Lowest(ta.Highest(atr, lenAtr), baseAtrLen).Get(0)
|
||||
m.atrBase = atrBase
|
||||
|
||||
//sma15 := ta.SMA(e.Close, 15).Get(0)
|
||||
//sma28 := ta.SMA(e.Close, 28).Get(0)
|
||||
|
||||
//tr := ta.TR(e.High, e.Low, e.Close)
|
||||
//rangeMa28 := ta.SMA(tr, 28).Get(0)
|
||||
//kcUpp28 := sma28 + rangeMa28
|
||||
//kcLow28 := sma28 - rangeMa28
|
||||
|
||||
closeDelta := math.Abs(e.Close.Get(0) - e.Close.Get(1))
|
||||
|
||||
//rmi := ta.RMI(e.Close, 8, 4).Get(0)
|
||||
//cci := ta.CCI(e.Close, 25).Get(0)
|
||||
//srsiK := ta.StochRSI(e.Close, 15, 20, 2, 2).Cols[0].Get(0)
|
||||
|
||||
hlc3 := ta.HLC3(e.High, e.Low, e.Close)
|
||||
bb2Up, _, bb2Dn := ta.BBANDS(hlc3, 20, 2, 2)
|
||||
bb2Upp, bb2Low := bb2Up.Get(0), bb2Dn.Get(0)
|
||||
//bb2Wid := (bb2Upp - bb2Low) / atrBase
|
||||
//bb2Mid := bb2Cols[1].Get(0)
|
||||
|
||||
//bb3Cols := ta.BBANDS(hlc3, 20, 3, 3).Cols
|
||||
//bb3Low := bb3Cols[2].Get(0)
|
||||
//bbDelta := (bb2Cols[2].Get(0) - bb3Low) / atrBase
|
||||
|
||||
//ema13 := ta.EMA(e.Close, 13).Get(0)
|
||||
ema8 := ta.EMA(e.Close, 8).Get(0)
|
||||
//ema16 := ta.EMA(e.Close, 16).Get(0)
|
||||
//ema20 := ta.EMA(e.Close, 20).Get(0)
|
||||
ema50 := ta.EMA(e.Close, 50).Get(0)
|
||||
//ema100 := ta.EMA(e.Close, 100).Get(0)
|
||||
ema200 := ta.EMA(e.Close, 200).Get(0)
|
||||
ewo := (ema50 - ema200) / atrBase
|
||||
ema12S := ta.EMA(e.Close, 12)
|
||||
ema26S := ta.EMA(e.Close, 26)
|
||||
ema12, ema26 := ema12S.Get(0), ema26S.Get(0)
|
||||
ema12P, ema26P := ema12S.Get(1), ema26S.Get(1)
|
||||
|
||||
//hh20 := ta.Highest(e.High, 20).Get(0)
|
||||
//ll20 := ta.Lowest(e.Low, 20).Get(0)
|
||||
//sma20 := ta.SMA(e.Close, 20).Get(0)
|
||||
//linRegSrc := e.Close.To("_linRegSrc", 20)
|
||||
//if !linRegSrc.Cached() {
|
||||
// linRegSrc.Append(c - ((hh20+ll20)/2+sma20)/2)
|
||||
//}
|
||||
//linReg20 := ta.LinReg(linRegSrc, 20)
|
||||
|
||||
//rsi := ta.RSI(e.Close, 14).Get(0)
|
||||
//rsiFast := ta.RSI(e.Close, 4).Get(0)
|
||||
//rsiSlowS := ta.RSI(e.Close, 20)
|
||||
//rsiSlow := rsiSlowS.Get(0)
|
||||
//crsi := ta.CRSI(e.Close, 3, 2, 100).Get(0)
|
||||
|
||||
//lowWid := atrBase * lowRate
|
||||
//highWid := atrBase * highRate
|
||||
//emaEnt := c < ema8-lowWid && c < ema16+highWid
|
||||
//
|
||||
//volMa12 := ta.SMA(e.Volume, 12).Get(1)
|
||||
//volMa24 := ta.SMA(e.Volume, 24).Get(1)
|
||||
|
||||
cti := ta.CTI(e.Close, 20).Get(0)
|
||||
t3 := T3(e.Close, 5).Get(0)
|
||||
fastD, _, fastK := ta.KDJBy(e.High, e.Low, e.Close, 5, 3, 3, "sma")
|
||||
|
||||
willR := ta.WillR(e, 14).Get(0)
|
||||
|
||||
//kdjRawX := fastK.Cross(fastD)
|
||||
//
|
||||
//adx := ta.ADX(e.High, e.Low, e.Close, 14).Get(0)
|
||||
//
|
||||
//vwapLow, _ := vwapB(hlc3, e.Volume, 20, 1)
|
||||
//
|
||||
//tcpPct := topPctChgDca(e.Open, e.Close, 4)
|
||||
|
||||
_, _, _ = o, bb2Upp, fastD
|
||||
|
||||
if fastK.Get(0) > 75 && s.OrderNum > 0 {
|
||||
s.CloseOrders(&strat.ExitReq{Tag: "fastk"})
|
||||
return
|
||||
}
|
||||
|
||||
for _, od := range s.LongOrders {
|
||||
profit := (c - od.InitPrice) / atrBase
|
||||
sl := od.GetStopLoss()
|
||||
if profit > 15 {
|
||||
sl.Price = od.InitPrice + atrBase*15
|
||||
} else if profit > 6 {
|
||||
sl.Price = od.InitPrice + atrBase*6
|
||||
}
|
||||
}
|
||||
|
||||
tag := ""
|
||||
if ewo < -11 && m.bigBBMid >= m.bigT3 && t3 <= ema8-atrBase*6 && cti < -0.5 && willR < -60 {
|
||||
//tag = "gumbo"
|
||||
tag = "gb"
|
||||
} else if ema26-ema12 > atrBase*5 && ema26P-ema12P > atrBase*2 &&
|
||||
c < bb2Low-atrBase*0.6 && closeDelta > atrBase*3 {
|
||||
//tag = "uptrend"
|
||||
tag = "up"
|
||||
}
|
||||
//else if rmi < 35 && cci <= -133 && srsiK < 25 && bbDelta > 4.5 && bb2Wid > 18 && closeDelta > atrBase*3 &&
|
||||
// c < bb3Low-atrBase*0.2 {
|
||||
// // 略不稳定,可选
|
||||
// tag = "BinH"
|
||||
//}
|
||||
// 下面的要么不稳定,要么几乎没有订单
|
||||
// else if bb2Low < kcLow28 && bb2Upp > kcUpp28 && linReg20.Get(2) > linReg20.Get(1) &&
|
||||
// linReg20.Get(1) < linReg20.Get(0) && linReg20.Get(0) < 0 && c < ema13-atrBase*6 &&
|
||||
// ewo < 0 && willR < -50 {
|
||||
// tag = "sqzmom"
|
||||
//} else if m.bigEma200 != nil && m.bigEma200.Get(0) > m.bigEma200.Get(12) &&
|
||||
// m.bigEma200.Get(12) > m.bigEma200.Get(24) &&
|
||||
// rsiFast < 45 && emaEnt && ewo > 4.18 && rsi < 35 {
|
||||
// tag = "ewo2"
|
||||
//} else if ema100 < ema200+atrBase*16 && bb2Wid > 10 && c < bb2Mid && volMa12 < volMa24 && cti < -0.5 &&
|
||||
// willR < -60 {
|
||||
// // 亏损,效果差
|
||||
// //tag = "deadfish"
|
||||
//} else if m.bigRoc < 10 && m.bigBBWid2 < 60 && o < ema8-atrBase*6 && kdjRawX == 1 &&
|
||||
// fastK.Get(0) < 20 && fastD.Get(0) < 20 && adx > 30 && ewo > 7 && cti < -0.5 && willR < -60 {
|
||||
// tag = "cofi"
|
||||
//} else if ema26-ema12 > atrBase*5 && ema26P-ema12P > atrBase*2 && c < ema20-atrBase*11 && rsi < 28 &&
|
||||
// crsi > 10 && closeDelta > atrBase*3 {
|
||||
// tag = "localDip"
|
||||
//} else if rsiFast < 45 && c < ema8-atrBase*11 && ewo > -5.585 && c < ema16+atrBase*16 && rsi < 35 {
|
||||
// tag = "ewo"
|
||||
//} else if rsiSlow < rsiSlowS.Get(1) && rsiFast < 46 && rsi > 19 && c < sma15-atrBase*11 && cti < -0.86 {
|
||||
// tag = "nfi32"
|
||||
//} else if c < vwapLow.Get(0) && tcpPct > 4 && cti < -0.86 && rsi < 35 {
|
||||
// tag = "vwap"
|
||||
//}
|
||||
if tag != "" && s.OrderNum == 0 {
|
||||
s.OpenOrder(&strat.EnterReq{
|
||||
Tag: tag,
|
||||
StopLossVal: atrBase * 20,
|
||||
})
|
||||
}
|
||||
},
|
||||
OnInfoBar: func(s *strat.StratJob, e *ta.BarEnv, pair, tf string) {
|
||||
m, _ := s.More.(*BBMod7Sta)
|
||||
m.bigEma200 = ta.EMA(e.Close, 200)
|
||||
m.bigRoc = ta.ROC(e.Close, 9).Get(0)
|
||||
|
||||
hlc3 := ta.HLC3(e.High, e.Low, e.Close)
|
||||
bb2Up, bb2Mid, bb2Dn := ta.BBANDS(hlc3, 20, 2, 2)
|
||||
bb2Upp, bb2Low := bb2Up.Get(0), bb2Dn.Get(0)
|
||||
m.bigBBWid2 = (bb2Upp - bb2Low) / m.atrBase
|
||||
m.bigBBMid = bb2Mid.Get(0)
|
||||
|
||||
m.bigT3 = T3(e.Close, 5).Get(0)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
T3 Average by HPotter on Tradingview
|
||||
https://www.tradingview.com/script/qzoC9H1I-T3-Average/
|
||||
*/
|
||||
func T3(p *ta.Series, period int) *ta.Series {
|
||||
res := p.To("_t3", period)
|
||||
if res.Cached() {
|
||||
return res
|
||||
}
|
||||
xe1 := ta.EMA(p, period)
|
||||
xe2 := ta.EMA(xe1, period)
|
||||
xe3 := ta.EMA(xe2, period)
|
||||
xe4 := ta.EMA(xe3, period)
|
||||
xe5 := ta.EMA(xe4, period)
|
||||
xe6 := ta.EMA(xe5, period)
|
||||
b := 0.7
|
||||
c1 := -b * b * b
|
||||
c2 := 3*b*b + 3*b*b*b
|
||||
c3 := -6*b*b - 3*b - 3*b*b*b
|
||||
c4 := 1 + 3*b + b*b*b + 3*b*b
|
||||
val := c1*xe6.Get(0) + c2*xe5.Get(0) + c3*xe4.Get(0) + c4*xe3.Get(0)
|
||||
return res.Append(val)
|
||||
}
|
||||
80
org/ft/BinHModWhiteHOV0.go
Normal file
80
org/ft/BinHModWhiteHOV0.go
Normal file
@@ -0,0 +1,80 @@
|
||||
package ft
|
||||
|
||||
import (
|
||||
"github.com/banbox/banbot/config"
|
||||
"github.com/banbox/banbot/core"
|
||||
"github.com/banbox/banbot/strat"
|
||||
ta "github.com/banbox/banta"
|
||||
"math"
|
||||
)
|
||||
|
||||
/*
|
||||
https://strat.ninja/overview.php?strategy=BinHModWhiteHOV0
|
||||
|
||||
收益太低,210101-241101,48品种,15%收益,回撤3.4%
|
||||
*/
|
||||
|
||||
func BinHModWhiteHOV0(pol *config.RunPolicyConfig) *strat.TradeStrat {
|
||||
bbWidthVal := pol.Def("bb_width", 13.5, core.PNorm(1, 15))
|
||||
bbDeltaDiff := pol.Def("bb_delta_diff", 4.4, core.PNorm(0.2, 12))
|
||||
bbTailDiff := pol.Def("bb_tail_diff", 0.132, core.PNorm(0.05, 0.450))
|
||||
bbBottomDeltaDiff := pol.Def("bb_bottom_delta_diff", 1.1, core.PNorm(0.8, 8))
|
||||
bbTopDeltaDiff := pol.Def("bb_top_delta_diff", 2.5, core.PNorm(1, 18))
|
||||
emaRise := int(pol.Def("ema_rise", 54, core.PNorm(6, 60)))
|
||||
emaSlowPeriod := int(pol.Def("ema_slow", 160, core.PNorm(140, 300)))
|
||||
emaTrendPeriod := int(pol.Def("ema_trend", 90, core.PNorm(50, 110)))
|
||||
ewoBaseLen := int(pol.Def("ewo_base", 70, core.PNorm(50, 150)))
|
||||
ewoStepLen := int(pol.Def("ewo_step", 90, core.PNorm(10, 150)))
|
||||
ewoHigh := pol.Def("ewo_high", 6, core.PNorm(1.0, 12.0))
|
||||
highOffset := pol.Def("high_offset", 0.0, core.PNorm(0.0, 4))
|
||||
lenAtr := 29
|
||||
baseAtrLen := int(float64(lenAtr) * 4.3)
|
||||
return &strat.TradeStrat{
|
||||
WarmupNum: 100,
|
||||
OnBar: func(s *strat.StratJob) {
|
||||
e := s.Env
|
||||
atr := ta.ATR(e.High, e.Low, e.Close, lenAtr)
|
||||
atrBase := ta.Lowest(ta.Highest(atr, lenAtr), baseAtrLen).Get(0)
|
||||
|
||||
bottom := e.Open.Min(e.Close)
|
||||
up := e.Open.Max(e.Close)
|
||||
bbUp, bbMd, bbDn := ta.BBANDS(e.Close, 40, 2.0, 2.0)
|
||||
bbUpp, bbMid, bbLow := bbUp.Get(0), bbMd.Get(0), bbDn.Get(0)
|
||||
bbWidthRaw := e.Close.To("_bbWid", 40)
|
||||
if !bbWidthRaw.Cached() {
|
||||
bbWidthRaw.Append((bbUpp - bbLow) / atrBase)
|
||||
}
|
||||
space := ta.SMA(bbWidthRaw, 60).Get(0)
|
||||
bbDelta := bbMid - bbLow
|
||||
bottomDelta := math.Abs(bottom.Get(0) - bottom.Get(1))
|
||||
topDelta := math.Abs(up.Get(0) - up.Get(1))
|
||||
tail := bottom.Get(0) - e.Low.Get(0)
|
||||
|
||||
emaTrend := ta.EMA(e.Close, emaTrendPeriod)
|
||||
emaSlower := ta.EMA(e.Close, emaSlowPeriod)
|
||||
ema1 := ta.EMA(e.Close, ewoBaseLen).Get(0)
|
||||
ema2 := ta.EMA(e.Close, ewoBaseLen+ewoStepLen).Get(0)
|
||||
ewo := (ema1 - ema2) / atrBase
|
||||
|
||||
buyProtection1 := emaTrend.Get(0) > emaSlower.Get(0)
|
||||
buyProtection2 := emaSlower.Get(0) > emaSlower.Get(emaRise) &&
|
||||
emaSlower.Get(emaRise) > emaSlower.Get(emaRise*2)
|
||||
buyProtection3 := ewo > ewoHigh
|
||||
|
||||
if buyProtection1 && buyProtection2 && buyProtection3 &&
|
||||
space > bbWidthVal && s.OrderNum == 0 &&
|
||||
bottom.Get(0) < math.Min(bottom.Get(1), bbDn.Get(1)) &&
|
||||
bbDelta > atrBase*bbDeltaDiff &&
|
||||
tail < bbDelta*bbTailDiff &&
|
||||
bottomDelta > atrBase*bbBottomDeltaDiff &&
|
||||
topDelta < atrBase*bbTopDeltaDiff &&
|
||||
bbDn.Get(1) > 0 {
|
||||
s.OpenOrder(&strat.EnterReq{Tag: "buy"})
|
||||
}
|
||||
|
||||
if e.Close.Get(0) > bbMid+atrBase*highOffset {
|
||||
s.CloseOrders(&strat.ExitReq{Tag: "sell"})
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
101
org/ft/BinHV27.go
Normal file
101
org/ft/BinHV27.go
Normal file
@@ -0,0 +1,101 @@
|
||||
package ft
|
||||
|
||||
import (
|
||||
"github.com/banbox/banbot/config"
|
||||
"github.com/banbox/banbot/core"
|
||||
"github.com/banbox/banbot/strat"
|
||||
ta "github.com/banbox/banta"
|
||||
)
|
||||
|
||||
/*
|
||||
https://strat.ninja/overview.php?strategy=BinHV27_long
|
||||
亏损,无效策略
|
||||
*/
|
||||
|
||||
func BinHV27(p *config.RunPolicyConfig) *strat.TradeStrat {
|
||||
lenAtr := int(p.Def("atr", 29, core.PNorm(7, 40)))
|
||||
baseAtrLen := int(float64(lenAtr) * 4.3)
|
||||
return &strat.TradeStrat{
|
||||
WarmupNum: 100,
|
||||
OnBar: func(s *strat.StratJob) {
|
||||
e := s.Env
|
||||
c := e.Close.Get(0)
|
||||
atr := ta.ATR(e.High, e.Low, e.Close, lenAtr)
|
||||
atrBase := ta.Lowest(ta.Highest(atr, lenAtr), baseAtrLen).Get(0)
|
||||
|
||||
ema60 := ta.EMA(e.Close, 60).Get(0)
|
||||
ema120 := ta.EMA(e.Close, 120).Get(0)
|
||||
sma120 := ta.SMA(e.Close, 120)
|
||||
sma240 := ta.SMA(e.Close, 240)
|
||||
|
||||
plusDi, minusDi := ta.PluMinDI(e.High, e.Low, e.Close, 14)
|
||||
minDiMa := ta.EMA(minusDi, 25).Get(0)
|
||||
|
||||
adx := ta.ADX(e.High, e.Low, e.Close, 14).Get(0)
|
||||
|
||||
rsi := ta.RSI(e.Close, 5)
|
||||
rsiMa := ta.EMA(rsi, 5).Get(0)
|
||||
|
||||
minDiOk := minusDi.Get(0) > minDiMa
|
||||
rsiOk := rsi.Get(0) >= rsi.Get(1)
|
||||
bigTrendChg := sma120.Get(0)-sma240.Get(0) > sma120.Get(1)-sma240.Get(1)
|
||||
bigContiUp := sma240.Get(0) > sma240.Get(1) && sma240.Get(1) > sma240.Get(2)
|
||||
bigUp := (sma120.Get(0) - sma240.Get(0)) > atrBase*0.7
|
||||
bigDown := !bigUp
|
||||
bigTrendChgCfm := bigTrendChg && sma120.Get(1)-sma240.Get(1) > sma120.Get(2)-sma240.Get(2)
|
||||
slowDown := sma120.Get(0)-sma120.Get(1) < sma120.Get(1)-sma120.Get(2)
|
||||
|
||||
if s.OrderNum > 0 {
|
||||
exitTag := ""
|
||||
if !bigTrendChgCfm && !bigContiUp && c > min(ema60, ema120) && bigDown {
|
||||
exitTag = "exit1"
|
||||
} else if !bigTrendChgCfm && !bigContiUp && c > ema120 && (rsiMa > 75 || c > sma240.Get(0)) && bigDown {
|
||||
exitTag = "exit2"
|
||||
} else if !bigTrendChgCfm && c > ema120 && adx > 30 && rsiMa >= 80 && bigUp {
|
||||
exitTag = "exit3"
|
||||
} else if bigTrendChgCfm && !bigContiUp && slowDown && rsiMa >= 75 {
|
||||
exitTag = "exit4"
|
||||
} else if bigTrendChgCfm && minusDi.Get(0) < plusDi.Get(0) && c > ema60 {
|
||||
exitTag = "exit5"
|
||||
}
|
||||
for _, od := range s.LongOrders {
|
||||
profit := (c - od.InitPrice) / atrBase
|
||||
if profit <= 3 && exitTag != "" {
|
||||
s.CloseOrders(&strat.ExitReq{Tag: exitTag, OrderID: od.ID})
|
||||
continue
|
||||
}
|
||||
sl := od.GetStopLoss()
|
||||
var newSl float64
|
||||
if profit > 16 {
|
||||
newSl = c - atrBase*8
|
||||
} else if profit > 3 {
|
||||
newSl = od.InitPrice + atrBase*profit*0.5
|
||||
}
|
||||
if newSl > sl.Price {
|
||||
sl.Price = newSl
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tag := ""
|
||||
if c < min(ema120, ema60) && minDiOk && rsiOk {
|
||||
if !bigTrendChg && !bigContiUp && adx > 25 && bigDown && rsiMa <= 20 {
|
||||
tag = "buy1"
|
||||
} else if !bigTrendChg && bigContiUp && adx > 30 && bigDown && rsiMa <= 20 {
|
||||
tag = "buy2"
|
||||
} else if !bigContiUp && adx > 35 && bigUp && rsiMa <= 20 {
|
||||
tag = "buy3"
|
||||
} else if bigContiUp && adx > 30 && bigUp && rsiMa <= 25 {
|
||||
tag = "buy4"
|
||||
}
|
||||
}
|
||||
|
||||
if tag != "" && s.OrderNum == 0 {
|
||||
s.OpenOrder(&strat.EnterReq{
|
||||
Tag: tag,
|
||||
StopLossVal: atrBase * 16,
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
81
org/ft/Cenderawasih.go
Normal file
81
org/ft/Cenderawasih.go
Normal file
@@ -0,0 +1,81 @@
|
||||
package ft
|
||||
|
||||
import (
|
||||
"github.com/banbox/banbot/config"
|
||||
"github.com/banbox/banbot/core"
|
||||
"github.com/banbox/banbot/strat"
|
||||
ta "github.com/banbox/banta"
|
||||
)
|
||||
|
||||
func CenderaWasih3(pol *config.RunPolicyConfig) *strat.TradeStrat {
|
||||
// 超参数解析
|
||||
hmaLen := int(pol.Def("hmaLen", 42, core.PNorm(5, 100)))
|
||||
hmaOffRate := pol.Def("hmaOffRate", 20, core.PNorm(2, 80))
|
||||
|
||||
zemaLen := int(pol.Def("zemaLen", 93, core.PNorm(5, 100)))
|
||||
zemaHighRate := pol.Def("zemaHighRate", 18, core.PNorm(1, 30))
|
||||
zemaLowRate := pol.Def("zemaLowRate", 24, core.PNorm(2, 50))
|
||||
|
||||
emaShortLen1 := int(pol.Def("emaShort1", 31, core.PNorm(5, 100)))
|
||||
emaHighRate1 := pol.Def("emaHigh1", 0.0, core.PNorm(0, 30))
|
||||
emaShortLen2 := int(pol.Def("emaShort2", 91, core.PNorm(5, 100)))
|
||||
emaHighRate2 := pol.Def("emaHigh2", 22.5, core.PNorm(0, 40))
|
||||
emaShortLenL1 := int(pol.Def("emaShortL1", 87, core.PNorm(5, 100)))
|
||||
emaLowRate1 := pol.Def("emaLow1", 32, core.PNorm(2, 60))
|
||||
emaShortLenL2 := int(pol.Def("emaShortL2", 98, core.PNorm(5, 100)))
|
||||
emaLowRate2 := pol.Def("emaLow2", 6, core.PNorm(2, 60))
|
||||
|
||||
lenAtr := 29
|
||||
baseAtrLen := int(float64(lenAtr) * 4.3)
|
||||
return &strat.TradeStrat{
|
||||
WarmupNum: 200,
|
||||
OnBar: func(s *strat.StratJob) {
|
||||
e := s.Env
|
||||
c := e.Close.Get(0)
|
||||
atr := ta.ATR(e.High, e.Low, e.Close, lenAtr)
|
||||
atrBase := ta.Lowest(ta.Highest(atr, lenAtr), baseAtrLen).Get(0)
|
||||
|
||||
hmaLow := ta.HMA(e.Close, hmaLen).Get(0) - atrBase*hmaOffRate
|
||||
|
||||
// 计算ZEMA指标
|
||||
ema1 := ta.EMA(e.Close, zemaLen)
|
||||
ema2 := ta.EMA(ema1, zemaLen)
|
||||
zema := ema1.Add(ema1.Sub(ema2)).Get(0)
|
||||
|
||||
// 计算ZEMA偏移量
|
||||
zemaHigh, zemaLow := zema+atrBase*zemaHighRate, zema-atrBase*zemaLowRate
|
||||
|
||||
emaHigh1 := ta.EMA(e.Close, emaShortLen1).Get(0) + atrBase*emaHighRate1
|
||||
emaHigh2 := ta.EMA(e.Close, emaShortLen2).Get(0) + atrBase*emaHighRate2
|
||||
emaLow1 := ta.EMA(e.Close, emaShortLenL1).Get(0) - atrBase*emaLowRate1
|
||||
emaLow2 := ta.EMA(e.Close, emaShortLenL2).Get(0) - atrBase*emaLowRate2
|
||||
|
||||
// 买入条件
|
||||
if c < hmaLow && s.OrderNum == 0 {
|
||||
s.OpenOrder(&strat.EnterReq{
|
||||
Tag: "buy",
|
||||
})
|
||||
}
|
||||
|
||||
exitTag := ""
|
||||
if c > zemaHigh {
|
||||
exitTag = "zemaHigh"
|
||||
} else if c < zemaLow {
|
||||
exitTag = "zemaLow"
|
||||
} else if c > emaHigh1 {
|
||||
exitTag = "emaH1"
|
||||
} else if c > emaHigh2 {
|
||||
exitTag = "emaH2"
|
||||
} else if c < emaLow1 {
|
||||
exitTag = "emaL1"
|
||||
} else if c < emaLow2 {
|
||||
exitTag = "emaL2"
|
||||
}
|
||||
if exitTag != "" {
|
||||
s.CloseOrders(&strat.ExitReq{
|
||||
Tag: exitTag,
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
108
org/ft/Clucha.go
Normal file
108
org/ft/Clucha.go
Normal file
@@ -0,0 +1,108 @@
|
||||
package ft
|
||||
|
||||
import (
|
||||
"github.com/banbox/banbot/config"
|
||||
"github.com/banbox/banbot/core"
|
||||
"github.com/banbox/banbot/strat"
|
||||
ta "github.com/banbox/banta"
|
||||
"math"
|
||||
)
|
||||
|
||||
/*
|
||||
https://strat.ninja/overview.php?strategy=ch
|
||||
48个品种 210101-241101 289% 回撤14%
|
||||
整体盈利,中间部分不稳定回撤
|
||||
*/
|
||||
|
||||
type CSSta struct {
|
||||
ROC1h float64
|
||||
}
|
||||
|
||||
func Clucha(pol *config.RunPolicyConfig) *strat.TradeStrat {
|
||||
BbdeltaClose := pol.Def("BbdeltaClose", 3.5, core.PNorm(2, 10))
|
||||
BbdeltaTail := pol.Def("BbdeltaTail", 0.72235, core.PNorm(0.7, 1.2))
|
||||
CloseBblower := pol.Def("CloseBblower", 2.3, core.PNorm(0.2, 10))
|
||||
ClosedeltaClose := pol.Def("ClosedeltaClose", 1.8, core.PNorm(0.2, 10))
|
||||
Rocr1h := pol.Def("Rocr1h", 0.79492, core.PNorm(0.1, 1.0))
|
||||
sellFastx := pol.Def("sellFastx", 75, core.PUniform(50, 100))
|
||||
sellDeadfishBbWidth := pol.Def("sellDeadfishBbWidth", 10, core.PUniform(6, 100))
|
||||
lenAtr := 29
|
||||
baseAtrLen := int(float64(lenAtr) * 4.3)
|
||||
return &strat.TradeStrat{
|
||||
WarmupNum: 50,
|
||||
EachMaxLong: 1, // 每个品种最多开1单
|
||||
OnPairInfos: func(s *strat.StratJob) []*strat.PairSub {
|
||||
return []*strat.PairSub{
|
||||
{"_cur_", "1h", 200},
|
||||
}
|
||||
},
|
||||
OnStartUp: func(s *strat.StratJob) {
|
||||
s.More = &CSSta{}
|
||||
},
|
||||
OnBar: func(s *strat.StratJob) {
|
||||
e := s.Env
|
||||
m, _ := s.More.(*CSSta)
|
||||
c := e.Close.Get(0)
|
||||
atr := ta.ATR(e.High, e.Low, e.Close, lenAtr)
|
||||
atrBase := ta.Lowest(ta.Highest(atr, lenAtr), baseAtrLen).Get(0)
|
||||
|
||||
// 计算指标
|
||||
_, haHigh, haLow, haClose := ta.HeikinAshi(e)
|
||||
hahlc3 := ta.HLC3(haHigh, haLow, haClose)
|
||||
|
||||
_, mid, lower := ta.BBANDS(hahlc3, 40, 2, 2)
|
||||
bbdelta := mid.Get(0) - lower.Get(0)
|
||||
closedelta := math.Abs(haClose.Get(0) - haClose.Get(1))
|
||||
tail := math.Abs(haClose.Get(0) - haLow.Get(0))
|
||||
emaSlow := ta.EMA(haClose, 50).Get(0)
|
||||
|
||||
hlc3 := ta.HLC3(e.High, e.Low, e.Close)
|
||||
bb20Up, bb20Md, bb20Dn := ta.BBANDS(hlc3, 20, 2, 2)
|
||||
bb20Wid := (bb20Up.Get(0) - bb20Dn.Get(0)) / atrBase
|
||||
bb20Mid := bb20Md.Get(0)
|
||||
|
||||
fastK := ta.Stoch(e.High, e.Low, e.Close, 5).Get(0)
|
||||
|
||||
volMa12 := ta.SMA(e.Volume, 12).Get(1)
|
||||
volMa24 := ta.SMA(e.Volume, 24).Get(1)
|
||||
|
||||
// 买入条件
|
||||
isEwo := m.ROC1h > Rocr1h &&
|
||||
((lower.Get(1) > 0 &&
|
||||
bbdelta > atrBase*BbdeltaClose &&
|
||||
closedelta > atrBase*ClosedeltaClose &&
|
||||
tail < bbdelta*BbdeltaTail &&
|
||||
haClose.Get(0) < lower.Get(1) &&
|
||||
haClose.Get(0) <= haClose.Get(1)) ||
|
||||
(haClose.Get(0) < emaSlow && haClose.Get(0) < lower.Get(0)-CloseBblower*atrBase))
|
||||
|
||||
if isEwo && s.OrderNum == 0 {
|
||||
s.OpenOrder(&strat.EnterReq{Tag: "buy_ewo"})
|
||||
}
|
||||
|
||||
// 自定义卖出逻辑
|
||||
for _, od := range s.LongOrders {
|
||||
holdNum := e.BarCount(od.EnterAt)
|
||||
profit := (c - od.InitPrice) / atrBase
|
||||
exitTag := ""
|
||||
if profit > 0 && fastK > sellFastx {
|
||||
exitTag = "fastx"
|
||||
} else if holdNum > 11.5 && profit > -2 && fastK > sellFastx {
|
||||
exitTag = "kalah"
|
||||
} else if holdNum > 288 && profit > -10 && fastK > sellFastx {
|
||||
exitTag = "lama"
|
||||
} else if profit < -10 && bb20Wid < sellDeadfishBbWidth && c > bb20Mid && volMa12 < volMa24 {
|
||||
exitTag = "deadfish"
|
||||
}
|
||||
if exitTag != "" {
|
||||
s.CloseOrders(&strat.ExitReq{OrderID: od.ID, Tag: exitTag})
|
||||
}
|
||||
}
|
||||
},
|
||||
OnInfoBar: func(s *strat.StratJob, e *ta.BarEnv, pair, tf string) {
|
||||
m, _ := s.More.(*CSSta)
|
||||
_, _, _, haClose := ta.HeikinAshi(e)
|
||||
m.ROC1h = ta.ROC(haClose, 168).Get(0)
|
||||
},
|
||||
}
|
||||
}
|
||||
79
org/ft/HPSV7.go
Normal file
79
org/ft/HPSV7.go
Normal file
@@ -0,0 +1,79 @@
|
||||
package ft
|
||||
|
||||
import (
|
||||
"github.com/banbox/banbot/config"
|
||||
"github.com/banbox/banbot/core"
|
||||
"github.com/banbox/banbot/strat"
|
||||
ta "github.com/banbox/banta"
|
||||
"math"
|
||||
)
|
||||
|
||||
/*
|
||||
https://github.com/mkajnar/DailyBuyStrategy
|
||||
历史提交中的策略
|
||||
*/
|
||||
|
||||
type hpsState struct {
|
||||
downBar int // 连续下跌的bar数量
|
||||
chg3MA float64 // 间隔3个bar的价格变化率均值
|
||||
}
|
||||
|
||||
func HPSV7Ultra(pol *config.RunPolicyConfig) *strat.TradeStrat {
|
||||
// donchLen := int(pol.Def("donchLen", 23, core.PNorm(5, 50)))
|
||||
rsiThs := pol.Def("rsiThs", 35, core.PNorm(10, 50))
|
||||
cciThs := pol.Def("cciThs", -100, core.PNorm(-200, -10))
|
||||
kickOffThs := -pol.Def("kickOffThs", 10, core.PNorm(1, 30))
|
||||
minRedNum := int(math.Round(pol.Def("minRedNum", 1, core.PNorm(0.7, 5.3))))
|
||||
chgRate1 := pol.Def("chgRate1", 0.3, core.PNorm(0.05, 2))
|
||||
chgRate2 := pol.Def("chgRate2", 2, core.PNorm(0.5, 5))
|
||||
|
||||
lenAtr := int(pol.Def("atr", 29, core.PNorm(7, 40)))
|
||||
baseAtrLen := int(float64(lenAtr) * 4.3)
|
||||
|
||||
chgAlpha := 0.35
|
||||
return &strat.TradeStrat{
|
||||
WarmupNum: 100,
|
||||
OnStartUp: func(s *strat.StratJob) {
|
||||
s.More = &hpsState{}
|
||||
},
|
||||
OnBar: func(s *strat.StratJob) {
|
||||
e := s.Env
|
||||
m, _ := s.More.(*hpsState)
|
||||
cc := e.Close
|
||||
o, c := e.Open.Get(0), e.Close.Get(0)
|
||||
atr := ta.ATR(e.High, e.Low, e.Close, lenAtr)
|
||||
atrBase := ta.Lowest(ta.Highest(atr, lenAtr), baseAtrLen).Get(0)
|
||||
if c < o {
|
||||
m.downBar += 1
|
||||
} else {
|
||||
m.downBar = 0
|
||||
}
|
||||
chg3 := c/cc.Get(3) - 1
|
||||
if !math.IsNaN(chg3) {
|
||||
m.chg3MA = m.chg3MA*(1-chgAlpha) + chg3*chgAlpha
|
||||
}
|
||||
|
||||
rsi := ta.RSI(e.Close, 14).Get(0)
|
||||
cci := ta.CCI(e.Close, 20).Get(0)
|
||||
// swingLow := cc.Get(1) < min(c, cc.Get(2))
|
||||
swingHigh := cc.Get(1) > max(c, cc.Get(2))
|
||||
|
||||
//donUpp := ta.Highest(e.High, donchLen).Get(0)
|
||||
//donLow := ta.Lowest(e.Low, donchLen).Get(0)
|
||||
//donMid := (donUpp + donLow) / 2
|
||||
// 原始策略入场要求close>donMid并记录到字段,但没有close<donMid时改回去的逻辑,实际上未生效
|
||||
|
||||
chg3Rate := m.chg3MA / (atrBase / c)
|
||||
chg3RateAbs := math.Abs(chg3Rate)
|
||||
if swingHigh {
|
||||
s.CloseOrders(&strat.ExitReq{Tag: "swingHigh"})
|
||||
} else if chg3Rate <= kickOffThs {
|
||||
s.CloseOrders(&strat.ExitReq{Tag: "kickOff"})
|
||||
} else if m.downBar >= minRedNum && rsi < rsiThs && cci < cciThs &&
|
||||
chg3RateAbs > chgRate1 && chg3RateAbs < chgRate2 && s.OrderNum == 0 {
|
||||
//(swingLow || c < donLow || c > donMid) &&
|
||||
s.OpenOrder(&strat.EnterReq{Tag: "long"})
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
144
org/ft/MadV9HO.go
Normal file
144
org/ft/MadV9HO.go
Normal file
@@ -0,0 +1,144 @@
|
||||
package ft
|
||||
|
||||
import (
|
||||
"github.com/banbox/banbot/config"
|
||||
"github.com/banbox/banbot/orm/ormo"
|
||||
"github.com/banbox/banbot/strat"
|
||||
ta "github.com/banbox/banta"
|
||||
"math"
|
||||
)
|
||||
|
||||
/*
|
||||
https://strat.ninja/overview.php?strategy=MadV9HO
|
||||
48个品种,210101-241101 收益360% 回撤5.9% 夏普11
|
||||
*/
|
||||
|
||||
type MadV9HOSta struct {
|
||||
bigEma50 float64
|
||||
bigEma200 float64
|
||||
bigRsi float64
|
||||
bigSSLUp float64
|
||||
bigSSLDn float64
|
||||
}
|
||||
|
||||
func MadV9HO(p *config.RunPolicyConfig) *strat.TradeStrat {
|
||||
//bbLowRate1 := p.Def("bbLowRate1", 2, core.PNorm(0.5, 10))
|
||||
//bbLowRate2 := p.Def("bbLowRate2", 3.6, core.PNorm(0.0, 10))
|
||||
lenAtr := 29
|
||||
baseAtrLen := int(float64(lenAtr) * 4.3)
|
||||
return &strat.TradeStrat{
|
||||
WarmupNum: 100,
|
||||
OnPairInfos: func(s *strat.StratJob) []*strat.PairSub {
|
||||
return []*strat.PairSub{
|
||||
{"_cur_", "1h", 200},
|
||||
}
|
||||
},
|
||||
OnStartUp: func(s *strat.StratJob) {
|
||||
s.More = &MadV9HOSta{}
|
||||
},
|
||||
OnBar: func(s *strat.StratJob) {
|
||||
e := s.Env
|
||||
m, _ := s.More.(*MadV9HOSta)
|
||||
o, c := e.Open.Get(0), e.Close.Get(0)
|
||||
atr := ta.ATR(e.High, e.Low, e.Close, lenAtr)
|
||||
atrBase := ta.Lowest(ta.Highest(atr, lenAtr), baseAtrLen).Get(0)
|
||||
|
||||
hlc3 := ta.HLC3(e.High, e.Low, e.Close)
|
||||
bbUpp, bbMid, bbLow := ta.BBANDS(hlc3, 20, 2, 2)
|
||||
|
||||
//volMa := ta.SMA(e.Volume, 30)
|
||||
|
||||
ema12S := ta.EMA(e.Close, 12)
|
||||
ema26S := ta.EMA(e.Close, 26)
|
||||
ema12, ema26 := ema12S.Get(0), ema26S.Get(0)
|
||||
ema12P, ema26P := ema12S.Get(1), ema26S.Get(1)
|
||||
//ema200 := ta.EMA(e.Close, 200).Get(0)
|
||||
//
|
||||
//rsi := ta.RSI(e.Close, 14).Get(0)
|
||||
//sma5 := ta.SMA(e.Close, 5).Get(0)
|
||||
|
||||
tag := ""
|
||||
volOk := e.Volume.Get(0) < e.Volume.Get(1)*8
|
||||
//vol30ok := volMa.Get(0) > volMa.Get(30)*0.5
|
||||
|
||||
_, _, _ = m, o, bbUpp
|
||||
|
||||
if ema26-ema12 > atrBase*6 && ema26P-ema12P > atrBase*2 && c < bbLow.Get(0) && volOk {
|
||||
tag = "buy6"
|
||||
}
|
||||
// 下面的要么不稳定,要么几乎没有订单
|
||||
//if c > max(ema200, m.bigEma200) && c < bbLow.Get(0)-atrBase*bbLowRate1 && vol30ok &&
|
||||
// volOk && o-c < bbUpp.Get(2)-bbLow.Get(2) {
|
||||
// tag = "buy1"
|
||||
//} else if c > ema200 && c < bbLow.Get(0)-atrBase*bbLowRate2 && vol30ok &&
|
||||
// volOk && o-c < bbUpp.Get(2)-bbLow.Get(2) {
|
||||
// // 订单很少,盈利很少
|
||||
// //tag = "buy2"
|
||||
//} else if c > m.bigEma200 && c < bbLow.Get(0) && rsi < 8.5 && volOk {
|
||||
// // 订单很少,盈利很少
|
||||
// //tag = "buy3"
|
||||
//} else if m.bigRsi < 10.3 && c < bbLow.Get(0) && volOk {
|
||||
// // 小额亏损
|
||||
// //tag = "buy4"
|
||||
//} else if c > max(ema200, m.bigEma200) && ema26-ema12 > atrBase*18 && ema26P-ema12P > atrBase*2 &&
|
||||
// c < bbLow.Get(0) && volOk && vol30ok {
|
||||
// tag = "buy5"
|
||||
//} else if m.bigRsi < 13 && ema26-ema12 > atrBase*18 && ema26P-ema12P > atrBase*2 && volOk && vol30ok {
|
||||
// // 订单很少,盈利很少
|
||||
// //tag = "buy7"
|
||||
//} else if m.bigRsi < 12.2 && rsi < 39.6 && volOk && vol30ok {
|
||||
// tag = "buy8"
|
||||
//} else if m.bigRsi < 18 && rsi < 24.2 && volOk && vol30ok {
|
||||
// tag = "buy9"
|
||||
//} else if c < sma5 && m.bigSSLUp > m.bigSSLDn && m.bigEma50 > m.bigEma200 && rsi < m.bigRsi-43.69 {
|
||||
// tag = "buy10"
|
||||
//}
|
||||
|
||||
if tag != "" && s.OrderNum == 0 {
|
||||
s.OpenOrder(&strat.EnterReq{Tag: tag})
|
||||
}
|
||||
|
||||
for _, od := range s.LongOrders {
|
||||
holdNum := int(math.Round(e.BarCount(od.EnterAt)))
|
||||
if holdNum >= 10 && od.ProfitRate < 0 && c+atrBase*3 < e.Open.Get(holdNum) {
|
||||
od.SetStopLoss(&ormo.ExitTrigger{Price: c - atrBase*2})
|
||||
}
|
||||
}
|
||||
|
||||
if s.OrderNum > 0 && c > bbMid.Get(0)+atrBase*2 {
|
||||
s.CloseOrders(&strat.ExitReq{Tag: "sell"})
|
||||
}
|
||||
},
|
||||
OnInfoBar: func(s *strat.StratJob, e *ta.BarEnv, pair, tf string) {
|
||||
m, _ := s.More.(*MadV9HOSta)
|
||||
m.bigEma50 = ta.EMA(e.Close, 50).Get(0)
|
||||
m.bigEma200 = ta.EMA(e.Close, 200).Get(0)
|
||||
m.bigRsi = ta.RSI(e.Close, 14).Get(0)
|
||||
atr := ta.ATR(e.High, e.Low, e.Close, 14).Get(0)
|
||||
smaHigh := ta.SMA(e.High, 20).Get(0) + atr
|
||||
smaLow := ta.SMA(e.Low, 20).Get(0) - atr
|
||||
hlv := e.Close.To("_hlv", 20)
|
||||
sslUp := e.Close.To("_sslUp", 20)
|
||||
sslDn := e.Close.To("_sslDn", 20)
|
||||
c := e.Close.Get(0)
|
||||
if !hlv.Cached() {
|
||||
if c > smaHigh {
|
||||
hlv.Append(1)
|
||||
} else if c < smaLow {
|
||||
hlv.Append(-1)
|
||||
} else {
|
||||
hlv.Append(hlv.Get(0))
|
||||
}
|
||||
if hlv.Get(0) < 0 {
|
||||
sslUp.Append(smaLow)
|
||||
sslDn.Append(smaHigh)
|
||||
} else {
|
||||
sslUp.Append(smaHigh)
|
||||
sslDn.Append(smaLow)
|
||||
}
|
||||
}
|
||||
m.bigSSLUp = sslUp.Get(0)
|
||||
m.bigSSLDn = sslDn.Get(0)
|
||||
},
|
||||
}
|
||||
}
|
||||
69
org/ft/SMAOG.go
Normal file
69
org/ft/SMAOG.go
Normal file
@@ -0,0 +1,69 @@
|
||||
package ft
|
||||
|
||||
import (
|
||||
"github.com/banbox/banbot/config"
|
||||
"github.com/banbox/banbot/core"
|
||||
"github.com/banbox/banbot/orm/ormo"
|
||||
"github.com/banbox/banbot/strat"
|
||||
ta "github.com/banbox/banta"
|
||||
)
|
||||
|
||||
type maogState struct {
|
||||
atrBase float64
|
||||
}
|
||||
|
||||
func SMAOG(pol *config.RunPolicyConfig) *strat.TradeStrat {
|
||||
longRate := pol.Def("longRate", 3.03, core.PNorm(1.5, 6))
|
||||
shortRate := pol.Def("shortRate", 1.03, core.PNorm(0.5, 4))
|
||||
|
||||
lls2 := pol.Def("lls2", 4, core.PNorm(0, 10))
|
||||
lls12 := pol.Def("lls12", 6, core.PNorm(2, 15))
|
||||
lls144 := pol.Def("lls144", 16, core.PNorm(4, 30))
|
||||
|
||||
lenAtr := int(pol.Def("atr", 20, core.PNorm(7, 40)))
|
||||
baseAtrLen := int(float64(lenAtr) * 4.3)
|
||||
return &strat.TradeStrat{
|
||||
WarmupNum: 200,
|
||||
DrawDownExit: true,
|
||||
OnStartUp: func(s *strat.StratJob) {
|
||||
s.More = &maogState{}
|
||||
},
|
||||
OnBar: func(s *strat.StratJob) {
|
||||
e := s.Env
|
||||
m, _ := s.More.(*maogState)
|
||||
c := e.Close.Get(0)
|
||||
oo := e.Open
|
||||
atr := ta.ATR(e.High, e.Low, e.Close, lenAtr)
|
||||
atrBase := ta.Lowest(ta.Highest(atr, lenAtr), baseAtrLen).Get(0)
|
||||
m.atrBase = atrBase
|
||||
|
||||
maBuy := ta.SMA(e.Close, 26).Get(0)
|
||||
maSell := ta.EMA(e.Close, 28).Get(0)
|
||||
badLL2 := ta.Lowest(e.Open, 2).Get(0)-c > atrBase*lls2
|
||||
badLL12 := ta.Lowest(e.Open, 12).Get(0)-c > atrBase*lls12
|
||||
badLL144 := ta.Lowest(e.Open, 144).Get(0)-c > atrBase*lls144
|
||||
pairBad := badLL2 || badLL12 || badLL144
|
||||
|
||||
ema50 := ta.EMA(e.Close, 50).Get(0)
|
||||
ema200 := ta.EMA(e.Close, 200).Get(0)
|
||||
rsiExit := ta.RSI(e.Close, 2)
|
||||
|
||||
if maSell-c < atrBase*shortRate {
|
||||
if oo.Get(0) < oo.Get(1) || rsiExit.Get(0) < 50 || rsiExit.Get(0) < rsiExit.Get(1) {
|
||||
s.CloseOrders(&strat.ExitReq{Tag: "short"})
|
||||
return
|
||||
}
|
||||
}
|
||||
if ema50 > ema200 && c > ema200 && !pairBad && maBuy-c > atrBase*longRate && s.OrderNum == 0 {
|
||||
s.OpenOrder(&strat.EnterReq{Tag: "long", StopLossVal: atrBase * 15})
|
||||
}
|
||||
},
|
||||
GetDrawDownExitRate: func(s *strat.StratJob, od *ormo.InOutOrder, maxChg float64) float64 {
|
||||
m, _ := s.More.(*maogState)
|
||||
if maxChg/(m.atrBase/od.InitPrice) > 2 {
|
||||
return 0.35
|
||||
}
|
||||
return 0
|
||||
},
|
||||
}
|
||||
}
|
||||
47
org/ft/Synthesis.go
Normal file
47
org/ft/Synthesis.go
Normal file
@@ -0,0 +1,47 @@
|
||||
package ft
|
||||
|
||||
import (
|
||||
"github.com/banbox/banbot/config"
|
||||
"github.com/banbox/banbot/core"
|
||||
"github.com/banbox/banbot/strat"
|
||||
ta "github.com/banbox/banta"
|
||||
)
|
||||
|
||||
/*
|
||||
https://strat.ninja/overview.php?strategy=Money
|
||||
过于简单,无法盈利,针对1h周期
|
||||
*/
|
||||
|
||||
func Synthesis(pol *config.RunPolicyConfig) *strat.TradeStrat {
|
||||
buyRSI := pol.Def("buy_rsi", 30, core.PNorm(20, 40))
|
||||
sellRSI := pol.Def("sell_rsi", 70, core.PNorm(60, 80))
|
||||
buyEmaShort := int(pol.Def("buy_ema_short", 10, core.PNorm(5, 15)))
|
||||
buyEmaLong := int(pol.Def("buy_ema_long", 50, core.PNorm(20, 60)))
|
||||
|
||||
return &strat.TradeStrat{
|
||||
WarmupNum: 100,
|
||||
EachMaxLong: 1,
|
||||
EachMaxShort: 1,
|
||||
OnBar: func(s *strat.StratJob) {
|
||||
e := s.Env
|
||||
// 计算指标
|
||||
rsi := ta.RSI(e.Close, 14)
|
||||
emaShort := ta.EMA(e.Close, buyEmaShort)
|
||||
emaLong := ta.EMA(e.Close, buyEmaLong)
|
||||
|
||||
// 买入条件:RSI低于买入阈值且短期EMA高于长期EMA
|
||||
if rsi.Get(0) < buyRSI && emaShort.Get(0) > emaLong.Get(0) && s.OrderNum == 0 {
|
||||
s.OpenOrder(&strat.EnterReq{
|
||||
Tag: "long",
|
||||
})
|
||||
}
|
||||
|
||||
// 卖出条件:RSI高于卖出阈值且短期EMA低于长期EMA
|
||||
if rsi.Get(0) > sellRSI && emaShort.Get(0) < emaLong.Get(0) {
|
||||
s.CloseOrders(&strat.ExitReq{
|
||||
Tag: "short",
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
64
org/ft/bbrsitv.go
Normal file
64
org/ft/bbrsitv.go
Normal file
@@ -0,0 +1,64 @@
|
||||
package ft
|
||||
|
||||
import (
|
||||
"github.com/banbox/banbot/config"
|
||||
"github.com/banbox/banbot/core"
|
||||
"github.com/banbox/banbot/strat"
|
||||
ta "github.com/banbox/banta"
|
||||
)
|
||||
|
||||
/*
|
||||
https://github.com/jilv220/freqtrade-stuff/BBRSITV.py
|
||||
|
||||
滚动优化:bt_opt -review-period 18M -run-period 2M -opt-rounds 20
|
||||
bt_opt_2d11bb5607 最近两年半40%收益,回撤37%;不稳定。
|
||||
|
||||
5m,80品种,3年531%,中间不够稳定,待优化
|
||||
15m, 80品种,3年553%,中间略不稳定,两次半年回撤,待优化
|
||||
1h,80品种,3年278%,回撤49%,熊市时回撤较大
|
||||
*/
|
||||
|
||||
func BBRSITV(pol *config.RunPolicyConfig) *strat.TradeStrat {
|
||||
ewoRate := pol.Def("ewoRate", 1.0, core.PNorm(0.1, 3))
|
||||
ewoHigh := 5 * ewoRate
|
||||
|
||||
maLen := int(pol.Def("maLen", 22, core.PNorm(5, 80)))
|
||||
maLenS := int(pol.Def("maLenS", 65, core.PNorm(5, 80)))
|
||||
rsiSigma := pol.Def("rsiSigma", 1.74, core.PNorm(0, 6))
|
||||
rsiSigmaS := pol.Def("rsiSigmaS", 1.9, core.PNorm(0, 6))
|
||||
rsiHigh := pol.Def("rsiHigh", 72, core.PNorm(60, 100))
|
||||
|
||||
lenAtr := int(pol.Def("atr", 20, core.PNorm(7, 40)))
|
||||
baseAtrLen := int(float64(lenAtr) * 4.3)
|
||||
return &strat.TradeStrat{
|
||||
WarmupNum: 200,
|
||||
EachMaxLong: 1,
|
||||
OnBar: func(s *strat.StratJob) {
|
||||
e := s.Env
|
||||
//c := e.Close.Get(0)
|
||||
atr := ta.ATR(e.High, e.Low, e.Close, lenAtr)
|
||||
atrBase := ta.Lowest(ta.Highest(atr, lenAtr), baseAtrLen).Get(0)
|
||||
|
||||
rsi := ta.RSI(e.Close, 14)
|
||||
rsiV := rsi.Get(0)
|
||||
//rsi4 := ta.RSI(e.Close, 4).Get(0)
|
||||
basisBuy := ta.EMA(rsi, maLen).Get(0)
|
||||
basisSell := ta.EMA(rsi, maLenS).Get(0)
|
||||
|
||||
devBuy := ta.StdDev(rsi, maLen)
|
||||
devSell := ta.StdDev(rsi, maLenS)
|
||||
|
||||
ema1 := ta.EMA(e.Close, 50).Get(0)
|
||||
ema2 := ta.EMA(e.Close, 200).Get(0)
|
||||
ewo := (ema1 - ema2) / atrBase
|
||||
|
||||
if rsiV > rsiHigh || rsiV > basisSell+devSell.Get(0)*rsiSigmaS {
|
||||
s.CloseOrders(&strat.ExitReq{Tag: "exit"})
|
||||
return
|
||||
}
|
||||
if rsiV < basisBuy-devBuy.Get(0)*rsiSigma && ewo > ewoHigh && s.OrderNum == 0 {
|
||||
s.OpenOrder(&strat.EnterReq{Tag: "long", StopLossVal: atrBase * 20})
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
245
org/ft/bin_ha_cluc_v8.go
Normal file
245
org/ft/bin_ha_cluc_v8.go
Normal file
@@ -0,0 +1,245 @@
|
||||
package ft
|
||||
|
||||
import (
|
||||
"github.com/banbox/banbot/config"
|
||||
"github.com/banbox/banbot/core"
|
||||
"github.com/banbox/banbot/orm/ormo"
|
||||
"github.com/banbox/banbot/strat"
|
||||
ta "github.com/banbox/banta"
|
||||
"math"
|
||||
)
|
||||
|
||||
/*
|
||||
|
||||
https://github.com/zmomz/freq_strategies/blob/f25f8493ebab589e327cd011b829d1c64cafae84/strategies/CombinedBinHAndClucV8Hyper.py#L53
|
||||
|
||||
滚动回测 bt_opt -review-period 18M -run-period 2M -opt-rounds 20
|
||||
bt_opt_d0c194932b 2年半收益61%,回撤14%;最近三四个月亏损
|
||||
*/
|
||||
|
||||
type haClucState struct {
|
||||
sma200Dec bool
|
||||
rsi float64
|
||||
atrBase float64
|
||||
|
||||
bigMa50 float64
|
||||
bigMa100 float64
|
||||
bigEMA200 float64
|
||||
bigSMA200 float64
|
||||
bigSma200Dec bool //bigSMA200是否低于20小时前的值
|
||||
bigRsi float64
|
||||
|
||||
bigHlv float64 // 大周期市场趋势
|
||||
sslDown float64
|
||||
sslUp float64
|
||||
}
|
||||
|
||||
func CombinedBinHAndClucV8Hyper(pol *config.RunPolicyConfig) *strat.TradeStrat {
|
||||
BuyThs1 := pol.Def("BuyThs1", 0.15, core.PNorm(0.05, 0.3))
|
||||
BuyThs2 := pol.Def("BuyThs2", 0.49, core.PNorm(0.1, 0.6))
|
||||
BuyThs3 := pol.Def("BuyThs3", 0.24, core.PNorm(0.15, 0.7))
|
||||
bb40BBDeltaClose := pol.Def("bb40BBDeltaClose", 7.4, core.PNorm(5, 30))
|
||||
bb40CloseDeltaClose := pol.Def("bb40CloseDeltaClose", 9, core.PNorm(3, 20))
|
||||
bb40TailBBDelta := pol.Def("bb40TailBBDelta", 0.27, core.PNorm(0.1, 0.5))
|
||||
|
||||
bb20CloseBBLower := pol.Def("bb20CloseBBLower", 0.94, core.PNorm(0.5, 3))
|
||||
bb20Vol := pol.Def("bb20Vol", 20.2, core.PNorm(5, 50))
|
||||
|
||||
rsiDiff := pol.Def("rsiDiff", 53.23, core.PNorm(20, 80))
|
||||
minInc := pol.Def("minInc", 1.2, core.PNorm(0.5, 5))
|
||||
rsi1H := 67.0
|
||||
rsiSml := 38.5
|
||||
mfiThs := 36.0
|
||||
|
||||
vol1 := 2.0
|
||||
emaOpenMult := pol.Def("emaOpenMult", 2.3, core.PNorm(1.5, 5))
|
||||
|
||||
earlyExitRate := pol.Def("earlyExitRate", 1, core.PNorm(-1, 2))
|
||||
earlyExitNum := int(pol.Def("earlyExitNum", 65, core.PNorm(10, 70)))
|
||||
shortRsiMain := pol.Def("shortRsiMain", 80.75, core.PNorm(70, 95))
|
||||
sellRoiProfit1 := pol.Def("sellRoiProfit1", 2, core.PNorm(0.3, 5))
|
||||
sellRoiRsi1 := pol.Def("sellRoiRsi1", 63.4, core.PNorm(40, 64))
|
||||
sellRoiProfit2 := pol.Def("sellRoiProfit2", 3, core.PNorm(1, 7))
|
||||
sellRoiRsi2 := pol.Def("sellRoiRsi2", 63.4, core.PNorm(40, 64))
|
||||
sellRoiProfit3 := pol.Def("sellRoiProfit3", 8, core.PNorm(4, 12))
|
||||
sellRoiRsi3 := pol.Def("sellRoiRsi3", 50.1, core.PNorm(45, 67))
|
||||
sellRoiProfit4 := pol.Def("sellRoiProfit4", 12.4, core.PNorm(7, 18))
|
||||
sellRoiRsi4 := pol.Def("sellRoiRsi4", 55.4, core.PNorm(50, 70))
|
||||
sellRoiProfit5 := pol.Def("sellRoiProfit5", 1, core.PNorm(1, 7))
|
||||
|
||||
trailProfitMin1 := pol.Def("trailProfitMin1", 0.06, core.PNorm(0.03, 0.3))
|
||||
trailProfitMin2 := pol.Def("trailProfitMin2", 0.04, core.PNorm(0.01, 0.1))
|
||||
customSL1 := -pol.Def("customSL1", 2.17, core.PNorm(0.5, 3))
|
||||
|
||||
lenAtr := int(pol.Def("atr", 40, core.PNorm(10, 40)))
|
||||
baseAtrLen := int(float64(lenAtr) * 4.3)
|
||||
|
||||
pol.KeepHyperOnly("earlyExitRate", "earlyExitNum", "sellRoiProfit1", "sellRoiProfit2", "sellRoiProfit3",
|
||||
"sellRoiProfit4", "sellRoiProfit5", "customSL1")
|
||||
|
||||
return &strat.TradeStrat{
|
||||
WarmupNum: 300,
|
||||
DrawDownExit: true,
|
||||
EachMaxLong: 1,
|
||||
OnStartUp: func(s *strat.StratJob) {
|
||||
s.More = &haClucState{}
|
||||
},
|
||||
OnPairInfos: func(s *strat.StratJob) []*strat.PairSub {
|
||||
return []*strat.PairSub{
|
||||
{"_cur_", "1h", 300},
|
||||
}
|
||||
},
|
||||
OnBar: func(s *strat.StratJob) {
|
||||
e := s.Env
|
||||
more, _ := s.More.(*haClucState)
|
||||
atr := ta.ATR(e.High, e.Low, e.Close, lenAtr)
|
||||
atrBase := ta.Lowest(ta.Highest(atr, lenAtr), baseAtrLen).Get(0)
|
||||
more.atrBase = atrBase
|
||||
|
||||
o, l, c, v := e.Open.Get(0), e.Low.Get(0), e.Close.Get(0), e.Volume.Get(0)
|
||||
c1, c2 := e.Close.Get(1), e.Close.Get(2)
|
||||
_, bbMidC, bbLowCol := ta.BBANDS(e.Close, 40, 2, 2)
|
||||
bbLow, bbMid := bbLowCol.Get(0), bbMidC.Get(0)
|
||||
bbDelta := math.Abs(bbMid - bbLow)
|
||||
closeDelta := math.Abs(c - e.Close.Get(1))
|
||||
tail := math.Abs(c - l)
|
||||
|
||||
avgPrice := ta.AvgPrice(e)
|
||||
bb20UppC, _, bb20Dn := ta.BBANDS(avgPrice, 20, 2, 2)
|
||||
bb20Upp, bb20Low := bb20UppC.Get(0), bb20Dn.Get(0)
|
||||
|
||||
volSlow1 := ta.SMA(e.Volume, 30).Get(1)
|
||||
volMa4 := ta.SMA(e.Volume, 4).Get(0)
|
||||
|
||||
ema12C, ema26C := ta.EMA(e.Close, 12), ta.EMA(e.Close, 26)
|
||||
ema12 := ema12C.Get(0)
|
||||
ema26 := ema26C.Get(0)
|
||||
ema50 := ta.EMA(e.Close, 50).Get(0)
|
||||
ema200 := ta.EMA(e.Close, 200).Get(0)
|
||||
|
||||
sma5 := ta.SMA(e.Close, 5).Get(0)
|
||||
sma200 := ta.SMA(e.Close, 200)
|
||||
sma200V := sma200.Get(0)
|
||||
|
||||
sma200Dec := sma200V < sma200.Get(20)
|
||||
more.sma200Dec = sma200Dec
|
||||
|
||||
mfi := ta.MFI(e, 14).Get(0)
|
||||
rsi := ta.RSI(e.Close, 14).Get(0)
|
||||
more.rsi = rsi
|
||||
|
||||
openHH2 := ta.Highest(e.Open, 2).Get(0)
|
||||
openHH12 := ta.Highest(e.Open, 12).Get(0)
|
||||
openHH144 := ta.Highest(e.Open, 144).Get(0)
|
||||
openLL24 := ta.Lowest(e.Open, 24).Get(0)
|
||||
|
||||
if c > bb20Upp && c1 > bb20UppC.Get(1) && c2 > bb20UppC.Get(2) {
|
||||
s.CloseOrders(&strat.ExitReq{Tag: "exit1", Dirt: core.OdDirtLong})
|
||||
return
|
||||
}
|
||||
if rsi > shortRsiMain {
|
||||
s.CloseOrders(&strat.ExitReq{Tag: "exit2", Dirt: core.OdDirtLong})
|
||||
return
|
||||
}
|
||||
|
||||
if (openHH2-c)/c < BuyThs1 && (openHH12-c)/c < BuyThs2 {
|
||||
if c > more.bigEMA200 && ema50 > ema200 && more.bigMa50 > more.bigEMA200 {
|
||||
if bbDelta > atrBase*bb40BBDeltaClose && closeDelta > atrBase*bb40CloseDeltaClose &&
|
||||
tail < bbDelta*bb40TailBBDelta && c < bbLowCol.Get(1) && c <= e.Close.Get(1) {
|
||||
s.OpenOrder(&strat.EnterReq{Tag: "long1"})
|
||||
return
|
||||
}
|
||||
}
|
||||
if c > more.bigEMA200 && c > ema200 && more.bigMa50 > max(more.bigMa100, more.bigEMA200) {
|
||||
if c < ema50 && (bb20Low-c) > atrBase*bb20CloseBBLower && v < volSlow1*bb20Vol {
|
||||
s.OpenOrder(&strat.EnterReq{Tag: "long2"})
|
||||
return
|
||||
}
|
||||
}
|
||||
if c < sma5 && more.sslUp > more.sslDown && ema50 > ema200 && more.bigMa50 > more.bigEMA200 {
|
||||
if (openHH144-c)/c < BuyThs3 && rsi < more.bigRsi-rsiDiff {
|
||||
s.OpenOrder(&strat.EnterReq{Tag: "long3"})
|
||||
return
|
||||
}
|
||||
}
|
||||
if !sma200Dec && !more.bigSma200Dec && (openHH144-c)/c < BuyThs3 && (openLL24-c)/c > atrBase*minInc {
|
||||
if more.bigRsi > rsi1H && rsi < rsiSml && mfi < mfiThs {
|
||||
s.OpenOrder(&strat.EnterReq{Tag: "long4"})
|
||||
return
|
||||
}
|
||||
}
|
||||
if c > more.bigMa100 && more.bigMa50 > more.bigMa100 && (openHH144-c)/c < BuyThs3 && volMa4*vol1 > v {
|
||||
if ema26 > ema12 && ema26-ema12 > atrBase*emaOpenMult {
|
||||
if ema26C.Get(1)-ema12C.Get(1) > o/100 && c < bb20Low {
|
||||
s.OpenOrder(&strat.EnterReq{Tag: "long5"})
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
OnInfoBar: func(s *strat.StratJob, e *ta.BarEnv, pair, tf string) {
|
||||
more, _ := s.More.(*haClucState)
|
||||
more.bigMa50 = ta.EMA(e.Close, 50).Get(0)
|
||||
more.bigMa100 = ta.EMA(e.Close, 100).Get(0)
|
||||
more.bigEMA200 = ta.EMA(e.Close, 200).Get(0)
|
||||
sma200 := ta.SMA(e.Close, 200)
|
||||
more.bigSMA200 = sma200.Get(0)
|
||||
more.bigSma200Dec = more.bigSMA200 < sma200.Get(20)
|
||||
more.bigRsi = ta.RSI(e.Close, 14).Get(0)
|
||||
|
||||
length := 20
|
||||
atr := ta.ATR(e.High, e.Low, e.Close, 14).Get(0)
|
||||
maHigh := ta.SMA(e.High, length).Get(0) + atr
|
||||
maLow := ta.SMA(e.Low, length).Get(0) - atr
|
||||
c := e.Close.Get(0)
|
||||
if c > maHigh {
|
||||
more.bigHlv = 1
|
||||
} else if c < maLow {
|
||||
more.bigHlv = -1
|
||||
}
|
||||
if more.bigHlv < 0 {
|
||||
more.sslDown = maHigh
|
||||
more.sslUp = maLow
|
||||
} else {
|
||||
more.sslDown = maLow
|
||||
more.sslUp = maHigh
|
||||
}
|
||||
},
|
||||
OnCheckExit: func(s *strat.StratJob, od *ormo.InOutOrder) *strat.ExitReq {
|
||||
more, _ := s.More.(*haClucState)
|
||||
holdNum := int((s.Env.TimeStop - od.RealEnterMS()) / s.Env.TFMSecs)
|
||||
// 计算相对利润率,1%利润对应均值大概为1
|
||||
profitRate := od.ProfitRate / od.Leverage / (more.atrBase / od.InitPrice)
|
||||
if holdNum >= earlyExitNum && profitRate < earlyExitRate {
|
||||
od.SetStopLoss(&ormo.ExitTrigger{Price: s.Env.Close.Get(0) - more.atrBase*0.65})
|
||||
} else if profitRate < customSL1 && more.sma200Dec && more.bigSma200Dec {
|
||||
return &strat.ExitReq{Tag: "sl2"}
|
||||
}
|
||||
if profitRate > sellRoiProfit4 && more.rsi < sellRoiRsi4 {
|
||||
return &strat.ExitReq{Tag: "roi4"}
|
||||
}
|
||||
if profitRate > sellRoiProfit3 && more.rsi < sellRoiRsi3 {
|
||||
return &strat.ExitReq{Tag: "roi3"}
|
||||
}
|
||||
if profitRate > sellRoiProfit2 && more.rsi < sellRoiRsi2 {
|
||||
return &strat.ExitReq{Tag: "roi2"}
|
||||
}
|
||||
if profitRate > sellRoiProfit1 && more.rsi < sellRoiRsi1 {
|
||||
return &strat.ExitReq{Tag: "roi1"}
|
||||
}
|
||||
if profitRate > 0 && profitRate < sellRoiProfit5 && more.sma200Dec {
|
||||
return &strat.ExitReq{Tag: "roi5"}
|
||||
}
|
||||
return nil
|
||||
},
|
||||
GetDrawDownExitRate: func(s *strat.StratJob, od *ormo.InOutOrder, maxChg float64) float64 {
|
||||
if maxChg > trailProfitMin1 {
|
||||
return 0.3
|
||||
} else if maxChg > trailProfitMin2 {
|
||||
return 0.7
|
||||
}
|
||||
return 0
|
||||
},
|
||||
}
|
||||
}
|
||||
97
org/ft/binance.go
Normal file
97
org/ft/binance.go
Normal file
@@ -0,0 +1,97 @@
|
||||
package ft
|
||||
|
||||
import (
|
||||
"github.com/banbox/banbot/config"
|
||||
"github.com/banbox/banbot/orm/ormo"
|
||||
"github.com/banbox/banbot/strat"
|
||||
ta "github.com/banbox/banta"
|
||||
)
|
||||
|
||||
/*
|
||||
https://strat.ninja/overview.php?strategy=binance
|
||||
210101-241101 48品种,收益159% 回撤5% 夏普10.25
|
||||
|
||||
*/
|
||||
|
||||
func binance(pol *config.RunPolicyConfig) *strat.TradeStrat {
|
||||
//ewoRate := pol.Def("ewoRate", 1.0, core.PNorm(0.1, 3))
|
||||
//ewoHigh := -2.7 * ewoRate
|
||||
//lowRate := pol.Def("lowRate", 8.6, core.PNorm(1, 3.5))
|
||||
//highRate := pol.Def("highRate", 2.7, core.PNorm(0.5, 2.5))
|
||||
//rsiLong := pol.Def("rsiLong", 30, core.PNorm(20, 65))
|
||||
//maLongF := pol.Def("maLong", 8, core.PNorm(8, 16))
|
||||
//maLong := int(math.Round(maLongF))
|
||||
//maRate := pol.Def("maRate", 2, core.PNorm(1.5, 3))
|
||||
//maShort := int(math.Round(maLongF * maRate))
|
||||
lenAtr := 29
|
||||
baseAtrLen := int(float64(lenAtr) * 4.3)
|
||||
return &strat.TradeStrat{
|
||||
WarmupNum: 100,
|
||||
EachMaxLong: 1,
|
||||
OnBar: func(s *strat.StratJob) {
|
||||
e := s.Env
|
||||
c := e.Close.Get(0)
|
||||
atr := ta.ATR(e.High, e.Low, e.Close, lenAtr)
|
||||
atrBase := ta.Lowest(ta.Highest(atr, lenAtr), baseAtrLen).Get(0)
|
||||
|
||||
//emaLong := ta.EMA(e.Close, maLong).Get(0)
|
||||
//emaShort := ta.EMA(e.Close, maShort).Get(0)
|
||||
|
||||
sma15 := ta.SMA(e.Close, 15).Get(0)
|
||||
cti := ta.CTI(e.Close, 20).Get(0)
|
||||
|
||||
//ema1 := ta.EMA(e.Close, 50).Get(0)
|
||||
//ema2 := ta.EMA(e.Close, 200).Get(0)
|
||||
//ewo := (ema1 - ema2) / atrBase
|
||||
|
||||
rsi := ta.RSI(e.Close, 14).Get(0)
|
||||
rsiFast := ta.RSI(e.Close, 4).Get(0)
|
||||
rsiSlowS := ta.RSI(e.Close, 20)
|
||||
rsiSlow, rsiSlowP := rsiSlowS.Get(0), rsiSlowS.Get(1)
|
||||
|
||||
fastK := ta.Stoch(e.High, e.Low, e.Close, 5).Get(0)
|
||||
|
||||
bb20Up, bb20Md, bb20Dn := ta.BBANDS(ta.HLC3(e.High, e.Low, e.Close), 20, 2, 2)
|
||||
bb20Upp, bb20Mid, bb20Low := bb20Up.Get(0), bb20Md.Get(0), bb20Dn.Get(0)
|
||||
bb20Wid := (bb20Upp - bb20Low) / atrBase
|
||||
|
||||
volMa12 := ta.SMA(e.Volume, 12).Get(1)
|
||||
volMa24 := ta.SMA(e.Volume, 24).Get(1)
|
||||
|
||||
//lowWid := atrBase * lowRate
|
||||
//highWid := atrBase * highRate
|
||||
|
||||
for _, od := range s.LongOrders {
|
||||
holdNum := e.BarCount(od.EnterAt)
|
||||
profit := (c - od.Enter.Average) / atrBase
|
||||
if od.Short {
|
||||
profit *= -1
|
||||
}
|
||||
if profit < -10 && bb20Wid < 10 && c > bb20Mid && volMa12 < volMa24 {
|
||||
s.CloseOrders(&strat.ExitReq{Tag: "deadfish"})
|
||||
continue
|
||||
}
|
||||
if fastK > 75 && (holdNum > 11.5 && profit > -2 || holdNum > 287 && profit > -10) {
|
||||
od.SetStopLoss(&ormo.ExitTrigger{Price: c - atrBase*0.2})
|
||||
} else if od.EnterTag == "ewo" && profit > 10 {
|
||||
od.SetStopLoss(&ormo.ExitTrigger{Price: c - atrBase})
|
||||
} else if profit > 0 && fastK > 75 {
|
||||
od.SetStopLoss(&ormo.ExitTrigger{Price: c - atrBase*0.2})
|
||||
}
|
||||
}
|
||||
|
||||
if rsiSlow < rsiSlowP && rsiFast < 63 && rsi > 16 && c < sma15-atrBase*13 && cti < -0.8 {
|
||||
s.OpenOrder(&strat.EnterReq{
|
||||
Tag: "buy1",
|
||||
})
|
||||
}
|
||||
// 略不稳定
|
||||
//emaEnt := c < emaLong-lowWid && c < emaShort-highWid
|
||||
//if rsiFast < 50 && emaEnt && ewo > ewoHigh && rsi < rsiLong {
|
||||
// s.OpenOrder(&strat.EnterReq{
|
||||
// Tag: "ewo",
|
||||
// })
|
||||
//}
|
||||
},
|
||||
}
|
||||
}
|
||||
35
org/ft/common.go
Normal file
35
org/ft/common.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package ft
|
||||
|
||||
import "github.com/banbox/banbot/strat"
|
||||
|
||||
func init() {
|
||||
strat.AddStratGroup("ft", map[string]strat.FuncMakeStrat{
|
||||
"smaoff": SMAOffset,
|
||||
"smaoff2": SMAOffsetV2,
|
||||
"bin_ha": CombinedBinHAndClucV8Hyper,
|
||||
"hpsv7": HPSV7Ultra,
|
||||
"namaoff": NotAnotherSMAOffset,
|
||||
"e0v1e": E0V1E,
|
||||
"smaog": SMAOG,
|
||||
"BBRSITV": BBRSITV,
|
||||
"ichiv3": ichiv3,
|
||||
"ichiV1": ichiV1,
|
||||
"BBMod2": BBMod2,
|
||||
"Synthesis": Synthesis,
|
||||
"CenderaWasih3": CenderaWasih3,
|
||||
"x_zvwap06": x_zvwap06,
|
||||
"binance": binance,
|
||||
"BinHModWhiteHOV0": BinHModWhiteHOV0,
|
||||
"Clucha": Clucha,
|
||||
"MadV9HO": MadV9HO,
|
||||
"BBMod7": BBMod7,
|
||||
"BinHV27": BinHV27,
|
||||
|
||||
"01": SMAOffset,
|
||||
"02": BBMod2,
|
||||
"03": BBMod7,
|
||||
"04": MadV9HO,
|
||||
"05": binance,
|
||||
"06": CenderaWasih3,
|
||||
})
|
||||
}
|
||||
165
org/ft/e0v1e.go
Normal file
165
org/ft/e0v1e.go
Normal file
@@ -0,0 +1,165 @@
|
||||
package ft
|
||||
|
||||
import (
|
||||
"github.com/banbox/banbot/config"
|
||||
"github.com/banbox/banbot/core"
|
||||
"github.com/banbox/banbot/orm/ormo"
|
||||
"github.com/banbox/banbot/strat"
|
||||
ta "github.com/banbox/banta"
|
||||
)
|
||||
|
||||
/*
|
||||
https://github.com/28dec/E0V1E-HO/blob/main/user_data/strategies/E0V1E_20231014_0847.py
|
||||
|
||||
|
||||
https://github.com/ssssi/freqtrade_strs/blob/main/binance/E0V1E.py
|
||||
|
||||
|
||||
https://strat.ninja/overview.php?strategy=E0V1E
|
||||
params: {ctiThs: -0.86, maOffRate: 11.5, buyRsi: 19, buyRsiFast: 46}
|
||||
比上面多了个入场逻辑,反而更差了
|
||||
|
||||
1h3年只有40订单,收益为正
|
||||
15m和5m收益均不稳定
|
||||
*/
|
||||
|
||||
type E0State struct {
|
||||
c float64
|
||||
h float64
|
||||
atrBase float64
|
||||
kdjK float64
|
||||
cci float64
|
||||
ma120 float64
|
||||
ma240 float64
|
||||
hold map[int64]bool
|
||||
hold1 map[int64]bool
|
||||
}
|
||||
|
||||
func E0V1E(pol *config.RunPolicyConfig) *strat.TradeStrat {
|
||||
buyRsiFast := pol.Def("buyRsiFast", 41, core.PNorm(20, 70))
|
||||
buyRsi := pol.Def("buyRsi", 46.7, core.PNorm(15, 50))
|
||||
maOffRate := pol.Def("maOffRate", 2.05, core.PNorm(0.2, 5))
|
||||
ctiThs := pol.Def("ctiThs", -0.73, core.PNorm(-1, 0))
|
||||
sellKdX := pol.Def("sellKdX", 85.2, core.PNorm(50, 100))
|
||||
sellCCI := pol.Def("sellCCI", 80, core.PNorm(0, 400))
|
||||
|
||||
lenAtr := int(pol.Def("atr", 13.35, core.PNorm(7, 25)))
|
||||
baseAtrLen := int(float64(lenAtr) * 4.3)
|
||||
|
||||
return &strat.TradeStrat{
|
||||
WarmupNum: 300,
|
||||
DrawDownExit: true,
|
||||
OnStartUp: func(s *strat.StratJob) {
|
||||
s.More = &E0State{
|
||||
hold: make(map[int64]bool),
|
||||
hold1: make(map[int64]bool),
|
||||
}
|
||||
},
|
||||
OnBar: func(s *strat.StratJob) {
|
||||
e := s.Env
|
||||
c := e.Close.Get(0)
|
||||
m, _ := s.More.(*E0State)
|
||||
atr := ta.ATR(e.High, e.Low, e.Close, lenAtr)
|
||||
atrBase := ta.Lowest(ta.Highest(atr, lenAtr), baseAtrLen).Get(0)
|
||||
m.atrBase = atrBase
|
||||
m.h = e.High.Get(0)
|
||||
|
||||
sma15 := ta.SMA(e.Close, 15).Get(0)
|
||||
cti := ta.CTI(e.Close, 20).Get(0)
|
||||
rsi := ta.RSI(e.Close, 14).Get(0)
|
||||
rsi4 := ta.RSI(e.Close, 4).Get(0)
|
||||
rsi20S := ta.RSI(e.Close, 20)
|
||||
rsi20 := rsi20S.Get(0)
|
||||
|
||||
kdjK, _, _ := ta.KDJBy(e.High, e.Low, e.Close, 5, 3, 3, "sma")
|
||||
cci := ta.CCI(e.Close, 20).Get(0)
|
||||
ma120 := ta.SMA(e.Close, 120).Get(0)
|
||||
ma240 := ta.SMA(e.Close, 240).Get(0)
|
||||
m.kdjK = kdjK.Get(0)
|
||||
m.cci = cci
|
||||
m.ma120 = ma120
|
||||
m.ma240 = ma240
|
||||
|
||||
fastK := ta.Stoch(e.High, e.Low, e.Close, 5).Get(0)
|
||||
|
||||
ema100 := ta.EMA(e.Close, 100).Get(0)
|
||||
ema200 := ta.EMA(e.Close, 200).Get(0)
|
||||
|
||||
hlc3 := ta.HLC3(e.High, e.Low, e.Close)
|
||||
bb20Up, bb20Md, bb20Dn := ta.BBANDS(hlc3, 20, 2, 2)
|
||||
bb20Wid := (bb20Up.Get(0) - bb20Dn.Get(0)) / atrBase
|
||||
bb20Mid := bb20Md.Get(0)
|
||||
|
||||
volMa12 := ta.SMA(e.Volume, 12).Get(1)
|
||||
volMa24 := ta.SMA(e.Volume, 24).Get(1)
|
||||
|
||||
willR := ta.WillR(e, 14).Get(0)
|
||||
|
||||
if s.OrderNum > 0 && fastK > 75 {
|
||||
// 这是strat.ninja的出场逻辑,差
|
||||
// s.CloseOrders(&strat.ExitReq{Tag: "exit"})
|
||||
// return
|
||||
}
|
||||
if s.OrderNum > 0 && e.Open.Get(0) < ma120 {
|
||||
s.CloseOrders(&strat.ExitReq{Tag: "ma120"})
|
||||
return
|
||||
}
|
||||
tag := ""
|
||||
if rsi20 < rsi20S.Get(1) && rsi4 < buyRsiFast && rsi > buyRsi && c < sma15-atrBase*maOffRate && cti < ctiThs {
|
||||
tag = "buy1"
|
||||
} else if ema100 < ema200+atrBase*17 && bb20Wid > 10 && c < bb20Mid && volMa12 > volMa24 && cti < -0.5 &&
|
||||
willR < -60 {
|
||||
// 这是strat.ninja的入场逻辑,差
|
||||
//tag = "buy2"
|
||||
}
|
||||
if s.OrderNum == 0 && tag != "" {
|
||||
s.OpenOrder(&strat.EnterReq{Tag: tag, StopLossVal: atrBase * 20})
|
||||
}
|
||||
},
|
||||
GetDrawDownExitRate: func(s *strat.StratJob, od *ormo.InOutOrder, maxChg float64) float64 {
|
||||
m, _ := s.More.(*E0State)
|
||||
bestRate := maxChg / (m.atrBase / od.InitPrice)
|
||||
if bestRate > 2.3 {
|
||||
return 0.3
|
||||
}
|
||||
return 0
|
||||
},
|
||||
OnCheckExit: func(s *strat.StratJob, od *ormo.InOutOrder) *strat.ExitReq {
|
||||
m, _ := s.More.(*E0State)
|
||||
if m.c > min(m.ma120, m.ma240) {
|
||||
m.hold[od.ID] = true
|
||||
} else {
|
||||
m.hold1[od.ID] = true
|
||||
}
|
||||
profitRate := od.ProfitRate / od.Leverage / (m.atrBase / od.InitPrice)
|
||||
if profitRate > 0 && m.kdjK > sellKdX {
|
||||
return &strat.ExitReq{Tag: "fastK"}
|
||||
}
|
||||
if m.cci > sellCCI {
|
||||
if profitRate > -0.5 {
|
||||
return &strat.ExitReq{Tag: "cci_.5"}
|
||||
}
|
||||
if profitRate > -2 {
|
||||
return &strat.ExitReq{Tag: "cci_2"}
|
||||
}
|
||||
if profitRate > -8 {
|
||||
return &strat.ExitReq{Tag: "cci_8"}
|
||||
}
|
||||
}
|
||||
holdNum := int((s.Env.TimeStop - od.RealEnterMS()) / s.Env.TFMSecs)
|
||||
if holdNum > 3 {
|
||||
_, inHold := m.hold[od.ID]
|
||||
if inHold && m.c < min(m.ma120, m.ma240) {
|
||||
delete(m.hold, od.ID)
|
||||
return &strat.ExitReq{Tag: "ma120"}
|
||||
}
|
||||
_, inHold1 := m.hold1[od.ID]
|
||||
if inHold1 && m.h > min(m.ma120, m.ma240) {
|
||||
delete(m.hold1, od.ID)
|
||||
return &strat.ExitReq{Tag: "x120_240"}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
}
|
||||
80
org/ft/ichiV1.go
Normal file
80
org/ft/ichiV1.go
Normal file
@@ -0,0 +1,80 @@
|
||||
package ft
|
||||
|
||||
import (
|
||||
"github.com/banbox/banbot/config"
|
||||
"github.com/banbox/banbot/strat"
|
||||
"github.com/banbox/banstagy/com"
|
||||
ta "github.com/banbox/banta"
|
||||
"gonum.org/v1/gonum/floats"
|
||||
)
|
||||
|
||||
func ichiV1(p *config.RunPolicyConfig) *strat.TradeStrat {
|
||||
senkouLevel := 1
|
||||
bullLevel := 6
|
||||
h1Rate := 2.0
|
||||
fanMagLen := 3
|
||||
lenAtr := 14
|
||||
baseAtrLen := int(float64(lenAtr) * 4.3)
|
||||
return &strat.TradeStrat{
|
||||
WarmupNum: 100,
|
||||
OnBar: func(s *strat.StratJob) {
|
||||
e := s.Env
|
||||
hkasOpen, _, _, _ := ta.HeikinAshi(e)
|
||||
c := e.Close.Get(0)
|
||||
close15m := ta.EMA(e.Close, 3).Get(0)
|
||||
close30m := ta.EMA(e.Close, 6).Get(0)
|
||||
close1hS := ta.EMA(e.Close, 12)
|
||||
close1h := close1hS.Get(0)
|
||||
close2h := ta.EMA(e.Close, 24).Get(0)
|
||||
close4h := ta.EMA(e.Close, 48).Get(0)
|
||||
close6h := ta.EMA(e.Close, 72).Get(0)
|
||||
close8hS := ta.EMA(e.Close, 96)
|
||||
close8h := close8hS.Get(0)
|
||||
|
||||
open15m := ta.EMA(hkasOpen, 3).Get(0)
|
||||
open30m := ta.EMA(hkasOpen, 6).Get(0)
|
||||
open1h := ta.EMA(hkasOpen, 12).Get(0)
|
||||
open2h := ta.EMA(hkasOpen, 24).Get(0)
|
||||
open4h := ta.EMA(hkasOpen, 48).Get(0)
|
||||
open6h := ta.EMA(hkasOpen, 72).Get(0)
|
||||
open8h := ta.EMA(hkasOpen, 96).Get(0)
|
||||
|
||||
atr := ta.ATR(e.High, e.Low, e.Close, lenAtr)
|
||||
atrBase := ta.Lowest(ta.Highest(atr, lenAtr), baseAtrLen).Get(0)
|
||||
|
||||
fanMagnitude := close1h / close8h
|
||||
fanMagnitudeGain := (close1h - close1hS.Get(1)) / atrBase
|
||||
|
||||
ihci := com.IchimokuCloud(e, 20, 60, 120, 30).Cols
|
||||
senkouA, senkouB := ihci[2].Get(0), ihci[3].Get(0)
|
||||
|
||||
closeArr := []float64{c, close15m, close30m, close1h, close2h, close4h, close6h, close8h}
|
||||
openArr := []float64{c, open15m, open30m, open1h, open2h, open4h, open6h, open8h}
|
||||
|
||||
senkouOK := floats.Min(closeArr[senkouLevel-1:]) > max(senkouA, senkouB)
|
||||
bullOk := true
|
||||
for i := bullLevel - 1; i < 8; i++ {
|
||||
if closeArr[i] <= openArr[i] {
|
||||
bullOk = false
|
||||
break
|
||||
}
|
||||
}
|
||||
fanMag := true
|
||||
for i := fanMagLen; i > 0; i-- {
|
||||
if close1hS.Get(i)/close8hS.Get(i) >= fanMagnitude {
|
||||
fanMag = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if s.OrderNum > 0 {
|
||||
if c < close2h {
|
||||
s.CloseOrders(&strat.ExitReq{Tag: "exit"})
|
||||
}
|
||||
} else if senkouOK && bullOk && fanMagnitude > 1 && fanMagnitudeGain >= h1Rate && fanMag {
|
||||
s.OpenOrder(&strat.EnterReq{
|
||||
Tag: "long",
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
78
org/ft/ichiv3.go
Normal file
78
org/ft/ichiv3.go
Normal file
@@ -0,0 +1,78 @@
|
||||
package ft
|
||||
|
||||
import (
|
||||
"github.com/banbox/banbot/config"
|
||||
"github.com/banbox/banbot/core"
|
||||
"github.com/banbox/banbot/strat"
|
||||
ta "github.com/banbox/banta"
|
||||
"math"
|
||||
)
|
||||
|
||||
/*
|
||||
SMAOffset 的升级版本,也称为 ElliotV8 NASOS
|
||||
https://github.com/jilv220/freqtrade-stuff/blob/main/ElliotV8_original_ichiv3.py
|
||||
|
||||
滚动回测远不如默认参数稳定
|
||||
滚动回测:bt_opt_0529d353d7
|
||||
bt_opt -review-period 18M -run-period 2M -opt-rounds 20
|
||||
*/
|
||||
|
||||
func ichiv3(pol *config.RunPolicyConfig) *strat.TradeStrat {
|
||||
ewoRate := pol.Def("ewoRate", 1.0, core.PNorm(0.1, 3))
|
||||
ewoHigh := 3.15 * ewoRate
|
||||
ewoLow := -17.15 * ewoRate
|
||||
lowRate := pol.Def("lowRate", 1.7, core.PNorm(1, 3.5))
|
||||
highRate := pol.Def("highRate", 0.85, core.PNorm(0.5, 2.5))
|
||||
highRate2 := highRate * 2
|
||||
rsiLong := pol.Def("rsiLong", 57, core.PNorm(50, 65))
|
||||
maLongF := pol.Def("maLong", 12, core.PNorm(8, 16))
|
||||
maLong := int(math.Round(maLongF))
|
||||
maRate := pol.Def("maRate", 1.833, core.PNorm(1.5, 3))
|
||||
maShort := int(math.Round(maLongF * maRate))
|
||||
lenAtr := 29
|
||||
baseAtrLen := int(float64(lenAtr) * 4.3)
|
||||
return &strat.TradeStrat{
|
||||
WarmupNum: 100,
|
||||
EachMaxLong: 1,
|
||||
OnBar: func(s *strat.StratJob) {
|
||||
e := s.Env
|
||||
c := e.Close.Get(0)
|
||||
atr := ta.ATR(e.High, e.Low, e.Close, lenAtr)
|
||||
atrBase := ta.Lowest(ta.Highest(atr, lenAtr), baseAtrLen).Get(0)
|
||||
|
||||
emaLong := ta.EMA(e.Close, maLong).Get(0)
|
||||
emaShort := ta.EMA(e.Close, maShort).Get(0)
|
||||
|
||||
hma50 := ta.HMA(e.Close, 50).Get(0)
|
||||
|
||||
ema1 := ta.EMA(e.Close, 50).Get(0)
|
||||
ema2 := ta.EMA(e.Close, 200).Get(0)
|
||||
ewo := (ema1 - ema2) / atrBase
|
||||
|
||||
rsi := ta.RSI(e.Close, 14).Get(0)
|
||||
rsiFast := ta.RSI(e.Close, 4).Get(0)
|
||||
rsiSlow := ta.RSI(e.Close, 20).Get(0)
|
||||
|
||||
lowWid := atrBase * lowRate
|
||||
highWid := atrBase * highRate
|
||||
highWid2 := atrBase * highRate2
|
||||
|
||||
emaEnt := c < emaLong-lowWid && c < emaShort+highWid
|
||||
if rsiFast < 35 && emaEnt && (ewo > ewoHigh && rsi < rsiLong || ewo < ewoLow) {
|
||||
s.OpenOrder(&strat.EnterReq{
|
||||
Tag: "long",
|
||||
})
|
||||
} else if rsiFast > rsiSlow && c < hma50 && c > emaShort+highWid {
|
||||
s.CloseOrders(&strat.ExitReq{
|
||||
Dirt: core.OdDirtLong,
|
||||
Tag: "exit",
|
||||
})
|
||||
} else if rsiFast > rsiSlow && c > hma50 && rsi > 50 && c > emaShort+highWid2 {
|
||||
s.CloseOrders(&strat.ExitReq{
|
||||
Dirt: core.OdDirtLong,
|
||||
Tag: "exit2",
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
74
org/ft/noAnSmaOff.go
Normal file
74
org/ft/noAnSmaOff.go
Normal file
@@ -0,0 +1,74 @@
|
||||
package ft
|
||||
|
||||
import (
|
||||
"github.com/banbox/banbot/config"
|
||||
"github.com/banbox/banbot/core"
|
||||
"github.com/banbox/banbot/strat"
|
||||
ta "github.com/banbox/banta"
|
||||
)
|
||||
|
||||
/*
|
||||
滚动优化:bt_opt -review-period 18M -run-period 2M -opt-rounds 20
|
||||
bt_opt_9954bcb1d0 最近两年半1.6%收益,回撤7.6%;不稳定。
|
||||
1h > 15m > 5m
|
||||
*/
|
||||
|
||||
func NotAnotherSMAOffset(pol *config.RunPolicyConfig) *strat.TradeStrat {
|
||||
maBuyLen := int(pol.Def("maBuyLen", 14, core.PNorm(5, 80)))
|
||||
maSellLen := int(pol.Def("maSellLen", 24, core.PNorm(5, 80)))
|
||||
lowOff := pol.Def("lowOff", 2, core.PNorm(0.5, 4))
|
||||
lowOff2 := pol.Def("lowOff2", 4, core.PNorm(1.5, 7))
|
||||
highOff := pol.Def("highOff", 1, core.PNorm(0.3, 2.5))
|
||||
highOff2 := pol.Def("highOff2", 0.5, core.PNorm(-0.5, 1.5))
|
||||
ewoLow := pol.Def("ewoLow", -21, core.PNorm(-25, -8))
|
||||
ewoHigh := pol.Def("ewoHigh", 2.33, core.PNorm(1, 12))
|
||||
ewoHigh2 := pol.Def("ewoHigh2", -2.33, core.PNorm(-6, 12))
|
||||
rsiBuy := pol.Def("rsiBuy", 69, core.PNorm(30, 85))
|
||||
hmaExRate := pol.Def("hmaExRate", 12, core.PNorm(3, 20))
|
||||
emaExRate := pol.Def("emaExRate", 4, core.PNorm(1.5, 7))
|
||||
|
||||
lenAtr := int(pol.Def("atr", 29, core.PNorm(7, 40)))
|
||||
baseAtrLen := int(float64(lenAtr) * 4.3)
|
||||
return &strat.TradeStrat{
|
||||
WarmupNum: 200,
|
||||
EachMaxLong: 1,
|
||||
OnBar: func(s *strat.StratJob) {
|
||||
e := s.Env
|
||||
c := e.Close.Get(0)
|
||||
atr := ta.ATR(e.High, e.Low, e.Close, lenAtr)
|
||||
atrBase := ta.Lowest(ta.Highest(atr, lenAtr), baseAtrLen).Get(0)
|
||||
|
||||
maBuy := ta.EMA(e.Close, maBuyLen).Get(0)
|
||||
maSell := ta.EMA(e.Close, maSellLen).Get(0)
|
||||
hma50 := ta.HMA(e.Close, 50).Get(0)
|
||||
ema100 := ta.EMA(e.Close, 100).Get(0)
|
||||
sma9 := ta.SMA(e.Close, 9).Get(0)
|
||||
|
||||
ema50 := ta.EMA(e.Close, 50).Get(0)
|
||||
ema200 := ta.EMA(e.Close, 200).Get(0)
|
||||
ewo := (ema50 - ema200) * 100 / e.Low.Get(0)
|
||||
|
||||
rsi14 := ta.RSI(e.Close, 14).Get(0)
|
||||
rsi4 := ta.RSI(e.Close, 4).Get(0)
|
||||
rsi20 := ta.RSI(e.Close, 20).Get(0)
|
||||
|
||||
if c > sma9 && c-maSell > atrBase*highOff2 && rsi14 > 50 && rsi4 > rsi20 {
|
||||
s.CloseOrders(&strat.ExitReq{Tag: "exit1"})
|
||||
} else if c < hma50 && c-maSell > atrBase*highOff && rsi4 > rsi20 {
|
||||
s.CloseOrders(&strat.ExitReq{Tag: "exit2"})
|
||||
} else if ema100-hma50 >= atrBase*hmaExRate {
|
||||
s.CloseOrders(&strat.ExitReq{Tag: "exit3"})
|
||||
} else if c-ema100 <= atrBase*emaExRate {
|
||||
s.CloseOrders(&strat.ExitReq{Tag: "exit4"})
|
||||
} else if rsi4 < 35 && maSell-c > atrBase*highOff && s.OrderNum == 0 {
|
||||
if maBuy-c > atrBase*lowOff && ewo > ewoHigh && rsi14 < rsiBuy {
|
||||
s.OpenOrder(&strat.EnterReq{Tag: "ewo1"})
|
||||
} else if maBuy-c > atrBase*lowOff2 && ewo > ewoHigh2 && rsi14 < min(25, rsiBuy) {
|
||||
s.OpenOrder(&strat.EnterReq{Tag: "ewo2"})
|
||||
} else if maBuy-c > atrBase*lowOff && ewo < ewoLow {
|
||||
s.OpenOrder(&strat.EnterReq{Tag: "ewoLow"})
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
73
org/ft/sma_offset.go
Normal file
73
org/ft/sma_offset.go
Normal file
@@ -0,0 +1,73 @@
|
||||
package ft
|
||||
|
||||
import (
|
||||
"github.com/banbox/banbot/config"
|
||||
"github.com/banbox/banbot/core"
|
||||
"github.com/banbox/banbot/strat"
|
||||
ta "github.com/banbox/banta"
|
||||
)
|
||||
|
||||
/*
|
||||
来自
|
||||
https://github.com/hippocritical/strategies/blob/main/SMAOffset_Hippocritical_dca/SMAOffset_Hippocritical_dca.py
|
||||
|
||||
也称ElliotV3 ElliotV5_SMA
|
||||
https://github.com/minulislam/freqtrade-strategies/user_data/strategies/ElliotV3.py
|
||||
|
||||
滚动测试:
|
||||
bt_opt_745b13cd06 bt_opt -review-period 18M -run-period 2M -opt-rounds 20
|
||||
|
||||
添加止损或长期未盈利退出,都会导致整体收益下降
|
||||
*/
|
||||
|
||||
func SMAOffset(pol *config.RunPolicyConfig) *strat.TradeStrat {
|
||||
ewoRate := pol.Def("ewoRate", 1.0, core.PNorm(0.1, 3))
|
||||
ewoHigh := 4.0 * ewoRate
|
||||
ewoLow := -12 * ewoRate
|
||||
|
||||
lowRate := pol.Def("lowRate", 3.03, core.PNorm(1.5, 5))
|
||||
highRate := pol.Def("highRate", 1.03, core.PNorm(0.5, 5))
|
||||
|
||||
lenAtr := int(pol.Def("atr", 29, core.PNorm(7, 40)))
|
||||
baseAtrLen := int(float64(lenAtr) * 4.3)
|
||||
return &strat.TradeStrat{
|
||||
WarmupNum: 300,
|
||||
EachMaxLong: 1,
|
||||
OnBar: func(s *strat.StratJob) {
|
||||
e := s.Env
|
||||
c := e.Close.Get(0)
|
||||
atr := ta.ATR(e.High, e.Low, e.Close, lenAtr)
|
||||
atrBase := ta.Lowest(ta.Highest(atr, lenAtr), baseAtrLen).Get(0)
|
||||
|
||||
emaLong := ta.EMA(e.Close, 16).Get(0)
|
||||
emaShort := ta.EMA(e.Close, 20).Get(0)
|
||||
ema1 := ta.EMA(e.Close, 50).Get(0)
|
||||
ema2 := ta.EMA(e.Close, 200).Get(0)
|
||||
ewo := (ema1 - ema2) / atrBase
|
||||
rsi := ta.RSI(e.Close, 14).Get(0)
|
||||
|
||||
if s.OrderNum > 0 {
|
||||
if c-emaShort > atrBase*highRate {
|
||||
s.CloseOrders(&strat.ExitReq{
|
||||
Dirt: core.OdDirtLong,
|
||||
Tag: "exit",
|
||||
})
|
||||
}
|
||||
return
|
||||
}
|
||||
if emaLong-c > atrBase*lowRate {
|
||||
tag := ""
|
||||
if ewo > ewoHigh && rsi < 59 {
|
||||
tag = "buy1"
|
||||
} else if ewo < ewoLow {
|
||||
//tag = "buy2"
|
||||
}
|
||||
if tag != "" {
|
||||
s.OpenOrder(&strat.EnterReq{
|
||||
Tag: tag,
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
74
org/ft/sma_offv2.go
Normal file
74
org/ft/sma_offv2.go
Normal file
@@ -0,0 +1,74 @@
|
||||
package ft
|
||||
|
||||
import (
|
||||
"github.com/banbox/banbot/config"
|
||||
"github.com/banbox/banbot/core"
|
||||
"github.com/banbox/banbot/orm/ormo"
|
||||
"github.com/banbox/banbot/strat"
|
||||
ta "github.com/banbox/banta"
|
||||
)
|
||||
|
||||
/*
|
||||
https://github.com/GeorgeMurAlkh/freqtrade-stuff/tree/main/user_data/strategies
|
||||
|
||||
考虑加入大趋势过滤
|
||||
|
||||
滚动回测:bt_opt_59cb7a0075
|
||||
bt_opt -review-period 18M -run-period 2M -opt-rounds 20
|
||||
波动性较大,2年累计收益300%但回撤48%
|
||||
*/
|
||||
|
||||
type SmaOf2 struct {
|
||||
goLong bool
|
||||
atrBase float64
|
||||
}
|
||||
|
||||
func SMAOffsetV2(pol *config.RunPolicyConfig) *strat.TradeStrat {
|
||||
longRate := pol.Def("longRate", 3.03, core.PNorm(1.5, 6))
|
||||
shortRate := pol.Def("shortRate", 1.03, core.PNorm(0.5, 4))
|
||||
|
||||
lenAtr := int(pol.Def("atr", 20, core.PNorm(7, 40)))
|
||||
baseAtrLen := int(float64(lenAtr) * 4.3)
|
||||
return &strat.TradeStrat{
|
||||
WarmupNum: 100,
|
||||
EachMaxLong: 1,
|
||||
OnStartUp: func(s *strat.StratJob) {
|
||||
s.More = &SmaOf2{}
|
||||
},
|
||||
OnPairInfos: func(s *strat.StratJob) []*strat.PairSub {
|
||||
return []*strat.PairSub{
|
||||
{"_cur_", "1h", 50},
|
||||
}
|
||||
},
|
||||
OnBar: func(s *strat.StratJob) {
|
||||
e := s.Env
|
||||
m, _ := s.More.(*SmaOf2)
|
||||
c := e.Close.Get(0)
|
||||
atr := ta.ATR(e.High, e.Low, e.Close, lenAtr)
|
||||
atrBase := ta.Lowest(ta.Highest(atr, lenAtr), baseAtrLen).Get(0)
|
||||
m.atrBase = atrBase
|
||||
|
||||
sma := ta.SMA(e.Close, 20).Get(0)
|
||||
if m.goLong && sma-c > atrBase*longRate && s.OrderNum == 0 {
|
||||
s.OpenOrder(&strat.EnterReq{Tag: "long"})
|
||||
} else if !m.goLong && c-sma > atrBase*shortRate {
|
||||
s.CloseOrders(&strat.ExitReq{Tag: "short"})
|
||||
}
|
||||
},
|
||||
OnInfoBar: func(s *strat.StratJob, e *ta.BarEnv, pair, tf string) {
|
||||
m, _ := s.More.(*SmaOf2)
|
||||
emaFast := ta.EMA(e.Close, 20).Get(0)
|
||||
emaSlow := ta.EMA(e.Close, 25).Get(0)
|
||||
m.goLong = emaFast > emaSlow
|
||||
},
|
||||
OnCheckExit: func(s *strat.StratJob, od *ormo.InOutOrder) *strat.ExitReq {
|
||||
m, _ := s.More.(*SmaOf2)
|
||||
holdNum := int((s.Env.TimeStop - od.RealEnterMS()) / s.Env.TFMSecs)
|
||||
profitRate := od.ProfitRate / od.Leverage / (m.atrBase / od.InitPrice)
|
||||
if holdNum > 8 && profitRate < -8 {
|
||||
return &strat.ExitReq{Tag: "sl"}
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
}
|
||||
197
org/ft/x_zvwap06.go
Normal file
197
org/ft/x_zvwap06.go
Normal file
@@ -0,0 +1,197 @@
|
||||
package ft
|
||||
|
||||
import (
|
||||
"github.com/banbox/banbot/config"
|
||||
"github.com/banbox/banbot/core"
|
||||
"github.com/banbox/banbot/orm/ormo"
|
||||
"github.com/banbox/banbot/strat"
|
||||
ta "github.com/banbox/banta"
|
||||
"gonum.org/v1/gonum/floats"
|
||||
"math"
|
||||
)
|
||||
|
||||
/*
|
||||
https://strat.ninja/overview.php?strategy=x_zvwap06
|
||||
整体盈利,48品种,盈利190%,回撤30%,中间不够稳定。
|
||||
*/
|
||||
|
||||
type zvwapSta struct {
|
||||
atrBase float64
|
||||
fastK float64
|
||||
rsi float64
|
||||
cmf15m float64
|
||||
cmf1h float64
|
||||
tpctChange1h float64
|
||||
}
|
||||
|
||||
func x_zvwap06(p *config.RunPolicyConfig) *strat.TradeStrat {
|
||||
tpctChange4Val := p.Def("tpctChange4", 8, core.PNorm(1, 16))
|
||||
ctiVal := p.Def("cti", -0.087, core.PNorm(-0.9, 0))
|
||||
rsiLongVal := p.Def("rsiLong", 35, core.PNorm(15, 50))
|
||||
bbWidVol := p.Def("bbWid", 6, core.PNorm(3, 15))
|
||||
bbMidRateVol := p.Def("bbMidRate", 0.4, core.PNorm(-20, 30))
|
||||
emaHighRate := p.Def("emaHighRate", 2, core.PNorm(1, 10))
|
||||
emaHighRate2 := p.Def("emaHighRate2", 3, core.PNorm(1, 10))
|
||||
|
||||
lenAtr := 29
|
||||
baseAtrLen := int(float64(lenAtr) * 4.3)
|
||||
return &strat.TradeStrat{
|
||||
WarmupNum: 100,
|
||||
OnStartUp: func(s *strat.StratJob) {
|
||||
s.More = &zvwapSta{}
|
||||
},
|
||||
OnPairInfos: func(s *strat.StratJob) []*strat.PairSub {
|
||||
return []*strat.PairSub{
|
||||
{"_cur_", "15m", 100},
|
||||
{"_cur_", "1h", 100},
|
||||
}
|
||||
},
|
||||
OnBar: func(s *strat.StratJob) {
|
||||
e := s.Env
|
||||
m, _ := s.More.(*zvwapSta)
|
||||
c := e.Close.Get(0)
|
||||
atr := ta.ATR(e.High, e.Low, e.Close, lenAtr)
|
||||
atrBase := ta.Lowest(ta.Highest(atr, lenAtr), baseAtrLen).Get(0)
|
||||
|
||||
hlc3 := ta.HLC3(e.High, e.Low, e.Close)
|
||||
|
||||
zvwpCol := zvwap(e.Close, e.Volume, 14)
|
||||
zvwp := zvwpCol.Get(0)
|
||||
|
||||
rsi := ta.RSI(e.Close, 14).Get(0)
|
||||
rsiFast := ta.RSI(e.Close, 4).Get(0)
|
||||
rsiSlow := ta.RSI(e.Close, 20).Get(0)
|
||||
rsi84 := ta.RSI(e.Close, 84).Get(0)
|
||||
rsi112 := ta.RSI(e.Close, 112).Get(0)
|
||||
m.rsi = rsi
|
||||
|
||||
//tpctChange0 := topPctChgDca(e.Open, e.Close, 0) / atrBase
|
||||
//tpctChange1 := topPctChgDca(e.Open, e.Close, 1) / atrBase
|
||||
//tpctChange2 := topPctChgDca(e.Open, e.Close, 2) / atrBase
|
||||
tpctChange4 := topPctChgDca(e.Open, e.Close, 4) / atrBase
|
||||
//tpctChange12 := topPctChgDca(e.Open, e.Close, 12) / atrBase
|
||||
//tpctChange72 := topPctChgDca(e.Open, e.Close, 72) / atrBase
|
||||
//tpctChange144 := topPctChgDca(e.Open, e.Close, 144) / atrBase
|
||||
|
||||
cti := ta.CTI(e.Close, 20).Get(0)
|
||||
cmf := ta.CMF(e, 20).Get(0)
|
||||
haOpen, _, _, haClose := ta.HeikinAshi(e)
|
||||
|
||||
ema22 := ta.EMA(e.Close, 22).Get(0)
|
||||
ema200 := ta.EMA(e.Close, 200).Get(0)
|
||||
|
||||
hma50 := ta.HMA(e.Close, 50).Get(0)
|
||||
//hma30 := ta.HMA(e.Close, 30).Get(0)
|
||||
//hma15 := ta.HMA(e.Close, 15).Get(0)
|
||||
|
||||
bb20Up, bb20Md, bb20Dn := ta.BBANDS(hlc3, 20, 2, 2)
|
||||
bb20Upp, bb20Mid, bb20Low := bb20Up.Get(0), bb20Md.Get(0), bb20Dn.Get(0)
|
||||
bb20Wid := (bb20Upp - bb20Low) / atrBase
|
||||
|
||||
deadfish := e.Close.To("_deadfish", 0)
|
||||
if !deadfish.Cached() {
|
||||
dfVal := 0.0
|
||||
if c < ema200 && bb20Wid < bbWidVol && c > bb20Mid+atrBase*bbMidRateVol && cmf < 0 &&
|
||||
haOpen.Get(0) > haClose.Get(0) {
|
||||
dfVal = 1
|
||||
}
|
||||
deadfish.Append(dfVal)
|
||||
}
|
||||
|
||||
fastK := ta.Stoch(e.High, e.Low, e.Close, 5).Get(0)
|
||||
m.fastK = fastK
|
||||
|
||||
for _, od := range s.LongOrders {
|
||||
profitRate := (c - od.InitPrice) / atrBase
|
||||
exitTag := ""
|
||||
if profitRate > 10 && c > hma50+atrBase && c > ema22+atrBase*emaHighRate && rsi > 50 && rsiFast > rsiSlow {
|
||||
exitTag = "sell1"
|
||||
} else if profitRate > 10 && c > hma50+atrBase && c > ema22+atrBase*emaHighRate2 {
|
||||
exitTag = "sell2"
|
||||
} else if profitRate > 10 && rsi < 42 && cmf < -0.4 {
|
||||
exitTag = "pft1"
|
||||
} else if profitRate > 10 && rsi < 43 && cmf < 0 && m.cmf15m < 0 && m.cmf1h < 0 {
|
||||
exitTag = "pft2"
|
||||
} else if profitRate > 10 && rsi < 41 && cmf < -0.2 && m.cmf1h < 0 {
|
||||
exitTag = "pft3"
|
||||
} else if profitRate > 10 && rsi < 44 && cmf < -0.1 && m.cmf15m < -0.1 && m.cmf1h < -0.1 {
|
||||
exitTag = "pft4"
|
||||
} else if profitRate > 10 && rsi < 40 && cmf < -0.2 && m.cmf15m < -0.2 {
|
||||
exitTag = "pft5"
|
||||
} else if profitRate > 10 && rsi < 43 && cmf < -0.4 && m.cmf15m < 0 && m.cmf1h < 0 {
|
||||
exitTag = "pft6"
|
||||
} else if profitRate > 4 && rsi < 30 && cmf < -0.4 {
|
||||
exitTag = "bear1"
|
||||
} else if profitRate > 6 && rsi < 35 && cmf < -0.4 {
|
||||
exitTag = "bear2"
|
||||
} else if profitRate > 2 && rsi < 25 && cmf < -0.6 {
|
||||
exitTag = "bear3"
|
||||
} else if profitRate < -10 && c < ema200 && bb20Wid < bbWidVol && c > bb20Mid+atrBase*bbMidRateVol && cmf < 0 {
|
||||
exitTag = "deadfish"
|
||||
}
|
||||
if exitTag != "" {
|
||||
s.CloseOrders(&strat.ExitReq{Tag: exitTag, OrderID: od.ID})
|
||||
}
|
||||
}
|
||||
|
||||
tag := ""
|
||||
if c < zvwp && tpctChange4 > tpctChange4Val && cti < ctiVal && rsi < rsiLongVal && max(rsi84, rsi112) < 60 &&
|
||||
floats.Max(deadfish.Range(0, 4)) == 0 {
|
||||
tag = "zvwap"
|
||||
} else if c < zvwp && tpctChange4 > 13 && cti < -0.8 && rsi < 35 && max(rsi84, rsi112) < 60 && m.tpctChange1h < 0.45 {
|
||||
tag = "pcdown"
|
||||
}
|
||||
if tag != "" && s.OrderNum == 0 {
|
||||
s.OpenOrder(&strat.EnterReq{Tag: tag})
|
||||
}
|
||||
},
|
||||
OnInfoBar: func(s *strat.StratJob, e *ta.BarEnv, pair, tf string) {
|
||||
m, _ := s.More.(*zvwapSta)
|
||||
if tf == "15m" {
|
||||
m.cmf15m = ta.CMF(e, 20).Get(0)
|
||||
} else {
|
||||
m.cmf1h = ta.CMF(e, 20).Get(0)
|
||||
m.tpctChange1h = topPctChgDca(e.Open, e.Close, 72) / m.atrBase
|
||||
}
|
||||
},
|
||||
OnCheckExit: func(s *strat.StratJob, od *ormo.InOutOrder) *strat.ExitReq {
|
||||
m, _ := s.More.(*zvwapSta)
|
||||
c := s.Env.Close.Get(0)
|
||||
profitRate := (c - od.InitPrice) / m.atrBase
|
||||
if od.Short {
|
||||
profitRate *= -1
|
||||
}
|
||||
if profitRate > 20 && profitRate < 80 && od.MaxDrawDown > 0.3 {
|
||||
return &strat.ExitReq{Tag: "trail1"}
|
||||
} else if profitRate > 8 && profitRate < 22 && od.MaxDrawDown > 0.35 {
|
||||
return &strat.ExitReq{Tag: "trail2"}
|
||||
} else if profitRate > 200 && m.rsi > 85 {
|
||||
return &strat.ExitReq{Tag: "rsi85"}
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func zvwap(p, v *ta.Series, period int) *ta.Series {
|
||||
res := p.To("_zvwap", period)
|
||||
if res.Cached() {
|
||||
return res
|
||||
}
|
||||
maP := ta.SMA(p, period)
|
||||
maV := ta.SMA(v, period)
|
||||
mean := ta.VWMA(p, maV, period)
|
||||
pow2 := mean.To("_pow2", period)
|
||||
pow2.Append(math.Pow(p.Get(0)-mean.Get(0), 2))
|
||||
pow2Ma := ta.SMA(pow2, period)
|
||||
vwapsd := math.Sqrt(pow2Ma.Get(0))
|
||||
return res.Append((maP.Get(0) - mean.Get(0)) / vwapsd)
|
||||
}
|
||||
|
||||
func topPctChgDca(o, c *ta.Series, period int) float64 {
|
||||
if period == 0 {
|
||||
return o.Get(0)/c.Get(0) - 1
|
||||
} else {
|
||||
return ta.Highest(o, period).Get(0)/c.Get(0) - 1
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user