7 changed files with 166 additions and 6 deletions
@ -0,0 +1,63 @@
|
||||
package strategy |
||||
|
||||
import ( |
||||
"math" |
||||
"sig-pub/pkg/types" |
||||
"sig-pub/pkg/zlog" |
||||
) |
||||
|
||||
// MeanReversionV1
|
||||
type MeanReversionV1 struct { |
||||
IIntervalSigStrategy |
||||
rate float64 |
||||
rate2 float64 |
||||
} |
||||
|
||||
func (s *MeanReversionV1) New() ISigStrategy { |
||||
return &MeanReversionV1{} |
||||
} |
||||
|
||||
func (s *MeanReversionV1) Meta() StrategyMeta { |
||||
return StrategyMeta{ |
||||
Name: "MeanReversionV1", |
||||
Desc: "均值回归策略v1", |
||||
Input: []types.InputArg{ |
||||
{Name: "rate", Type: types.InputTypeUFloat, Desc: "上线影线与基线比例"}, |
||||
{Name: "rate2", Type: types.InputTypeUFloat, Desc: "上线影线之间比例"}, |
||||
}, |
||||
} |
||||
} |
||||
|
||||
func (s *MeanReversionV1) Init(input types.Input) (err error) { // 校验参数, 并根据参数初始化策略
|
||||
s.rate = input.Float("rate") |
||||
s.rate2 = input.Float("rate2") |
||||
return |
||||
} |
||||
|
||||
func (s *MeanReversionV1) CandlePeriods(ctx IIntervalSigStrategyContext) (iss *types.IntervalState[int16]) { |
||||
iss = types.NewIntervalState[int16]() |
||||
iss.Set(types.Interval5m, 1) |
||||
iss.Set(types.Interval15m, 2) |
||||
iss.Set(types.Interval30m, 2) |
||||
return |
||||
} |
||||
|
||||
func (s *MeanReversionV1) Update(ctx IIntervalSigStrategyContext) (side types.Side) { |
||||
// O 109744.8 H 110600 L 109507.5 C 109686.8
|
||||
k0 := ctx.Get("5m", 0) |
||||
open, close, high, low := k0.OpenF64(), k0.CloseF64(), k0.HighF64(), k0.LowF64() |
||||
base := math.Abs(open - close) |
||||
rup := (high - max(open, close)) / base |
||||
rdown := (min(open, close) - low) / base |
||||
|
||||
if k0.Ts == 1761833700000 { |
||||
zlog.Debugf("base=%.4f, rup=%.4f, rdown=%.4f", base, rup, rdown) |
||||
} |
||||
if rup > s.rate && rup/rdown > s.rate2 { |
||||
return types.SideLong |
||||
} |
||||
if rdown > s.rate && rdown/rup > s.rate2 { |
||||
return types.SideShort |
||||
} |
||||
return |
||||
} |
||||
@ -0,0 +1,83 @@
|
||||
package strategy |
||||
|
||||
import ( |
||||
"math" |
||||
"sig-pub/pkg/types" |
||||
) |
||||
|
||||
// TrendTrackV1 趋势追踪策略v1
|
||||
type TrendTrackV1 struct { |
||||
} |
||||
|
||||
func (s *TrendTrackV1) New() ISigStrategy { |
||||
return &TrendTrackV1{} |
||||
} |
||||
|
||||
func (s *TrendTrackV1) Meta() StrategyMeta { |
||||
return StrategyMeta{ |
||||
Name: "TrendTrackV1", |
||||
Desc: "趋势追踪策略v1", |
||||
Input: []types.InputArg{ |
||||
// {Name: "trend1Window", Type: types.InputTypeUInt, Desc: "SuperTrend ATR周期"},
|
||||
}, |
||||
} |
||||
} |
||||
|
||||
// Init 校验参数, 并根据参数初始化策略
|
||||
func (s *TrendTrackV1) Init(input types.Input) (err error) { |
||||
return |
||||
} |
||||
|
||||
func (s *TrendTrackV1) CandlePeriods(ctx ISingleSigStrategyContext) int16 { |
||||
return max( |
||||
ctx.Indicator("RSI", types.Input{"window": 14}).CandlePeriods(), |
||||
ctx.Indicator("ADX", types.Input{"window": 14}).CandlePeriods(), |
||||
ctx.Indicator("SuperTrend", types.Input{"window": 14, "mul": 2}).CandlePeriods(), |
||||
) |
||||
} |
||||
|
||||
func (s *TrendTrackV1) Update(ctx ISingleSigStrategyContext) (side types.Side) { |
||||
// RSI向上强度衰减后,RSI转向下且强度增加,考虑趋势反转,发出卖出信号
|
||||
rsi := ctx.Indicator("RSI", types.Input{"window": 14}) |
||||
r0 := rsi.Get(0) |
||||
r1 := rsi.Get(1) |
||||
r2 := rsi.Get(2) |
||||
r3 := rsi.Get(3) |
||||
|
||||
d1 := r0 - r1 |
||||
d2 := r1 - r2 |
||||
d3 := r2 - r3 |
||||
|
||||
upWeakening := d3 > d2 && d2 > 0 |
||||
turnDown := d1 < 0 |
||||
downStrengthUp := math.Abs(d1) > d2 |
||||
|
||||
if upWeakening && turnDown && downStrengthUp { |
||||
return types.SideShort |
||||
} |
||||
return |
||||
|
||||
// adx := ctx.Indicator("ADX", types.Input{"window": 14})
|
||||
// superTrend := ctx.Indicator("SuperTrend", types.Input{"window": 14, "mul": 2})
|
||||
|
||||
// rsi
|
||||
// adxValue := adx.Get(0) // 趋势强度
|
||||
// direction := superTrend.State("direction", 0) // 趋势方向
|
||||
|
||||
// if direction == 1 && adxValue > 25 {
|
||||
// return types.SideLong
|
||||
// }
|
||||
|
||||
// if direction == -1 && adxValue > 25 {
|
||||
// return types.SideShort
|
||||
// }
|
||||
|
||||
// macd := ctx.Indicator("MACD", types.Input{"fast": 12, "slow": 26, "singal": 9})
|
||||
// macdDea := macd.StateSeries("dea", 0, 2)
|
||||
// macdDif := macd.StateSeries("dif", 0, 2)
|
||||
// crossover := macdDif[0] > macdDea[0] && macdDif[1] < macdDea[1] // 金叉
|
||||
// crossunder := macdDif[0] < macdDea[0] && macdDif[1] > macdDea[1] // 死叉
|
||||
|
||||
// volAvg := ctx.Series(1, 20).Vol().Avg()
|
||||
// vol := ctx.Get(0).VolF64()
|
||||
} |
||||
Loading…
Reference in new issue