From 27b3ff8af194ecbf6498412cbeaa554f309ca9e3 Mon Sep 17 00:00:00 2001 From: strange Date: Tue, 27 Jan 2026 15:50:49 +0000 Subject: [PATCH] 1 --- api/trading.proto | 1 + config/exchange.toml | 4 ++-- internal/trading/trading_service.go | 1 + pkg/indicator/boll.go | 16 +++++++-------- pkg/indicator/ema.go | 2 +- pkg/indicator/indicator_registry.go | 2 +- pkg/indicator/sam.go | 8 +++++--- pkg/types/input.go | 16 +++++++-------- pkg/types/kline.go | 30 ++++++++++++++--------------- pkg/types/kline_series.go | 14 +++++++------- 10 files changed, 49 insertions(+), 45 deletions(-) diff --git a/api/trading.proto b/api/trading.proto index 196abcb..aa1a673 100644 --- a/api/trading.proto +++ b/api/trading.proto @@ -78,6 +78,7 @@ message RspStrategySeries { repeated int32 signal = 1; // pub.Side: 1.buy,2.sell repeated int64 times = 2; repeated double prices = 3; + repeated int32 direction = 4; // 1.up,2.down } message ReqBacktest { diff --git a/config/exchange.toml b/config/exchange.toml index caa8ef0..19bb205 100644 --- a/config/exchange.toml +++ b/config/exchange.toml @@ -19,8 +19,8 @@ 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://192.168.1.5:7890" +# httpProxy = "http://10.255.183.209:7890" # 模拟盘API交易地址如下: # REST:https://www.okx.com diff --git a/internal/trading/trading_service.go b/internal/trading/trading_service.go index f9bcb36..0075f28 100644 --- a/internal/trading/trading_service.go +++ b/internal/trading/trading_service.go @@ -360,6 +360,7 @@ func (svc *TradingService) StrategySeries(ctx context.Context, req *pb.ReqStrate } side := lang.Ternary(sigSide == types.SideLong, pb.Side_BUY, pb.Side_SELL) rsp.Signal = append(rsp.Signal, int32(side)) + rsp.Direction = append(rsp.Direction, lang.Ternary[int32](k.OpenF64() > k.CloseF64(), 1, 2)) rsp.Prices = append(rsp.Prices, k.CloseF64()) // 处理k线时间 ktime := k.Ts diff --git a/pkg/indicator/boll.go b/pkg/indicator/boll.go index 148b20f..4f1b436 100644 --- a/pkg/indicator/boll.go +++ b/pkg/indicator/boll.go @@ -5,20 +5,20 @@ import ( "sig-pub/pkg/types" ) -// Boll 布林带 -type Boll struct { +// BOLL 布林带 +type BOLL struct { } -func (c *Boll) Meta() IndicatorMeta { +func (c *BOLL) Meta() IndicatorMeta { return IndicatorMeta{ - Name: "Boll", + Name: "BOLL", Input: []types.InputArg{ {Name: "window", Type: types.InputTypeUInt, Desc: "窗口大小"}, - {Name: "pt", Type: types.InputTypeKPriceType, Desc: "k线序列类型"}, + {Name: "pt", Type: types.InputTypePriceType, Desc: "k线序列类型"}, }, State: []string{"ub", "lb"}, Plots: []Plot{ - {Name: "中轨", State: "vector", Type: PlotHistogram, Props: PlotProps{"color": ColorOrange}}, + {Name: "中轨", State: "vector", Type: PlotLine, Props: PlotProps{"color": ColorOrange}}, {Name: "上轨", State: "ub", Type: PlotLine, Props: PlotProps{"color": ColorRed2}}, {Name: "下轨", State: "lb", Type: PlotLine, Props: PlotProps{"color": ColorRed2}}, {Name: "布林带阴影", State: "ub,lb", Type: PlotShadow, Props: PlotProps{"shadowColor": "rgba(241, 169, 166, 0.2)"}}, @@ -26,11 +26,11 @@ func (c *Boll) Meta() IndicatorMeta { } } -func (c *Boll) CandlePeriods(ctx IIndicatorContext) int16 { +func (c *BOLL) CandlePeriods(ctx IIndicatorContext) int16 { return ctx.Input().Int16("window") } -func (c *Boll) Calculate(ctx IIndicatorContext) (vector float64) { +func (c *BOLL) Calculate(ctx IIndicatorContext) (vector float64) { window := ctx.Input().Int16("window") pt := ctx.Input().PriceType() priceSeries := ctx.Series(0, int16(window)).Price(pt) diff --git a/pkg/indicator/ema.go b/pkg/indicator/ema.go index 893d88c..3f08cee 100644 --- a/pkg/indicator/ema.go +++ b/pkg/indicator/ema.go @@ -13,7 +13,7 @@ func (c *EMA) Meta() IndicatorMeta { Name: "EMA", Input: []types.InputArg{ {Name: "window", Type: types.InputTypeUInt, Desc: "窗口大小"}, - {Name: "pt", Type: types.InputTypeKPriceType, Desc: "k线序列类型"}, + {Name: "pt", Type: types.InputTypePriceType, Desc: "k线序列类型"}, }, } } diff --git a/pkg/indicator/indicator_registry.go b/pkg/indicator/indicator_registry.go index 3487e76..88e9b1d 100644 --- a/pkg/indicator/indicator_registry.go +++ b/pkg/indicator/indicator_registry.go @@ -25,7 +25,7 @@ func (r *IndicatorRegistry) Init() (err error) { r.MustRegistIndicator(&MACD{}) r.MustRegistIndicator(&OBV{}) r.MustRegistIndicator(&WOBV{}) - r.MustRegistIndicator(&Boll{}) + r.MustRegistIndicator(&BOLL{}) r.MustRegistIndicator(&SuperTrend{}) r.MustRegistIndicator(&ADX{}) r.MustRegistIndicator(&KDJ{}) diff --git a/pkg/indicator/sam.go b/pkg/indicator/sam.go index a51248e..cbdb409 100644 --- a/pkg/indicator/sam.go +++ b/pkg/indicator/sam.go @@ -14,7 +14,8 @@ func (c *SMA) Meta() IndicatorMeta { return IndicatorMeta{ Name: "SMA", Input: []types.InputArg{ - {Name: "window", Type: types.InputTypeUInt, Desc: "窗口大小"}, + {Name: "window", Type: types.InputTypeUInt, Desc: "窗口大小", Default: 9}, + {Name: "pt", Type: types.InputTypePriceType, Desc: "k线序列类型", Default: types.PriceTypeDefault}, }, } } @@ -26,9 +27,10 @@ func (c *SMA) CandlePeriods(ctx IIndicatorContext) int16 { // Calculate 计算单根k线sma指标 func (c *SMA) Calculate(ctx IIndicatorContext) (vector float64) { window := ctx.Input().Int16("window") - closeSeries := ctx.Series(0, window).Close() + pt := ctx.Input().PriceType() + priceSeries := ctx.Series(0, window).Price(pt) // sma := talib.Sma(closeSeries, int(window)) // _ = sma[len(sma)-1] - vector = closeSeries.Avg() + vector = priceSeries.Avg() return } diff --git a/pkg/types/input.go b/pkg/types/input.go index 974d132..3f98d25 100644 --- a/pkg/types/input.go +++ b/pkg/types/input.go @@ -97,7 +97,7 @@ func (in Input) Int16(k string) (v int16) { func (in Input) String(k string) (v string) { if k == "pt" && in != nil { if _, ok := in[k]; !ok { - in[k] = KPriceTypeDefault + in[k] = PriceTypeDefault } } v, err := cast.ToStringE(in.get(k, "string")) @@ -115,12 +115,12 @@ func (in Input) Time(k string) (v time.Time) { return } -func (in Input) PriceType(k ...string) (v KPriceType) { +func (in Input) PriceType(k ...string) (v PriceType) { key := "pt" if len(k) > 0 { key = k[0] } - v = KPriceType(in.String(key)) + v = PriceType(in.String(key)) return } @@ -158,11 +158,11 @@ const ( InputTypeInt InputTypeUInt InputTypeTime - InputTypeKPriceType // K线价格类型 - InputTypeUFloats // float数组 - InputTypeUFloats2D // float二维数组 - InputTypeSelect // 单选 - InputTypeCheckBox // 多选 + InputTypePriceType // K线价格类型 + InputTypeUFloats // float数组 + InputTypeUFloats2D // float二维数组 + InputTypeSelect // 单选 + InputTypeCheckBox // 多选 ) type InputArg struct { diff --git a/pkg/types/kline.go b/pkg/types/kline.go index 15d40fd..0000990 100644 --- a/pkg/types/kline.go +++ b/pkg/types/kline.go @@ -89,35 +89,35 @@ func (k Kline) HL2() float64 { return (k.HighF64() + k.LowF64()) / 2 } -func (s Kline) Price(t KPriceType) float64 { +func (s Kline) Price(t PriceType) float64 { switch t { - case KPriceTypeOpen: + case PriceTypeOpen: return s.OpenF64() - case KPriceTypeClose: + case PriceTypeClose: return s.CloseF64() - case KPriceTypeHigh: + case PriceTypeHigh: return s.HighF64() - case KPriceTypeLow: + case PriceTypeLow: return s.LowF64() - case KPriceTypeVol: + case PriceTypeVol: return s.VolF64() - case KPriceTypeVolQuote: + case PriceTypeVolQuote: return s.VolQtyF64() default: panic(fmt.Errorf("kline price type %s not support", t)) } } -type KPriceType string +type PriceType string const ( - KPriceTypeHigh KPriceType = "high" - KPriceTypeLow KPriceType = "low" - KPriceTypeOpen KPriceType = "open" - KPriceTypeClose KPriceType = "close" - KPriceTypeVol KPriceType = "vol" - KPriceTypeVolQuote KPriceType = "volQuote" - KPriceTypeDefault KPriceType = KPriceTypeClose + PriceTypeHigh PriceType = "high" + PriceTypeLow PriceType = "low" + PriceTypeOpen PriceType = "open" + PriceTypeClose PriceType = "close" + PriceTypeVol PriceType = "vol" + PriceTypeVolQuote PriceType = "volQuote" + PriceTypeDefault PriceType = PriceTypeClose ) // ChannelKline k线订阅消息 diff --git a/pkg/types/kline_series.go b/pkg/types/kline_series.go index 505143d..0205d0e 100644 --- a/pkg/types/kline_series.go +++ b/pkg/types/kline_series.go @@ -153,19 +153,19 @@ func (s Klines) VolQuote() series.Floats { return collect.Mapping(s, func(k Kline) float64 { return decimals.MustToFloat64(k.VolQuote) }) } -func (s Klines) Price(t KPriceType) series.Floats { +func (s Klines) Price(t PriceType) series.Floats { switch t { - case KPriceTypeHigh: + case PriceTypeHigh: return s.High() - case KPriceTypeLow: + case PriceTypeLow: return s.Low() - case KPriceTypeOpen: + case PriceTypeOpen: return s.Open() - case KPriceTypeClose: + case PriceTypeClose: return s.Close() - case KPriceTypeVol: + case PriceTypeVol: return s.Vol() - case KPriceTypeVolQuote: + case PriceTypeVolQuote: return s.VolQuote() default: panic(fmt.Errorf("unsupport kline price type: %s", t))