From b2c3c30eacb94d24a88f5f90d451b164ab34ab7f Mon Sep 17 00:00:00 2001 From: strange Date: Tue, 28 Oct 2025 01:54:51 +0800 Subject: [PATCH] trading strategy series, all series sort desc --- config/exchange.toml | 4 +-- internal/trading/indicator_series.go | 1 + internal/trading/kline_series.go | 8 ++++-- internal/trading/trading_service.go | 42 +++++++++++++++------------- pkg/types/series/floats.go | 6 ++-- 5 files changed, 35 insertions(+), 26 deletions(-) diff --git a/config/exchange.toml b/config/exchange.toml index 4d567a5..c0a42b7 100644 --- a/config/exchange.toml +++ b/config/exchange.toml @@ -18,8 +18,8 @@ receiveBuffer = 4096 marketSubscribeLimit = 16 consumeBatch = 1024 consumeLater = 2000 # 时间到达later或者数据累计到batch触发consume -# 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/indicator_series.go b/internal/trading/indicator_series.go index fc03e22..0091ffe 100644 --- a/internal/trading/indicator_series.go +++ b/internal/trading/indicator_series.go @@ -30,6 +30,7 @@ func (s *WindowIndicatorSeries) Get(offset int16) (vector float64) { return } +// Series 返回指标值序列降序 func (s *WindowIndicatorSeries) Series(offset, count int16) (matrix series.Floats) { // 设置当前相对offset s.indicatorContext.AddOffset(offset) diff --git a/internal/trading/kline_series.go b/internal/trading/kline_series.go index 37c8083..05406b7 100644 --- a/internal/trading/kline_series.go +++ b/internal/trading/kline_series.go @@ -73,7 +73,7 @@ func (s *KlineSeries) Get(offset int16) (k types.Kline, ok bool) { return *(s.klines[index]), true } -// Series 时间升序序列[count...offset] +// Series 时间降序序列[count...offset] // offset: 从序列尾部开始偏移量 // count: 从offset位置开始向序列头部k线条数 func (s *KlineSeries) Series(offset, count int16) (klines series.Klines, ok bool) { @@ -93,9 +93,11 @@ func (s *KlineSeries) Series(offset, count int16) (klines series.Klines, ok bool if ok = indexEnd >= 0 && indexEnd < length && indexStart >= 0 && indexStart < length; !ok { return } - klines = make(series.Klines, 0, indexEnd-indexStart+1) + total := indexEnd - indexStart + 1 + klines = make(series.Klines, total) for i := indexStart; i <= indexEnd; i++ { - klines = append(klines, *(s.klines[i])) + offset := total - 1 - (i - indexStart) + klines[offset] = *(s.klines[i]) } return klines, true } diff --git a/internal/trading/trading_service.go b/internal/trading/trading_service.go index e4d80a6..3672e05 100644 --- a/internal/trading/trading_service.go +++ b/internal/trading/trading_service.go @@ -180,11 +180,11 @@ func (svc *TradingService) IndicatorSeries(indicatorName string, window uint32, if totalK, err = indCtx.Init(sr); err != nil { return } - count := uint32(totalK) - window + count := totalK - int(window) matrix = make([]float64, 0, sr.Count) times = make([]int64, 0, sr.Count) - for i := range count { + for i := count - 1; i >= 0; i-- { indCtx.SetOffset(int16(i)) vector := indicator.Calculate(indCtx, int16(window)) matrix = append(matrix, vector) @@ -227,30 +227,34 @@ func (svc *TradingService) StrategySeries(req *pb.ReqStrategySeries, rsp *pb.Rsp // } // recover todo out of range count, totalK := 0, 0 - indCtx := NewHistoryIndicatorContext(svc.exchangeClient) + indicatorContext := NewHistoryIndicatorContext(svc.exchangeClient) req.Series.Window += MaxIndicatorWindow - if totalK, err = indCtx.Init(req.Series); err != nil { + if totalK, err = indicatorContext.Init(req.Series); err != nil { return } count = totalK - MaxIndicatorWindow - strategyCtx := NewStrategyContext(indCtx, svc.indicatorReg) - for i := range count { - strategyCtx.SetOffset(int16(i)) - side := sigStrategy.Update(strategyCtx) + strategyContext := NewStrategyContext(indicatorContext, svc.indicatorReg) + for i := count - 1; i >= 0; i-- { + strategyContext.SetOffset(int16(i)) + side := sigStrategy.Update(strategyContext) if side == pb.Side_BUY || side == pb.Side_SELL { - k := strategyCtx.Get(0) + signalK := strategyContext.Get(0) rsp.Signal = append(rsp.Signal, side) - rsp.Times = append(rsp.Times, k.Ts) - - strategyCtx.indicatorContext.AddOffset(1) - nextK := strategyCtx.Get(0) - strategyCtx.indicatorContext.AddOffset(-1) - // win = c.Get(0).Close.Cmp(signalPrice) < 0 - rsp.Wins = strategyCtx.wins - // signal []pb.Side // 0.sell,1.buy - // signalTimes []int64 - // wins []bool + rsp.Times = append(rsp.Times, signalK.Ts) + { + // todo delete + win := false + if indicatorContext.GetOffset() > 0 { + nextK := indicatorContext.Get(-1) + if side == pb.Side_BUY { + win = nextK.Close.Cmp(signalK.Close) > 0 + } else { + win = nextK.Close.Cmp(signalK.Close) < 0 + } + } + rsp.Wins = append(rsp.Wins, win) + } } } // 信号点胜率判断 diff --git a/pkg/types/series/floats.go b/pkg/types/series/floats.go index d7cf0a1..bb8677a 100644 --- a/pkg/types/series/floats.go +++ b/pkg/types/series/floats.go @@ -6,6 +6,7 @@ import ( "gonum.org/v1/gonum/floats" ) +// 时间降序指标 type Floats []float64 func NewFloats(vs ...float64) Floats { @@ -25,12 +26,13 @@ func (s Floats) Length() int { } func (s Floats) Diff() (values Floats) { + length := s.Length() for i, v := range s { - if i == 0 { + if i == length-1 { values.Push(0) continue } - values.Push(v - s[i-1]) + values.Push(v - s[i+1]) } return values }