87 lines
2.0 KiB
Go
87 lines
2.0 KiB
Go
package trend
|
||
|
||
import (
|
||
"github.com/banbox/banbot/config"
|
||
"github.com/banbox/banbot/core"
|
||
"github.com/banbox/banbot/strat"
|
||
ta "github.com/banbox/banta"
|
||
"math"
|
||
)
|
||
|
||
/*
|
||
https://www.forexfactory.com/thread/291622-trading-made-simple
|
||
在1d周期,大多数品种上长期较好;稳定性一般
|
||
*/
|
||
|
||
func eelfranzTDI(p *config.RunPolicyConfig) *strat.TradeStrat {
|
||
var rsiLen = p.DefInt("rsiLen", 13, core.PNorm(8, 25))
|
||
var rsiMaLen = p.DefInt("rsiMa", 34, core.PNorm(20, 40))
|
||
var fastLen = p.DefInt("fast", 2, core.PNorm(2, 5))
|
||
var slowLen = p.DefInt("slow", 7, core.PNorm(4, 15))
|
||
return &strat.TradeStrat{
|
||
WarmupNum: 50,
|
||
OnBar: func(s *strat.StratJob) {
|
||
e := s.Env
|
||
rsi := ta.RSI(e.Close, rsiLen)
|
||
rsiMa := ta.SMA(rsi, rsiMaLen).Get(0)
|
||
|
||
stDev := StDev(rsi, rsiMaLen).Get(0)
|
||
upZone := rsiMa + 1.6185*stDev
|
||
dnZone := rsiMa - 1.6185*stDev
|
||
// market base line
|
||
marketBase := (upZone + dnZone) / 2
|
||
|
||
// rsi price line: green
|
||
fast := ta.SMA(rsi, fastLen).Get(0)
|
||
// trade signal line: red
|
||
slow := ta.SMA(rsi, slowLen).Get(0)
|
||
|
||
if len(s.LongOrders) > 0 {
|
||
if fast < slow {
|
||
s.CloseOrders(&strat.ExitReq{
|
||
Tag: "exitL",
|
||
Dirt: core.OdDirtLong,
|
||
})
|
||
}
|
||
} else if fast > max(slow, marketBase) {
|
||
s.OpenOrder(&strat.EnterReq{
|
||
Tag: "long",
|
||
})
|
||
}
|
||
if len(s.ShortOrders) > 0 {
|
||
if fast > slow {
|
||
s.CloseOrders(&strat.ExitReq{
|
||
Tag: "exitS",
|
||
Dirt: core.OdDirtShort,
|
||
})
|
||
}
|
||
} else if slow > max(fast, marketBase) {
|
||
s.OpenOrder(&strat.EnterReq{
|
||
Tag: "short",
|
||
Short: true,
|
||
})
|
||
}
|
||
},
|
||
}
|
||
}
|
||
|
||
func StDev(obj *ta.Series, period int) *ta.Series {
|
||
res := obj.To("stDev", period)
|
||
if res.Cached() {
|
||
return res
|
||
}
|
||
arr := ta.WrapFloatArr(res, period, obj.Get(0))
|
||
if len(arr) < period {
|
||
return res.Append(math.NaN())
|
||
} else {
|
||
var sum, ssum float64
|
||
for _, v := range arr {
|
||
sum += v
|
||
ssum += v * v
|
||
}
|
||
var lenFlt = float64(period)
|
||
variance := (ssum*lenFlt - sum*sum) / (lenFlt * (lenFlt - 1))
|
||
return res.Append(math.Sqrt(variance))
|
||
}
|
||
}
|