binance: use currency.Pair for request arguments (#608)

* binance: use currency.Pair for request arguments

* request calls use type safe arguments
* binance API handles the correct conversion now on a lower level
* consolidate formatting to a single place
* remove unused Pair.ID

* add tests for formatting

* fix linter issue
This commit is contained in:
Rauno Ots
2020-12-13 23:36:46 +01:00
committed by GitHub
parent f3da99bf8f
commit ddd19ab6d9
9 changed files with 207 additions and 127 deletions

View File

@@ -100,14 +100,19 @@ func NewPairFromString(currencyPair string) (Pair, error) {
// apply the same format
func NewPairFromFormattedPairs(currencyPair string, pairs Pairs, pairFmt PairFormat) (Pair, error) {
for x := range pairs {
fPair := pairs[x].Format(pairFmt.Delimiter, pairFmt.Uppercase)
if strings.EqualFold(fPair.String(), currencyPair) {
fPair := pairFmt.Format(pairs[x])
if strings.EqualFold(fPair, currencyPair) {
return pairs[x], nil
}
}
return NewPairFromString(currencyPair)
}
// Format formats the given pair as a string
func (f *PairFormat) Format(pair Pair) string {
return pair.Format(f.Delimiter, f.Uppercase).String()
}
// MatchPairsWithNoDelimiter will move along a predictable index on the provided currencyPair
// it will then split on that index and verify whether that currencypair exists in the
// supplied pairs

View File

@@ -776,3 +776,62 @@ func TestMatchPairsWithNoDelimiter(t *testing.T) {
t.Errorf("unexpected response base: %v quote: %v", p.Base.String(), p.Quote.String())
}
}
func TestPairFormat_Format(t *testing.T) {
type fields struct {
Uppercase bool
Delimiter string
Separator string
Index string
}
tests := []struct {
name string
fields fields
arg Pair
want string
}{
{
name: "empty",
fields: fields{},
arg: Pair{},
want: "",
},
{
name: "empty format",
fields: fields{},
arg: Pair{
Delimiter: "<>",
Base: AAA,
Quote: BTC,
},
want: "aaabtc",
},
{
name: "format",
fields: fields{
Uppercase: true,
Delimiter: "!!!",
},
arg: Pair{
Delimiter: "<>",
Base: AAA,
Quote: BTC,
},
want: "AAA!!!BTC",
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
f := &PairFormat{
Uppercase: tt.fields.Uppercase,
Delimiter: tt.fields.Delimiter,
Separator: tt.fields.Separator,
Index: tt.fields.Index,
}
if got := f.Format(tt.arg); got != tt.want {
t.Errorf("PairFormat.Format() = %v, want %v", got, tt.want)
}
})
}
}

View File

@@ -2,7 +2,6 @@ package currency
// Pair holds currency pair information
type Pair struct {
ID string `json:"id"`
Delimiter string `json:"delimiter,omitempty"`
Base Code `json:"base,omitempty"`
Quote Code `json:"quote,omitempty"`

View File

@@ -10,7 +10,6 @@ import (
"net/url"
"sort"
"strconv"
"strings"
"time"
"github.com/thrasher-corp/gocryptotrader/common"
@@ -89,7 +88,11 @@ func (b *Binance) GetOrderBook(obd OrderBookDataRequestParams) (OrderBook, error
}
params := url.Values{}
params.Set("symbol", strings.ToUpper(obd.Symbol))
symbol, err := b.formatSymbol(obd.Symbol)
if err != nil {
return orderbook, err
}
params.Set("symbol", symbol)
params.Set("limit", fmt.Sprintf("%d", obd.Limit))
var resp OrderBookData
@@ -142,7 +145,11 @@ func (b *Binance) GetMostRecentTrades(rtr RecentTradeRequestParams) ([]RecentTra
var resp []RecentTrade
params := url.Values{}
params.Set("symbol", strings.ToUpper(rtr.Symbol))
symbol, err := b.formatSymbol(rtr.Symbol)
if err != nil {
return nil, err
}
params.Set("symbol", symbol)
params.Set("limit", fmt.Sprintf("%d", rtr.Limit))
path := fmt.Sprintf("%s%s?%s", b.API.Endpoints.URL, recentTrades, params.Encode())
@@ -168,7 +175,11 @@ func (b *Binance) GetHistoricalTrades(symbol string, limit int, fromID int64) ([
// https://binance-docs.github.io/apidocs/spot/en/#compressed-aggregate-trades-list
func (b *Binance) GetAggregatedTrades(arg *AggregatedTradeRequestParams) ([]AggregatedTrade, error) {
params := url.Values{}
params.Set("symbol", arg.Symbol)
symbol, err := b.formatSymbol(arg.Symbol)
if err != nil {
return nil, err
}
params.Set("symbol", symbol)
// if the user request is directly not supported by the exchange, we might be able to fulfill it
// by merging results from multiple API requests
needBatch := false
@@ -291,7 +302,11 @@ func (b *Binance) GetSpotKline(arg *KlinesRequestParams) ([]CandleStick, error)
var klineData []CandleStick
params := url.Values{}
params.Set("symbol", arg.Symbol)
symbol, err := b.formatSymbol(arg.Symbol)
if err != nil {
return nil, err
}
params.Set("symbol", symbol)
params.Set("interval", arg.Interval)
if arg.Limit != 0 {
params.Set("limit", strconv.Itoa(arg.Limit))
@@ -355,10 +370,14 @@ func (b *Binance) GetSpotKline(arg *KlinesRequestParams) ([]CandleStick, error)
// GetAveragePrice returns current average price for a symbol.
//
// symbol: string of currency pair
func (b *Binance) GetAveragePrice(symbol string) (AveragePrice, error) {
func (b *Binance) GetAveragePrice(symbol currency.Pair) (AveragePrice, error) {
resp := AveragePrice{}
params := url.Values{}
params.Set("symbol", strings.ToUpper(symbol))
symbolValue, err := b.formatSymbol(symbol)
if err != nil {
return resp, err
}
params.Set("symbol", symbolValue)
path := fmt.Sprintf("%s%s?%s", b.API.Endpoints.URL, averagePrice, params.Encode())
@@ -368,10 +387,14 @@ func (b *Binance) GetAveragePrice(symbol string) (AveragePrice, error) {
// GetPriceChangeStats returns price change statistics for the last 24 hours
//
// symbol: string of currency pair
func (b *Binance) GetPriceChangeStats(symbol string) (PriceChangeStats, error) {
func (b *Binance) GetPriceChangeStats(symbol currency.Pair) (PriceChangeStats, error) {
resp := PriceChangeStats{}
params := url.Values{}
params.Set("symbol", strings.ToUpper(symbol))
symbolValue, err := b.formatSymbol(symbol)
if err != nil {
return resp, err
}
params.Set("symbol", symbolValue)
path := fmt.Sprintf("%s%s?%s", b.API.Endpoints.URL, priceChange, params.Encode())
@@ -388,27 +411,35 @@ func (b *Binance) GetTickers() ([]PriceChangeStats, error) {
// GetLatestSpotPrice returns latest spot price of symbol
//
// symbol: string of currency pair
func (b *Binance) GetLatestSpotPrice(symbol string) (SymbolPrice, error) {
func (b *Binance) GetLatestSpotPrice(symbol currency.Pair) (SymbolPrice, error) {
resp := SymbolPrice{}
params := url.Values{}
params.Set("symbol", strings.ToUpper(symbol))
symbolValue, err := b.formatSymbol(symbol)
if err != nil {
return resp, err
}
params.Set("symbol", symbolValue)
path := fmt.Sprintf("%s%s?%s", b.API.Endpoints.URL, symbolPrice, params.Encode())
return resp, b.SendHTTPRequest(path, symbolPriceLimit(symbol), &resp)
return resp, b.SendHTTPRequest(path, symbolPriceLimit(symbolValue), &resp)
}
// GetBestPrice returns the latest best price for symbol
//
// symbol: string of currency pair
func (b *Binance) GetBestPrice(symbol string) (BestPrice, error) {
func (b *Binance) GetBestPrice(symbol currency.Pair) (BestPrice, error) {
resp := BestPrice{}
params := url.Values{}
params.Set("symbol", strings.ToUpper(symbol))
symbolValue, err := b.formatSymbol(symbol)
if err != nil {
return resp, err
}
params.Set("symbol", symbolValue)
path := fmt.Sprintf("%s%s?%s", b.API.Endpoints.URL, bestPrice, params.Encode())
return resp, b.SendHTTPRequest(path, bestPriceLimit(symbol), &resp)
return resp, b.SendHTTPRequest(path, bestPriceLimit(symbolValue), &resp)
}
// NewOrder sends a new order to Binance
@@ -435,7 +466,11 @@ func (b *Binance) newOrder(api string, o *NewOrderRequest, resp *NewOrderRespons
path := b.API.Endpoints.URL + api
params := url.Values{}
params.Set("symbol", o.Symbol)
symbol, err := b.formatSymbol(o.Symbol)
if err != nil {
return err
}
params.Set("symbol", symbol)
params.Set("side", o.Side)
params.Set("type", string(o.TradeType))
if o.QuoteOrderQty > 0 {
@@ -469,13 +504,17 @@ func (b *Binance) newOrder(api string, o *NewOrderRequest, resp *NewOrderRespons
}
// CancelExistingOrder sends a cancel order to Binance
func (b *Binance) CancelExistingOrder(symbol string, orderID int64, origClientOrderID string) (CancelOrderResponse, error) {
func (b *Binance) CancelExistingOrder(symbol currency.Pair, orderID int64, origClientOrderID string) (CancelOrderResponse, error) {
var resp CancelOrderResponse
path := b.API.Endpoints.URL + cancelOrder
symbolValue, err := b.formatSymbol(symbol)
if err != nil {
return resp, err
}
params := url.Values{}
params.Set("symbol", symbol)
params.Set("symbol", symbolValue)
if orderID != 0 {
params.Set("orderId", strconv.FormatInt(orderID, 10))
@@ -491,15 +530,23 @@ func (b *Binance) CancelExistingOrder(symbol string, orderID int64, origClientOr
// OpenOrders Current open orders. Get all open orders on a symbol.
// Careful when accessing this with no symbol: The number of requests counted against the rate limiter
// is significantly higher
func (b *Binance) OpenOrders(symbol string) ([]QueryOrderData, error) {
func (b *Binance) OpenOrders(pair *currency.Pair) ([]QueryOrderData, error) {
var resp []QueryOrderData
path := b.API.Endpoints.URL + openOrders
params := url.Values{}
var symbol string
if pair != nil {
var err error
symbol, err = b.formatSymbol(*pair)
if err != nil {
return resp, err
}
}
if symbol != "" {
params.Set("symbol", strings.ToUpper(symbol))
params.Set("symbol", symbol)
}
if err := b.SendAuthHTTPRequest(http.MethodGet, path, params, openOrdersLimit(symbol), &resp); err != nil {
@@ -512,13 +559,17 @@ func (b *Binance) OpenOrders(symbol string) ([]QueryOrderData, error) {
// AllOrders Get all account orders; active, canceled, or filled.
// orderId optional param
// limit optional param, default 500; max 500
func (b *Binance) AllOrders(symbol, orderID, limit string) ([]QueryOrderData, error) {
func (b *Binance) AllOrders(symbol currency.Pair, orderID, limit string) ([]QueryOrderData, error) {
var resp []QueryOrderData
path := b.API.Endpoints.URL + allOrders
params := url.Values{}
params.Set("symbol", strings.ToUpper(symbol))
symbolValue, err := b.formatSymbol(symbol)
if err != nil {
return resp, err
}
params.Set("symbol", symbolValue)
if orderID != "" {
params.Set("orderId", orderID)
}
@@ -533,13 +584,17 @@ func (b *Binance) AllOrders(symbol, orderID, limit string) ([]QueryOrderData, er
}
// QueryOrder returns information on a past order
func (b *Binance) QueryOrder(symbol, origClientOrderID string, orderID int64) (QueryOrderData, error) {
func (b *Binance) QueryOrder(symbol currency.Pair, origClientOrderID string, orderID int64) (QueryOrderData, error) {
var resp QueryOrderData
path := b.API.Endpoints.URL + queryOrder
params := url.Values{}
params.Set("symbol", strings.ToUpper(symbol))
symbolValue, err := b.formatSymbol(symbol)
if err != nil {
return resp, err
}
params.Set("symbol", symbolValue)
if origClientOrderID != "" {
params.Set("origClientOrderId", origClientOrderID)
}

View File

@@ -61,9 +61,8 @@ func TestFetchTradablePairs(t *testing.T) {
func TestGetOrderBook(t *testing.T) {
t.Parallel()
_, err := b.GetOrderBook(OrderBookDataRequestParams{
Symbol: "BTCUSDT",
Symbol: currency.NewPair(currency.BTC, currency.USDT),
Limit: 10,
})
@@ -76,7 +75,7 @@ func TestGetMostRecentTrades(t *testing.T) {
t.Parallel()
_, err := b.GetMostRecentTrades(RecentTradeRequestParams{
Symbol: "BTCUSDT",
Symbol: currency.NewPair(currency.BTC, currency.USDT),
Limit: 15,
})
@@ -100,7 +99,7 @@ func TestGetHistoricalTrades(t *testing.T) {
func TestGetAggregatedTrades(t *testing.T) {
t.Parallel()
_, err := b.GetAggregatedTrades(&AggregatedTradeRequestParams{
Symbol: currency.NewPair(currency.BTC, currency.USDT).String(),
Symbol: currency.NewPair(currency.BTC, currency.USDT),
Limit: 5,
})
if err != nil {
@@ -111,7 +110,7 @@ func TestGetAggregatedTrades(t *testing.T) {
func TestGetSpotKline(t *testing.T) {
t.Parallel()
_, err := b.GetSpotKline(&KlinesRequestParams{
Symbol: "BTCUSDT",
Symbol: currency.NewPair(currency.BTC, currency.USDT),
Interval: kline.FiveMin.Short(),
Limit: 24,
StartTime: time.Unix(1577836800, 0),
@@ -125,7 +124,7 @@ func TestGetSpotKline(t *testing.T) {
func TestGetAveragePrice(t *testing.T) {
t.Parallel()
_, err := b.GetAveragePrice("BTCUSDT")
_, err := b.GetAveragePrice(currency.NewPair(currency.BTC, currency.USDT))
if err != nil {
t.Error("Binance GetAveragePrice() error", err)
}
@@ -134,7 +133,7 @@ func TestGetAveragePrice(t *testing.T) {
func TestGetPriceChangeStats(t *testing.T) {
t.Parallel()
_, err := b.GetPriceChangeStats("BTCUSDT")
_, err := b.GetPriceChangeStats(currency.NewPair(currency.BTC, currency.USDT))
if err != nil {
t.Error("Binance GetPriceChangeStats() error", err)
}
@@ -152,7 +151,7 @@ func TestGetTickers(t *testing.T) {
func TestGetLatestSpotPrice(t *testing.T) {
t.Parallel()
_, err := b.GetLatestSpotPrice("BTCUSDT")
_, err := b.GetLatestSpotPrice(currency.NewPair(currency.BTC, currency.USDT))
if err != nil {
t.Error("Binance GetLatestSpotPrice() error", err)
}
@@ -161,7 +160,7 @@ func TestGetLatestSpotPrice(t *testing.T) {
func TestGetBestPrice(t *testing.T) {
t.Parallel()
_, err := b.GetBestPrice("BTCUSDT")
_, err := b.GetBestPrice(currency.NewPair(currency.BTC, currency.USDT))
if err != nil {
t.Error("Binance GetBestPrice() error", err)
}
@@ -170,7 +169,7 @@ func TestGetBestPrice(t *testing.T) {
func TestQueryOrder(t *testing.T) {
t.Parallel()
_, err := b.QueryOrder("BTCUSDT", "", 1337)
_, err := b.QueryOrder(currency.NewPair(currency.BTC, currency.USDT), "", 1337)
switch {
case areTestAPIKeysSet() && err != nil:
t.Error("QueryOrder() error", err)
@@ -184,7 +183,8 @@ func TestQueryOrder(t *testing.T) {
func TestOpenOrders(t *testing.T) {
t.Parallel()
_, err := b.OpenOrders("BTCUSDT")
p := currency.NewPair(currency.BTC, currency.USDT)
_, err := b.OpenOrders(&p)
switch {
case areTestAPIKeysSet() && err != nil:
t.Error("OpenOrders() error", err)
@@ -198,7 +198,7 @@ func TestOpenOrders(t *testing.T) {
func TestAllOrders(t *testing.T) {
t.Parallel()
_, err := b.AllOrders("BTCUSDT", "", "")
_, err := b.AllOrders(currency.NewPair(currency.BTC, currency.USDT), "", "")
switch {
case areTestAPIKeysSet() && err != nil:
t.Error("AllOrders() error", err)
@@ -366,7 +366,7 @@ func TestNewOrderTest(t *testing.T) {
t.Parallel()
req := &NewOrderRequest{
Symbol: "LTCBTC",
Symbol: currency.NewPair(currency.LTC, currency.BTC),
Side: order.Buy.String(),
TradeType: BinanceRequestParamsOrderLimit,
Price: 0.0025,
@@ -385,7 +385,7 @@ func TestNewOrderTest(t *testing.T) {
}
req = &NewOrderRequest{
Symbol: "LTCBTC",
Symbol: currency.NewPair(currency.LTC, currency.BTC),
Side: order.Sell.String(),
TradeType: BinanceRequestParamsOrderMarket,
Price: 0.0045,
@@ -458,7 +458,7 @@ func TestGetAggregatedTradesBatched(t *testing.T) {
name: "mock batch with timerange",
mock: true,
args: &AggregatedTradeRequestParams{
Symbol: currencyPair.String(),
Symbol: currencyPair,
StartTime: start,
EndTime: start.Add(75 * time.Minute),
},
@@ -468,7 +468,7 @@ func TestGetAggregatedTradesBatched(t *testing.T) {
{
name: "batch with timerange",
args: &AggregatedTradeRequestParams{
Symbol: currencyPair.String(),
Symbol: currencyPair,
StartTime: start,
EndTime: start.Add(75 * time.Minute),
},
@@ -479,7 +479,7 @@ func TestGetAggregatedTradesBatched(t *testing.T) {
name: "mock custom limit with start time set, no end time",
mock: true,
args: &AggregatedTradeRequestParams{
Symbol: currency.NewPair(currency.BTC, currency.USDT).String(),
Symbol: currency.NewPair(currency.BTC, currency.USDT),
StartTime: start,
Limit: 1001,
},
@@ -489,7 +489,7 @@ func TestGetAggregatedTradesBatched(t *testing.T) {
{
name: "custom limit with start time set, no end time",
args: &AggregatedTradeRequestParams{
Symbol: currency.NewPair(currency.BTC, currency.USDT).String(),
Symbol: currency.NewPair(currency.BTC, currency.USDT),
StartTime: time.Date(2020, 11, 18, 12, 0, 0, 0, time.UTC),
Limit: 1001,
},
@@ -500,7 +500,7 @@ func TestGetAggregatedTradesBatched(t *testing.T) {
name: "mock recent trades",
mock: true,
args: &AggregatedTradeRequestParams{
Symbol: currency.NewPair(currency.BTC, currency.USDT).String(),
Symbol: currency.NewPair(currency.BTC, currency.USDT),
Limit: 3,
},
numExpected: 3,
@@ -541,14 +541,14 @@ func TestGetAggregatedTradesErrors(t *testing.T) {
{
name: "get recent trades does not support custom limit",
args: &AggregatedTradeRequestParams{
Symbol: currency.NewPair(currency.BTC, currency.USDT).String(),
Symbol: currency.NewPair(currency.BTC, currency.USDT),
Limit: 1001,
},
},
{
name: "start time and fromId cannot be both set",
args: &AggregatedTradeRequestParams{
Symbol: currency.NewPair(currency.BTC, currency.USDT).String(),
Symbol: currency.NewPair(currency.BTC, currency.USDT),
StartTime: start,
EndTime: start.Add(75 * time.Minute),
FromID: 2,
@@ -557,7 +557,7 @@ func TestGetAggregatedTradesErrors(t *testing.T) {
{
name: "can't get most recent 5000 (more than 1000 not allowed)",
args: &AggregatedTradeRequestParams{
Symbol: currency.NewPair(currency.BTC, currency.USDT).String(),
Symbol: currency.NewPair(currency.BTC, currency.USDT),
Limit: 5000,
},
},

View File

@@ -70,8 +70,8 @@ type ExchangeInfo struct {
// OrderBookDataRequestParams represents Klines request data.
type OrderBookDataRequestParams struct {
Symbol string `json:"symbol"` // Required field; example LTCBTC,BTCUSDT
Limit int `json:"limit"` // Default 100; max 1000. Valid limits:[5, 10, 20, 50, 100, 500, 1000]
Symbol currency.Pair `json:"symbol"` // Required field; example LTCBTC,BTCUSDT
Limit int `json:"limit"` // Default 100; max 1000. Valid limits:[5, 10, 20, 50, 100, 500, 1000]
}
// OrderbookItem stores an individual orderbook item
@@ -118,8 +118,8 @@ type WebsocketDepthStream struct {
// RecentTradeRequestParams represents Klines request data.
type RecentTradeRequestParams struct {
Symbol string `json:"symbol"` // Required field. example LTCBTC, BTCUSDT
Limit int `json:"limit"` // Default 500; max 500.
Symbol currency.Pair `json:"symbol"` // Required field. example LTCBTC, BTCUSDT
Limit int `json:"limit"` // Default 500; max 500.
}
// RecentTrade holds recent trade data
@@ -213,7 +213,7 @@ type HistoricalTrade struct {
// AggregatedTradeRequestParams holds request params
type AggregatedTradeRequestParams struct {
Symbol string // Required field; example LTCBTC, BTCUSDT
Symbol currency.Pair // Required field; example LTCBTC, BTCUSDT
// The first trade to retrieve
FromID int64
// The API seems to accept (start and end time) or FromID and no other combinations
@@ -297,7 +297,7 @@ type BestPrice struct {
// NewOrderRequest request type
type NewOrderRequest struct {
// Symbol (currency pair to trade)
Symbol string
Symbol currency.Pair
// Side Buy or Sell
Side string
// TradeType (market or limit order)
@@ -435,9 +435,9 @@ var (
// KlinesRequestParams represents Klines request data.
type KlinesRequestParams struct {
Symbol string // Required field; example LTCBTC, BTCUSDT
Interval string // Time interval period
Limit int // Default 500; max 500.
Symbol currency.Pair // Required field; example LTCBTC, BTCUSDT
Interval string // Time interval period
Limit int // Default 500; max 500.
StartTime time.Time
EndTime time.Time
}

View File

@@ -407,13 +407,8 @@ func stringToOrderStatus(status string) (order.Status, error) {
// SeedLocalCache seeds depth data
func (b *Binance) SeedLocalCache(p currency.Pair) error {
fPair, err := b.FormatExchangeCurrency(p, asset.Spot)
if err != nil {
return err
}
ob, err := b.GetOrderBook(OrderBookDataRequestParams{
Symbol: fPair.String(),
Symbol: p,
Limit: 1000,
})
if err != nil {

View File

@@ -400,13 +400,8 @@ func (b *Binance) FetchOrderbook(p currency.Pair, assetType asset.Item) (*orderb
// UpdateOrderbook updates and returns the orderbook for a currency pair
func (b *Binance) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) {
fpair, err := b.FormatExchangeCurrency(p, assetType)
if err != nil {
return nil, err
}
orderbookNew, err := b.GetOrderBook(OrderBookDataRequestParams{
Symbol: fpair.String(),
Symbol: p,
Limit: 1000})
if err != nil {
return nil, err
@@ -523,14 +518,9 @@ func (b *Binance) GetWithdrawalsHistory(c currency.Code) (resp []exchange.Withdr
// GetRecentTrades returns the most recent trades for a currency and asset
func (b *Binance) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade.Data, error) {
var err error
p, err = b.FormatExchangeCurrency(p, assetType)
if err != nil {
return nil, err
}
var resp []trade.Data
limit := 1000
tradeData, err := b.GetMostRecentTrades(RecentTradeRequestParams{p.String(), limit})
tradeData, err := b.GetMostRecentTrades(RecentTradeRequestParams{p, limit})
if err != nil {
return nil, err
}
@@ -558,12 +548,8 @@ func (b *Binance) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trad
// GetHistoricTrades returns historic trade data within the timeframe provided
func (b *Binance) GetHistoricTrades(p currency.Pair, a asset.Item, from, to time.Time) ([]trade.Data, error) {
p, err := b.FormatExchangeCurrency(p, a)
if err != nil {
return nil, err
}
req := AggregatedTradeRequestParams{
Symbol: p.String(),
Symbol: p,
StartTime: from,
EndTime: to,
}
@@ -620,13 +606,8 @@ func (b *Binance) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) {
return submitOrderResponse, errors.New("unsupported order type")
}
fPair, err := b.FormatExchangeCurrency(s.Pair, s.AssetType)
if err != nil {
return submitOrderResponse, err
}
var orderRequest = NewOrderRequest{
Symbol: fPair.String(),
Symbol: s.Pair,
Side: sideType,
Price: s.Price,
Quantity: s.Amount,
@@ -676,12 +657,7 @@ func (b *Binance) CancelOrder(o *order.Cancel) error {
return err
}
fpair, err := b.FormatExchangeCurrency(o.Pair, o.AssetType)
if err != nil {
return err
}
_, err = b.CancelExistingOrder(fpair.String(),
_, err = b.CancelExistingOrder(o.Pair,
orderIDInt,
o.AccountID)
return err
@@ -697,15 +673,18 @@ func (b *Binance) CancelAllOrders(_ *order.Cancel) (order.CancelAllResponse, err
cancelAllOrdersResponse := order.CancelAllResponse{
Status: make(map[string]string),
}
openOrders, err := b.OpenOrders("")
openOrders, err := b.OpenOrders(nil)
if err != nil {
return cancelAllOrdersResponse, err
}
for i := range openOrders {
_, err = b.CancelExistingOrder(openOrders[i].Symbol,
openOrders[i].OrderID,
"")
pair, _, err := b.GetRequestFormattedPairAndAssetType(openOrders[i].Symbol)
if err != nil {
cancelAllOrdersResponse.Status[strconv.FormatInt(openOrders[i].OrderID, 10)] = err.Error()
continue
}
_, err = b.CancelExistingOrder(pair, openOrders[i].OrderID, "")
if err != nil {
cancelAllOrdersResponse.Status[strconv.FormatInt(openOrders[i].OrderID, 10)] = err.Error()
}
@@ -720,17 +699,12 @@ func (b *Binance) GetOrderInfo(orderID string, pair currency.Pair, assetType ass
assetType = asset.Spot
}
formattedPair, err := b.FormatExchangeCurrency(pair, assetType)
if err != nil {
return
}
orderIDInt64, err := convert.Int64FromString(orderID)
if err != nil {
return
}
resp, err := b.QueryOrder(formattedPair.String(), "", orderIDInt64)
resp, err := b.QueryOrder(pair, "", orderIDInt64)
if err != nil {
return
}
@@ -758,7 +732,7 @@ func (b *Binance) GetOrderInfo(orderID string, pair currency.Pair, assetType ass
ID: strconv.FormatInt(resp.OrderID, 10),
Side: orderSide,
Type: orderType,
Pair: formattedPair,
Pair: pair,
Cost: resp.CummulativeQuoteQty,
AssetType: assetType,
CloseTime: resp.UpdateTime,
@@ -826,13 +800,7 @@ func (b *Binance) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail,
var orders []order.Detail
for x := range req.Pairs {
fpair, err := b.FormatExchangeCurrency(req.Pairs[x],
asset.Spot)
if err != nil {
return nil, err
}
resp, err := b.OpenOrders(fpair.String())
resp, err := b.OpenOrders(&req.Pairs[x])
if err != nil {
return nil, err
}
@@ -879,11 +847,7 @@ func (b *Binance) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail,
var orders []order.Detail
for x := range req.Pairs {
fpair, err := b.FormatExchangeCurrency(req.Pairs[x], asset.Spot)
if err != nil {
return nil, err
}
resp, err := b.AllOrders(fpair.String(),
resp, err := b.AllOrders(req.Pairs[x],
"",
"1000")
if err != nil {
@@ -951,13 +915,9 @@ func (b *Binance) GetHistoricCandles(pair currency.Pair, a asset.Item, start, en
return kline.Item{}, errors.New(kline.ErrRequestExceedsExchangeLimits)
}
fpair, err := b.FormatExchangeCurrency(pair, a)
if err != nil {
return kline.Item{}, err
}
req := KlinesRequestParams{
Interval: b.FormatExchangeKlineInterval(interval),
Symbol: fpair.String(),
Symbol: pair,
StartTime: start,
EndTime: end,
Limit: int(b.Features.Enabled.Kline.ResultLimit),
@@ -1003,16 +963,11 @@ func (b *Binance) GetHistoricCandlesExtended(pair currency.Pair, a asset.Item, s
Interval: interval,
}
formattedPair, err := b.FormatExchangeCurrency(pair, a)
if err != nil {
return kline.Item{}, err
}
dates := kline.CalcDateRanges(start, end, interval, b.Features.Enabled.Kline.ResultLimit)
for x := range dates {
req := KlinesRequestParams{
Interval: b.FormatExchangeKlineInterval(interval),
Symbol: formattedPair.String(),
Symbol: pair,
StartTime: dates[x].Start,
EndTime: dates[x].End,
Limit: int(b.Features.Enabled.Kline.ResultLimit),

View File

@@ -6,6 +6,8 @@ import (
"time"
"github.com/thrasher-corp/gocryptotrader/common/convert"
"github.com/thrasher-corp/gocryptotrader/currency"
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
)
// binanceTime provides an internal conversion helper
@@ -344,3 +346,13 @@ func (a *wsListStatus) UnmarshalJSON(data []byte) error {
a.Data.TransactionTime = aux.Data.TransactionTime.Time()
return nil
}
// formatSymbol formats the given pair to a string suitable for exchange API requests
// currently applicable to Spot and Margin assets
func (b *Binance) formatSymbol(pair currency.Pair) (string, error) {
pairFmt, err := b.GetPairFormat(asset.Spot, true)
if err != nil {
return pair.String(), err
}
return pairFmt.Format(pair), nil
}