bbgo/doc/development/adding-new-exchange.md

5.7 KiB

Adding New Exchange

Open an issue and paste the following checklist to that issue.

You should send multiple small pull request to implement them.

Please avoid sending a pull request with huge changes

Important -- for the underlying http API please use requestgen https://github.com/c9s/requestgen to generate the requests.

Checklist

Exchange Interface - (required) the minimum requirement for spot trading

  • QueryMarkets
  • QueryTickers
  • QueryOpenOrders
  • SubmitOrders
  • CancelOrders
  • NewStream

Trading History Service Interface - (optional) used for syncing user trading data

  • QueryClosedOrders
  • QueryTrades

Order Query Service Interface - (optional) used for querying order status

  • QueryOrder

Back-testing service - (optional, required by backtesting) kline data is used for back-testing

  • QueryKLines

Convert functions (required):

  • MarketData convert functions
    • toGlobalMarket
    • toGlobalTicker
    • toGlobalKLine
  • UserData convert functions
    • toGlobalOrder
    • toGlobalTrade
    • toGlobalAccount
    • toGlobalBalance

Stream

  • UserDataStream
    • Trade message parser
    • Order message parser
    • Account message parser
    • Balance message parser
  • MarketDataStream
    • OrderBook message parser (or depth)
    • KLine message parser (required for backtesting and strategy)
    • Public trade message parser (optional)
    • Ticker message parser (optional)
  • ping/pong handling. (you can reuse the existing types.StandardStream)
  • heart-beat handling or keep-alive handling. (already included in types.StandardStream)
  • handling reconnect. (already included in types.StandardStream)

Database

  • Add a new kline table for the exchange (required for back-testing)
    • Add MySQL migration SQL
    • Add SQLite migration SQL

Exchange Factory

  • Add the exchange constructor to the exchange instance factory function.
  • Add extended fields to the ExchangeSession struct. (optional)

Tools

Implementation

Go to pkg/types/exchange.go and add your exchange type:

const (
	ExchangeMax      = ExchangeName("max")
	ExchangeBinance  = ExchangeName("binance")
	ExchangeFTX      = ExchangeName("ftx")
	ExchangeOKEx     = ExchangeName("okex")
        ExchangeKucoin   = ExchangeName("kucoin")
        ExchangeBacktest = ExchangeName("backtest")
)

Go to pkg/cmd/cmdutil/exchange.go and add your exchange to the factory

func NewExchangeStandard(n types.ExchangeName, key, secret, passphrase, subAccount string) (types.Exchange, error) {
	switch n {

	case types.ExchangeFTX:
		return ftx.NewExchange(key, secret, subAccount), nil

	case types.ExchangeBinance:
		return binance.New(key, secret), nil

	case types.ExchangeOKEx:
		return okex.New(key, secret, passphrase), nil

    // ...
	}
}

Using requestgen

Alias

You can put the go:generate alias on the top of the file:

//go:generate -command GetRequest requestgen -method GET
//go:generate -command PostRequest requestgen -method POST
//go:generate -command DeleteRequest requestgen -method DELETE

Please note that the alias only works in the same file.

Defining Request Type Names

Please define request type name in the following format:

{Verb}{Service}{Resource}Request

for example:

type GetMarginMarketsRequest struct {
	client requestgen.APIClient
}

then you can attach the go:generate command on that type:


//go:generate GetRequest -url "/api/v3/wallet/m/limits" -type GetMarginBorrowingLimitsRequest -responseType .MarginBorrowingLimitMap

Un-marshalling Timestamps

For millisecond timestamps, you can use types.MillisecondTimestamp, it will automatically convert the timestamp into time.Time:

type MarginInterestRecord struct {
  Currency     string                     `json:"currency"`
  CreatedAt    types.MillisecondTimestamp `json:"created_at"`
}

Un-marshalling numbers

For number fields, especially floating numbers, please use fixedpoint.Value, it can parse int, float64, float64 in string:

type A struct {
  Amount       fixedpoint.Value           `json:"amount"`
}

Test Market Data Stream

Test order book stream

godotenv -f .env.local -- go run ./cmd/bbgo orderbook --config config/bbgo.yaml --session kucoin --symbol BTCUSDT

Test User Data Stream

godotenv -f .env.local -- go run ./cmd/bbgo --config config/bbgo.yaml userdatastream --session kucoin

Test Restful Endpoints

You can choose the session name to set-up for testing:

export BBGO_SESSION=ftx
export BBGO_SESSION=kucoin
export BBGO_SESSION=binance

Test user account balance

godotenv -f .env.local -- go run ./cmd/bbgo balances --session $BBGO_SESSION

Test order submit

godotenv -f .env.local -- go run ./cmd/bbgo submit-order --session $BBGO_SESSION --symbol=BTCUSDT --side=buy --price=18000 --quantity=0.001

Test open orders query

godotenv -f .env.local -- go run ./cmd/bbgo list-orders --session $BBGO_SESSION --symbol=BTCUSDT open
godotenv -f .env.local -- go run ./cmd/bbgo list-orders --session $BBGO_SESSION --symbol=BTCUSDT closed

Test order status

godotenv -f .env.local -- go run ./cmd/bbgo get-order --session $BBGO_SESSION --order-id ORDER_ID

Test order cancel

godotenv -f .env.local -- go run ./cmd/bbgo cancel-order --session $BBGO_SESSION --order-uuid 61c745c44592c200014abdcf