diff --git a/README.md b/README.md index f846c54..51ab40b 100644 --- a/README.md +++ b/README.md @@ -87,8 +87,16 @@ strategy0: 趋势追踪,增长趋势, 回测信号可视化, /trading/strategySeries 一样从postgres拉信号/订单数据 -go plugin插件化(指标/策略), 调度docker容器运行回测, grpc资源访问 +用户方向(操作体验优化): + - 账户净值曲线、总收益曲线 + - 月份收益分布柱状图 + - 动态策略脚本: + - python, pine script + - Wasm(WebAssembly), 接口类型WIT + - go plugin插件化(指标/策略, 安全问题?), 调度docker容器运行回测, grpc资源访问 +收益方向: + - trade strategy + - 自动测试(因子挖掘): + 1. 指标分类 + 2. 指标参数组合迭代 (确定潜在的可调参数) -确定潜在的可调参数 - -Wasm(WebAssembly), 接口类型WIT diff --git a/config/exchange.toml b/config/exchange.toml index 662a8bd..e65fb93 100644 --- a/config/exchange.toml +++ b/config/exchange.toml @@ -18,8 +18,9 @@ receiveBuffer = 4096 marketSubscribeLimit = 16 consumeBatch = 1024 consumeLater = 2000 # 时间到达later或者数据累计到batch触发consume +httpProxy = "" # httpProxy = "http://192.168.1.5:7890" -httpProxy = "http://10.255.183.209:7890" +# httpProxy = "http://10.255.183.209:7890" # 模拟盘API交易地址如下: # REST:https://www.okx.com diff --git a/pkg/strategy/sig_strategy_registry.go b/pkg/strategy/sig_strategy_registry.go index 50973c5..d268715 100644 --- a/pkg/strategy/sig_strategy_registry.go +++ b/pkg/strategy/sig_strategy_registry.go @@ -25,6 +25,9 @@ func (r *SigStrategyRegistry) Init() (err error) { r.MustRegistStrategy(&GoldX{}) r.MustRegistStrategy(&SupertrendBOSWaves{}) r.MustRegistStrategy(&CrossStar{}) + r.MustRegistStrategy(&SuperTrendRSI{}) + r.MustRegistStrategy(&SuperTrend2Macd{}) + r.MustRegistStrategy(&SuperTrendMacdRSI{}) return } diff --git a/pkg/strategy/super_trend2_macd.go b/pkg/strategy/super_trend2_macd.go new file mode 100644 index 0000000..ca36010 --- /dev/null +++ b/pkg/strategy/super_trend2_macd.go @@ -0,0 +1,79 @@ +package strategy + +import "sig-pub/pkg/types" + +// SuperTrend2Macd 结合super trend和rsi指标策略 +type SuperTrend2Macd struct { +} + +func (s *SuperTrend2Macd) New() ISigStrategy { + return &SuperTrend2Macd{} +} + +func (s *SuperTrend2Macd) Meta() StrategyMeta { + return StrategyMeta{ + Name: "SuperTrend2Macd", + Desc: "双 SuperTrend + MACD + 成交量", + Input: []types.InputArg{ + // {Name: "trend1Window", Type: types.InputTypeUInt, Desc: "SuperTrend ATR周期"}, + // {Name: "trend1Mul", Type: types.InputTypeUInt, Desc: "SuperTrend multipiler"}, + // {Name: "trend2Window", Type: types.InputTypeUInt, Desc: "SuperTrend ATR周期"}, + // {Name: "trend2Mul", Type: types.InputTypeUInt, Desc: "SuperTrend multipiler"}, + // {Name: "rsiWindow", Type: types.InputTypeUInt, Desc: "rsi周期"}, + }, + } +} + +// Init 校验参数, 并根据参数初始化策略 +func (s *SuperTrend2Macd) Init(input types.Input) (err error) { + return +} + +func (s *SuperTrend2Macd) CandlePeriods(ctx ISingleSigStrategyContext) int16 { + return max( + ctx.Indicator("SuperTrend", types.Input{"window": 10, "mul": 3}).CandlePeriods(), + ctx.Indicator("SuperTrend", types.Input{"window": 14, "mul": 2}).CandlePeriods(), + ctx.Indicator("MacdDEA", types.Input{"fast": 12, "slow": 26, "singal": 9}).CandlePeriods(), + ctx.Indicator("MacdDIF", types.Input{"fast": 12, "slow": 26, "singal": 9}).CandlePeriods(), + 21, + ) +} + +func (s *SuperTrend2Macd) Update(ctx ISingleSigStrategyContext) (side types.Side) { + superTrend1 := ctx.Indicator("SuperTrend", types.Input{"window": 10, "mul": 3}) + superTrend2 := ctx.Indicator("SuperTrend", types.Input{"window": 14, "mul": 2}) + + // 買入:SuperTrend 轉綠(綠線在價格下方)且 RSI > 50(確認動能向上) + // 賣出:SuperTrend 轉紅,或 RSI < 30(超賣退出) + // 風險控制:止損 3%(SuperTrend 線為參考),無固定止盈(讓利潤奔跑) + trend1Directions := superTrend1.StateSeries("direction", 0, 2) + trend2Directions := superTrend2.StateSeries("direction", 0, 2) + + macdDea := ctx.Indicator("MacdDEA", types.Input{"fast": 12, "slow": 26, "singal": 9}).Series(0, 2) // macd_dea信号线 + macdDif := ctx.Indicator("MacdDIF", types.Input{"fast": 12, "slow": 26, "singal": 9}).Series(0, 2) // macd_dif线 + + 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() + + if trend1Directions[0] == 1 && trend1Directions[1] == -1 && + trend2Directions[0] == 1 && trend2Directions[1] == -1 { + if crossover { + if vol > volAvg*1.5 { + return types.SideLong + } + } + } + + if trend1Directions[0] == -1 && trend1Directions[1] == 1 && + trend2Directions[0] == -1 && trend2Directions[1] == 1 { + if crossunder { + if vol > volAvg*1.5 { + return types.SideShort + } + } + } + return +} diff --git a/pkg/strategy/super_trend_macd_rsi.go b/pkg/strategy/super_trend_macd_rsi.go new file mode 100644 index 0000000..a1f68dc --- /dev/null +++ b/pkg/strategy/super_trend_macd_rsi.go @@ -0,0 +1,72 @@ +package strategy + +import "sig-pub/pkg/types" + +// SuperTrendMacdRSI 结合super trend和rsi指标策略 +type SuperTrendMacdRSI struct { +} + +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周期"}, + // {Name: "trendMultipiler", Type: types.InputTypeUInt, Desc: "SuperTrend multipiler"}, + // {Name: "rsiWindow", Type: types.InputTypeUInt, Desc: "rsi周期"}, + }, + } +} + +// Init 校验参数, 并根据参数初始化策略 +func (s *SuperTrendMacdRSI) Init(input types.Input) (err error) { + return +} + +func (s *SuperTrendMacdRSI) CandlePeriods(ctx ISingleSigStrategyContext) int16 { + return max( + ctx.Indicator("SuperTrend", types.Input{"window": 10, "mul": 3}).CandlePeriods(), + ctx.Indicator("RSI", 14).CandlePeriods(), + ctx.Indicator("MacdDEA", types.Input{"fast": 12, "slow": 26, "singal": 9}).CandlePeriods(), + ctx.Indicator("MacdDEA", types.Input{"fast": 12, "slow": 26, "singal": 9}).CandlePeriods(), + ctx.Indicator("MacdDIF", types.Input{"fast": 12, "slow": 26, "singal": 9}).CandlePeriods(), + 21, + ) +} + +func (s *SuperTrendMacdRSI) Update(ctx ISingleSigStrategyContext) (side types.Side) { + superTrend := ctx.Indicator("SuperTrend", types.Input{"window": 10, "mul": 3}) + rsi := ctx.Indicator("RSI", 14).Get(0) + macdHist := ctx.Indicator("Macd", types.Input{"fast": 12, "slow": 26, "singal": 9}).Get(0) // macd柱 + macdDea := ctx.Indicator("MacdDEA", types.Input{"fast": 12, "slow": 26, "singal": 9}).Series(0, 2) // macd_dea信号线 + macdDif := ctx.Indicator("MacdDIF", types.Input{"fast": 12, "slow": 26, "singal": 9}).Series(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 { + // SuperTrend 趋势确认 + if closeP > trend && trendDirection == 1 { + // 成交量过滤 + if vol > volAvg*1.5 { + return types.SideLong + } + } + } + } + return +} diff --git a/pkg/strategy/super_trend_rsi.go b/pkg/strategy/super_trend_rsi.go index e885252..e8b118f 100644 --- a/pkg/strategy/super_trend_rsi.go +++ b/pkg/strategy/super_trend_rsi.go @@ -13,7 +13,7 @@ func (s *SuperTrendRSI) New() ISigStrategy { func (s *SuperTrendRSI) Meta() StrategyMeta { return StrategyMeta{ Name: "SuperTrendRSI", - Desc: "金叉策略", + Desc: "超级趋势结合RSI(动能过滤)策略", Input: []types.InputArg{ {Name: "trendWindow", Type: types.InputTypeUInt, Desc: "SuperTrend ATR周期"}, {Name: "trendMultipiler", Type: types.InputTypeUInt, Desc: "SuperTrend multipiler"}, @@ -30,7 +30,7 @@ func (s *SuperTrendRSI) Init(input types.Input) (err error) { func (s *SuperTrendRSI) CandlePeriods(ctx ISingleSigStrategyContext) int16 { return max( ctx.Indicator("SuperTrend", types.Input{ - "window": ctx.Input().Int16("trendPeriod"), + "window": ctx.Input().Int16("trendWindow"), "mul": ctx.Input().Int16("trendMultipiler"), }).CandlePeriods(), ctx.Indicator("RSI", types.Input{"window": ctx.Input().Int16("rsiWindow")}).CandlePeriods(), @@ -39,12 +39,24 @@ func (s *SuperTrendRSI) CandlePeriods(ctx ISingleSigStrategyContext) int16 { func (s *SuperTrendRSI) Update(ctx ISingleSigStrategyContext) (side types.Side) { superTrend := ctx.Indicator("SuperTrend", types.Input{ - "window": ctx.Input().Int16("trendPeriod"), + "window": ctx.Input().Int16("trendWindow"), "mul": ctx.Input().Int16("trendMultipiler"), }) rsi := ctx.Indicator("RSI", types.Input{"window": ctx.Input().Int16("rsiWindow")}) - _, _ = superTrend, rsi - + // 買入:SuperTrend 轉綠(綠線在價格下方)且 RSI > 50(確認動能向上) + // 賣出:SuperTrend 轉紅,或 RSI < 30(超賣退出) + // 風險控制:止損 3%(SuperTrend 線為參考),無固定止盈(讓利潤奔跑) + trendDirections := superTrend.StateSeries("direction", 0, 2) + if trendDirections[0] == 1 && trendDirections[1] == -1 { + if rsi.Get(0) > 50 { + return types.SideLong + } + } + if trendDirections[0] == -1 && trendDirections[1] == 1 { + if rsi.Get(0) < 30 { + return types.SideShort + } + } return } diff --git a/pkg/trade/trade_strategy.go b/pkg/trade/trade_strategy.go index 35cb1cb..1e585bb 100644 --- a/pkg/trade/trade_strategy.go +++ b/pkg/trade/trade_strategy.go @@ -46,7 +46,7 @@ func (s *TradeStrategy) SigTrade(side types.Side, k types.Kline) (ta TradeArg, e Side: side, Price: price, Leverage: 1, - Qty: 0.01, + Qty: 0.02, KInterval: string(k.Interval), KTime: k.Ts, Time: time,