package okx import ( "fmt" "sig-pub/pkg/types" "strconv" "github.com/govalues/decimal" ) // WS/K线频道 // 获取K线数据,推送频率最快是间隔1秒推送一次数据。 type CandleData [][]string var ( // k线类型 // 如 [1s/1m/3m/5m/15m/30m/1H/2H/4H] // 香港时间开盘价k线:[6H/12H/1D/2D/3D/1W/1M/3M] // UTC时间开盘价k线:[6Hutc/12Hutc/1Dutc/2Dutc/3Dutc/1Wutc/1Mutc/3Mutc] // "candle1s" candle3Mutc candle1Mutc candle1Wutc candle1Dutc candle2Dutc candle3Dutc candle5Dutc candle12Hutc candle6Hutc // candles = []string{"candle3M", "candle1M", "candle1W", "candle1D", "candle2D", "candle3D", "candle5D", "candle12H", "candle6H", "candle4H", "candle2H", "candle1H", "candle30m", "candle15m", "candle5m", "candle3m", "candle1m"} // // subCandles = []string{ // "candle3M", "candle1M", // "candle1W", "candle1D", "candle2D", "candle3D", "candle5D", // "candle12H", "candle6H", "candle4H", "candle2H", "candle1H", // "candle30m", "candle15m", "candle5m", "candle3m", "candle1m", // "candle1s", // } ) // ChannelCandle k线订阅频道 type ChannelCandle struct { cfg wsChannelConfig[*CandleData, *types.ChannelKline] wsChannel *wsChannel[*CandleData, *types.ChannelKline] } func NewChannelCandle( traceId string, httpProxy string, ) *ChannelCandle { var candles []string for _, interval := range subscribeCandles { candles = append(candles, "candle"+interval) } cfg := wsChannelConfig[*CandleData, *types.ChannelKline]{ channelId: traceId, httpProxy: httpProxy, wsUrl: "/ws/v5/business", subscribeChannels: candles, dataInstanceFunc: func() *CandleData { var d CandleData return &d }, dataMappingFunc: candleData2Klines, } return &ChannelCandle{cfg: cfg} } func (c *ChannelCandle) Init() (err error) { c.wsChannel = newWsChannel(c.cfg) return c.wsChannel.Init() } func (c *ChannelCandle) Consumer() <-chan *types.ChannelKline { return c.wsChannel.Consumer() } func (c *ChannelCandle) Subscribe(instIds ...string) (err error) { return c.wsChannel.Subscribe(instIds...) } func (c *ChannelCandle) Unsubscribe(instIds ...string) (err error) { return c.wsChannel.Unsubscribe(instIds...) } func (c *ChannelCandle) IsSubscribe(instId string) bool { return c.wsChannel.IsSubscribed(instId) } func (c *ChannelCandle) GetSubscribes() (instIds []string) { return c.wsChannel.GetSubscribes() } // func candleData2Klines() (klines []*types.Kline) { func candleData2Klines(channelData *ChannelData[*CandleData]) (r *types.ChannelKline, err error) { r = &types.ChannelKline{ ExgInstId: channelData.InstId, Exchange: types.ExchangeOKX, } for _, data := range *channelData.Data { ts, e := strconv.ParseInt(data[0], 10, 64) if e != nil { err = e return } kline := &types.Kline{ Ts: ts, Confirm: data[8] == "1", } switch channelData.Channel { default: err = fmt.Errorf("unsupport candle: %s", channelData.Channel) continue case "candle1s": kline.Interval = types.Interval1s // case "candle5s": // kline.Interval = types.Interval5s case "candle1m": kline.Interval = types.Interval1m case "candle3m": kline.Interval = types.Interval3m case "candle5m": kline.Interval = types.Interval5m case "candle15m": kline.Interval = types.Interval15m case "candle30m": kline.Interval = types.Interval30m case "candle1H": kline.Interval = types.Interval1h case "candle2H": kline.Interval = types.Interval2h case "candle4H": kline.Interval = types.Interval4h case "candle6H": kline.Interval = types.Interval6h case "candle12H": kline.Interval = types.Interval12h case "candle1D": kline.Interval = types.Interval1d case "candle2D": kline.Interval = types.Interval2d case "candle3D": kline.Interval = types.Interval3d case "candle5D": kline.Interval = types.Interval5d case "candle1W": kline.Interval = types.Interval1w case "candle1M": kline.Interval = types.Interval1mo case "candle3M": kline.Interval = types.Interval3mo } var kinds = []*decimal.Decimal{&kline.Open, &kline.High, &kline.Low, &kline.Close, &kline.Vol, nil, &kline.VolQuote} for i := 1; i <= 7; i++ { if kinds[i-1] == nil { continue } *kinds[i-1], err = decimal.Parse(data[i]) if err != nil { return } } // ims, ok := kline.Interval.Milliseconds() // if !ok { // err = fmt.Errorf("unsupport interval: %v", kline.Interval) // continue // } // kline.Tid = ts / ims r.Klines = append(r.Klines, kline) } return }