This commit is contained in:
2026-08-24 20:53:21 +08:00
commit 6e78bba16a
287 changed files with 32443 additions and 0 deletions

105
trend/MACDX.go Normal file
View File

@@ -0,0 +1,105 @@
package trend
import (
"fmt"
"github.com/banbox/banbot/config"
"github.com/banbox/banbot/core"
"github.com/banbox/banbot/strat"
ta "github.com/banbox/banta"
"math"
)
/*
视频号:山居听雨楼 2025/02/19
“有没有一眼就能看清楚,而且很好用的交易方法。。。。。这里分享一个只用macd的交易方法。”
【主要思想】
大周期(1d)MACD快线和慢线都处于0轴上方看多,都处于0轴下方看空;
小周期(8h)MACD:
看多时:快线上穿0轴或金叉,做多;死叉平仓。
看空时:快线下穿0轴或死叉,做空,死叉平仓。
测试小周期金叉死叉无需要求0轴上下,略好一点。
测试小周期当前参数4h盈利最佳。大周期1d最佳。
*/
func MACDX2(p *config.RunPolicyConfig) *strat.TradeStrat {
return &strat.TradeStrat{
WarmupNum: 300,
RunTimeFrames: []string{"4h"},
OnPairInfos: func(s *strat.StratJob) []*strat.PairSub {
return []*strat.PairSub{
{"_cur_", "1d", 150},
}
},
OnStartUp: func(s *strat.StratJob) {
s.More = 0
},
OnBar: func(s *strat.StratJob) {
e := s.Env
dirt := s.More.(int)
macd, signal := ta.MACD(e.Close, 26, 56, 20)
macdX := macd.Cross(signal)
macdX2 := macd.Cross(0)
atr := ta.ATR(e.High, e.Low, e.Close, 30)
openRate := 0.015 * e.Close.Get(0) / atr.Get(0)
if openRate < 1 {
openRate = math.Sqrt(openRate)
}
openRate *= 1.3
er := ta.ER(e.Close, 50)
erDelta := min(1.3, er.Get(0)/er.Get(12))
if erDelta > 1 {
openRate *= erDelta
}
if len(s.LongOrders) > 0 {
if macdX == -1 {
s.CloseOrders(&strat.ExitReq{Tag: "closeL", Dirt: core.OdDirtLong, Log: true})
}
} else if dirt > 0 && openRate > 0 {
if macdX == 1 {
s.OpenOrder(&strat.EnterReq{Tag: "long", CostRate: openRate, Log: true})
} else if macdX2 == 1 {
s.OpenOrder(&strat.EnterReq{Tag: "long2", CostRate: openRate, Log: true})
}
}
if len(s.ShortOrders) > 0 {
if macdX == 1 {
s.CloseOrders(&strat.ExitReq{Tag: "closeS", Dirt: core.OdDirtShort, Log: true})
}
} else if dirt < 0 && openRate > 0 {
if macdX == -1 {
s.OpenOrder(&strat.EnterReq{Tag: "short", Short: true, CostRate: openRate, Log: true})
} else if macdX2 == -1 {
s.OpenOrder(&strat.EnterReq{Tag: "short2", Short: true, CostRate: openRate, Log: true})
}
}
if !s.IsWarmUp {
line := fmt.Sprintf("%s %s %s %d %d %f %f %f %f %f macd:%f signal:%f atr:%f er:%f x1:%v x2:%v dirt:%v rate:%f",
s.Account, s.Symbol.Symbol, s.TimeFrame, len(s.LongOrders), len(s.ShortOrders),
e.Open.Get(0), e.High.Get(0), e.Low.Get(0), e.Close.Get(0), e.Volume.Get(0),
macd.Get(0), signal.Get(0), atr.Get(0), er.Get(0), macdX, macdX2, dirt, openRate)
s.Strat.WriteOutput(line, true)
}
},
OnInfoBar: func(s *strat.StratJob, e *ta.BarEnv, pair, tf string) {
macdS, signalS := ta.MACD(e.Close, 12, 26, 9)
macd := macdS.Get(0)
signal := signalS.Get(0)
if macd > 0 && signal > 0 {
s.More = 1
} else if macd < 0 && signal < 0 {
s.More = -1
} else {
s.More = 0
}
if !s.IsWarmUp {
line := fmt.Sprintf("%s %s %f %f %f %f %f macd:%f signal:%f",
pair, tf, e.Open.Get(0), e.High.Get(0), e.Low.Get(0), e.Close.Get(0), e.Volume.Get(0),
macd, signal)
s.Strat.WriteOutput(line, true)
}
},
}
}