implement QueryAccounts and QueryMarkets

This commit is contained in:
c9s 2021-12-22 00:30:16 +08:00
parent 77418c9415
commit fce71cb37e
4 changed files with 143 additions and 22 deletions

View File

@ -1 +1,25 @@
package kucoin
import (
"github.com/c9s/bbgo/pkg/exchange/kucoin/kucoinapi"
"github.com/c9s/bbgo/pkg/types"
)
func toGlobalBalanceMap(accounts []kucoinapi.Account) types.BalanceMap {
balances := types.BalanceMap{}
// for now, we only return the trading account
for _, account := range accounts {
switch account.Type {
case kucoinapi.AccountTypeTrade:
balances[account.Currency] = types.Balance{
Currency: account.Currency,
Available: account.Available,
Locked: account.Holds,
}
}
}
return balances
}

View File

@ -2,7 +2,10 @@ package kucoin
import (
"context"
"math"
"strings"
"github.com/c9s/bbgo/pkg/exchange/kucoin/kucoinapi"
"github.com/c9s/bbgo/pkg/types"
"github.com/sirupsen/logrus"
)
@ -16,14 +19,88 @@ var log = logrus.WithFields(logrus.Fields{
type Exchange struct {
key, secret, passphrase string
client *kucoinapi.RestClient
}
func (e *Exchange) NewStream() types.Stream {
panic("implement me")
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) {
panic("implement me")
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) {
@ -38,10 +115,21 @@ func (e *Exchange) QueryKLines(ctx context.Context, symbol string, interval type
panic("implement me")
}
func New(key, secret, passphrase string) *Exchange {
return &Exchange{
key: key,
secret: secret,
passphrase: passphrase,
}
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")
}

View File

@ -8,8 +8,8 @@ type AccountService struct {
type SubAccount struct {
UserID string `json:"userId"`
Name string `json:"subName"`
Type string `json:"type"`
Name string `json:"subName"`
Type string `json:"type"`
Remark string `json:"remarks"`
}
@ -38,12 +38,12 @@ func (s *AccountService) QuerySubAccounts() ([]SubAccount, error) {
}
type Account struct {
ID string `json:"id"`
Currency string `json:"currency"`
Type string `json:"type"`
Balance fixedpoint.Value `json:"balance"`
ID string `json:"id"`
Currency string `json:"currency"`
Type AccountType `json:"type"`
Balance fixedpoint.Value `json:"balance"`
Available fixedpoint.Value `json:"available"`
Holds fixedpoint.Value `json:"holds"`
Holds fixedpoint.Value `json:"holds"`
}
func (s *AccountService) ListAccounts() ([]Account, error) {
@ -58,8 +58,8 @@ func (s *AccountService) ListAccounts() ([]Account, error) {
}
var apiResponse struct {
Code string `json:"code"`
Message string `json:"msg"`
Code string `json:"code"`
Message string `json:"msg"`
Data []Account `json:"data"`
}
@ -71,7 +71,7 @@ func (s *AccountService) ListAccounts() ([]Account, error) {
}
func (s *AccountService) GetAccount(accountID string) (*Account, error) {
req, err := s.client.newAuthenticatedRequest("GET", "/api/v1/accounts/" + accountID, nil, nil)
req, err := s.client.newAuthenticatedRequest("GET", "/api/v1/accounts/"+accountID, nil, nil)
if err != nil {
return nil, err
}
@ -82,8 +82,8 @@ func (s *AccountService) GetAccount(accountID string) (*Account, error) {
}
var apiResponse struct {
Code string `json:"code"`
Message string `json:"msg"`
Code string `json:"code"`
Message string `json:"msg"`
Data *Account `json:"data"`
}
@ -92,4 +92,4 @@ func (s *AccountService) GetAccount(accountID string) (*Account, error) {
}
return apiResponse.Data, nil
}
}

View File

@ -1,5 +1,14 @@
package kucoinapi
type AccountType string
const (
AccountTypeMain AccountType = "main"
AccountTypeTrade AccountType = "trade"
AccountTypeMargin AccountType = "margin"
AccountTypePool AccountType = "pool"
)
type TradeType string
const (