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

127
old/macd_v1.go Normal file
View File

@@ -0,0 +1,127 @@
package old
import (
"fmt"
"github.com/banbox/banbot/btime"
"github.com/banbox/banbot/config"
"github.com/banbox/banbot/strat"
"github.com/banbox/banexg/log"
"github.com/banbox/banstagy/com"
ta "github.com/banbox/banta"
"go.uber.org/zap"
)
func MACD(pol *config.RunPolicyConfig) *strat.TradeStrat {
return &strat.TradeStrat{
Version: 1,
WarmupNum: 300,
MinTfScore: 0.75,
DrawDownExit: true,
OnStartUp: onStartUp,
OnBar: onBar,
}
}
type MoreMACD struct {
*com.ExmTrace
max1 *com.ExmItem
max2 *com.ExmItem
slope float64 // 斜率
delta float64 // 直线偏移值
}
/*
val: 当前指标值
pNum: 前一个索引
ptime:前一个时间戳
*/
func (m *MoreMACD) update(val float64, pNum int, ptime int64) bool {
if m.ExmTrace.Update(val, pNum, ptime) {
var exm *com.ExmItem
last := m.Hist[len(m.Hist)-1]
if last.Valid && m.ExmTrace.Expect < 0 {
exm = last
} else if len(m.Hist) > 1 && m.ExmTrace.Expect > 0 {
exm = m.Hist[len(m.Hist)-2]
} else {
return false
}
// 更新最高点和次高点
if m.max1 == nil || exm.Value >= m.max1.Value {
m.max1 = exm
m.max2 = nil
} else if m.max1 != nil && pNum-exm.BarNum > 500 {
// 最高点超过500个bar过期
if m.max2 != nil && m.max2.Value > exm.Value {
exm = m.max2
}
m.max1 = m.max2
m.max2 = nil
} else if m.max2 == nil || exm.Value > m.max2.Value {
m.max2 = exm
return true
}
}
return false
}
func onStartUp(s *strat.StratJob) {
s.More = &MoreMACD{
ExmTrace: &com.ExmTrace{},
}
}
func onBar(s *strat.StratJob) {
e := s.Env
macd, _ := ta.MACD(e.Close, 12, 26, 9)
atr := ta.ATR(e.High, e.Low, e.Close, 14).Get(0)
m, _ := s.More.(*MoreMACD)
c := e.Close.Get(0)
if m.slope > 0 && m.max1 != nil && m.max2 != nil {
point := m.slope*float64(e.BarNum) + m.delta
tag := ""
stopLoss := float64(0)
if c-atr*2 > point && len(s.LongOrders) == 0 {
// 突破压力线,做多
tag = "long"
stopLoss = point - atr
} else if c+atr*0.5 > point && c <= point+atr && len(s.ShortOrders) == 0 {
// 触发压力线,开空
tag = "short"
stopLoss = max(c, point) + atr*2
}
if tag != "" && !s.IsWarmUp {
price1 := e.Close.Get(e.BarNum - m.max1.BarNum)
price2 := e.Close.Get(e.BarNum - m.max2.BarNum)
date := btime.ToDateStr(e.TimeStop, "")
date1 := btime.ToDateStr(m.max1.TimeMS, "")
date2 := btime.ToDateStr(m.max2.TimeMS, "")
log.Info(fmt.Sprintf("%s open %s, %s %s %.5f - %s %.5f", date, tag, s.Symbol.Symbol,
date1, price1, date2, price2))
err := s.OpenOrder(&strat.EnterReq{
Tag: tag,
StopLoss: stopLoss,
Short: tag == "short",
})
if err != nil {
log.Error("open fail", zap.Error(err))
}
}
}
if m.update(macd.Get(0), e.BarNum-1, e.TimeStart-e.TFMSecs) {
price1 := e.Close.Get(e.BarNum - m.max1.BarNum)
price2 := e.Close.Get(e.BarNum - m.max2.BarNum)
// 更新斜率和偏移值
m.slope = (price2 - price1) / float64(m.max2.BarNum-m.max1.BarNum)
m.delta = price1 - m.slope*float64(m.max1.BarNum)
//date1 := btime.ToDateStr(m.max1.TimeMS, "")
//date2 := btime.ToDateStr(m.max2.TimeMS, "")
//log.Info(fmt.Sprintf("update pt2, %s %s %.5f - %s %.5f", s.Symbols.Symbols,
// date1, price1, date2, price2))
}
}