package sig import ( "context" "fmt" "io" "sig-pub/api/pb" "sig-pub/pkg/indicator" "sig-pub/pkg/types" "sig-pub/pkg/types/series" "sig-pub/pkg/zlog" "google.golang.org/grpc" ) type IOffsetIndicatorContext interface { indicator.IIndicatorContext SetOffset(offset int16) AddOffset(offset int16) GetOffset() (offset int16) } // IndicatorContext 指标上下文, 提供k线序列给指标计算使用 type IndicatorContext struct { IOffsetIndicatorContext kSeries *KlineSeries offset int16 } func NewIndicatorContext(kSeries *KlineSeries) *IndicatorContext { return &IndicatorContext{ kSeries: kSeries, } } func (c *IndicatorContext) SetOffset(offset int16) { c.offset = offset } func (c *IndicatorContext) AddOffset(offset int16) { c.offset += offset } func (c *IndicatorContext) GetOffset() (offset int16) { return c.offset } func (c *IndicatorContext) Get(offset int16) (kline types.Kline) { offset += c.offset k, ok := c.kSeries.Get(offset) if !ok { lastTs := c.kSeries.LastTs() zlog.Warningf("get kline series offset out of range: offset=%d, lastTs=%d", offset, lastTs) panic(fmt.Errorf("get kline series offset out of range: offset=%d", offset)) } return k } func (c *IndicatorContext) Series(offset, count int16) (klines series.Klines) { offset += c.offset ks, ok := c.kSeries.Series(offset, count) if !ok { zlog.Warningf("get kline series offset out of range: offset=%d, count=%d, lastTs=%d", offset, count, c.kSeries.LastTs()) panic(fmt.Errorf("get kline series offset out of range: offset=%d, count=%d", offset, count)) } return ks } type HistoryIndicatorContext struct { IOffsetIndicatorContext exchangeClient pb.ExchangeServiceClient context *IndicatorContext } func NewHistoryIndicatorContext(exchangeClient pb.ExchangeServiceClient) *HistoryIndicatorContext { return &HistoryIndicatorContext{ exchangeClient: exchangeClient, } } func (c *HistoryIndicatorContext) Init(sr *pb.SeriesRange) (totalK int, err error) { // fetch history series req := &pb.ReqHistoryKlineStream{ Series: sr, } stream, err := c.exchangeClient.HistoryKlineStream(context.Background(), req, grpc.UseCompressor("snappy")) if err != nil { zlog.Errorf("fetch history kline stream error: instId=%s(%s), interval=%s, %#v, err=%v", sr.InstId, sr.Exchange, sr.Interval, req, err) return } interval := types.Interval(sr.Interval) klineSeries := NewKlineSeries(sr.Exchange, sr.InstId, interval) for { msg, err0 := stream.Recv() if err0 == io.EOF { break } if err0 != nil { err = err0 zlog.Error("fetch kline stream recv error: ", err0) return } // zlog.Debugf("recv: %s(%s), %s, branch=%d, ts=%d~%d", instId, exchange, interval, len(msg.Klines), msg.Klines[0].Ts, msg.Klines[len(msg.Klines)-1].Ts) totalK += len(msg.Klines) for _, k := range msg.Klines { kline := new(types.Kline) kline.ParsePBKline(sr.Exchange, k) if lastTs, ok := klineSeries.Update(kline); !ok { err = fmt.Errorf("history stream kline not series: last=%d", lastTs) return } } } c.context = NewIndicatorContext(klineSeries) return } func (c *HistoryIndicatorContext) SetOffset(offset int16) { c.context.SetOffset(offset) } func (c *HistoryIndicatorContext) AddOffset(offset int16) { c.context.AddOffset(offset) } func (c *HistoryIndicatorContext) GetOffset() (offset int16) { return c.context.GetOffset() } func (c *HistoryIndicatorContext) Get(offset int16) (kline types.Kline) { return c.context.Get(offset) } func (c *HistoryIndicatorContext) Series(offset, count int16) (klines series.Klines) { return c.context.Series(offset, count) }