mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-13 02:23:51 +00:00
Merge pull request #494 from zenixls2/feature/ftx_pub_trade
This commit is contained in:
commit
42a503c0f9
|
@ -111,25 +111,36 @@ func (s *Stream) addSubscription(request websocketRequest) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Stream) Subscribe(channel types.Channel, symbol string, option types.SubscribeOptions) {
|
func (s *Stream) Subscribe(channel types.Channel, symbol string, option types.SubscribeOptions) {
|
||||||
if channel == types.BookChannel {
|
switch channel {
|
||||||
|
case types.BookChannel:
|
||||||
s.addSubscription(websocketRequest{
|
s.addSubscription(websocketRequest{
|
||||||
Operation: subscribe,
|
Operation: subscribe,
|
||||||
Channel: orderBookChannel,
|
Channel: orderBookChannel,
|
||||||
Market: toLocalSymbol(TrimUpperString(symbol)),
|
Market: toLocalSymbol(TrimUpperString(symbol)),
|
||||||
})
|
})
|
||||||
} else if channel == types.BookTickerChannel {
|
return
|
||||||
|
case types.BookTickerChannel:
|
||||||
s.addSubscription(websocketRequest{
|
s.addSubscription(websocketRequest{
|
||||||
Operation: subscribe,
|
Operation: subscribe,
|
||||||
Channel: bookTickerChannel,
|
Channel: bookTickerChannel,
|
||||||
Market: toLocalSymbol(TrimUpperString(symbol)),
|
Market: toLocalSymbol(TrimUpperString(symbol)),
|
||||||
})
|
})
|
||||||
} else if channel == types.KLineChannel {
|
return
|
||||||
|
case types.KLineChannel:
|
||||||
// FTX does not support kline channel, do polling
|
// FTX does not support kline channel, do polling
|
||||||
interval := types.Interval(option.Interval)
|
interval := types.Interval(option.Interval)
|
||||||
ks := klineSubscription{symbol: symbol, interval: interval}
|
ks := klineSubscription{symbol: symbol, interval: interval}
|
||||||
s.klineSubscriptions = append(s.klineSubscriptions, ks)
|
s.klineSubscriptions = append(s.klineSubscriptions, ks)
|
||||||
} else {
|
return
|
||||||
panic("only support book/kline channel now")
|
case types.MarketTradeChannel:
|
||||||
|
s.addSubscription(websocketRequest{
|
||||||
|
Operation: subscribe,
|
||||||
|
Channel: marketTradeChannel,
|
||||||
|
Market: toLocalSymbol(TrimUpperString(symbol)),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
default:
|
||||||
|
panic("only support book/kline/trade channel now")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,8 @@ func (h *messageHandler) handleMessage(message []byte) {
|
||||||
h.handleOrderBook(r)
|
h.handleOrderBook(r)
|
||||||
case bookTickerChannel:
|
case bookTickerChannel:
|
||||||
h.handleBookTicker(r)
|
h.handleBookTicker(r)
|
||||||
|
case marketTradeChannel:
|
||||||
|
h.handleMarketTrade(r)
|
||||||
case privateOrdersChannel:
|
case privateOrdersChannel:
|
||||||
h.handlePrivateOrders(r)
|
h.handlePrivateOrders(r)
|
||||||
case privateTradesChannel:
|
case privateTradesChannel:
|
||||||
|
@ -83,6 +85,21 @@ func (h *messageHandler) handleOrderBook(response websocketResponse) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *messageHandler) handleMarketTrade(response websocketResponse) {
|
||||||
|
if response.Type == subscribedRespType {
|
||||||
|
h.handleSubscribedMessage(response)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
trades, err := response.toMarketTradeResponse()
|
||||||
|
if err != nil {
|
||||||
|
logger.WithError(err).Errorf("failed to generate market trade %v", response)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, trade := range trades {
|
||||||
|
h.EmitMarketTrade(trade)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (h *messageHandler) handleBookTicker(response websocketResponse) {
|
func (h *messageHandler) handleBookTicker(response websocketResponse) {
|
||||||
if response.Type == subscribedRespType {
|
if response.Type == subscribedRespType {
|
||||||
h.handleSubscribedMessage(response)
|
h.handleSubscribedMessage(response)
|
||||||
|
|
|
@ -24,6 +24,7 @@ const unsubscribe operation = "unsubscribe"
|
||||||
type channel string
|
type channel string
|
||||||
|
|
||||||
const orderBookChannel channel = "orderbook"
|
const orderBookChannel channel = "orderbook"
|
||||||
|
const marketTradeChannel channel = "trades"
|
||||||
const bookTickerChannel channel = "ticker"
|
const bookTickerChannel channel = "ticker"
|
||||||
const privateOrdersChannel channel = "orders"
|
const privateOrdersChannel channel = "orders"
|
||||||
const privateTradesChannel channel = "fills"
|
const privateTradesChannel channel = "fills"
|
||||||
|
@ -119,6 +120,42 @@ type orderUpdateResponse struct {
|
||||||
Data ftxapi.Order `json:"data"`
|
Data ftxapi.Order `json:"data"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type trade struct {
|
||||||
|
Price fixedpoint.Value `json:"price"`
|
||||||
|
Size fixedpoint.Value `json:"size"`
|
||||||
|
Side string `json:"side"`
|
||||||
|
Liquidation bool `json:"liquidation"`
|
||||||
|
Time time.Time `json:"time"`
|
||||||
|
}
|
||||||
|
type tradeResponse struct {
|
||||||
|
mandatoryFields
|
||||||
|
Data []trade `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r websocketResponse) toMarketTradeResponse() (t []types.Trade, err error) {
|
||||||
|
if r.Channel != marketTradeChannel {
|
||||||
|
return t, fmt.Errorf("type %s, channel %s: channel incorrect", r.Type, r.Channel)
|
||||||
|
}
|
||||||
|
var tds []trade
|
||||||
|
if err = json.Unmarshal(r.Data, &tds); err != nil {
|
||||||
|
return t, err
|
||||||
|
}
|
||||||
|
t = make([]types.Trade, len(tds))
|
||||||
|
for i, td := range tds {
|
||||||
|
tt := &t[i]
|
||||||
|
tt.Exchange = types.ExchangeFTX
|
||||||
|
tt.Price = td.Price
|
||||||
|
tt.Quantity = td.Size
|
||||||
|
tt.QuoteQuantity = td.Size
|
||||||
|
tt.Symbol = r.Market
|
||||||
|
tt.Side = types.SideType(TrimUpperString(string(td.Side)))
|
||||||
|
tt.IsBuyer = true
|
||||||
|
tt.IsMaker = false
|
||||||
|
tt.Time = types.Time(td.Time)
|
||||||
|
}
|
||||||
|
return t, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (r websocketResponse) toOrderUpdateResponse() (orderUpdateResponse, error) {
|
func (r websocketResponse) toOrderUpdateResponse() (orderUpdateResponse, error) {
|
||||||
if r.Channel != privateOrdersChannel {
|
if r.Channel != privateOrdersChannel {
|
||||||
return orderUpdateResponse{}, fmt.Errorf("type %s, channel %s: %w", r.Type, r.Channel, errUnsupportedConversion)
|
return orderUpdateResponse{}, fmt.Errorf("type %s, channel %s: %w", r.Type, r.Channel, errUnsupportedConversion)
|
||||||
|
@ -150,7 +187,7 @@ func (r websocketResponse) toTradeUpdateResponse() (tradeUpdateResponse, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Private:
|
Private:
|
||||||
order: {"type": "subscribed", "channel": "orders"}
|
order: {"type": "subscribed", "channel": "orders"}
|
||||||
|
|
||||||
Public
|
Public
|
||||||
|
|
Loading…
Reference in New Issue
Block a user