fix(ftxExchange): setup a symbol mapping table

ftx uses BTC/USDT symbol styles, however bbgo uses the BTCUSDT style
We setup a mapping table in Markets() to make conversion
This commit is contained in:
Jui-Nan Lin 2021-05-17 18:32:29 +08:00
parent 345c3c9e2c
commit 316799d5a0
4 changed files with 18 additions and 10 deletions

View File

@ -20,6 +20,10 @@ func toGlobalSymbol(original string) string {
return strings.ReplaceAll(TrimUpperString(original), "/", "") return strings.ReplaceAll(TrimUpperString(original), "/", "")
} }
func toLocalSymbol(original string) string {
return symbolMap[original]
}
func TrimUpperString(original string) string { func TrimUpperString(original string) string {
return strings.ToUpper(strings.TrimSpace(original)) return strings.ToUpper(strings.TrimSpace(original))
} }

View File

@ -21,6 +21,7 @@ const (
) )
var logger = logrus.WithField("exchange", "ftx") var logger = logrus.WithField("exchange", "ftx")
var symbolMap map[string]string
type Exchange struct { type Exchange struct {
key, secret string key, secret string
@ -33,6 +34,7 @@ func NewExchange(key, secret string, subAccount string) *Exchange {
if err != nil { if err != nil {
panic(err) panic(err)
} }
symbolMap = make(map[string]string)
return &Exchange{ return &Exchange{
restEndpoint: u, restEndpoint: u,
key: key, key: key,
@ -73,6 +75,7 @@ func (e *Exchange) QueryMarkets(ctx context.Context) (types.MarketMap, error) {
markets := types.MarketMap{} markets := types.MarketMap{}
for _, m := range resp.Result { for _, m := range resp.Result {
symbol := toGlobalSymbol(m.Name) symbol := toGlobalSymbol(m.Name)
symbolMap[symbol] = m.Name
market := types.Market{ market := types.Market{
Symbol: symbol, Symbol: symbol,
@ -157,7 +160,7 @@ func (e *Exchange) QueryKLines(ctx context.Context, symbol string, interval type
if !isIntervalSupportedInKLine(interval) { if !isIntervalSupportedInKLine(interval) {
return nil, fmt.Errorf("interval %s is not supported", interval.String()) return nil, fmt.Errorf("interval %s is not supported", interval.String())
} }
resp, err := e.newRest().HistoricalPrices(ctx, symbol, interval, int64(options.Limit), since, until) resp, err := e.newRest().HistoricalPrices(ctx, toLocalSymbol(symbol), interval, int64(options.Limit), since, until)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -224,7 +227,7 @@ func (e *Exchange) QueryTrades(ctx context.Context, symbol string, options *type
for since.Before(until) { for since.Before(until) {
// DO not set limit to `1` since you will always get the same response. // DO not set limit to `1` since you will always get the same response.
resp, err := e.newRest().Fills(ctx, symbol, since, until, limit, true) resp, err := e.newRest().Fills(ctx, toLocalSymbol(symbol), since, until, limit, true)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -302,7 +305,7 @@ func (e *Exchange) SubmitOrders(ctx context.Context, orders ...types.SubmitOrder
return createdOrders, fmt.Errorf("unsupported TimeInForce %s. only support GTC", so.TimeInForce) return createdOrders, fmt.Errorf("unsupported TimeInForce %s. only support GTC", so.TimeInForce)
} }
or, err := e.newRest().PlaceOrder(ctx, PlaceOrderPayload{ or, err := e.newRest().PlaceOrder(ctx, PlaceOrderPayload{
Market: TrimUpperString(so.Symbol), Market: toLocalSymbol(TrimUpperString(so.Symbol)),
Side: TrimLowerString(string(so.Side)), Side: TrimLowerString(string(so.Side)),
Price: so.Price, Price: so.Price,
Type: TrimLowerString(string(so.Type)), Type: TrimLowerString(string(so.Type)),
@ -329,7 +332,7 @@ func (e *Exchange) SubmitOrders(ctx context.Context, orders ...types.SubmitOrder
func (e *Exchange) QueryOpenOrders(ctx context.Context, symbol string) (orders []types.Order, err error) { func (e *Exchange) QueryOpenOrders(ctx context.Context, symbol string) (orders []types.Order, err error) {
// TODO: invoke open trigger orders // TODO: invoke open trigger orders
resp, err := e.newRest().OpenOrders(ctx, symbol) resp, err := e.newRest().OpenOrders(ctx, toLocalSymbol(symbol))
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -362,7 +365,7 @@ func (e *Exchange) QueryClosedOrders(ctx context.Context, symbol string, since,
s := since s := since
var lastOrder order var lastOrder order
for hasMoreData { for hasMoreData {
resp, err := e.newRest().OrdersHistory(ctx, symbol, s, until, limit) resp, err := e.newRest().OrdersHistory(ctx, toLocalSymbol(symbol), s, until, limit)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -109,7 +109,7 @@ func (s *Stream) Subscribe(channel types.Channel, symbol string, _ types.Subscri
s.addSubscription(websocketRequest{ s.addSubscription(websocketRequest{
Operation: subscribe, Operation: subscribe,
Channel: orderBookChannel, Channel: orderBookChannel,
Market: TrimUpperString(symbol), Market: toLocalSymbol(TrimUpperString(symbol)),
}) })
} }

View File

@ -58,6 +58,7 @@ type loginArgs struct {
Key string `json:"key"` Key string `json:"key"`
Signature string `json:"sign"` Signature string `json:"sign"`
Time int64 `json:"time"` Time int64 `json:"time"`
SubAccount string `json:"subaccount"`
} }
func newLoginRequest(key, secret string, t time.Time) websocketRequest { func newLoginRequest(key, secret string, t time.Time) websocketRequest {
@ -361,7 +362,7 @@ func toGlobalOrderBook(r orderBookResponse) (types.OrderBook, error) {
} }
return types.OrderBook{ return types.OrderBook{
// ex. BTC/USDT // ex. BTC/USDT
Symbol: strings.ToUpper(r.Market), Symbol: toGlobalSymbol(strings.ToUpper(r.Market)),
Bids: bids, Bids: bids,
Asks: asks, Asks: asks,
}, nil }, nil