init
This commit is contained in:
113
trend/20250208/MACDEMAV2.go
Normal file
113
trend/20250208/MACDEMAV2.go
Normal file
@@ -0,0 +1,113 @@
|
||||
package trend
|
||||
|
||||
import (
|
||||
"github.com/banbox/banbot/config"
|
||||
"github.com/banbox/banbot/core"
|
||||
"github.com/banbox/banbot/strat"
|
||||
"github.com/banbox/banstagy/com"
|
||||
ta "github.com/banbox/banta"
|
||||
"math"
|
||||
)
|
||||
|
||||
/*
|
||||
备份于2025/02/25
|
||||
测试加入1d的大周期过滤,对做多或做空都未获得更好效果,反而略差
|
||||
|
||||
20210101-20250101
|
||||
只做多:1776%,回撤28.8%,夏普3.93
|
||||
多空双开:1913%,回撤22%,夏普4.53
|
||||
做空部分单独运行波动很大,但和做多一起运行可减少做多的回撤
|
||||
|
||||
参考SMACross1加入海龟资金和ErDelta过滤后:
|
||||
170品种下:夏普从7.97提升到8.91,显示最大回撤从18.71%下降到17.65%;收益从718%变为707%
|
||||
*/
|
||||
type entExitMore struct {
|
||||
enter *strat.EnterReq
|
||||
exit *strat.ExitReq
|
||||
}
|
||||
|
||||
func MACDEMAV2(p *config.RunPolicyConfig) *strat.TradeStrat {
|
||||
// 初始HMA 25 4
|
||||
maType := com.DefMaType(p, "ma", com.MaHMA) // hma 包揽优化列表头部
|
||||
maLen := p.DefInt("maLen", 25, core.PNormF(7, 100, 25, 0)) // 超过40表现不佳,20多表现最好
|
||||
maRate := p.Def("maRate", 4.1, core.PNorm(1.5, 7))
|
||||
emaLen := p.DefInt("emaLen", 100, core.PNormF(30, 240, 100, 0))
|
||||
macdRt := p.Def("macdRt", 1, core.PNormF(0.7, 3, 1.2, 0))
|
||||
maBigLen := int(math.Round(float64(maLen) * maRate))
|
||||
mc1, mc2, mc3 := int(math.Round(12*macdRt)), int(math.Round(26*macdRt)), int(math.Round(9*macdRt))
|
||||
p.KeepHyperOnly("ma", "maLen", "maRate")
|
||||
return &strat.TradeStrat{
|
||||
WarmupNum: 500,
|
||||
EachMaxLong: 1,
|
||||
EachMaxShort: 1,
|
||||
//OnStartUp: func(s *strat.StratJob) {
|
||||
// s.More = &entExitMore{}
|
||||
//},
|
||||
//OnPairInfos: func(s *strat.StratJob) []*strat.PairSub {
|
||||
// return []*strat.PairSub{
|
||||
// {"_cur_", "4h", 500},
|
||||
// }
|
||||
//},
|
||||
//OnBar: func(s *strat.StratJob) {
|
||||
// m, _ := s.More.(*entExitMore)
|
||||
// if m.enter != nil {
|
||||
// s.OpenOrder(m.enter)
|
||||
// m.enter = nil
|
||||
// }
|
||||
// if m.exit != nil {
|
||||
// s.CloseOrders(m.exit)
|
||||
// m.exit = nil
|
||||
// }
|
||||
//},
|
||||
//OnInfoBar: func(s *strat.StratJob, e *ta.BarEnv, pair, tf string) {
|
||||
// m, _ := s.More.(*entExitMore)
|
||||
OnBar: func(s *strat.StratJob) {
|
||||
e := s.Env
|
||||
c := e.Close.Get(0)
|
||||
atr := ta.ATR(e.High, e.Low, e.Close, 30)
|
||||
openRate := 0.015 * c / atr.Get(0)
|
||||
if openRate < 1 {
|
||||
openRate = math.Sqrt(openRate)
|
||||
}
|
||||
er := ta.ER(e.Close, 50)
|
||||
erDelta := min(1.3, er.Get(0)/er.Get(12))
|
||||
if erDelta > 1 {
|
||||
openRate *= erDelta
|
||||
} else {
|
||||
openRate = 0
|
||||
}
|
||||
|
||||
ema := ta.EMA(e.Close, emaLen).Get(0)
|
||||
macd, signal := ta.MACD(e.Close, mc1, mc2, mc3)
|
||||
macdSub := macd.Get(0) - signal.Get(0)
|
||||
|
||||
if c > ema && macdSub > 0 && len(s.LongOrders) == 0 {
|
||||
s.OpenOrder(&strat.EnterReq{
|
||||
Tag: "long",
|
||||
CostRate: openRate,
|
||||
})
|
||||
} else if len(s.LongOrders) > 0 && (macdSub < 0 && c < ema) {
|
||||
s.CloseOrders(&strat.ExitReq{
|
||||
Tag: "closeL",
|
||||
Dirt: core.OdDirtLong,
|
||||
})
|
||||
}
|
||||
|
||||
ma1 := com.GetMA(e.Close, e.Volume, maType, maLen)
|
||||
ma2 := com.GetMA(e.Close, e.Volume, maType, maBigLen)
|
||||
cross := ma1.Cross(ma2)
|
||||
if cross == 1 && len(s.ShortOrders) > 0 {
|
||||
s.CloseOrders(&strat.ExitReq{
|
||||
Tag: "closeS",
|
||||
Dirt: core.OdDirtShort,
|
||||
})
|
||||
} else if cross == -1 && len(s.ShortOrders) == 0 {
|
||||
s.OpenOrder(&strat.EnterReq{
|
||||
Tag: "short",
|
||||
Short: true,
|
||||
CostRate: openRate,
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user