You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

118 lines
3.4 KiB

package strategy
import (
"fmt"
"sig-pub/pkg/types"
)
// SuperTrendMacdRSI 结合super trend和rsi指标策略
type SuperTrendMacdRSI struct {
trendWindow int16
trendMul float64 // super trend
rsi int16 // rsi
fast, slow, singal int16 // macd
}
func (s *SuperTrendMacdRSI) New() ISigStrategy {
return &SuperTrendMacdRSI{}
}
func (s *SuperTrendMacdRSI) Meta() StrategyMeta {
return StrategyMeta{
Name: "SuperTrendMacdRSI",
Desc: "SuperTrend + MACD + RSI 量化策略",
Input: []types.InputArg{
{Name: "trendWindow", Type: types.InputTypeUInt, Desc: "SuperTrend ATR周期", Default: 10},
{Name: "trendMul", Type: types.InputTypeUFloat, Desc: "SuperTrend multipiler", Default: 3},
{Name: "rsi", Type: types.InputTypeUInt, Desc: "rsi周期", Default: 14},
{Name: "fast", Type: types.InputTypeUInt, Desc: "macd fast period", Default: 12},
{Name: "slow", Type: types.InputTypeUInt, Desc: "macd slow period", Default: 26},
{Name: "singal", Type: types.InputTypeUInt, Desc: "macd singal period", Default: 9},
},
}
}
// Init 校验参数, 并根据参数初始化策略
func (s *SuperTrendMacdRSI) Init(input types.Input) (err error) {
s.trendWindow = input.Int16("trendWindow")
s.trendMul = input.Float("trendMul")
s.rsi = input.Int16("rsi")
s.fast = input.Int16("fast")
s.slow = input.Int16("slow")
s.singal = input.Int16("singal")
if s.fast >= s.slow {
return fmt.Errorf("macd fast(%d) >= slow(%d)", s.fast, s.slow)
}
return
}
func (s *SuperTrendMacdRSI) CandlePeriods(ctx ISingleSigStrategyContext) int16 {
return max(
ctx.Indicator("SuperTrend", types.Input{"window": s.trendWindow, "mul": s.trendMul}).CandlePeriods(),
ctx.Indicator("RSI", s.rsi).CandlePeriods(),
ctx.Indicator("MACD", types.Input{
"fast": s.fast,
"slow": s.slow,
"singal": s.singal,
}).CandlePeriods(),
21,
)
}
func (s *SuperTrendMacdRSI) Update(ctx ISingleSigStrategyContext) (side types.Side) {
superTrend := ctx.Indicator("SuperTrend", types.Input{"window": s.trendWindow, "mul": s.trendMul})
rsi := ctx.Indicator("RSI", s.rsi).Get(0)
macd := ctx.Indicator("MACD", types.Input{"fast": s.fast, "slow": s.slow, "singal": s.singal})
macdHist := macd.Get(0)
macdDea := macd.StateSeries("dea", 0, 2) // macd_dea信号线
macdDif := macd.StateSeries("dif", 0, 2) // macd_dif线
crossover := macdDif[0] > macdDea[0] && macdDif[1] < macdDea[1] // 金叉
crossunder := macdDif[0] < macdDea[0] && macdDif[1] > macdDea[1] // 死叉
closeP := ctx.Get(0).CloseF64()
volAvg := ctx.Series(1, 20).Vol().Avg()
vol := ctx.Get(0).VolF64()
trend := superTrend.Get(0)
trendDirection := superTrend.State("direction", 0)
// 金叉状态且正向扩张
if crossover && macdHist > 0 {
// RSI 强度过滤
if rsi > 50 && rsi < 70 {
// SuperTrend 趋势确认
if closeP > trend && trendDirection == 1 {
// 成交量过滤
if vol > volAvg*1.5 {
return types.SideLong
}
}
}
}
if crossunder && macdHist < 0 {
if rsi > 30 && rsi < 50 {
// SuperTrend 趋势确认
if closeP < trend && trendDirection == -1 {
// 成交量过滤
if vol > volAvg*1.5 {
return types.SideShort
}
}
}
}
_ = `
// 策略算子脚本DST, 优化golang底层不影响策略语法
st1 = sig.SuperTrend(window=10, mul=3)
rsi = sig.RSI(window=14)
closeAvg = close[1:10].avg()
st1[0]
st1[0:10]
st1.direction[0]
if rsi[0] > 50
...
`
return
}