Files
banstagy/trend/MACDEMAV2.go
2026-08-24 20:53:21 +08:00

114 lines
3.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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"
)
/*
测试加入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%
2025/02/25 ERChg<1时保留ATR比率开单,整体*1.15
*/
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", 15, 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)
}
openRate *= 1.15
er := ta.ER(e.Close, 50)
erDelta := min(1.3, er.Get(0)/er.Get(12))
if erDelta > 1 {
openRate *= erDelta
}
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,
})
}
},
}
}