mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-20 23:16:49 +00:00
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:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"`
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user