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