diff --git a/pkg/exchange/okex/convert.go b/pkg/exchange/okex/convert.go new file mode 100644 index 000000000..29ae720a7 --- /dev/null +++ b/pkg/exchange/okex/convert.go @@ -0,0 +1,7 @@ +package okex + +import "strings" + +func toGlobalSymbol(symbol string) string { + return strings.ReplaceAll(symbol, "-", "") +} diff --git a/pkg/exchange/okex/exchange.go b/pkg/exchange/okex/exchange.go index 7d2c700ea..387769262 100644 --- a/pkg/exchange/okex/exchange.go +++ b/pkg/exchange/okex/exchange.go @@ -1,6 +1,11 @@ package okex import ( + "context" + "math" + + "github.com/c9s/bbgo/pkg/exchange/okex/okexapi" + "github.com/c9s/bbgo/pkg/types" "github.com/sirupsen/logrus" ) @@ -9,4 +14,74 @@ var log = logrus.WithFields(logrus.Fields{ }) type Exchange struct { + key, secret, passphrase string + + client *okexapi.RestClient +} + +func New(key, secret, passphrase string) *Exchange { + client := okexapi.NewClient() + client.Auth(key, secret, passphrase) + + return &Exchange{ + key: key, + secret: secret, + passphrase: passphrase, + } +} + +func (e *Exchange) Name() types.ExchangeName { + return types.ExchangeOKEx +} + +func (e *Exchange) QueryMarkets(ctx context.Context) (types.MarketMap, error) { + instruments, err := e.client.PublicDataService.NewGetInstrumentsRequest(). + InstrumentType(okexapi.InstrumentTypeSpot). + Do(ctx) + + if err != nil { + return nil, err + } + + markets := types.MarketMap{} + for _, instrument := range instruments { + symbol := toGlobalSymbol(instrument.InstrumentID) + market := types.Market{ + Symbol: symbol, + QuoteCurrency: instrument.QuoteCurrency, + BaseCurrency: instrument.BaseCurrency, + + // convert tick size OKEx to precision + PricePrecision: int(-math.Log10(instrument.TickSize.Float64())), + VolumePrecision: int(-math.Log10(instrument.LotSize.Float64())), + + // TickSize: OKEx's price tick, for BTC-USDT it's "0.1" + TickSize: instrument.TickSize.Float64(), + + // Quantity step size, for BTC-USDT, it's "0.00000001" + StepSize: instrument.LotSize.Float64(), + + // for BTC-USDT, it's "0.00001" + MinQuantity: instrument.MinSize.Float64(), + + // OKEx does not offer minimal notional, use 1 USD here. + MinNotional: 1.0, + MinAmount: 1.0, + } + markets[symbol] = market + } + + return markets, nil +} + +func (e *Exchange) QueryTicker(ctx context.Context, symbol string) (*types.Ticker, error) { + return nil, nil +} + +func (e *Exchange) QueryTickers(ctx context.Context, symbol string) (*types.Ticker, error) { + return nil, nil +} + +func (e *Exchange) PlatformFeeCurrency() string { + return "OKB" } diff --git a/pkg/types/exchange.go b/pkg/types/exchange.go index eee865685..17c43a0c6 100644 --- a/pkg/types/exchange.go +++ b/pkg/types/exchange.go @@ -43,6 +43,7 @@ const ( ExchangeMax = ExchangeName("max") ExchangeBinance = ExchangeName("binance") ExchangeFTX = ExchangeName("ftx") + ExchangeOKEx = ExchangeName("okex") ExchangeBacktest = ExchangeName("backtest") )