mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-10 17:13:51 +00:00
182 lines
4.4 KiB
Go
182 lines
4.4 KiB
Go
package kucoin
|
|
|
|
import (
|
|
"context"
|
|
"math"
|
|
"strings"
|
|
|
|
"github.com/c9s/bbgo/pkg/exchange/kucoin/kucoinapi"
|
|
"github.com/c9s/bbgo/pkg/types"
|
|
"github.com/sirupsen/logrus"
|
|
)
|
|
|
|
// OKB is the platform currency of OKEx, pre-allocate static string here
|
|
const KCS = "KCS"
|
|
|
|
var log = logrus.WithFields(logrus.Fields{
|
|
"exchange": "kucoin",
|
|
})
|
|
|
|
type Exchange struct {
|
|
key, secret, passphrase string
|
|
client *kucoinapi.RestClient
|
|
}
|
|
|
|
func New(key, secret, passphrase string) *Exchange {
|
|
client := kucoinapi.NewClient()
|
|
|
|
// for public access mode
|
|
if len(key) > 0 && len(secret) > 0 && len(passphrase) > 0 {
|
|
client.Auth(key, secret, passphrase)
|
|
}
|
|
|
|
return &Exchange{
|
|
key: key,
|
|
secret: secret,
|
|
passphrase: passphrase,
|
|
client: client,
|
|
}
|
|
}
|
|
|
|
func (e *Exchange) Name() types.ExchangeName {
|
|
return types.ExchangeKucoin
|
|
}
|
|
|
|
func (e *Exchange) PlatformFeeCurrency() string {
|
|
return KCS
|
|
}
|
|
|
|
func (e *Exchange) QueryAccount(ctx context.Context) (*types.Account, error) {
|
|
accounts, err := e.client.AccountService.ListAccounts()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// for now, we only return the trading account
|
|
a := types.NewAccount()
|
|
balances := toGlobalBalanceMap(accounts)
|
|
a.UpdateBalances(balances)
|
|
return a, nil
|
|
}
|
|
|
|
func (e *Exchange) QueryAccountBalances(ctx context.Context) (types.BalanceMap, error) {
|
|
accounts, err := e.client.AccountService.ListAccounts()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return toGlobalBalanceMap(accounts), nil
|
|
}
|
|
|
|
func toGlobalSymbol(symbol string) string {
|
|
return strings.ReplaceAll(symbol, "-", "")
|
|
}
|
|
|
|
func (e *Exchange) QueryMarkets(ctx context.Context) (types.MarketMap, error) {
|
|
markets, err := e.client.MarketDataService.ListSymbols()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
marketMap := types.MarketMap{}
|
|
for _, m := range markets {
|
|
symbol := toGlobalSymbol(m.Symbol)
|
|
marketMap[symbol] = types.Market{
|
|
Symbol: symbol,
|
|
LocalSymbol: m.Symbol,
|
|
PricePrecision: int(math.Log10(m.PriceIncrement.Float64())), // convert 0.0001 to 4
|
|
VolumePrecision: int(math.Log10(m.BaseIncrement.Float64())),
|
|
QuoteCurrency: m.QuoteCurrency,
|
|
BaseCurrency: m.BaseCurrency,
|
|
MinNotional: m.QuoteMinSize.Float64(),
|
|
MinAmount: m.QuoteMinSize.Float64(),
|
|
MinQuantity: m.BaseMinSize.Float64(),
|
|
MaxQuantity: 0, // not used
|
|
StepSize: m.BaseIncrement.Float64(),
|
|
|
|
MinPrice: 0, // not used
|
|
MaxPrice: 0, // not used
|
|
TickSize: m.PriceIncrement.Float64(),
|
|
}
|
|
}
|
|
|
|
return marketMap, nil
|
|
}
|
|
|
|
func (e *Exchange) QueryTicker(ctx context.Context, symbol string) (*types.Ticker, error) {
|
|
s, err := e.client.MarketDataService.GetTicker24HStat(symbol)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &types.Ticker{
|
|
Time: s.Time.Time(),
|
|
Volume: s.Volume.Float64(),
|
|
Last: s.Last.Float64(),
|
|
Open: s.Last.Float64() - s.ChangePrice.Float64(),
|
|
High: s.High.Float64(),
|
|
Low: s.Low.Float64(),
|
|
Buy: s.Buy.Float64(),
|
|
Sell: s.Sell.Float64(),
|
|
}, nil
|
|
}
|
|
|
|
func (e *Exchange) QueryTickers(ctx context.Context, symbols ...string) (map[string]types.Ticker, error) {
|
|
tickers := map[string]types.Ticker{}
|
|
if len(symbols) > 0 {
|
|
for _, s := range symbols {
|
|
t, err := e.QueryTicker(ctx, s)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
tickers[s] = *t
|
|
}
|
|
|
|
return tickers, nil
|
|
}
|
|
|
|
allTickers, err := e.client.MarketDataService.ListTickers()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
for _, s := range allTickers.Ticker {
|
|
tickers[ s.Symbol ] = types.Ticker{
|
|
Time: s.Time.Time(),
|
|
Volume: s.Volume.Float64(),
|
|
Last: s.Last.Float64(),
|
|
Open: s.Last.Float64() - s.ChangePrice.Float64(),
|
|
High: s.High.Float64(),
|
|
Low: s.Low.Float64(),
|
|
Buy: s.Buy.Float64(),
|
|
Sell: s.Sell.Float64(),
|
|
}
|
|
}
|
|
|
|
return tickers, nil
|
|
}
|
|
|
|
func (e *Exchange) QueryKLines(ctx context.Context, symbol string, interval types.Interval, options types.KLineQueryOptions) ([]types.KLine, error) {
|
|
panic("implement me")
|
|
}
|
|
|
|
func (e *Exchange) SubmitOrders(ctx context.Context, orders ...types.SubmitOrder) (createdOrders types.OrderSlice, err error) {
|
|
panic("implement me")
|
|
return nil, nil
|
|
}
|
|
|
|
func (e *Exchange) QueryOpenOrders(ctx context.Context, symbol string) (orders []types.Order, err error) {
|
|
panic("implement me")
|
|
return nil, nil
|
|
}
|
|
|
|
func (e *Exchange) CancelOrders(ctx context.Context, orders ...types.Order) error {
|
|
panic("implement me")
|
|
return nil
|
|
}
|
|
|
|
func (e *Exchange) NewStream() types.Stream {
|
|
panic("implement me")
|
|
}
|