package trading import ( "fmt" "sig-pub/api/pb" "sig-pub/pkg/types" "sig-pub/pkg/types/series" "sig-pub/pkg/zlog" "sync" ) const ( MaxSeriesKlines = 1280 // slice扩容12次后cap=1280 ) type KlineSeries struct { sync.RWMutex Exchange pb.ExchangeType InstId string Interval types.Interval IntervalAdder types.IntervalAdder lastTs int64 klines []*types.Kline } func NewKlineSeries(exchange pb.ExchangeType, instId string, interval types.Interval) *KlineSeries { intervalAdder, ok := types.SupportedIntervals[interval] if !ok { panic(fmt.Errorf("unsupport interval: %s", interval)) } return &KlineSeries{ Exchange: exchange, InstId: instId, Interval: interval, IntervalAdder: intervalAdder, klines: make([]*types.Kline, 0, MaxSeriesKlines/10), } } // Get // [0]当前k线 func (s *KlineSeries) Get(start int16) types.Kline { index := len(s.klines) - 1 - int(start) if index >= 0 && index < len(s.klines)-1 { return *(s.klines[index]) } // todo query store ts := s.Interval.MustAddMul(s.lastTs, int64(-start)) for _, k := range s.klines { if k.Ts == ts { return *k } } panic("kline not exists") } // Series [start...end] func (s *KlineSeries) Series(start, end int16) (klines series.Klines) { endTs := s.Interval.MustAddMul(s.lastTs, int64(-start)) startTs := s.Interval.MustAddMul(s.lastTs, int64(-end)) _ = endTs _ = startTs // return a.klineStore.GetRange(startTs, endTs) // todo return } // 检查k线序列完整 func (s *KlineSeries) Update(kline *types.Kline) (lastTs int64, serial bool) { s.Lock() defer s.Unlock() serial = true lastTs = s.lastTs if kline.Ts <= s.lastTs { return } // 检查k线是否连续 if len(s.klines) > 0 { expectTs := s.Interval.MustAddMul(s.lastTs, 1) if kline.Ts != expectTs { serial = false zlog.Warningf("k线不连续: instId=%s(%s), interval=%s, lastTs=%d, expected=%d, got=%d", s.InstId, s.Exchange, s.Interval, s.lastTs, expectTs, kline.Ts) return } } if len(s.klines) < MaxSeriesKlines { s.klines = append(s.klines, kline) } else { // 循环复用切片空间,避免扩容 length := len(s.klines) copy(s.klines, s.klines[length-MaxSeriesKlines+1:]) s.klines[MaxSeriesKlines-1] = kline s.klines = s.klines[:MaxSeriesKlines] } s.lastTs = kline.Ts return }