package exchange import ( "context" "fmt" "sig-pub/api/pb" "sig-pub/pkg/types" "sig-pub/pkg/utils/collect" "sync/atomic" "github.com/govalues/decimal" ) // 交易所行情数据订阅 type ExchangeSubscriber interface { // 交易所类型 ExhcangeType() pb.ExchangeType // 消费k线行情数据 ConsumerKline() <-chan *types.ChannelKline // 订阅产品k线行情 SubscribeKline(instIds ...string) (err error) // 取消订阅产品k线行情 UnsubscribeKline(instIds ...string) (err error) } // 交易所行情数据请求 type ExchangeFetcher interface { // 交易所类型 ExhcangeType() pb.ExchangeType // 获取区间内历史k线数据 FetchHistoryKlines(ctx context.Context, instId string, interval types.Interval, after, before int64) (klines []*types.Kline, err error) } // 交易所交互接口 type Exchange struct { ExchangeType pb.ExchangeType Fetcher ExchangeFetcher Subscriber ExchangeSubscriber TradeInstIds *collect.SyncMap[string, string] // map[string]*ExchangeTradeInstance // ExchangeInsts *collect.SyncMap[string, *ExchangeTradeInstance] // map[string]*ExchangeTradeInstance // } // 交易所交易产品 type ExchangeTradeInstance struct { Inst *types.TradeInstance Status atomic.Int32 // 交易产品状态, 0.初始化中 1.正常, todo status change event publish LiveKline *types.IntervalState[types.Kline] // 实时k线数据 LiveKStartTs *types.IntervalState[int64] // ws开始订阅k线标记时间戳 HistoryMarkTs *types.IntervalState[int64] // 拉取历史k线标记时间戳 Last decimal.Decimal // 交易产品实时价格tick更新 } func NewExchange(fetcher ExchangeFetcher, subscriber ExchangeSubscriber) *Exchange { exType := fetcher.ExhcangeType() if exType != subscriber.ExhcangeType() { panic(fmt.Errorf("exchange type not match: %#v, %#v", exType, subscriber.ExhcangeType())) } return &Exchange{ ExchangeType: exType, Fetcher: fetcher, Subscriber: subscriber, TradeInstIds: collect.NewSyncMap[string, string](), ExchangeInsts: collect.NewSyncMap[string, *ExchangeTradeInstance](), } }