diff --git a/.golangci.yml b/.golangci.yml index 5fdbce3e..2283b0f5 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -57,7 +57,7 @@ linters: - nakedret # - nestif # - nlreturn -# - noctx + - noctx - nolintlint # - prealloc - rowserrcheck diff --git a/backtester/backtest/backtest.go b/backtester/backtest/backtest.go index e19be682..7532bbc8 100644 --- a/backtester/backtest/backtest.go +++ b/backtester/backtest/backtest.go @@ -1,6 +1,7 @@ package backtest import ( + "context" "errors" "fmt" "path/filepath" @@ -245,7 +246,7 @@ func (bt *BackTest) setupExchangeSettings(cfg *config.Config) (exchange.Exchange } if makerFee == 0 || takerFee == 0 { var apiMakerFee, apiTakerFee float64 - apiMakerFee, apiTakerFee = getFees(exch, pair) + apiMakerFee, apiTakerFee = getFees(context.TODO(), exch, pair) if makerFee == 0 { makerFee = apiMakerFee } @@ -400,26 +401,28 @@ func (bt *BackTest) setupBot(cfg *config.Config, bot *engine.Engine) error { } // getFees will return an exchange's fee rate from GCT's wrapper function -func getFees(exch gctexchange.IBotExchange, fPair currency.Pair) (makerFee, takerFee float64) { +func getFees(ctx context.Context, exch gctexchange.IBotExchange, fPair currency.Pair) (makerFee, takerFee float64) { var err error - takerFee, err = exch.GetFeeByType(&gctexchange.FeeBuilder{ - FeeType: gctexchange.OfflineTradeFee, - Pair: fPair, - IsMaker: false, - PurchasePrice: 1, - Amount: 1, - }) + takerFee, err = exch.GetFeeByType(ctx, + &gctexchange.FeeBuilder{ + FeeType: gctexchange.OfflineTradeFee, + Pair: fPair, + IsMaker: false, + PurchasePrice: 1, + Amount: 1, + }) if err != nil { log.Errorf(log.BackTester, "Could not retrieve taker fee for %v. %v", exch.GetName(), err) } - makerFee, err = exch.GetFeeByType(&gctexchange.FeeBuilder{ - FeeType: gctexchange.OfflineTradeFee, - Pair: fPair, - IsMaker: true, - PurchasePrice: 1, - Amount: 1, - }) + makerFee, err = exch.GetFeeByType(ctx, + &gctexchange.FeeBuilder{ + FeeType: gctexchange.OfflineTradeFee, + Pair: fPair, + IsMaker: true, + PurchasePrice: 1, + Amount: 1, + }) if err != nil { log.Errorf(log.BackTester, "Could not retrieve maker fee for %v. %v", exch.GetName(), err) } @@ -621,7 +624,7 @@ func loadAPIData(cfg *config.Config, exch gctexchange.IBotExchange, fPair curren if err != nil { return nil, err } - candles, err := api.LoadData( + candles, err := api.LoadData(context.TODO(), dataType, cfg.DataSettings.APIData.StartDate, cfg.DataSettings.APIData.EndDate, @@ -942,7 +945,7 @@ func (bt *BackTest) RunLive() error { // from live. Its purpose is to be able to perform strategy analysis against current data func (bt *BackTest) loadLiveDataLoop(resp *kline.DataFromKline, cfg *config.Config, exch gctexchange.IBotExchange, fPair currency.Pair, a asset.Item, dataType int64) { startDate := time.Now() - candles, err := live.LoadData( + candles, err := live.LoadData(context.TODO(), exch, dataType, cfg.DataSettings.Interval, @@ -981,7 +984,7 @@ func (bt *BackTest) loadLiveData(resp *kline.DataFromKline, cfg *config.Config, if exch == nil { return errNilExchange } - candles, err := live.LoadData( + candles, err := live.LoadData(context.TODO(), exch, dataType, cfg.DataSettings.Interval, @@ -992,7 +995,7 @@ func (bt *BackTest) loadLiveData(resp *kline.DataFromKline, cfg *config.Config, } resp.Item.Candles = append(resp.Item.Candles, candles.Candles...) - _, err = exch.FetchOrderbook(fPair, a) + _, err = exch.FetchOrderbook(context.TODO(), fPair, a) if err != nil { return err } diff --git a/backtester/data/kline/api/api.go b/backtester/data/kline/api/api.go index 737fa25c..85d556aa 100644 --- a/backtester/data/kline/api/api.go +++ b/backtester/data/kline/api/api.go @@ -1,6 +1,7 @@ package api import ( + "context" "fmt" "strings" "time" @@ -14,12 +15,12 @@ import ( ) // LoadData retrieves data from a GoCryptoTrader exchange wrapper which calls the exchange's API -func LoadData(dataType int64, startDate, endDate time.Time, interval time.Duration, exch exchange.IBotExchange, fPair currency.Pair, a asset.Item) (*kline.Item, error) { +func LoadData(ctx context.Context, dataType int64, startDate, endDate time.Time, interval time.Duration, exch exchange.IBotExchange, fPair currency.Pair, a asset.Item) (*kline.Item, error) { var candles kline.Item var err error switch dataType { case common.DataCandle: - candles, err = exch.GetHistoricCandlesExtended( + candles, err = exch.GetHistoricCandlesExtended(ctx, fPair, a, startDate, @@ -30,7 +31,7 @@ func LoadData(dataType int64, startDate, endDate time.Time, interval time.Durati } case common.DataTrade: var trades []trade.Data - trades, err = exch.GetHistoricTrades( + trades, err = exch.GetHistoricTrades(ctx, fPair, a, startDate, diff --git a/backtester/data/kline/api/api_test.go b/backtester/data/kline/api/api_test.go index 05b20eed..0576aeb8 100644 --- a/backtester/data/kline/api/api_test.go +++ b/backtester/data/kline/api/api_test.go @@ -1,6 +1,7 @@ package api import ( + "context" "errors" "testing" "time" @@ -37,7 +38,8 @@ func TestLoadCandles(t *testing.T) { interval := gctkline.OneMin a := asset.Spot var data *gctkline.Item - data, err = LoadData(common.DataCandle, tt1, tt2, interval.Duration(), exch, cp, a) + data, err = LoadData(context.Background(), + common.DataCandle, tt1, tt2, interval.Duration(), exch, cp, a) if err != nil { t.Fatal(err) } @@ -45,7 +47,8 @@ func TestLoadCandles(t *testing.T) { t.Error("expected candles") } - _, err = LoadData(-1, tt1, tt2, interval.Duration(), exch, cp, a) + _, err = LoadData(context.Background(), + -1, tt1, tt2, interval.Duration(), exch, cp, a) if !errors.Is(err, common.ErrInvalidDataType) { t.Errorf("expected '%v' received '%v'", err, common.ErrInvalidDataType) } @@ -73,7 +76,8 @@ func TestLoadTrades(t *testing.T) { tt2 := time.Now().Round(interval.Duration()) a := asset.Spot var data *gctkline.Item - data, err = LoadData(common.DataTrade, tt1, tt2, interval.Duration(), exch, cp, a) + data, err = LoadData(context.Background(), + common.DataTrade, tt1, tt2, interval.Duration(), exch, cp, a) if err != nil { t.Fatal(err) } diff --git a/backtester/data/kline/live/live.go b/backtester/data/kline/live/live.go index 9f33f794..01a90164 100644 --- a/backtester/data/kline/live/live.go +++ b/backtester/data/kline/live/live.go @@ -1,6 +1,7 @@ package live import ( + "context" "fmt" "strings" "time" @@ -14,12 +15,12 @@ import ( ) // LoadData retrieves data from a GoCryptoTrader exchange wrapper which calls the exchange's API for the latest interval -func LoadData(exch exchange.IBotExchange, dataType int64, interval time.Duration, fPair currency.Pair, a asset.Item) (*kline.Item, error) { +func LoadData(ctx context.Context, exch exchange.IBotExchange, dataType int64, interval time.Duration, fPair currency.Pair, a asset.Item) (*kline.Item, error) { var candles kline.Item var err error switch dataType { case common.DataCandle: - candles, err = exch.GetHistoricCandles( + candles, err = exch.GetHistoricCandles(ctx, fPair, a, time.Now().Add(-interval*2), // multiplied by 2 to ensure the latest candle is always included @@ -30,7 +31,11 @@ func LoadData(exch exchange.IBotExchange, dataType int64, interval time.Duration } case common.DataTrade: var trades []trade.Data - trades, err = exch.GetHistoricTrades(fPair, a, time.Now().Add(-interval*2), time.Now()) // multiplied by 2 to ensure the latest candle is always included + trades, err = exch.GetHistoricTrades(ctx, + fPair, + a, + time.Now().Add(-interval*2), // multiplied by 2 to ensure the latest candle is always included + time.Now()) if err != nil { return nil, err } @@ -41,10 +46,10 @@ func LoadData(exch exchange.IBotExchange, dataType int64, interval time.Duration } base := exch.GetBase() if len(candles.Candles) <= 1 && base.GetSupportedFeatures().RESTCapabilities.TradeHistory { - trades, err = exch.GetHistoricTrades( + trades, err = exch.GetHistoricTrades(ctx, fPair, a, - time.Now().Add(-interval), // multiplied by 2 to ensure the latest candle is always included + time.Now().Add(-interval), time.Now()) if err != nil { return nil, fmt.Errorf("could not retrieve live trade data for %v %v %v, %v", exch.GetName(), a, fPair, err) diff --git a/backtester/data/kline/live/live_test.go b/backtester/data/kline/live/live_test.go index aa9abf27..a8434089 100644 --- a/backtester/data/kline/live/live_test.go +++ b/backtester/data/kline/live/live_test.go @@ -1,6 +1,7 @@ package live import ( + "context" "errors" "testing" @@ -36,14 +37,15 @@ func TestLoadCandles(t *testing.T) { ConfigFormat: pFormat, } var data *gctkline.Item - data, err = LoadData(exch, common.DataCandle, interval.Duration(), cp1, a) + data, err = LoadData(context.Background(), + exch, common.DataCandle, interval.Duration(), cp1, a) if err != nil { t.Fatal(err) } if len(data.Candles) == 0 { t.Error("expected candles") } - _, err = LoadData(exch, -1, interval.Duration(), cp1, a) + _, err = LoadData(context.Background(), exch, -1, interval.Duration(), cp1, a) if !errors.Is(err, common.ErrInvalidDataType) { t.Errorf("expected '%v' received '%v'", err, common.ErrInvalidDataType) } @@ -71,7 +73,7 @@ func TestLoadTrades(t *testing.T) { ConfigFormat: pFormat, } var data *gctkline.Item - data, err = LoadData(exch, common.DataTrade, interval.Duration(), cp1, a) + data, err = LoadData(context.Background(), exch, common.DataTrade, interval.Duration(), cp1, a) if err != nil { t.Fatal(err) } diff --git a/backtester/eventhandlers/exchange/exchange.go b/backtester/eventhandlers/exchange/exchange.go index 30c70ab8..12a6320b 100644 --- a/backtester/eventhandlers/exchange/exchange.go +++ b/backtester/eventhandlers/exchange/exchange.go @@ -1,6 +1,7 @@ package exchange import ( + "context" "fmt" "github.com/gofrs/uuid" @@ -108,7 +109,7 @@ func (e *Exchange) ExecuteOrder(o order.Event, data data.Handler, bot *engine.En return f, err } - orderID, err := e.placeOrder(adjustedPrice, limitReducedAmount, cs.UseRealOrders, cs.CanUseExchangeLimits, f, bot) + orderID, err := e.placeOrder(context.TODO(), adjustedPrice, limitReducedAmount, cs.UseRealOrders, cs.CanUseExchangeLimits, f, bot) if err != nil { if f.GetDirection() == gctorder.Buy { f.SetDirection(common.CouldNotBuy) @@ -198,7 +199,7 @@ func reduceAmountToFitPortfolioLimit(adjustedPrice, amount, sizedPortfolioTotal return amount } -func (e *Exchange) placeOrder(price, amount float64, useRealOrders, useExchangeLimits bool, f *fill.Fill, bot *engine.Engine) (string, error) { +func (e *Exchange) placeOrder(ctx context.Context, price, amount float64, useRealOrders, useExchangeLimits bool, f *fill.Fill, bot *engine.Engine) (string, error) { if f == nil { return "", common.ErrNilEvent } @@ -222,7 +223,7 @@ func (e *Exchange) placeOrder(price, amount float64, useRealOrders, useExchangeL } if useRealOrders { - resp, err := bot.OrderManager.Submit(o) + resp, err := bot.OrderManager.Submit(ctx, o) if resp != nil { orderID = resp.OrderID } diff --git a/backtester/eventhandlers/exchange/exchange_test.go b/backtester/eventhandlers/exchange/exchange_test.go index 5eb414e4..948595dd 100644 --- a/backtester/eventhandlers/exchange/exchange_test.go +++ b/backtester/eventhandlers/exchange/exchange_test.go @@ -1,6 +1,7 @@ package exchange import ( + "context" "errors" "strings" "testing" @@ -151,30 +152,30 @@ func TestPlaceOrder(t *testing.T) { t.Error(err) } e := Exchange{} - _, err = e.placeOrder(1, 1, false, true, nil, nil) + _, err = e.placeOrder(context.Background(), 1, 1, false, true, nil, nil) if !errors.Is(err, common.ErrNilEvent) { t.Errorf("expected: %v, received %v", common.ErrNilEvent, err) } f := &fill.Fill{} - _, err = e.placeOrder(1, 1, false, true, f, bot) + _, err = e.placeOrder(context.Background(), 1, 1, false, true, f, bot) if err != nil && err.Error() != "order exchange name must be specified" { t.Error(err) } f.Exchange = testExchange - _, err = e.placeOrder(1, 1, false, true, f, bot) + _, err = e.placeOrder(context.Background(), 1, 1, false, true, f, bot) if !errors.Is(err, gctorder.ErrPairIsEmpty) { t.Errorf("expected: %v, received %v", gctorder.ErrPairIsEmpty, err) } f.CurrencyPair = currency.NewPair(currency.BTC, currency.USDT) f.AssetType = asset.Spot f.Direction = gctorder.Buy - _, err = e.placeOrder(1, 1, false, true, f, bot) + _, err = e.placeOrder(context.Background(), 1, 1, false, true, f, bot) if err != nil { t.Error(err) } - _, err = e.placeOrder(1, 1, true, true, f, bot) + _, err = e.placeOrder(context.Background(), 1, 1, true, true, f, bot) if err != nil && !strings.Contains(err.Error(), "unset/default API keys") { t.Error(err) } @@ -203,7 +204,7 @@ func TestExecuteOrder(t *testing.T) { p := currency.NewPair(currency.BTC, currency.USDT) a := asset.Spot - _, err = exch.FetchOrderbook(p, a) + _, err = exch.FetchOrderbook(context.Background(), p, a) if err != nil { t.Fatal(err) } @@ -298,12 +299,12 @@ func TestExecuteOrderBuySellSizeLimit(t *testing.T) { } p := currency.NewPair(currency.BTC, currency.USDT) a := asset.Spot - _, err = exch.FetchOrderbook(p, a) + _, err = exch.FetchOrderbook(context.Background(), p, a) if err != nil { t.Fatal(err) } - err = exch.UpdateOrderExecutionLimits(asset.Spot) + err = exch.UpdateOrderExecutionLimits(context.Background(), asset.Spot) if err != nil { t.Fatal(err) } diff --git a/backtester/eventhandlers/exchange/slippage/slippage_test.go b/backtester/eventhandlers/exchange/slippage/slippage_test.go index 60c23532..a3b395b9 100644 --- a/backtester/eventhandlers/exchange/slippage/slippage_test.go +++ b/backtester/eventhandlers/exchange/slippage/slippage_test.go @@ -1,6 +1,7 @@ package slippage import ( + "context" "testing" "github.com/thrasher-corp/gocryptotrader/currency" @@ -22,7 +23,7 @@ func TestCalculateSlippageByOrderbook(t *testing.T) { b := bitstamp.Bitstamp{} b.SetDefaults() cp := currency.NewPair(currency.BTC, currency.USD) - ob, err := b.FetchOrderbook(cp, asset.Spot) + ob, err := b.FetchOrderbook(context.Background(), cp, asset.Spot) if err != nil { t.Fatal(err) } diff --git a/cmd/apichecker/apicheck.go b/cmd/apichecker/apicheck.go index d157f8bc..2620f67e 100644 --- a/cmd/apichecker/apicheck.go +++ b/cmd/apichecker/apicheck.go @@ -71,9 +71,11 @@ const ( ) var ( - verbose, add, create, testMode bool - apiKey, apiToken, trelloBoardID, trelloBoardName, trelloListID, trelloChecklistID, trelloCardID, exchangeName, checkType, tokenData, key, val, tokenDataEnd, textTokenData, dateFormat, regExp, checkString, path string - configData, testConfigData, usageData Config + verbose, add, create, testMode bool + apiKey, apiToken, trelloBoardID, trelloBoardName, trelloListID, + trelloChecklistID, trelloCardID, exchangeName, checkType, tokenData, + key, val, tokenDataEnd, textTokenData, dateFormat, regExp, path string + configData, testConfigData, usageData Config ) func main() { @@ -606,9 +608,9 @@ func fillData(exchName, checkType string, data interface{}) (ExchangeInfo, error // htmlScrapeDefault gets check string data for the default cases func htmlScrapeDefault(htmlData *HTMLScrapingData) ([]string, error) { var resp []string - temp, err := http.Get(htmlData.Path) + temp, err := sendHTTPGetRequest(htmlData.Path, nil) if err != nil { - return resp, err + return nil, err } defer temp.Body.Close() tokenizer := html.NewTokenizer(temp.Body) @@ -660,13 +662,14 @@ loop: // htmlScrapeBTSE gets the check string for BTSE exchange func htmlScrapeBTSE(htmlData *HTMLScrapingData) ([]string, error) { - var resp []string - temp, err := http.Get(htmlData.Path) + temp, err := sendHTTPGetRequest(htmlData.Path, nil) if err != nil { - return resp, err + return nil, err } defer temp.Body.Close() tokenizer := html.NewTokenizer(temp.Body) + + var resp []string loop: for { next := tokenizer.Next() @@ -693,9 +696,9 @@ loop: // htmlScrapeBitmex gets the check string for Bitmex exchange func htmlScrapeBitmex(htmlData *HTMLScrapingData) ([]string, error) { var resp []string - temp, err := http.Get(htmlData.Path) + temp, err := sendHTTPGetRequest(htmlData.Path, nil) if err != nil { - return resp, err + return nil, err } defer temp.Body.Close() tokenizer := html.NewTokenizer(temp.Body) @@ -731,11 +734,12 @@ loop: // htmlScrapeHitBTC gets the check string for HitBTC Exchange func htmlScrapeHitBTC(htmlData *HTMLScrapingData) ([]string, error) { - temp, err := http.Get(htmlData.Path) + temp, err := sendHTTPGetRequest(htmlData.Path, nil) if err != nil { return nil, err } defer temp.Body.Close() + a, err := ioutil.ReadAll(temp.Body) if err != nil { return nil, err @@ -766,9 +770,9 @@ func htmlScrapeHitBTC(htmlData *HTMLScrapingData) ([]string, error) { // htmlScrapeBTCMarkets gets the check string for BTCMarkets exchange func htmlScrapeBTCMarkets(htmlData *HTMLScrapingData) ([]string, error) { var resp []string - temp, err := http.Get(htmlData.Path) + temp, err := sendHTTPGetRequest(htmlData.Path, nil) if err != nil { - return resp, err + return nil, err } defer temp.Body.Close() tempData, err := ioutil.ReadAll(temp.Body) @@ -787,9 +791,9 @@ func htmlScrapeBTCMarkets(htmlData *HTMLScrapingData) ([]string, error) { // htmlScrapeOk gets the check string for Okex func htmlScrapeOk(htmlData *HTMLScrapingData) ([]string, error) { var resp []string - temp, err := http.Get(htmlData.Path) + temp, err := sendHTTPGetRequest(htmlData.Path, nil) if err != nil { - return resp, err + return nil, err } defer temp.Body.Close() tokenizer := html.NewTokenizer(temp.Body) @@ -841,11 +845,12 @@ loop: // htmlScrapeANX gets the check string for BTCMarkets exchange func htmlScrapeANX(htmlData *HTMLScrapingData) ([]string, error) { - temp, err := http.Get(htmlData.Path) + temp, err := sendHTTPGetRequest(htmlData.Path, nil) if err != nil { return nil, err } defer temp.Body.Close() + a, err := ioutil.ReadAll(temp.Body) if err != nil { return nil, err @@ -875,16 +880,15 @@ func htmlScrapeANX(htmlData *HTMLScrapingData) ([]string, error) { // htmlScrapeExmo gets the check string for Exmo Exchange func htmlScrapeExmo(htmlData *HTMLScrapingData) ([]string, error) { - temp, err := http.NewRequest(http.MethodGet, htmlData.Path, nil) - if err != nil { - return nil, err - } - temp.Header.Set("User-Agent", "GCT") - httpClient := &http.Client{} - httpResp, err := httpClient.Do(temp) + header := map[string]string{ + "User-Agent": "GCT", + } + + httpResp, err := sendHTTPGetRequest(htmlData.Path, header) if err != nil { return nil, err } + defer httpResp.Body.Close() a, err := ioutil.ReadAll(httpResp.Body) if err != nil { @@ -902,9 +906,9 @@ func htmlScrapeExmo(htmlData *HTMLScrapingData) ([]string, error) { // htmlScrapePoloniex gets the check string for Poloniex Exchange func htmlScrapePoloniex(htmlData *HTMLScrapingData) ([]string, error) { var resp []string - temp, err := http.Get(htmlData.Path) + temp, err := sendHTTPGetRequest(htmlData.Path, nil) if err != nil { - return resp, err + return nil, err } defer temp.Body.Close() tokenizer := html.NewTokenizer(temp.Body) @@ -955,9 +959,9 @@ loop: // htmlScrapeItBit gets the check string for ItBit Exchange func htmlScrapeItBit(htmlData *HTMLScrapingData) ([]string, error) { var resp []string - temp, err := http.Get(htmlData.Path) + temp, err := sendHTTPGetRequest(htmlData.Path, nil) if err != nil { - return resp, err + return nil, err } defer temp.Body.Close() tokenizer := html.NewTokenizer(temp.Body) @@ -989,11 +993,12 @@ loop: // htmlScrapeBitstamp gets the check string for Bitstamp Exchange func htmlScrapeBitstamp(htmlData *HTMLScrapingData) ([]string, error) { - temp, err := http.Get(htmlData.Path) + temp, err := sendHTTPGetRequest(htmlData.Path, nil) if err != nil { return nil, err } defer temp.Body.Close() + a, err := ioutil.ReadAll(temp.Body) if err != nil { return nil, err @@ -1010,9 +1015,9 @@ func htmlScrapeBitstamp(htmlData *HTMLScrapingData) ([]string, error) { // htmlScrapeAlphaPoint gets the check string for Kraken Exchange func htmlScrapeAlphaPoint(htmlData *HTMLScrapingData) ([]string, error) { var resp []string - temp, err := http.Get(htmlData.Path) + temp, err := sendHTTPGetRequest(htmlData.Path, nil) if err != nil { - return resp, err + return nil, err } defer temp.Body.Close() tokenizer := html.NewTokenizer(temp.Body) @@ -1065,9 +1070,9 @@ loop: // htmlScrapeYobit gets the check string for Yobit Exchange func htmlScrapeYobit(htmlData *HTMLScrapingData) ([]string, error) { var resp []string - temp, err := http.Get(htmlData.Path) + temp, err := sendHTTPGetRequest(htmlData.Path, nil) if err != nil { - return resp, err + return nil, err } defer temp.Body.Close() tokenizer := html.NewTokenizer(temp.Body) @@ -1123,11 +1128,12 @@ loop: // htmlScrapeLocalBitcoins gets the check string for Yobit Exchange func htmlScrapeLocalBitcoins(htmlData *HTMLScrapingData) ([]string, error) { - temp, err := http.Get(htmlData.Path) + temp, err := sendHTTPGetRequest(htmlData.Path, nil) if err != nil { return nil, err } defer temp.Body.Close() + a, err := ioutil.ReadAll(temp.Body) if err != nil { return nil, err @@ -1463,9 +1469,9 @@ func trelloCreateNewChecklist() error { // htmlScrapeKraken gets the check string for Kraken Exchange func htmlScrapeKraken(htmlData *HTMLScrapingData) ([]string, error) { var resp []string - temp, err := http.Get(htmlData.Path) + temp, err := sendHTTPGetRequest(htmlData.Path, nil) if err != nil { - return resp, err + return nil, err } defer temp.Body.Close() tokenizer := html.NewTokenizer(temp.Body) @@ -1520,9 +1526,9 @@ loop: func htmlScrapeBitflyer(htmlData *HTMLScrapingData) ([]string, error) { var resp []string var tempArray []string - temp, err := http.Get(htmlData.Path) + temp, err := sendHTTPGetRequest(htmlData.Path, nil) if err != nil { - return resp, err + return nil, err } defer temp.Body.Close() tokenizer := html.NewTokenizer(temp.Body) @@ -1571,7 +1577,7 @@ loop: // htmlScrapeFTX gets the check string for FTX exchange func htmlScrapeFTX(htmlData *HTMLScrapingData) ([]string, error) { - temp, err := http.Get(htmlData.Path) + temp, err := sendHTTPGetRequest(htmlData.Path, nil) if err != nil { return nil, err } @@ -1660,11 +1666,12 @@ loop: // htmlScrapeBitfinex gets the check string for Bitfinex exchange func htmlScrapeBitfinex(htmlData *HTMLScrapingData) ([]string, error) { - temp, err := http.Get(htmlData.Path) + temp, err := sendHTTPGetRequest(htmlData.Path, nil) if err != nil { return nil, err } defer temp.Body.Close() + a, err := ioutil.ReadAll(temp.Body) if err != nil { return nil, err @@ -1693,11 +1700,12 @@ func htmlScrapeBitfinex(htmlData *HTMLScrapingData) ([]string, error) { // htmlScrapeBinance gets checkstring for binance exchange func htmlScrapeBinance(htmlData *HTMLScrapingData) ([]string, error) { - temp, err := http.Get(htmlData.Path) + temp, err := sendHTTPGetRequest(htmlData.Path, nil) if err != nil { return nil, err } defer temp.Body.Close() + tokenizer := html.NewTokenizer(temp.Body) var resp []string loop: @@ -1744,3 +1752,18 @@ loop: } return resp, nil } + +func sendHTTPGetRequest(path string, headers map[string]string) (*http.Response, error) { + req, err := http.NewRequestWithContext(context.TODO(), + http.MethodGet, + path, + nil) + if err != nil { + return nil, err + } + + for k, v := range headers { + req.Header.Set(k, v) + } + return http.DefaultClient.Do(req) +} diff --git a/cmd/documentation/documentation.go b/cmd/documentation/documentation.go index c0ff5cd0..537d7d93 100644 --- a/cmd/documentation/documentation.go +++ b/cmd/documentation/documentation.go @@ -1,6 +1,7 @@ package main import ( + "context" "encoding/json" "errors" "flag" @@ -8,6 +9,7 @@ import ( "html/template" "io/ioutil" "log" + "net/http" "os" "path/filepath" "strings" @@ -162,7 +164,7 @@ func main() { if verbose { fmt.Println("Fetching repository contributor list...") } - contributors, err = GetContributorList(config.GithubRepo) + contributors, err = GetContributorList(config.GithubRepo, verbose) if err != nil { log.Fatalf("Documentation Generation Tool - GetContributorList error %s", err) @@ -432,9 +434,19 @@ func GetTemplateFiles() (*template.Template, error) { // GetContributorList fetches a list of contributors from the github api // endpoint -func GetContributorList(repo string) ([]Contributor, error) { +func GetContributorList(repo string, verbose bool) ([]Contributor, error) { + contents, err := common.SendHTTPRequest(context.TODO(), + http.MethodGet, + repo+GithubAPIEndpoint, + nil, + nil, + verbose) + if err != nil { + return nil, err + } + var resp []Contributor - return resp, common.SendHTTPGetRequest(repo+GithubAPIEndpoint, true, false, &resp) + return resp, json.Unmarshal(contents, &resp) } // GetDocumentationAttributes returns specific attributes for a file template diff --git a/cmd/exchange_template/wrapper_file.tmpl b/cmd/exchange_template/wrapper_file.tmpl index d288ee64..7d555a2f 100644 --- a/cmd/exchange_template/wrapper_file.tmpl +++ b/cmd/exchange_template/wrapper_file.tmpl @@ -214,14 +214,14 @@ func ({{.Variable}} *{{.CapitalName}}) Run() { } // FetchTradablePairs returns a list of the exchanges tradable pairs -func ({{.Variable}} *{{.CapitalName}}) FetchTradablePairs(asset asset.Item) ([]string, error) { +func ({{.Variable}} *{{.CapitalName}}) FetchTradablePairs(ctx context.Context, asset asset.Item) ([]string, error) { // Implement fetching the exchange available pairs if supported return nil, nil } // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func ({{.Variable}} *{{.CapitalName}}) UpdateTradablePairs(forceUpdate bool) error { +func ({{.Variable}} *{{.CapitalName}}) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { pairs, err := {{.Variable}}.FetchTradablePairs(asset.Spot) if err != nil { return err @@ -237,7 +237,7 @@ func ({{.Variable}} *{{.CapitalName}}) UpdateTradablePairs(forceUpdate bool) err // UpdateTicker updates and returns the ticker for a currency pair -func ({{.Variable}} *{{.CapitalName}}) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) { +func ({{.Variable}} *{{.CapitalName}}) UpdateTicker(ctx context.Context, p currency.Pair, assetType asset.Item) (*ticker.Price, error) { // NOTE: EXAMPLE FOR GETTING TICKER PRICE /* tickerPrice := new(ticker.Price) @@ -298,7 +298,7 @@ func ({{.Variable}} *{{.CapitalName}}) UpdateTickers(assetType asset.Item) error } // FetchTicker returns the ticker for a currency pair -func ({{.Variable}} *{{.CapitalName}}) FetchTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) { +func ({{.Variable}} *{{.CapitalName}}) FetchTicker(ctx context.Context, p currency.Pair, assetType asset.Item) (*ticker.Price, error) { tickerNew, err := ticker.GetTicker({{.Variable}}.Name, p, assetType) if err != nil { return {{.Variable}}.UpdateTicker(p, assetType) @@ -307,7 +307,7 @@ func ({{.Variable}} *{{.CapitalName}}) FetchTicker(p currency.Pair, assetType as } // FetchOrderbook returns orderbook base on the currency pair -func ({{.Variable}} *{{.CapitalName}}) FetchOrderbook(currency currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func ({{.Variable}} *{{.CapitalName}}) FetchOrderbook(ctx context.Context, c currency.Pair, assetType asset.Item) (*orderbook.Base, error) { ob, err := orderbook.Get({{.Variable}}.Name, currency, assetType) if err != nil { return {{.Variable}}.UpdateOrderbook(currency, assetType) @@ -316,7 +316,7 @@ func ({{.Variable}} *{{.CapitalName}}) FetchOrderbook(currency currency.Pair, as } // UpdateOrderbook updates and returns the orderbook for a currency pair -func ({{.Variable}} *{{.CapitalName}}) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func ({{.Variable}} *{{.CapitalName}}) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { book := &orderbook.Base{ Exchange: {{.Variable}}.Name, Pair: p, @@ -355,28 +355,28 @@ func ({{.Variable}} *{{.CapitalName}}) UpdateOrderbook(p currency.Pair, assetTyp } // UpdateAccountInfo retrieves balances for all enabled currencies -func ({{.Variable}} *{{.CapitalName}}) UpdateAccountInfo(assetType asset.Item) (account.Holdings, error) { +func ({{.Variable}} *{{.CapitalName}}) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { return account.Holdings{}, common.ErrNotYetImplemented } // FetchAccountInfo retrieves balances for all enabled currencies -func ({{.Variable}} *{{.CapitalName}}) FetchAccountInfo(assetType asset.Item) (account.Holdings, error) { +func ({{.Variable}} *{{.CapitalName}}) FetchAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { return account.Holdings{}, common.ErrNotYetImplemented } // GetFundingHistory returns funding history, deposits and // withdrawals -func ({{.Variable}} *{{.CapitalName}}) GetFundingHistory() ([]exchange.FundHistory, error) { +func ({{.Variable}} *{{.CapitalName}}) GetFundingHistory(ctx context.Context) ([]exchange.FundHistory, error) { return nil, common.ErrNotYetImplemented } // GetWithdrawalsHistory returns previous withdrawals data -func ({{.Variable}} *{{.CapitalName}}) GetWithdrawalsHistory(c currency.Code) (resp []exchange.WithdrawalHistory, err error) { +func ({{.Variable}} *{{.CapitalName}}) GetWithdrawalsHistory(ctx context.Context, c currency.Code) (resp []exchange.WithdrawalHistory, err error) { return nil, common.ErrNotYetImplemented } // GetRecentTrades returns the most recent trades for a currency and asset -func ({{.Variable}} *{{.CapitalName}}) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade.Data, error) { +func ({{.Variable}} *{{.CapitalName}}) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { return nil, common.ErrNotYetImplemented } @@ -386,7 +386,7 @@ func ({{.Variable}} *{{.CapitalName}}) GetHistoricTrades (p currency.Pair, asset } // SubmitOrder submits a new order -func ({{.Variable}} *{{.CapitalName}}) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { +func ({{.Variable}} *{{.CapitalName}}) SubmitOrder(ctx context.Context, s *order.Submit) (order.SubmitResponse, error) { var submitOrderResponse order.SubmitResponse if err := s.Validate(); err != nil { return submitOrderResponse, err @@ -404,7 +404,7 @@ func ({{.Variable}} *{{.CapitalName}}) ModifyOrder(action *order.Modify) (string } // CancelOrder cancels an order by its corresponding ID number -func ({{.Variable}} *{{.CapitalName}}) CancelOrder(ord *order.Cancel) error { +func ({{.Variable}} *{{.CapitalName}}) CancelOrder(ctx context.Context, ord *order.Cancel) error { // if err := ord.Validate(ord.StandardCancel()); err != nil { // return err // } @@ -412,12 +412,12 @@ func ({{.Variable}} *{{.CapitalName}}) CancelOrder(ord *order.Cancel) error { } // CancelBatchOrders cancels orders by their corresponding ID numbers -func ({{.Variable}} *{{.CapitalName}}) CancelBatchOrders(orders []order.Cancel) (order.CancelBatchResponse, error) { +func ({{.Variable}} *{{.CapitalName}}) CancelBatchOrders(ctx context.Context, orders []order.Cancel) (order.CancelBatchResponse, error) { return order.CancelBatchResponse{}, common.ErrNotYetImplemented } // CancelAllOrders cancels all orders associated with a currency pair -func ({{.Variable}} *{{.CapitalName}}) CancelAllOrders(orderCancellation *order.Cancel) (order.CancelAllResponse, error) { +func ({{.Variable}} *{{.CapitalName}}) CancelAllOrders(ctx context.Context, orderCancellation *order.Cancel) (order.CancelAllResponse, error) { // if err := orderCancellation.Validate(); err != nil { // return err // } @@ -425,18 +425,18 @@ func ({{.Variable}} *{{.CapitalName}}) CancelAllOrders(orderCancellation *order. } // GetOrderInfo returns order information based on order ID -func ({{.Variable}} *{{.CapitalName}}) GetOrderInfo(orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { +func ({{.Variable}} *{{.CapitalName}}) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { return order.Detail{}, common.ErrNotYetImplemented } // GetDepositAddress returns a deposit address for a specified currency -func ({{.Variable}} *{{.CapitalName}}) GetDepositAddress(cryptocurrency currency.Code, accountID string) (string, error) { +func ({{.Variable}} *{{.CapitalName}}) GetDepositAddress(ctx context.Context, c currency.Code, accountID string) (string, error) { return "", common.ErrNotYetImplemented } // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is // submitted -func ({{.Variable}} *{{.CapitalName}}) WithdrawCryptocurrencyFunds(withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func ({{.Variable}} *{{.CapitalName}}) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { // if err := withdrawRequest.Validate(); err != nil { // return nil, err // } @@ -445,7 +445,7 @@ func ({{.Variable}} *{{.CapitalName}}) WithdrawCryptocurrencyFunds(withdrawReque // WithdrawFiatFunds returns a withdrawal ID when a withdrawal is // submitted -func ({{.Variable}} *{{.CapitalName}}) WithdrawFiatFunds(withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func ({{.Variable}} *{{.CapitalName}}) WithdrawFiatFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { // if err := withdrawRequest.Validate(); err != nil { // return nil, err // } @@ -454,7 +454,7 @@ func ({{.Variable}} *{{.CapitalName}}) WithdrawFiatFunds(withdrawRequest *withdr // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a withdrawal is // submitted -func ({{.Variable}} *{{.CapitalName}}) WithdrawFiatFundsToInternationalBank(withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func ({{.Variable}} *{{.CapitalName}}) WithdrawFiatFundsToInternationalBank(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { // if err := withdrawRequest.Validate(); err != nil { // return nil, err // } @@ -462,7 +462,7 @@ func ({{.Variable}} *{{.CapitalName}}) WithdrawFiatFundsToInternationalBank(with } // GetActiveOrders retrieves any orders that are active/open -func ({{.Variable}} *{{.CapitalName}}) GetActiveOrders(getOrdersRequest *order.GetOrdersRequest) ([]order.Detail, error) { +func ({{.Variable}} *{{.CapitalName}}) GetActiveOrders(ctx context.Context, getOrdersRequest *order.GetOrdersRequest) ([]order.Detail, error) { // if err := getOrdersRequest.Validate(); err != nil { // return nil, err // } @@ -471,7 +471,7 @@ func ({{.Variable}} *{{.CapitalName}}) GetActiveOrders(getOrdersRequest *order.G // GetOrderHistory retrieves account order information // Can Limit response to specific order status -func ({{.Variable}} *{{.CapitalName}}) GetOrderHistory(getOrdersRequest *order.GetOrdersRequest) ([]order.Detail, error) { +func ({{.Variable}} *{{.CapitalName}}) GetOrderHistory(ctx context.Context, getOrdersRequest *order.GetOrdersRequest) ([]order.Detail, error) { // if err := getOrdersRequest.Validate(); err != nil { // return nil, err // } @@ -479,23 +479,23 @@ func ({{.Variable}} *{{.CapitalName}}) GetOrderHistory(getOrdersRequest *order.G } // GetFeeByType returns an estimate of fee based on the type of transaction -func ({{.Variable}} *{{.CapitalName}}) GetFeeByType(feeBuilder *exchange.FeeBuilder) (float64, error) { +func ({{.Variable}} *{{.CapitalName}}) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { return 0, common.ErrNotYetImplemented } // ValidateCredentials validates current credentials used for wrapper -func ({{.Variable}} *{{.CapitalName}}) ValidateCredentials(assetType asset.Item) error { +func ({{.Variable}} *{{.CapitalName}}) ValidateCredentials(ctx context.Context, assetType asset.Item) error { _, err := {{.Variable}}.UpdateAccountInfo(assetType) return {{.Variable}}.CheckTransientError(err) } // GetHistoricCandles returns candles between a time period for a set time interval -func ({{.Variable}} *{{.CapitalName}}) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func ({{.Variable}} *{{.CapitalName}}) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { return kline.Item{}, common.ErrNotYetImplemented } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func ({{.Variable}} *{{.CapitalName}}) GetHistoricCandlesExtended(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func ({{.Variable}} *{{.CapitalName}}) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { return kline.Item{}, common.ErrNotYetImplemented } diff --git a/cmd/exchange_wrapper_coverage/main.go b/cmd/exchange_wrapper_coverage/main.go index efb14b81..637c94c4 100644 --- a/cmd/exchange_wrapper_coverage/main.go +++ b/cmd/exchange_wrapper_coverage/main.go @@ -1,6 +1,7 @@ package main import ( + "context" "errors" "log" "math/rand" @@ -83,136 +84,136 @@ func testWrappers(e exchange.IBotExchange) []string { var funcs []string - _, err := e.FetchTicker(p, assetType) + _, err := e.FetchTicker(context.TODO(), p, assetType) if errors.Is(err, common.ErrNotYetImplemented) { funcs = append(funcs, "FetchTicker") } - _, err = e.UpdateTicker(p, assetType) + _, err = e.UpdateTicker(context.TODO(), p, assetType) if errors.Is(err, common.ErrNotYetImplemented) { funcs = append(funcs, "UpdateTicker") } - _, err = e.FetchOrderbook(p, assetType) + _, err = e.FetchOrderbook(context.TODO(), p, assetType) if errors.Is(err, common.ErrNotYetImplemented) { funcs = append(funcs, "FetchOrderbook") } - _, err = e.UpdateOrderbook(p, assetType) + _, err = e.UpdateOrderbook(context.TODO(), p, assetType) if errors.Is(err, common.ErrNotYetImplemented) { funcs = append(funcs, "UpdateOrderbook") } - _, err = e.FetchTradablePairs(asset.Spot) + _, err = e.FetchTradablePairs(context.TODO(), asset.Spot) if errors.Is(err, common.ErrNotYetImplemented) { funcs = append(funcs, "FetchTradablePairs") } - err = e.UpdateTradablePairs(false) + err = e.UpdateTradablePairs(context.TODO(), false) if errors.Is(err, common.ErrNotYetImplemented) { funcs = append(funcs, "UpdateTradablePairs") } - _, err = e.FetchAccountInfo(assetType) + _, err = e.FetchAccountInfo(context.TODO(), assetType) if errors.Is(err, common.ErrNotYetImplemented) { funcs = append(funcs, "GetAccountInfo") } - _, err = e.GetRecentTrades(p, assetType) + _, err = e.GetRecentTrades(context.TODO(), p, assetType) if errors.Is(err, common.ErrNotYetImplemented) { funcs = append(funcs, "GetRecentTrades") } - _, err = e.GetHistoricTrades(p, assetType, time.Time{}, time.Time{}) + _, err = e.GetHistoricTrades(context.TODO(), p, assetType, time.Time{}, time.Time{}) if errors.Is(err, common.ErrNotYetImplemented) { funcs = append(funcs, "GetHistoricTrades") } - _, err = e.GetFundingHistory() + _, err = e.GetFundingHistory(context.TODO()) if errors.Is(err, common.ErrNotYetImplemented) { funcs = append(funcs, "GetFundingHistory") } - _, err = e.SubmitOrder(nil) + _, err = e.SubmitOrder(context.TODO(), nil) if errors.Is(err, common.ErrNotYetImplemented) { funcs = append(funcs, "SubmitOrder") } - _, err = e.ModifyOrder(nil) + _, err = e.ModifyOrder(context.TODO(), nil) if errors.Is(err, common.ErrNotYetImplemented) { funcs = append(funcs, "ModifyOrder") } - err = e.CancelOrder(nil) + err = e.CancelOrder(context.TODO(), nil) if errors.Is(err, common.ErrNotYetImplemented) { funcs = append(funcs, "CancelOrder") } - _, err = e.CancelBatchOrders(nil) + _, err = e.CancelBatchOrders(context.TODO(), nil) if errors.Is(err, common.ErrNotYetImplemented) { funcs = append(funcs, "CancelBatchOrders") } - _, err = e.CancelAllOrders(nil) + _, err = e.CancelAllOrders(context.TODO(), nil) if errors.Is(err, common.ErrNotYetImplemented) { funcs = append(funcs, "CancelAllOrders") } - _, err = e.GetOrderInfo("1", p, assetType) + _, err = e.GetOrderInfo(context.TODO(), "1", p, assetType) if errors.Is(err, common.ErrNotYetImplemented) { funcs = append(funcs, "GetOrderInfo") } - _, err = e.GetOrderHistory(nil) + _, err = e.GetOrderHistory(context.TODO(), nil) if errors.Is(err, common.ErrNotYetImplemented) { funcs = append(funcs, "GetOrderHistory") } - _, err = e.GetActiveOrders(nil) + _, err = e.GetActiveOrders(context.TODO(), nil) if errors.Is(err, common.ErrNotYetImplemented) { funcs = append(funcs, "GetActiveOrders") } - _, err = e.GetDepositAddress(currency.BTC, "") + _, err = e.GetDepositAddress(context.TODO(), currency.BTC, "") if errors.Is(err, common.ErrNotYetImplemented) { funcs = append(funcs, "GetDepositAddress") } - _, err = e.WithdrawCryptocurrencyFunds(nil) + _, err = e.WithdrawCryptocurrencyFunds(context.TODO(), nil) if errors.Is(err, common.ErrNotYetImplemented) { funcs = append(funcs, "WithdrawCryptocurrencyFunds") } - _, err = e.WithdrawFiatFunds(nil) + _, err = e.WithdrawFiatFunds(context.TODO(), nil) if errors.Is(err, common.ErrNotYetImplemented) { funcs = append(funcs, "WithdrawFiatFunds") } - _, err = e.WithdrawFiatFundsToInternationalBank(nil) + _, err = e.WithdrawFiatFundsToInternationalBank(context.TODO(), nil) if errors.Is(err, common.ErrNotYetImplemented) { funcs = append(funcs, "WithdrawFiatFundsToInternationalBank") } - _, err = e.GetHistoricCandles(currency.Pair{}, asset.Spot, time.Unix(0, 0), time.Unix(0, 0), kline.OneDay) + _, err = e.GetHistoricCandles(context.TODO(), currency.Pair{}, asset.Spot, time.Unix(0, 0), time.Unix(0, 0), kline.OneDay) if errors.Is(err, common.ErrNotYetImplemented) { funcs = append(funcs, "GetHistoricCandles") } - _, err = e.GetHistoricCandlesExtended(currency.Pair{}, asset.Spot, time.Unix(0, 0), time.Unix(0, 0), kline.OneDay) + _, err = e.GetHistoricCandlesExtended(context.TODO(), currency.Pair{}, asset.Spot, time.Unix(0, 0), time.Unix(0, 0), kline.OneDay) if errors.Is(err, common.ErrNotYetImplemented) { funcs = append(funcs, "GetHistoricCandlesExtended") } - _, err = e.UpdateAccountInfo(assetType) + _, err = e.UpdateAccountInfo(context.TODO(), assetType) if errors.Is(err, common.ErrNotYetImplemented) { funcs = append(funcs, "UpdateAccountInfo") } - _, err = e.GetFeeByType(&exchange.FeeBuilder{}) + _, err = e.GetFeeByType(context.TODO(), &exchange.FeeBuilder{}) if errors.Is(err, common.ErrNotYetImplemented) { funcs = append(funcs, "GetFeeByType") } - err = e.UpdateOrderExecutionLimits(asset.DownsideProfitContract) + err = e.UpdateOrderExecutionLimits(context.TODO(), asset.DownsideProfitContract) if errors.Is(err, common.ErrNotYetImplemented) { funcs = append(funcs, "UpdateOrderExecutionLimits") } diff --git a/cmd/exchange_wrapper_issues/main.go b/cmd/exchange_wrapper_issues/main.go index 4d329901..8550fb99 100644 --- a/cmd/exchange_wrapper_issues/main.go +++ b/cmd/exchange_wrapper_issues/main.go @@ -1,6 +1,7 @@ package main import ( + "context" "encoding/json" "errors" "flag" @@ -342,7 +343,7 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config) if !authenticatedOnly { var fetchTickerResponse *ticker.Price - fetchTickerResponse, err = e.FetchTicker(p, assetTypes[i]) + fetchTickerResponse, err = e.FetchTicker(context.TODO(), p, assetTypes[i]) msg = "" if err != nil { msg = err.Error() @@ -356,7 +357,7 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config) }) var updateTickerResponse *ticker.Price - updateTickerResponse, err = e.UpdateTicker(p, assetTypes[i]) + updateTickerResponse, err = e.UpdateTicker(context.TODO(), p, assetTypes[i]) msg = "" if err != nil { msg = err.Error() @@ -370,7 +371,7 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config) }) var fetchOrderbookResponse *orderbook.Base - fetchOrderbookResponse, err = e.FetchOrderbook(p, assetTypes[i]) + fetchOrderbookResponse, err = e.FetchOrderbook(context.TODO(), p, assetTypes[i]) msg = "" if err != nil { msg = err.Error() @@ -384,7 +385,7 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config) }) var updateOrderbookResponse *orderbook.Base - updateOrderbookResponse, err = e.UpdateOrderbook(p, assetTypes[i]) + updateOrderbookResponse, err = e.UpdateOrderbook(context.TODO(), p, assetTypes[i]) msg = "" if err != nil { msg = err.Error() @@ -398,7 +399,7 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config) }) var fetchTradablePairsResponse []string - fetchTradablePairsResponse, err = e.FetchTradablePairs(assetTypes[i]) + fetchTradablePairsResponse, err = e.FetchTradablePairs(context.TODO(), assetTypes[i]) msg = "" if err != nil { msg = err.Error() @@ -411,7 +412,7 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config) Response: jsonifyInterface([]interface{}{fetchTradablePairsResponse}), }) // r6 - err = e.UpdateTradablePairs(false) + err = e.UpdateTradablePairs(context.TODO(), false) msg = "" if err != nil { msg = err.Error() @@ -425,7 +426,7 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config) }) var getHistoricTradesResponse []trade.Data - getHistoricTradesResponse, err = e.GetHistoricTrades(p, assetTypes[i], time.Now().Add(-time.Hour), time.Now()) + getHistoricTradesResponse, err = e.GetHistoricTrades(context.TODO(), p, assetTypes[i], time.Now().Add(-time.Hour), time.Now()) msg = "" if err != nil { msg = err.Error() @@ -439,7 +440,7 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config) }) var getRecentTradesResponse []trade.Data - getRecentTradesResponse, err = e.GetRecentTrades(p, assetTypes[i]) + getRecentTradesResponse, err = e.GetRecentTrades(context.TODO(), p, assetTypes[i]) msg = "" if err != nil { msg = err.Error() @@ -454,7 +455,7 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config) var getHistoricCandlesResponse kline.Item startTime, endTime := time.Now().AddDate(0, 0, -1), time.Now() - getHistoricCandlesResponse, err = e.GetHistoricCandles(p, assetTypes[i], startTime, endTime, kline.OneDay) + getHistoricCandlesResponse, err = e.GetHistoricCandles(context.TODO(), p, assetTypes[i], startTime, endTime, kline.OneDay) msg = "" if err != nil { msg = err.Error() @@ -468,7 +469,7 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config) }) var getHisotirCandlesExtendedResponse kline.Item - getHisotirCandlesExtendedResponse, err = e.GetHistoricCandlesExtended(p, assetTypes[i], startTime, endTime, kline.OneDay) + getHisotirCandlesExtendedResponse, err = e.GetHistoricCandlesExtended(context.TODO(), p, assetTypes[i], startTime, endTime, kline.OneDay) msg = "" if err != nil { msg = err.Error() @@ -481,7 +482,7 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config) SentParams: jsonifyInterface([]interface{}{p, assetTypes[i], startTime, endTime, kline.OneDay}), }) - err = e.UpdateOrderExecutionLimits(assetTypes[i]) + err = e.UpdateOrderExecutionLimits(context.TODO(), assetTypes[i]) msg = "" if err != nil { msg = err.Error() @@ -497,7 +498,7 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config) } var fetchAccountInfoResponse account.Holdings - fetchAccountInfoResponse, err = e.FetchAccountInfo(assetTypes[i]) + fetchAccountInfoResponse, err = e.FetchAccountInfo(context.TODO(), assetTypes[i]) msg = "" if err != nil { msg = err.Error() @@ -510,7 +511,7 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config) }) var getFundingHistoryResponse []exchange.FundHistory - getFundingHistoryResponse, err = e.GetFundingHistory() + getFundingHistoryResponse, err = e.GetFundingHistory(context.TODO()) msg = "" if err != nil { msg = err.Error() @@ -529,7 +530,7 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config) Amount: config.OrderSubmission.Amount, } var getFeeByTypeResponse float64 - getFeeByTypeResponse, err = e.GetFeeByType(&feeType) + getFeeByTypeResponse, err = e.GetFeeByType(context.TODO(), &feeType) msg = "" if err != nil { msg = err.Error() @@ -552,7 +553,7 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config) AssetType: assetTypes[i], } var submitOrderResponse order.SubmitResponse - submitOrderResponse, err = e.SubmitOrder(s) + submitOrderResponse, err = e.SubmitOrder(context.TODO(), s) msg = "" if err != nil { msg = err.Error() @@ -573,7 +574,7 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config) Price: config.OrderSubmission.Price, Amount: config.OrderSubmission.Amount, } - modifyOrderResponse, err := e.ModifyOrder(&modifyRequest) + modifyOrderResponse, err := e.ModifyOrder(context.TODO(), &modifyRequest) msg = "" if err != nil { msg = err.Error() @@ -592,7 +593,7 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config) ID: config.OrderSubmission.OrderID, AssetType: assetTypes[i], } - err = e.CancelOrder(&cancelRequest) + err = e.CancelOrder(context.TODO(), &cancelRequest) msg = "" if err != nil { msg = err.Error() @@ -614,7 +615,7 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config) }) var CancelBatchOrdersResponse order.CancelBatchResponse - CancelBatchOrdersResponse, err = e.CancelBatchOrders(request) + CancelBatchOrdersResponse, err = e.CancelBatchOrders(context.TODO(), request) msg = "" if err != nil { msg = err.Error() @@ -628,7 +629,7 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config) }) var cancellAllOrdersResponse order.CancelAllResponse - cancellAllOrdersResponse, err = e.CancelAllOrders(&cancelRequest) + cancellAllOrdersResponse, err = e.CancelAllOrders(context.TODO(), &cancelRequest) msg = "" if err != nil { msg = err.Error() @@ -642,7 +643,7 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config) }) var r15 order.Detail - r15, err = e.GetOrderInfo(config.OrderSubmission.OrderID, p, assetTypes[i]) + r15, err = e.GetOrderInfo(context.TODO(), config.OrderSubmission.OrderID, p, assetTypes[i]) msg = "" if err != nil { msg = err.Error() @@ -661,7 +662,7 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config) Pairs: []currency.Pair{p}, } var getOrderHistoryResponse []order.Detail - getOrderHistoryResponse, err = e.GetOrderHistory(&historyRequest) + getOrderHistoryResponse, err = e.GetOrderHistory(context.TODO(), &historyRequest) msg = "" if err != nil { msg = err.Error() @@ -680,7 +681,7 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config) Pairs: []currency.Pair{p}, } var getActiveOrdersResponse []order.Detail - getActiveOrdersResponse, err = e.GetActiveOrders(&orderRequest) + getActiveOrdersResponse, err = e.GetActiveOrders(context.TODO(), &orderRequest) msg = "" if err != nil { msg = err.Error() @@ -694,7 +695,7 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config) }) var getDepositAddressResponse string - getDepositAddressResponse, err = e.GetDepositAddress(p.Base, "") + getDepositAddressResponse, err = e.GetDepositAddress(context.TODO(), p.Base, "") msg = "" if err != nil { msg = err.Error() @@ -714,7 +715,7 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config) Amount: config.OrderSubmission.Amount, } var GetFeeByTypeResponse float64 - GetFeeByTypeResponse, err = e.GetFeeByType(&feeType) + GetFeeByTypeResponse, err = e.GetFeeByType(context.TODO(), &feeType) msg = "" if err != nil { msg = err.Error() @@ -740,7 +741,7 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config) msg = err.Error() responseContainer.ErrorCount++ } - withdrawCryptocurrencyFundsResponse, err := e.WithdrawCryptocurrencyFunds(&withdrawRequest) + withdrawCryptocurrencyFundsResponse, err := e.WithdrawCryptocurrencyFunds(context.TODO(), &withdrawRequest) if err != nil { msg += ", " + err.Error() responseContainer.ErrorCount++ @@ -761,7 +762,7 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config) BankTransactionType: exchange.WireTransfer, } var getFeeByTypeFiatResponse float64 - getFeeByTypeFiatResponse, err = e.GetFeeByType(&feeType) + getFeeByTypeFiatResponse, err = e.GetFeeByType(context.TODO(), &feeType) msg = "" if err != nil { msg = err.Error() @@ -804,7 +805,7 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config) IntermediaryBankCode: config.BankDetails.IntermediaryBankCode, }, } - withdrawFiatFundsResponse, err := e.WithdrawFiatFunds(&withdrawRequestFiat) + withdrawFiatFundsResponse, err := e.WithdrawFiatFunds(context.TODO(), &withdrawRequestFiat) msg = "" if err != nil { msg = err.Error() @@ -817,7 +818,7 @@ func testWrappers(e exchange.IBotExchange, base *exchange.Base, config *Config) Response: withdrawFiatFundsResponse, }) - withdrawFiatFundsInternationalResponse, err := e.WithdrawFiatFundsToInternationalBank(&withdrawRequestFiat) + withdrawFiatFundsInternationalResponse, err := e.WithdrawFiatFundsToInternationalBank(context.TODO(), &withdrawRequestFiat) msg = "" if err != nil { msg = err.Error() diff --git a/cmd/gctcli/commands.go b/cmd/gctcli/commands.go index 65e74ecd..dd0cfe61 100644 --- a/cmd/gctcli/commands.go +++ b/cmd/gctcli/commands.go @@ -1,7 +1,6 @@ package main import ( - "context" "errors" "fmt" "io/ioutil" @@ -16,7 +15,6 @@ import ( "github.com/thrasher-corp/gocryptotrader/currency" "github.com/thrasher-corp/gocryptotrader/gctrpc" "github.com/urfave/cli/v2" - "google.golang.org/grpc" ) var startTime, endTime, order string @@ -28,15 +26,15 @@ var getInfoCommand = &cli.Command{ Action: getInfo, } -func getInfo(_ *cli.Context) error { - conn, err := setupClient() +func getInfo(c *cli.Context) error { + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.GetInfo(context.Background(), + result, err := client.GetInfo(c.Context, &gctrpc.GetInfoRequest{}, ) @@ -54,15 +52,15 @@ var getSubsystemsCommand = &cli.Command{ Action: getSubsystems, } -func getSubsystems(_ *cli.Context) error { - conn, err := setupClient() +func getSubsystems(c *cli.Context) error { + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.GetSubsystems(context.Background(), + result, err := client.GetSubsystems(c.Context, &gctrpc.GetSubsystemsRequest{}, ) @@ -103,14 +101,14 @@ func enableSubsystem(c *cli.Context) error { return errors.New("invalid subsystem supplied") } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.EnableSubsystem(context.Background(), + result, err := client.EnableSubsystem(c.Context, &gctrpc.GenericSubsystemRequest{ Subsystem: subsystemName, }, @@ -153,14 +151,14 @@ func disableSubsystem(c *cli.Context) error { return errors.New("invalid subsystem supplied") } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.DisableSubsystem(context.Background(), + result, err := client.DisableSubsystem(c.Context, &gctrpc.GenericSubsystemRequest{ Subsystem: subsystemName, }, @@ -180,15 +178,15 @@ var getRPCEndpointsCommand = &cli.Command{ Action: getRPCEndpoints, } -func getRPCEndpoints(_ *cli.Context) error { - conn, err := setupClient() +func getRPCEndpoints(c *cli.Context) error { + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.GetRPCEndpoints(context.Background(), + result, err := client.GetRPCEndpoints(c.Context, &gctrpc.GetRPCEndpointsRequest{}, ) @@ -206,15 +204,15 @@ var getCommunicationRelayersCommand = &cli.Command{ Action: getCommunicationRelayers, } -func getCommunicationRelayers(_ *cli.Context) error { - conn, err := setupClient() +func getCommunicationRelayers(c *cli.Context) error { + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.GetCommunicationRelayers(context.Background(), + result, err := client.GetCommunicationRelayers(c.Context, &gctrpc.GetCommunicationRelayersRequest{}, ) @@ -240,11 +238,11 @@ var getExchangesCommand = &cli.Command{ } func getExchanges(c *cli.Context) error { - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) var enabledOnly bool if c.IsSet("enabled") { @@ -252,7 +250,7 @@ func getExchanges(c *cli.Context) error { } client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.GetExchanges(context.Background(), + result, err := client.GetExchanges(c.Context, &gctrpc.GetExchangesRequest{ Enabled: enabledOnly, }, @@ -291,14 +289,14 @@ func enableExchange(c *cli.Context) error { exchangeName = c.Args().First() } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.EnableExchange(context.Background(), + result, err := client.EnableExchange(c.Context, &gctrpc.GenericExchangeNameRequest{ Exchange: exchangeName, }, @@ -337,14 +335,14 @@ func disableExchange(c *cli.Context) error { exchangeName = c.Args().First() } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.DisableExchange(context.Background(), + result, err := client.DisableExchange(c.Context, &gctrpc.GenericExchangeNameRequest{ Exchange: exchangeName, }, @@ -383,14 +381,14 @@ func getExchangeOTPCode(c *cli.Context) error { exchangeName = c.Args().First() } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.GetExchangeOTPCode(context.Background(), + result, err := client.GetExchangeOTPCode(c.Context, &gctrpc.GenericExchangeNameRequest{ Exchange: exchangeName, }, @@ -411,14 +409,14 @@ var getExchangeOTPsCommand = &cli.Command{ } func getExchangeOTPCodes(c *cli.Context) error { - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.GetExchangeOTPCodes(context.Background(), + result, err := client.GetExchangeOTPCodes(c.Context, &gctrpc.GetExchangeOTPsRequest{}) if err != nil { @@ -454,14 +452,14 @@ func getExchangeInfo(c *cli.Context) error { exchangeName = c.Args().First() } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.GetExchangeInfo(context.Background(), + result, err := client.GetExchangeInfo(c.Context, &gctrpc.GenericExchangeNameRequest{ Exchange: exchangeName, }, @@ -537,14 +535,14 @@ func getTicker(c *cli.Context) error { return err } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.GetTicker(context.Background(), + result, err := client.GetTicker(c.Context, &gctrpc.GetTickerRequest{ Exchange: exchangeName, Pair: &gctrpc.CurrencyPair{ @@ -570,15 +568,15 @@ var getTickersCommand = &cli.Command{ Action: getTickers, } -func getTickers(_ *cli.Context) error { - conn, err := setupClient() +func getTickers(c *cli.Context) error { + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.GetTickers(context.Background(), &gctrpc.GetTickersRequest{}) + result, err := client.GetTickers(c.Context, &gctrpc.GetTickersRequest{}) if err != nil { return err } @@ -649,14 +647,14 @@ func getOrderbook(c *cli.Context) error { return err } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.GetOrderbook(context.Background(), + result, err := client.GetOrderbook(c.Context, &gctrpc.GetOrderbookRequest{ Exchange: exchangeName, Pair: &gctrpc.CurrencyPair{ @@ -682,15 +680,15 @@ var getOrderbooksCommand = &cli.Command{ Action: getOrderbooks, } -func getOrderbooks(_ *cli.Context) error { - conn, err := setupClient() +func getOrderbooks(c *cli.Context) error { + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.GetOrderbooks(context.Background(), &gctrpc.GetOrderbooksRequest{}) + result, err := client.GetOrderbooks(c.Context, &gctrpc.GetOrderbooksRequest{}) if err != nil { return err } @@ -738,14 +736,14 @@ func getAccountInfo(c *cli.Context) error { return errInvalidAsset } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.GetAccountInfo(context.Background(), + result, err := client.GetAccountInfo(c.Context, &gctrpc.GetAccountInfoRequest{ Exchange: exchange, AssetType: assetType, @@ -800,14 +798,14 @@ func getAccountInfoStream(c *cli.Context) error { return errInvalidAsset } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.GetAccountInfoStream(context.Background(), + result, err := client.GetAccountInfoStream(c.Context, &gctrpc.GetAccountInfoRequest{Exchange: exchangeName, AssetType: assetType}) if err != nil { return err @@ -870,14 +868,14 @@ func updateAccountInfo(c *cli.Context) error { return errInvalidAsset } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.UpdateAccountInfo(context.Background(), + result, err := client.UpdateAccountInfo(c.Context, &gctrpc.GetAccountInfoRequest{ Exchange: exchange, AssetType: assetType, @@ -897,15 +895,15 @@ var getConfigCommand = &cli.Command{ Action: getConfig, } -func getConfig(_ *cli.Context) error { - conn, err := setupClient() +func getConfig(c *cli.Context) error { + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.GetConfig(context.Background(), &gctrpc.GetConfigRequest{}) + result, err := client.GetConfig(c.Context, &gctrpc.GetConfigRequest{}) if err != nil { return err } @@ -920,15 +918,15 @@ var getPortfolioCommand = &cli.Command{ Action: getPortfolio, } -func getPortfolio(_ *cli.Context) error { - conn, err := setupClient() +func getPortfolio(c *cli.Context) error { + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.GetPortfolio(context.Background(), &gctrpc.GetPortfolioRequest{}) + result, err := client.GetPortfolio(c.Context, &gctrpc.GetPortfolioRequest{}) if err != nil { return err } @@ -943,15 +941,15 @@ var getPortfolioSummaryCommand = &cli.Command{ Action: getPortfolioSummary, } -func getPortfolioSummary(_ *cli.Context) error { - conn, err := setupClient() +func getPortfolioSummary(c *cli.Context) error { + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.GetPortfolioSummary(context.Background(), &gctrpc.GetPortfolioSummaryRequest{}) + result, err := client.GetPortfolioSummary(c.Context, &gctrpc.GetPortfolioSummaryRequest{}) if err != nil { return err } @@ -1047,14 +1045,14 @@ func addPortfolioAddress(c *cli.Context) error { supportedExchanges = c.Args().Get(5) } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.AddPortfolioAddress(context.Background(), + result, err := client.AddPortfolioAddress(c.Context, &gctrpc.AddPortfolioAddressRequest{ Address: address, CoinType: coinType, @@ -1121,14 +1119,14 @@ func removePortfolioAddress(c *cli.Context) error { description = c.Args().Get(2) } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.RemovePortfolioAddress(context.Background(), + result, err := client.RemovePortfolioAddress(c.Context, &gctrpc.RemovePortfolioAddressRequest{ Address: address, CoinType: coinType, @@ -1150,15 +1148,15 @@ var getForexProvidersCommand = &cli.Command{ Action: getForexProviders, } -func getForexProviders(_ *cli.Context) error { - conn, err := setupClient() +func getForexProviders(c *cli.Context) error { + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.GetForexProviders(context.Background(), &gctrpc.GetForexProvidersRequest{}) + result, err := client.GetForexProviders(c.Context, &gctrpc.GetForexProvidersRequest{}) if err != nil { return err } @@ -1173,15 +1171,15 @@ var getForexRatesCommand = &cli.Command{ Action: getForexRates, } -func getForexRates(_ *cli.Context) error { - conn, err := setupClient() +func getForexRates(c *cli.Context) error { + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.GetForexRates(context.Background(), &gctrpc.GetForexRatesRequest{}) + result, err := client.GetForexRates(c.Context, &gctrpc.GetForexRatesRequest{}) if err != nil { return err } @@ -1289,15 +1287,14 @@ func getOrders(c *cli.Context) error { return errors.New("start cannot be after end") } - var conn *grpc.ClientConn - conn, err = setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.GetOrders(context.Background(), &gctrpc.GetOrdersRequest{ + result, err := client.GetOrders(c.Context, &gctrpc.GetOrdersRequest{ Exchange: exchangeName, AssetType: assetType, Pair: &gctrpc.CurrencyPair{ @@ -1378,15 +1375,14 @@ func getManagedOrders(c *cli.Context) error { return err } - var conn *grpc.ClientConn - conn, err = setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.GetManagedOrders(context.Background(), &gctrpc.GetOrdersRequest{ + result, err := client.GetManagedOrders(c.Context, &gctrpc.GetOrdersRequest{ Exchange: exchangeName, AssetType: assetType, Pair: &gctrpc.CurrencyPair{ @@ -1473,14 +1469,14 @@ func getOrder(c *cli.Context) error { orderID = c.Args().Get(3) } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.GetOrder(context.Background(), &gctrpc.GetOrderRequest{ + result, err := client.GetOrder(c.Context, &gctrpc.GetOrderRequest{ Exchange: exchangeName, OrderId: orderID, Pair: &gctrpc.CurrencyPair{ @@ -1636,14 +1632,14 @@ func submitOrder(c *cli.Context) error { return err } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.SubmitOrder(context.Background(), &gctrpc.SubmitOrderRequest{ + result, err := client.SubmitOrder(c.Context, &gctrpc.SubmitOrderRequest{ Exchange: exchangeName, Pair: &gctrpc.CurrencyPair{ Delimiter: p.Delimiter, @@ -1745,14 +1741,14 @@ func simulateOrder(c *cli.Context) error { return err } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.SimulateOrder(context.Background(), &gctrpc.SimulateOrderRequest{ + result, err := client.SimulateOrder(c.Context, &gctrpc.SimulateOrderRequest{ Exchange: exchangeName, Pair: &gctrpc.CurrencyPair{ Delimiter: p.Delimiter, @@ -1846,14 +1842,14 @@ func whaleBomb(c *cli.Context) error { return err } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.WhaleBomb(context.Background(), &gctrpc.WhaleBombRequest{ + result, err := client.WhaleBomb(c.Context, &gctrpc.WhaleBombRequest{ Exchange: exchangeName, Pair: &gctrpc.CurrencyPair{ Delimiter: p.Delimiter, @@ -1985,14 +1981,14 @@ func cancelOrder(c *cli.Context) error { } } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.CancelOrder(context.Background(), &gctrpc.CancelOrderRequest{ + result, err := client.CancelOrder(c.Context, &gctrpc.CancelOrderRequest{ Exchange: exchangeName, AccountId: accountID, OrderId: orderID, @@ -2127,14 +2123,14 @@ func cancelBatchOrders(c *cli.Context) error { } } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.CancelBatchOrders(context.Background(), &gctrpc.CancelBatchOrdersRequest{ + result, err := client.CancelBatchOrders(c.Context, &gctrpc.CancelBatchOrdersRequest{ Exchange: exchangeName, AccountId: accountID, OrdersId: orderID, @@ -2209,14 +2205,14 @@ func cancelAllOrders(c *cli.Context) error { exchangeName = c.Args().First() } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.CancelAllOrders(context.Background(), &gctrpc.CancelAllOrdersRequest{ + result, err := client.CancelAllOrders(c.Context, &gctrpc.CancelAllOrdersRequest{ Exchange: exchangeName, }) if err != nil { @@ -2289,14 +2285,14 @@ func modifyOrder(c *cli.Context) error { } // Setup gRPC, make a request and display response. - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.ModifyOrder(context.Background(), &gctrpc.ModifyOrderRequest{ + result, err := client.ModifyOrder(c.Context, &gctrpc.ModifyOrderRequest{ Exchange: exchangeName, OrderId: orderID, Pair: &gctrpc.CurrencyPair{ @@ -2322,15 +2318,15 @@ var getEventsCommand = &cli.Command{ Action: getEvents, } -func getEvents(_ *cli.Context) error { - conn, err := setupClient() +func getEvents(c *cli.Context) error { + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.GetEvents(context.Background(), &gctrpc.GetEventsRequest{}) + result, err := client.GetEvents(c.Context, &gctrpc.GetEventsRequest{}) if err != nil { return err } @@ -2468,14 +2464,14 @@ func addEvent(c *cli.Context) error { return err } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.AddEvent(context.Background(), &gctrpc.AddEventRequest{ + result, err := client.AddEvent(c.Context, &gctrpc.AddEventRequest{ Exchange: exchangeName, Item: item, ConditionParams: &gctrpc.ConditionParams{ @@ -2534,14 +2530,14 @@ func removeEvent(c *cli.Context) error { return errors.New("event id must be specified") } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.RemoveEvent(context.Background(), + result, err := client.RemoveEvent(c.Context, &gctrpc.RemoveEventRequest{Id: eventID}) if err != nil { return err @@ -2576,14 +2572,14 @@ func getCryptocurrencyDepositAddresses(c *cli.Context) error { exchangeName = c.Args().First() } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.GetCryptocurrencyDepositAddresses(context.Background(), + result, err := client.GetCryptocurrencyDepositAddresses(c.Context, &gctrpc.GetCryptocurrencyDepositAddressesRequest{Exchange: exchangeName}) if err != nil { return err @@ -2634,14 +2630,14 @@ func getCryptocurrencyDepositAddress(c *cli.Context) error { return errors.New("cryptocurrency must be set") } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.GetCryptocurrencyDepositAddress(context.Background(), + result, err := client.GetCryptocurrencyDepositAddress(c.Context, &gctrpc.GetCryptocurrencyDepositAddressRequest{ Exchange: exchangeName, Cryptocurrency: cryptocurrency, @@ -2748,15 +2744,15 @@ func withdrawCryptocurrencyFunds(c *cli.Context) error { description = c.Args().Get(6) } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.WithdrawCryptocurrencyFunds(context.Background(), + result, err := client.WithdrawCryptocurrencyFunds(c.Context, &gctrpc.WithdrawCryptoRequest{ Exchange: exchange, Currency: cur, @@ -2844,14 +2840,14 @@ func withdrawFiatFunds(c *cli.Context) error { description = c.Args().Get(4) } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.WithdrawFiatFunds(context.Background(), + result, err := client.WithdrawFiatFunds(c.Context, &gctrpc.WithdrawFiatRequest{ Exchange: exchange, Currency: cur, @@ -2967,15 +2963,15 @@ func withdrawlRequestByID(c *cli.Context) error { return errors.New("an ID must be specified") } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.WithdrawalEventByID(context.Background(), + result, err := client.WithdrawalEventByID(c.Context, &gctrpc.WithdrawalEventByIDRequest{ Id: ID, }, @@ -3031,15 +3027,15 @@ func withdrawlRequestByExchangeID(c *cli.Context) error { } } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.WithdrawalEventsByExchange(context.Background(), + result, err := client.WithdrawalEventsByExchange(c.Context, &gctrpc.WithdrawalEventsByExchangeRequest{ Exchange: exchange, Id: ID, @@ -3106,14 +3102,14 @@ func withdrawlRequestByDate(c *cli.Context) error { return errors.New("start cannot be after end") } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.WithdrawalEventsByDate(context.Background(), + result, err := client.WithdrawalEventsByDate(c.Context, &gctrpc.WithdrawalEventsByDateRequest{ Exchange: exchange, Start: negateLocalOffset(s), @@ -3157,15 +3153,15 @@ func getLoggerDetails(c *cli.Context) error { return errors.New("a logger must be specified") } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.GetLoggerDetails(context.Background(), + result, err := client.GetLoggerDetails(c.Context, &gctrpc.GetLoggerDetailsRequest{ Logger: logger, }, @@ -3222,15 +3218,15 @@ func setLoggerDetails(c *cli.Context) error { return errors.New("level must be specified") } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.SetLoggerDetails(context.Background(), + result, err := client.SetLoggerDetails(c.Context, &gctrpc.SetLoggerDetailsRequest{ Logger: logger, Level: level, @@ -3306,14 +3302,14 @@ func getOrderbookStream(c *cli.Context) error { return err } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.GetOrderbookStream(context.Background(), + result, err := client.GetOrderbookStream(c.Context, &gctrpc.GetOrderbookStreamRequest{ Exchange: exchangeName, Pair: &gctrpc.CurrencyPair{ @@ -3411,14 +3407,14 @@ func getExchangeOrderbookStream(c *cli.Context) error { exchangeName = c.Args().First() } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.GetExchangeOrderbookStream(context.Background(), + result, err := client.GetExchangeOrderbookStream(c.Context, &gctrpc.GetExchangeOrderbookStreamRequest{ Exchange: exchangeName, }) @@ -3507,14 +3503,14 @@ func getTickerStream(c *cli.Context) error { return err } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.GetTickerStream(context.Background(), + result, err := client.GetTickerStream(c.Context, &gctrpc.GetTickerStreamRequest{ Exchange: exchangeName, Pair: &gctrpc.CurrencyPair{ @@ -3582,14 +3578,14 @@ func getExchangeTickerStream(c *cli.Context) error { exchangeName = c.Args().First() } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.GetExchangeTickerStream(context.Background(), + result, err := client.GetExchangeTickerStream(c.Context, &gctrpc.GetExchangeTickerStreamRequest{ Exchange: exchangeName, }) @@ -3699,16 +3695,16 @@ func getAuditEvent(c *cli.Context) error { return errors.New("start cannot be after end") } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.GetAuditEvent(context.Background(), + result, err := client.GetAuditEvent(c.Context, &gctrpc.GetAuditEventRequest{ StartDate: negateLocalOffset(s), EndDate: negateLocalOffset(e), @@ -3865,14 +3861,14 @@ func gctScriptAutoload(c *cli.Context) error { return cli.ShowSubcommandHelp(c) } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - executeCommand, err := client.GCTScriptAutoLoadToggle(context.Background(), + executeCommand, err := client.GCTScriptAutoLoadToggle(c.Context, &gctrpc.GCTScriptAutoLoadRequest{ Script: script, Status: status, @@ -3903,14 +3899,14 @@ func gctScriptExecute(c *cli.Context) error { } } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - executeCommand, err := client.GCTScriptExecute(context.Background(), + executeCommand, err := client.GCTScriptExecute(c.Context, &gctrpc.GCTScriptExecuteRequest{ Script: &gctrpc.GCTScript{ Name: filename, @@ -3928,14 +3924,14 @@ func gctScriptExecute(c *cli.Context) error { } func gctScriptStatus(c *cli.Context) error { - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - executeCommand, err := client.GCTScriptStatus(context.Background(), + executeCommand, err := client.GCTScriptStatus(c.Context, &gctrpc.GCTScriptStatusRequest{}) if err != nil { @@ -3947,14 +3943,14 @@ func gctScriptStatus(c *cli.Context) error { } func gctScriptList(c *cli.Context) error { - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - executeCommand, err := client.GCTScriptListAll(context.Background(), + executeCommand, err := client.GCTScriptListAll(c.Context, &gctrpc.GCTScriptListAllRequest{}) if err != nil { @@ -3976,14 +3972,14 @@ func gctScriptStop(c *cli.Context) error { } } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - executeCommand, err := client.GCTScriptStop(context.Background(), + executeCommand, err := client.GCTScriptStop(c.Context, &gctrpc.GCTScriptStopRequest{ Script: &gctrpc.GCTScript{UUID: uuid}, }) @@ -3997,14 +3993,14 @@ func gctScriptStop(c *cli.Context) error { } func gctScriptStopAll(c *cli.Context) error { - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - executeCommand, err := client.GCTScriptStopAll(context.Background(), + executeCommand, err := client.GCTScriptStopAll(c.Context, &gctrpc.GCTScriptStopAllRequest{}) if err != nil { @@ -4026,14 +4022,14 @@ func gctScriptRead(c *cli.Context) error { } } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - executeCommand, err := client.GCTScriptReadScript(context.Background(), + executeCommand, err := client.GCTScriptReadScript(c.Context, &gctrpc.GCTScriptReadScriptRequest{ Script: &gctrpc.GCTScript{ Name: uuid, @@ -4059,14 +4055,14 @@ func gctScriptQuery(c *cli.Context) error { } } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - executeCommand, err := client.GCTScriptQuery(context.Background(), + executeCommand, err := client.GCTScriptQuery(c.Context, &gctrpc.GCTScriptQueryRequest{ Script: &gctrpc.GCTScript{ UUID: uuid, @@ -4122,11 +4118,11 @@ func gctScriptUpload(c *cli.Context) error { return err } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) data, err := ioutil.ReadAll(file) @@ -4134,7 +4130,7 @@ func gctScriptUpload(c *cli.Context) error { return err } - uploadCommand, err := client.GCTScriptUpload(context.Background(), + uploadCommand, err := client.GCTScriptUpload(c.Context, &gctrpc.GCTScriptUploadRequest{ ScriptName: filepath.Base(file.Name()), Data: data, @@ -4256,11 +4252,11 @@ func getHistoricCandles(c *cli.Context) error { fillMissingData = c.Bool("fill") } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) candleInterval := time.Duration(candleGranularity) * time.Second @@ -4268,7 +4264,7 @@ func getHistoricCandles(c *cli.Context) error { s := e.Add(-candleInterval * time.Duration(candleRangeSize)) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.GetHistoricCandles(context.Background(), + result, err := client.GetHistoricCandles(c.Context, &gctrpc.GetHistoricCandlesRequest{ Exchange: exchangeName, Pair: &gctrpc.CurrencyPair{ @@ -4449,14 +4445,14 @@ func getHistoricCandlesExtended(c *cli.Context) error { return errors.New("start cannot be after end") } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.GetHistoricCandles(context.Background(), + result, err := client.GetHistoricCandles(c.Context, &gctrpc.GetHistoricCandlesRequest{ Exchange: exchangeName, Pair: &gctrpc.CurrencyPair{ @@ -4598,19 +4594,14 @@ func findMissingSavedCandleIntervals(c *cli.Context) error { return errors.New("start cannot be after end") } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer func() { - err = conn.Close() - if err != nil { - fmt.Print(err) - } - }() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.FindMissingSavedCandleIntervals(context.Background(), + result, err := client.FindMissingSavedCandleIntervals(c.Context, &gctrpc.FindMissingCandlePeriodsRequest{ ExchangeName: exchangeName, Pair: &gctrpc.CurrencyPair{ diff --git a/cmd/gctcli/data_history.go b/cmd/gctcli/data_history.go index aa97327d..5c93464a 100644 --- a/cmd/gctcli/data_history.go +++ b/cmd/gctcli/data_history.go @@ -1,7 +1,6 @@ package main import ( - "context" "errors" "fmt" "strings" @@ -315,16 +314,12 @@ func getDataHistoryJob(c *cli.Context) error { return errors.New("can only set 'id' OR 'nickname'") } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer func() { - err = conn.Close() - if err != nil { - fmt.Print(err) - } - }() + defer closeConn(conn, cancel) + client := gctrpc.NewGoCryptoTraderClient(conn) request := &gctrpc.GetDataHistoryJobDetailsRequest{ Id: id, @@ -334,7 +329,7 @@ func getDataHistoryJob(c *cli.Context) error { request.FullDetails = true } - result, err := client.GetDataHistoryJobDetails(context.Background(), request) + result, err := client.GetDataHistoryJobDetails(c.Context, request) if err != nil { return err } @@ -342,20 +337,15 @@ func getDataHistoryJob(c *cli.Context) error { return nil } -func getActiveDataHistoryJobs(_ *cli.Context) error { - conn, err := setupClient() +func getActiveDataHistoryJobs(c *cli.Context) error { + conn, cancel, err := setupClient(c) if err != nil { return err } - defer func() { - err = conn.Close() - if err != nil { - fmt.Print(err) - } - }() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.GetActiveDataHistoryJobs(context.Background(), + result, err := client.GetActiveDataHistoryJobs(c.Context, &gctrpc.GetInfoRequest{}) if err != nil { return err @@ -498,16 +488,12 @@ func upsertDataHistoryJob(c *cli.Context) error { } } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer func() { - err = conn.Close() - if err != nil { - fmt.Print(err) - } - }() + defer closeConn(conn, cancel) + client := gctrpc.NewGoCryptoTraderClient(conn) request := &gctrpc.UpsertDataHistoryJobRequest{ Nickname: nickname, @@ -535,7 +521,7 @@ func upsertDataHistoryJob(c *cli.Context) error { ReplaceOnIssue: replaceOnIssue, } - result, err := client.UpsertDataHistoryJob(context.Background(), request) + result, err := client.UpsertDataHistoryJob(c.Context, request) if err != nil { return err } @@ -571,19 +557,14 @@ func getDataHistoryJobsBetween(c *cli.Context) error { return errors.New("start cannot be after end") } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer func() { - err = conn.Close() - if err != nil { - fmt.Print(err) - } - }() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.GetDataHistoryJobsBetween(context.Background(), + result, err := client.GetDataHistoryJobsBetween(c.Context, &gctrpc.GetDataHistoryJobsBetweenRequest{ StartDate: negateLocalOffset(s), EndDate: negateLocalOffset(e), @@ -628,16 +609,12 @@ func setDataHistoryJobStatus(c *cli.Context) error { return fmt.Errorf("unable to modify data history job status, unrecognised command '%v'", c.Command.Name) } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer func() { - err = conn.Close() - if err != nil { - fmt.Print(err) - } - }() + defer closeConn(conn, cancel) + client := gctrpc.NewGoCryptoTraderClient(conn) request := &gctrpc.SetDataHistoryJobStatusRequest{ Id: id, @@ -645,7 +622,7 @@ func setDataHistoryJobStatus(c *cli.Context) error { Status: status, } - result, err := client.SetDataHistoryJobStatus(context.Background(), request) + result, err := client.SetDataHistoryJobStatus(c.Context, request) if err != nil { return err } @@ -665,22 +642,18 @@ func getDataHistoryJobSummary(c *cli.Context) error { nickname = c.Args().First() } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer func() { - err = conn.Close() - if err != nil { - fmt.Print(err) - } - }() + defer closeConn(conn, cancel) + client := gctrpc.NewGoCryptoTraderClient(conn) request := &gctrpc.GetDataHistoryJobDetailsRequest{ Nickname: nickname, } - result, err := client.GetDataHistoryJobSummary(context.Background(), request) + result, err := client.GetDataHistoryJobSummary(c.Context, request) if err != nil { return err } @@ -711,23 +684,19 @@ func setPrerequisiteJob(c *cli.Context) error { return errors.New("prerequisite required") } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer func() { - err = conn.Close() - if err != nil { - fmt.Print(err) - } - }() + defer closeConn(conn, cancel) + client := gctrpc.NewGoCryptoTraderClient(conn) request := &gctrpc.UpdateDataHistoryJobPrerequisiteRequest{ PrerequisiteJobNickname: prerequisite, Nickname: nickname, } - result, err := client.UpdateDataHistoryJobPrerequisite(context.Background(), request) + result, err := client.UpdateDataHistoryJobPrerequisite(c.Context, request) if err != nil { return err } diff --git a/cmd/gctcli/helpers.go b/cmd/gctcli/helpers.go index 8a1872d9..57c277b7 100644 --- a/cmd/gctcli/helpers.go +++ b/cmd/gctcli/helpers.go @@ -1,9 +1,13 @@ package main import ( + "context" + "fmt" "os" "os/exec" "runtime" + + "google.golang.org/grpc" ) func clearScreen() error { @@ -18,3 +22,13 @@ func clearScreen() error { return cmd.Run() } } + +func closeConn(conn *grpc.ClientConn, cancel context.CancelFunc) { + err := conn.Close() + if err != nil { + fmt.Println(err) + } + if cancel != nil { + cancel() + } +} diff --git a/cmd/gctcli/main.go b/cmd/gctcli/main.go index 8eea6574..ce96fd6c 100644 --- a/cmd/gctcli/main.go +++ b/cmd/gctcli/main.go @@ -1,16 +1,19 @@ package main import ( + "context" "encoding/json" "fmt" "log" "os" "path/filepath" "runtime" + "time" "github.com/thrasher-corp/gocryptotrader/common" "github.com/thrasher-corp/gocryptotrader/core" "github.com/thrasher-corp/gocryptotrader/gctrpc/auth" + "github.com/thrasher-corp/gocryptotrader/signaler" "github.com/urfave/cli/v2" "google.golang.org/grpc" "google.golang.org/grpc/credentials" @@ -22,8 +25,11 @@ var ( password string pairDelimiter string certPath string + timeout time.Duration ) +const defaultTimeout = time.Second * 30 + func jsonOutput(in interface{}) { j, err := json.MarshalIndent(in, "", " ") if err != nil { @@ -32,10 +38,10 @@ func jsonOutput(in interface{}) { fmt.Print(string(j)) } -func setupClient() (*grpc.ClientConn, error) { +func setupClient(c *cli.Context) (*grpc.ClientConn, context.CancelFunc, error) { creds, err := credentials.NewClientTLSFromFile(certPath, "") if err != nil { - return nil, err + return nil, nil, err } opts := []grpc.DialOption{grpc.WithTransportCredentials(creds), @@ -44,12 +50,11 @@ func setupClient() (*grpc.ClientConn, error) { Password: password, }), } - conn, err := grpc.Dial(host, opts...) - if err != nil { - return nil, err - } - return conn, err + var cancel context.CancelFunc + c.Context, cancel = context.WithTimeout(c.Context, timeout) + conn, err := grpc.DialContext(c.Context, host, opts...) + return conn, cancel, err } func main() { @@ -89,6 +94,12 @@ func main() { Usage: "the path to TLS cert of the gRPC server", Destination: &certPath, }, + &cli.DurationFlag{ + Name: "timeout", + Value: defaultTimeout, + Usage: "the default context timeout value for requests", + Destination: &timeout, + }, } app.Commands = []*cli.Command{ getInfoCommand, @@ -152,7 +163,16 @@ func main() { dataHistoryCommands, } - err := app.Run(os.Args) + ctx, cancel := context.WithCancel(context.Background()) + go func() { + // Capture cancel for interrupt + signaler.WaitForInterrupt() + cancel() + fmt.Println("rpc process interrupted") + os.Exit(1) + }() + + err := app.RunContext(ctx, os.Args) if err != nil { log.Fatal(err) } diff --git a/cmd/gctcli/pair_management.go b/cmd/gctcli/pair_management.go index 6eb85037..7baf550f 100644 --- a/cmd/gctcli/pair_management.go +++ b/cmd/gctcli/pair_management.go @@ -1,7 +1,6 @@ package main import ( - "context" "strings" "github.com/thrasher-corp/gocryptotrader/currency" @@ -217,15 +216,15 @@ func enableDisableExchangePair(c *cli.Context) error { }) } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.SetExchangePair(context.Background(), + result, err := client.SetExchangePair(c.Context, &gctrpc.SetExchangePairRequest{ Exchange: exchange, Pairs: validPairs, @@ -266,14 +265,14 @@ func getExchangePairs(c *cli.Context) error { return errInvalidAsset } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.GetExchangePairs(context.Background(), + result, err := client.GetExchangePairs(c.Context, &gctrpc.GetExchangePairsRequest{ Exchange: exchange, Asset: asset, @@ -315,14 +314,14 @@ func enableDisableExchangeAsset(c *cli.Context) error { return errInvalidAsset } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.SetExchangeAsset(context.Background(), + result, err := client.SetExchangeAsset(c.Context, &gctrpc.SetExchangeAssetRequest{ Exchange: exchange, Asset: asset, @@ -352,14 +351,14 @@ func enableDisableAllExchangePairs(c *cli.Context) error { exchange = c.Args().First() } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.SetAllExchangePairs(context.Background(), + result, err := client.SetAllExchangePairs(c.Context, &gctrpc.SetExchangeAllPairsRequest{ Exchange: exchange, Enable: enable, @@ -384,14 +383,14 @@ func updateExchangeSupportedPairs(c *cli.Context) error { exchange = c.Args().First() } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.UpdateExchangeSupportedPairs(context.Background(), + result, err := client.UpdateExchangeSupportedPairs(c.Context, &gctrpc.UpdateExchangeSupportedPairsRequest{ Exchange: exchange, }, @@ -415,14 +414,14 @@ func getExchangeAssets(c *cli.Context) error { exchange = c.Args().First() } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.GetExchangeAssets(context.Background(), + result, err := client.GetExchangeAssets(c.Context, &gctrpc.GetExchangeAssetsRequest{ Exchange: exchange, }, diff --git a/cmd/gctcli/trades.go b/cmd/gctcli/trades.go index d086b42e..bfc47452 100644 --- a/cmd/gctcli/trades.go +++ b/cmd/gctcli/trades.go @@ -1,7 +1,6 @@ package main import ( - "context" "errors" "fmt" "strconv" @@ -277,19 +276,14 @@ func findMissingSavedTradeIntervals(c *cli.Context) error { return fmt.Errorf("invalid time format for end: %v", err) } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer func() { - err = conn.Close() - if err != nil { - fmt.Print(err) - } - }() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.FindMissingSavedTradeIntervals(context.Background(), + result, err := client.FindMissingSavedTradeIntervals(c.Context, &gctrpc.FindMissingTradePeriodsRequest{ ExchangeName: exchangeName, Pair: &gctrpc.CurrencyPair{ @@ -332,19 +326,14 @@ func setExchangeTradeProcessing(c *cli.Context) error { } } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer func() { - err = conn.Close() - if err != nil { - fmt.Print(err) - } - }() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.SetExchangeTradeProcessing(context.Background(), + result, err := client.SetExchangeTradeProcessing(c.Context, &gctrpc.SetExchangeTradeProcessingRequest{ Exchange: exchangeName, Status: status, @@ -420,19 +409,14 @@ func getSavedTrades(c *cli.Context) error { return errors.New("start cannot be after end") } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer func() { - err = conn.Close() - if err != nil { - fmt.Print(err) - } - }() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.GetSavedTrades(context.Background(), + result, err := client.GetSavedTrades(c.Context, &gctrpc.GetSavedTradesRequest{ Exchange: exchangeName, Pair: &gctrpc.CurrencyPair{ @@ -489,19 +473,14 @@ func getRecentTrades(c *cli.Context) error { return errInvalidAsset } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer func() { - err = conn.Close() - if err != nil { - fmt.Print(err) - } - }() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.GetRecentTrades(context.Background(), + result, err := client.GetRecentTrades(c.Context, &gctrpc.GetSavedTradesRequest{ Exchange: exchangeName, Pair: &gctrpc.CurrencyPair{ @@ -581,20 +560,15 @@ func getHistoricTrades(c *cli.Context) error { return errors.New("start cannot be after end") } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer func() { - err = conn.Close() - if err != nil { - fmt.Print(err) - } - }() + defer closeConn(conn, cancel) streamStartTime := time.Now() client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.GetHistoricTrades(context.Background(), + result, err := client.GetHistoricTrades(c.Context, &gctrpc.GetSavedTradesRequest{ Exchange: exchangeName, Pair: &gctrpc.CurrencyPair{ @@ -724,19 +698,14 @@ func convertSavedTradesToCandles(c *cli.Context) error { return errors.New("start cannot be after end") } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer func() { - err = conn.Close() - if err != nil { - fmt.Print(err) - } - }() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.ConvertTradesToCandles(context.Background(), + result, err := client.ConvertTradesToCandles(c.Context, &gctrpc.ConvertTradesToCandlesRequest{ Exchange: exchangeName, Pair: &gctrpc.CurrencyPair{ diff --git a/cmd/gctcli/websocket_management.go b/cmd/gctcli/websocket_management.go index 10f983cd..b101db58 100644 --- a/cmd/gctcli/websocket_management.go +++ b/cmd/gctcli/websocket_management.go @@ -1,8 +1,6 @@ package main import ( - "context" - "github.com/thrasher-corp/gocryptotrader/gctrpc" "github.com/urfave/cli/v2" ) @@ -106,14 +104,14 @@ func getwebsocketInfo(c *cli.Context) error { exchange = c.Args().First() } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.WebsocketGetInfo(context.Background(), + result, err := client.WebsocketGetInfo(c.Context, &gctrpc.WebsocketGetInfoRequest{Exchange: exchange}) if err != nil { return err @@ -135,14 +133,14 @@ func enableDisableWebsocket(c *cli.Context) error { exchange = c.Args().First() } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.WebsocketSetEnabled(context.Background(), + result, err := client.WebsocketSetEnabled(c.Context, &gctrpc.WebsocketSetEnabledRequest{Exchange: exchange, Enable: enable}) if err != nil { return err @@ -163,14 +161,14 @@ func getSubscriptions(c *cli.Context) error { exchange = c.Args().First() } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.WebsocketGetSubscriptions(context.Background(), + result, err := client.WebsocketGetSubscriptions(c.Context, &gctrpc.WebsocketGetSubscriptionsRequest{Exchange: exchange}) if err != nil { return err @@ -198,14 +196,14 @@ func setProxy(c *cli.Context) error { proxy = c.Args().Get(1) } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.WebsocketSetProxy(context.Background(), + result, err := client.WebsocketSetProxy(c.Context, &gctrpc.WebsocketSetProxyRequest{Exchange: exchange, Proxy: proxy}) if err != nil { return err @@ -233,14 +231,14 @@ func setURL(c *cli.Context) error { url = c.Args().Get(1) } - conn, err := setupClient() + conn, cancel, err := setupClient(c) if err != nil { return err } - defer conn.Close() + defer closeConn(conn, cancel) client := gctrpc.NewGoCryptoTraderClient(conn) - result, err := client.WebsocketSetURL(context.Background(), + result, err := client.WebsocketSetURL(c.Context, &gctrpc.WebsocketSetURLRequest{Exchange: exchange, Url: url}) if err != nil { return err diff --git a/cmd/portfolio/portfolio.go b/cmd/portfolio/portfolio.go index 36cf9ad6..f6536a38 100644 --- a/cmd/portfolio/portfolio.go +++ b/cmd/portfolio/portfolio.go @@ -1,6 +1,7 @@ package main import ( + "context" "flag" "fmt" "log" @@ -138,7 +139,7 @@ func main() { bf.SetDefaults() bf.Verbose = false pair := "t" + y.Coin.String() + currency.USD.String() - ticker, errf := bf.GetTicker(pair) + ticker, errf := bf.GetTicker(context.TODO(), pair) if errf != nil { log.Println(errf) } else { diff --git a/common/common.go b/common/common.go index a18cecc1..0b30df09 100644 --- a/common/common.go +++ b/common/common.go @@ -1,7 +1,7 @@ package common import ( - "encoding/json" + "context" "errors" "fmt" "io" @@ -27,14 +27,15 @@ const ( // SimpleTimeFormatWithTimezone a common, but non-implemented time format in golang SimpleTimeFormatWithTimezone = "2006-01-02 15:04:05 MST" // GctExt is the extension for GCT Tengo script files - GctExt = ".gct" + GctExt = ".gct" + defaultTimeout = time.Second * 15 ) // Vars for common.go operations var ( - HTTPClient *http.Client - HTTPUserAgent string - m sync.Mutex + _HTTPClient *http.Client + _HTTPUserAgent string + m sync.RWMutex // ErrNotYetImplemented defines a common error across the code base that // alerts of a function that has not been completed or tied into main code ErrNotYetImplemented = errors.New("not yet implemented") @@ -49,24 +50,45 @@ var ( // ErrStartEqualsEnd is an error for start end check calculations ErrStartEqualsEnd = errors.New("start date equals end date") // ErrStartAfterTimeNow is an error for start end check calculations - ErrStartAfterTimeNow = errors.New("start date is after current time") + ErrStartAfterTimeNow = errors.New("start date is after current time") + errCannotSetInvalidTimeout = errors.New("cannot set new HTTP client with timeout that is equal or less than 0") + errUserAgentInvalid = errors.New("cannot set invalid user agent") + errHTTPClientInvalid = errors.New("custom http client cannot be nil") ) -func initialiseHTTPClient() { - m.Lock() - // If the HTTPClient isn't set, start a new client with a default timeout of 15 seconds - if HTTPClient == nil { - HTTPClient = NewHTTPClientWithTimeout(time.Second * 15) +// SetHTTPClientWithTimeout sets a new *http.Client with different timeout +// settings +func SetHTTPClientWithTimeout(t time.Duration) error { + if t <= 0 { + return errCannotSetInvalidTimeout } + m.Lock() + _HTTPClient = NewHTTPClientWithTimeout(t) m.Unlock() + return nil } -// SetHTTPClientWithTimeout protects the setting of the -// global HTTPClient -func SetHTTPClientWithTimeout(t time.Duration) { +// SetHTTPUserAgent sets the user agent which will be used for all common HTTP +// requests. +func SetHTTPUserAgent(agent string) error { + if agent == "" { + return errUserAgentInvalid + } m.Lock() - defer m.Unlock() - HTTPClient = NewHTTPClientWithTimeout(t) + _HTTPUserAgent = agent + m.Unlock() + return nil +} + +// SetHTTPClient sets a custom HTTP client. +func SetHTTPClient(client *http.Client) error { + if client == nil { + return errHTTPClientInvalid + } + m.Lock() + _HTTPClient = client + m.Unlock() + return nil } // NewHTTPClientWithTimeout initialises a new HTTP client and its underlying @@ -180,92 +202,69 @@ func YesOrNo(input string) bool { return false } -// SendHTTPRequest sends a request using the http package and returns a response -// as a string and an error -func SendHTTPRequest(method, urlPath string, headers map[string]string, body io.Reader) (string, error) { - result := strings.ToUpper(method) +// SendHTTPRequest sends a request using the http package and returns the body +// contents +func SendHTTPRequest(ctx context.Context, method, urlPath string, headers map[string]string, body io.Reader, verbose bool) ([]byte, error) { + method = strings.ToUpper(method) - if result != http.MethodOptions && result != http.MethodGet && - result != http.MethodHead && result != http.MethodPost && - result != http.MethodPut && result != http.MethodDelete && - result != http.MethodTrace && result != http.MethodConnect { - return "", errors.New("invalid HTTP method specified") + if method != http.MethodOptions && method != http.MethodGet && + method != http.MethodHead && method != http.MethodPost && + method != http.MethodPut && method != http.MethodDelete && + method != http.MethodTrace && method != http.MethodConnect { + return nil, errors.New("invalid HTTP method specified") } - initialiseHTTPClient() - - req, err := http.NewRequest(method, urlPath, body) + req, err := http.NewRequestWithContext(ctx, method, urlPath, body) if err != nil { - return "", err + return nil, err } for k, v := range headers { req.Header.Add(k, v) } - if HTTPUserAgent != "" && req.Header.Get("User-Agent") == "" { - req.Header.Add("User-Agent", HTTPUserAgent) - } - - m.Lock() - resp, err := HTTPClient.Do(req) - if err != nil { - m.Unlock() - return "", err - } - m.Unlock() - - contents, err := ioutil.ReadAll(resp.Body) - defer resp.Body.Close() - - if err != nil { - return "", err - } - - return string(contents), nil -} - -// SendHTTPGetRequest sends a simple get request using a url string & JSON -// decodes the response into a struct pointer you have supplied. Returns an error -// on failure. -func SendHTTPGetRequest(urlPath string, jsonDecode, isVerbose bool, result interface{}) error { - if isVerbose { - log.Debugf(log.Global, "Raw URL: %s\n", urlPath) - } - - initialiseHTTPClient() - - m.Lock() - res, err := HTTPClient.Get(urlPath) - if err != nil { - m.Unlock() - return err - } - m.Unlock() - - if res.StatusCode != 200 { - return fmt.Errorf("common.SendHTTPGetRequest() error: HTTP status code %d", res.StatusCode) - } - - contents, err := ioutil.ReadAll(res.Body) - if err != nil { - return err - } - - if isVerbose { - log.Debugf(log.Global, "Raw Resp: %s\n", string(contents)) - } - - defer res.Body.Close() - - if jsonDecode { - err := json.Unmarshal(contents, result) - if err != nil { - return err + if verbose { + log.Debugf(log.Global, "Request path: %s", urlPath) + for k, d := range req.Header { + log.Debugf(log.Global, "Request header [%s]: %s", k, d) + } + log.Debugf(log.Global, "Request type: %s", method) + if body != nil { + log.Debugf(log.Global, "Request body: %v", body) } } - return nil + m.RLock() + if _HTTPUserAgent != "" && req.Header.Get("User-Agent") == "" { + req.Header.Add("User-Agent", _HTTPUserAgent) + } + + if _HTTPClient == nil { + m.RUnlock() + m.Lock() + // Set *http.Client with default timeout if not populated. + _HTTPClient = NewHTTPClientWithTimeout(defaultTimeout) + m.Unlock() + m.RLock() + } + + resp, err := _HTTPClient.Do(req) + m.RUnlock() + if err != nil { + return nil, err + } + defer resp.Body.Close() + + contents, err := ioutil.ReadAll(resp.Body) + + if verbose { + log.Debugf(log.Global, "HTTP status: %s, Code: %v", + resp.Status, + resp.StatusCode) + log.Debugf(log.Global, "Raw response: %s", string(contents)) + } + + return contents, err } // EncodeURLValues concatenates url values onto a url string and returns a diff --git a/common/common_test.go b/common/common_test.go index 9ee3554b..a4af1d4d 100644 --- a/common/common_test.go +++ b/common/common_test.go @@ -1,7 +1,9 @@ package common import ( + "context" "errors" + "net/http" "net/url" "os" "os/user" @@ -14,6 +16,106 @@ import ( "time" ) +func TestSendHTTPRequest(t *testing.T) { + // t.Parallel() not used to maintain code coverage for assigning the default + // HTTPClient. + methodPost := "pOst" + methodGet := "GeT" + methodDelete := "dEleTe" + methodGarbage := "ding" + + headers := make(map[string]string) + headers["Content-Type"] = "application/x-www-form-urlencoded" + + _, err := SendHTTPRequest(context.Background(), + methodGarbage, "https://www.google.com", headers, + strings.NewReader(""), true, + ) + if err == nil { + t.Error("Expected error 'invalid HTTP method specified'") + } + _, err = SendHTTPRequest(context.Background(), + methodPost, "https://www.google.com", headers, + strings.NewReader(""), true, + ) + if err != nil { + t.Error(err) + } + _, err = SendHTTPRequest(context.Background(), + methodGet, "https://www.google.com", headers, + strings.NewReader(""), true, + ) + if err != nil { + t.Error(err) + } + + err = SetHTTPUserAgent("GCTbot/1337.69 (+http://www.lol.com/)") + if !errors.Is(err, nil) { + t.Fatalf("received: %v but expected: %v", err, nil) + } + + _, err = SendHTTPRequest(context.Background(), + methodDelete, "https://www.google.com", headers, + strings.NewReader(""), true, + ) + if err != nil { + t.Error(err) + } + _, err = SendHTTPRequest(context.Background(), + methodGet, ":missingprotocolscheme", headers, + strings.NewReader(""), true, + ) + if err == nil { + t.Error("Common HTTPRequest accepted missing protocol") + } + _, err = SendHTTPRequest(context.Background(), + methodGet, "test://unsupportedprotocolscheme", headers, + strings.NewReader(""), true, + ) + if err == nil { + t.Error("Common HTTPRequest accepted invalid protocol") + } +} + +func TestSetHTTPClientWithTimeout(t *testing.T) { + t.Parallel() + err := SetHTTPClientWithTimeout(-0) + if !errors.Is(err, errCannotSetInvalidTimeout) { + t.Fatalf("received: %v but expected: %v", err, errCannotSetInvalidTimeout) + } + + err = SetHTTPClientWithTimeout(time.Second * 15) + if !errors.Is(err, nil) { + t.Fatalf("received: %v but expected: %v", err, nil) + } +} + +func TestSetHTTPUserAgent(t *testing.T) { + t.Parallel() + err := SetHTTPUserAgent("") + if !errors.Is(err, errUserAgentInvalid) { + t.Fatalf("received: %v but expected: %v", err, errUserAgentInvalid) + } + + err = SetHTTPUserAgent("testy test") + if !errors.Is(err, nil) { + t.Fatalf("received: %v but expected: %v", err, nil) + } +} + +func TestSetHTTPClient(t *testing.T) { + t.Parallel() + err := SetHTTPClient(nil) + if !errors.Is(err, errHTTPClientInvalid) { + t.Fatalf("received: %v but expected: %v", err, errHTTPClientInvalid) + } + + err = SetHTTPClient(new(http.Client)) + if !errors.Is(err, nil) { + t.Fatalf("received: %v but expected: %v", err, nil) + } +} + func TestIsEnabled(t *testing.T) { t.Parallel() expected := "Enabled" @@ -231,96 +333,6 @@ func TestYesOrNo(t *testing.T) { } } -func TestSendHTTPRequest(t *testing.T) { - methodPost := "pOst" - methodGet := "GeT" - methodDelete := "dEleTe" - methodGarbage := "ding" - - headers := make(map[string]string) - headers["Content-Type"] = "application/x-www-form-urlencoded" - - _, err := SendHTTPRequest( - methodGarbage, "https://www.google.com", headers, - strings.NewReader(""), - ) - if err == nil { - t.Error("Expected error 'invalid HTTP method specified'") - } - _, err = SendHTTPRequest( - methodPost, "https://www.google.com", headers, - strings.NewReader(""), - ) - if err != nil { - t.Error(err) - } - _, err = SendHTTPRequest( - methodGet, "https://www.google.com", headers, - strings.NewReader(""), - ) - if err != nil { - t.Error(err) - } - _, err = SendHTTPRequest( - methodDelete, "https://www.google.com", headers, - strings.NewReader(""), - ) - if err != nil { - t.Error(err) - } - _, err = SendHTTPRequest( - methodGet, ":missingprotocolscheme", headers, - strings.NewReader(""), - ) - if err == nil { - t.Error("Common HTTPRequest accepted missing protocol") - } - _, err = SendHTTPRequest( - methodGet, "test://unsupportedprotocolscheme", headers, - strings.NewReader(""), - ) - if err == nil { - t.Error("Common HTTPRequest accepted invalid protocol") - } -} - -func TestSendHTTPGetRequest(t *testing.T) { - t.Parallel() - type test struct { - Address string `json:"address"` - ETH struct { - Balance float64 `json:"balance"` - TotalIn float64 `json:"totalIn"` - TotalOut float64 `json:"totalOut"` - } `json:"ETH"` - } - ethURL := `https://api.ethplorer.io/getAddressInfo/0xff71cb760666ab06aa73f34995b42dd4b85ea07b?apiKey=freekey` - result := test{} - - var badresult int - - err := SendHTTPGetRequest(ethURL, true, true, &result) - if err != nil { - t.Errorf("common SendHTTPGetRequest error: %s", err) - } - err = SendHTTPGetRequest("DINGDONG", true, false, &result) - if err == nil { - t.Error("common SendHTTPGetRequest error") - } - err = SendHTTPGetRequest(ethURL, false, false, &result) - if err != nil { - t.Errorf("common SendHTTPGetRequest error: %s", err) - } - err = SendHTTPGetRequest("https://httpstat.us/202", false, false, &result) - if err == nil { - t.Error("= common SendHTTPGetRequest error: Ignored unexpected status code") - } - err = SendHTTPGetRequest(ethURL, true, false, &badresult) - if err == nil { - t.Error("common SendHTTPGetRequest error: Unmarshalled into bad type") - } -} - func TestEncodeURLValues(t *testing.T) { t.Parallel() urlstring := "https://www.test.com" @@ -498,6 +510,7 @@ func TestCreateDir(t *testing.T) { } func TestChangePermission(t *testing.T) { + t.Parallel() testDir := filepath.Join(os.TempDir(), "TestFileASDFGHJ") switch runtime.GOOS { case "windows": @@ -557,6 +570,7 @@ func initStringSlice(size int) (out []string) { } func TestSplitStringSliceByLimit(t *testing.T) { + t.Parallel() slice50 := initStringSlice(50) out := SplitStringSliceByLimit(slice50, 20) if len(out) != 3 { @@ -576,6 +590,7 @@ func TestSplitStringSliceByLimit(t *testing.T) { } func TestInArray(t *testing.T) { + t.Parallel() InArray(nil, nil) array := [6]int{2, 3, 5, 7, 11, 13} @@ -614,6 +629,7 @@ func TestInArray(t *testing.T) { } func TestErrors(t *testing.T) { + t.Parallel() var test Errors if test.Error() != "" { t.Fatal("string should be nil") @@ -629,6 +645,7 @@ func TestErrors(t *testing.T) { } func TestParseStartEndDate(t *testing.T) { + t.Parallel() pt := time.Date(1999, 1, 1, 0, 0, 0, 0, time.Local) ft := time.Date(2222, 1, 1, 0, 0, 0, 0, time.Local) et := time.Date(2020, 1, 1, 1, 0, 0, 0, time.Local) diff --git a/communications/slack/slack.go b/communications/slack/slack.go index f760beca..91382cd8 100644 --- a/communications/slack/slack.go +++ b/communications/slack/slack.go @@ -4,6 +4,7 @@ package slack import ( + "context" "encoding/json" "errors" "fmt" @@ -151,7 +152,17 @@ func (s *Slack) GetUsersInGroup(group string) []string { // token and a channel func (s *Slack) NewConnection() error { if !s.Connected { - err := common.SendHTTPGetRequest(s.BuildURL(s.VerificationToken), true, s.Verbose, &s.Details) + contents, err := common.SendHTTPRequest(context.TODO(), + http.MethodGet, + s.BuildURL(s.VerificationToken), + nil, + nil, + s.Verbose) + if err != nil { + return err + } + + err = json.Unmarshal(contents, &s.Details) if err != nil { return err } diff --git a/communications/smsglobal/smsglobal.go b/communications/smsglobal/smsglobal.go index a32ea9ee..d1a3983f 100644 --- a/communications/smsglobal/smsglobal.go +++ b/communications/smsglobal/smsglobal.go @@ -2,6 +2,7 @@ package smsglobal import ( + "context" "errors" "flag" "net/http" @@ -179,15 +180,17 @@ func (s *SMSGlobal) SendMessage(to, message string) error { headers := make(map[string]string) headers["Content-Type"] = "application/x-www-form-urlencoded" - resp, err := common.SendHTTPRequest(http.MethodPost, + resp, err := common.SendHTTPRequest(context.TODO(), + http.MethodPost, smsGlobalAPIURL, headers, - strings.NewReader(values.Encode())) + strings.NewReader(values.Encode()), + s.Verbose) if err != nil { return err } - if !strings.Contains(resp, "OK: 0; Sent queued message") { + if !strings.Contains(string(resp), "OK: 0; Sent queued message") { return errSMSNotSent } return nil diff --git a/communications/telegram/telegram.go b/communications/telegram/telegram.go index 8d67b96e..b239268c 100644 --- a/communications/telegram/telegram.go +++ b/communications/telegram/telegram.go @@ -5,6 +5,7 @@ package telegram import ( "bytes" + "context" "encoding/json" "errors" "fmt" @@ -245,13 +246,15 @@ func (t *Telegram) SendHTTPRequest(path string, data []byte, result interface{}) headers := make(map[string]string) headers["content-type"] = "application/json" - resp, err := common.SendHTTPRequest(http.MethodPost, + resp, err := common.SendHTTPRequest(context.TODO(), + http.MethodPost, path, headers, - bytes.NewBuffer(data)) + bytes.NewBuffer(data), + t.Verbose) if err != nil { return err } - return json.Unmarshal([]byte(resp), result) + return json.Unmarshal(resp, result) } diff --git a/currency/coinmarketcap/coinmarketcap.go b/currency/coinmarketcap/coinmarketcap.go index 6a5c10bd..2189823f 100644 --- a/currency/coinmarketcap/coinmarketcap.go +++ b/currency/coinmarketcap/coinmarketcap.go @@ -683,7 +683,7 @@ func (c *Coinmarketcap) SendHTTPRequest(method, endpoint string, v url.Values, r Headers: headers, Result: result, Verbose: c.Verbose} - return c.Requester.SendPayload(context.Background(), request.Unset, func() (*request.Item, error) { + return c.Requester.SendPayload(context.TODO(), request.Unset, func() (*request.Item, error) { return item, nil }) } diff --git a/currency/forexprovider/currencyconverterapi/currencyconverterapi.go b/currency/forexprovider/currencyconverterapi/currencyconverterapi.go index bf1d41b3..fc9fa5fa 100644 --- a/currency/forexprovider/currencyconverterapi/currencyconverterapi.go +++ b/currency/forexprovider/currencyconverterapi/currencyconverterapi.go @@ -167,7 +167,7 @@ func (c *CurrencyConverter) SendHTTPRequest(endPoint string, values url.Values, Result: result, AuthRequest: auth, Verbose: c.Verbose} - err := c.Requester.SendPayload(context.Background(), request.Unset, func() (*request.Item, error) { + err := c.Requester.SendPayload(context.TODO(), request.Unset, func() (*request.Item, error) { return item, nil }) diff --git a/currency/forexprovider/currencylayer/currencylayer.go b/currency/forexprovider/currencylayer/currencylayer.go index 87b69ca4..f9e127bb 100644 --- a/currency/forexprovider/currencylayer/currencylayer.go +++ b/currency/forexprovider/currencylayer/currencylayer.go @@ -212,7 +212,7 @@ func (c *CurrencyLayer) SendHTTPRequest(endPoint string, values url.Values, resu Result: &result, AuthRequest: auth, Verbose: c.Verbose} - return c.Requester.SendPayload(context.Background(), request.Unset, func() (*request.Item, error) { + return c.Requester.SendPayload(context.TODO(), request.Unset, func() (*request.Item, error) { return item, nil }) } diff --git a/currency/forexprovider/exchangerate.host/exchangerate.go b/currency/forexprovider/exchangerate.host/exchangerate.go index 21d23aa0..cc2314de 100644 --- a/currency/forexprovider/exchangerate.host/exchangerate.go +++ b/currency/forexprovider/exchangerate.host/exchangerate.go @@ -259,7 +259,7 @@ func (e *ExchangeRateHost) SendHTTPRequest(endpoint string, v url.Values, result Result: &result, Verbose: e.Verbose, } - return e.Requester.SendPayload(context.Background(), request.Unset, func() (*request.Item, error) { + return e.Requester.SendPayload(context.TODO(), request.Unset, func() (*request.Item, error) { return item, nil }) } diff --git a/currency/forexprovider/exchangeratesapi.io/exchangeratesapi.go b/currency/forexprovider/exchangeratesapi.io/exchangeratesapi.go index eb7505fe..1d7f2d53 100644 --- a/currency/forexprovider/exchangeratesapi.io/exchangeratesapi.go +++ b/currency/forexprovider/exchangeratesapi.io/exchangeratesapi.go @@ -269,7 +269,7 @@ func (e *ExchangeRates) SendHTTPRequest(endPoint string, values url.Values, resu Result: result, Verbose: e.Verbose, } - err := e.Requester.SendPayload(context.Background(), request.Unset, func() (*request.Item, error) { + err := e.Requester.SendPayload(context.TODO(), request.Unset, func() (*request.Item, error) { return item, nil }) if err != nil { diff --git a/currency/forexprovider/openexchangerates/openexchangerates.go b/currency/forexprovider/openexchangerates/openexchangerates.go index 6b215c5b..8132cf31 100644 --- a/currency/forexprovider/openexchangerates/openexchangerates.go +++ b/currency/forexprovider/openexchangerates/openexchangerates.go @@ -223,7 +223,7 @@ func (o *OXR) SendHTTPRequest(endpoint string, values url.Values, result interfa Path: path, Result: result, Verbose: o.Verbose} - return o.Requester.SendPayload(context.Background(), request.Unset, func() (*request.Item, error) { + return o.Requester.SendPayload(context.TODO(), request.Unset, func() (*request.Item, error) { return item, nil }) } diff --git a/docs/ADD_NEW_EXCHANGE.md b/docs/ADD_NEW_EXCHANGE.md index caca9067..8d08d643 100644 --- a/docs/ADD_NEW_EXCHANGE.md +++ b/docs/ADD_NEW_EXCHANGE.md @@ -350,7 +350,7 @@ This will generate a readme file for the exchange which can be found in the new ```go // SendHTTPRequest sends an unauthenticated HTTP request -func (f *FTX) SendHTTPRequest(path string, result interface{}) error { +func (f *FTX) SendHTTPRequest(ctx context.Context, path string, result interface{}) error { // This is used to generate the *http.Request, used in conjunction with the // generate functionality below. item := &request.Item{ @@ -369,9 +369,6 @@ func (f *FTX) SendHTTPRequest(path string, result interface{}) error { endpoint := request.Unset // Used in conjunction with the rate limiting // system defined in the exchange package to slow down outbound requests // depending on each individual endpoint. - - ctx := context.Background() - return f.SendPayload(ctx, endpoint, generate) } ``` @@ -425,7 +422,7 @@ Create a get function in ftx.go file and unmarshall the data in the created type // GetMarkets gets market data func (f *FTX) GetMarkets() (Markets, error) { var resp Markets - return resp, f.SendHTTPRequest(ftxAPIURL+getMarkets, &resp) + return resp, f.SendHTTPRequest(ctx, ftxAPIURL+getMarkets, &resp) } ``` @@ -458,7 +455,7 @@ Ensure each endpoint is implemented and has an associated test to improve test c Authenticated request function is created based on the way the exchange documentation specifies: https://docs.ftx.com/#authentication ```go // SendAuthHTTPRequest sends an authenticated request -func (f *FTX) SendAuthHTTPRequest(method, path string, data, result interface{}) error { +func (f *FTX) SendAuthHTTPRequest(ctx context.Context, method, path string, data, result interface{}) error { // A potential example below of closing over authenticated variables which may // be required to regenerate on every request between each attempt after rate // limiting. This is for when signatures are based on timestamps/nonces that are @@ -506,8 +503,6 @@ func (f *FTX) SendAuthHTTPRequest(method, path string, data, result interface{}) // system defined in the exchange package to slow down outbound requests // depending on each individual endpoint. - ctx := context.Background() - return f.SendPayload(ctx, endpoint, generate) } ``` @@ -524,7 +519,7 @@ https://docs.ftx.com/#get-account-information: // GetAccountInfo gets account info func (f *FTX) GetAccountInfo() (AccountData, error) { var resp AccountData - return resp, f.SendAuthHTTPRequest(http.MethodGet, getAccountInfo, nil, &resp) + return resp, f.SendAuthHTTPRequest(ctx, http.MethodGet, getAccountInfo, nil, &resp) } ``` @@ -556,7 +551,7 @@ func (f *FTX) GetTriggerOrderHistory(marketName string, startTime, endTime time. if limit != "" { params.Set("limit", limit) } - return resp, f.SendAuthHTTPRequest(http.MethodGet, getTriggerOrderHistory+params.Encode(), nil, &resp) + return resp, f.SendAuthHTTPRequest(ctx, http.MethodGet, getTriggerOrderHistory+params.Encode(), nil, &resp) } ``` @@ -616,7 +611,7 @@ func (f *FTX) Order(marketName, side, orderType, reduceOnly, ioc, postOnly, clie req["clientID"] = clientID } var resp PlaceOrder - return resp, f.SendAuthHTTPRequest(http.MethodPost, placeOrder, req, &resp) + return resp, f.SendAuthHTTPRequest(ctx, http.MethodPost, placeOrder, req, &resp) } ``` @@ -630,7 +625,7 @@ Unsupported Example: ```go // WithdrawFiatFunds returns a withdrawal ID when a withdrawal is // submitted -func (f *FTX) WithdrawFiatFunds(withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (f *FTX) WithdrawFiatFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { var resp *withdraw.ExchangeResponse return resp, common.ErrFunctionNotSupported } @@ -640,7 +635,7 @@ Supported Examples: ```go // FetchTradablePairs returns a list of the exchanges tradable pairs -func (f *FTX) FetchTradablePairs(a asset.Item) ([]string, error) { +func (f *FTX) FetchTradablePairs(ctx context.Context, a asset.Item) ([]string, error) { if !f.SupportsAsset(a) { return nil, fmt.Errorf("asset type of %s is not supported by %s", a, f.Name) } diff --git a/docs/OHLCV.md b/docs/OHLCV.md index 2f951e8f..ed4fa288 100644 --- a/docs/OHLCV.md +++ b/docs/OHLCV.md @@ -23,14 +23,14 @@ Candle retrieval is handled by two methods GetHistoricCandles which makes a single request to the exchange and follows all exchange limitations ```go -func (b *base) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (b *base) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { return kline.Item{}, common.ErrFunctionNotSupported } ``` GetHistoricCandlesExtended that will make multiple requests to an exchange if the requested periods are outside exchange limits ```go -func (b *base) GetHistoricCandlesExtended(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (b *base) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { return kline.Item{}, common.ErrFunctionNotSupported } ``` diff --git a/engine/apiserver.go b/engine/apiserver.go index 67c9701f..9e4e539a 100644 --- a/engine/apiserver.go +++ b/engine/apiserver.go @@ -320,7 +320,7 @@ func getAllActiveOrderbooks(m iExchangeManager) []EnabledExchangeOrderbooks { continue } for z := range currencies { - ob, err := exchanges[x].FetchOrderbook(currencies[z], assets[y]) + ob, err := exchanges[x].FetchOrderbook(context.TODO(), currencies[z], assets[y]) if err != nil { log.Errorf(log.APIServerMgr, "Exchange %s failed to retrieve %s orderbook. Err: %s\n", exchName, @@ -357,7 +357,7 @@ func getAllActiveTickers(m iExchangeManager) []EnabledExchangeCurrencies { continue } for z := range currencies { - t, err := exchanges[x].FetchTicker(currencies[z], assets[y]) + t, err := exchanges[x].FetchTicker(context.TODO(), currencies[z], assets[y]) if err != nil { log.Errorf(log.APIServerMgr, "Exchange %s failed to retrieve %s ticker. Err: %s\n", exchName, @@ -383,7 +383,7 @@ func getAllActiveAccounts(m iExchangeManager) []AllEnabledExchangeAccounts { exchName := exchanges[x].GetName() var exchangeAccounts AllEnabledExchangeAccounts for y := range assets { - a, err := exchanges[x].FetchAccountInfo(assets[y]) + a, err := exchanges[x].FetchAccountInfo(context.TODO(), assets[y]) if err != nil { log.Errorf(log.APIServerMgr, "Exchange %s failed to retrieve %s ticker. Err: %s\n", @@ -818,7 +818,7 @@ func wsGetTicker(client *websocketClient, data interface{}) error { } return err } - tick, err := exch.FetchTicker(p, a) + tick, err := exch.FetchTicker(context.TODO(), p, a) if err != nil { wsResp.Error = err.Error() sendErr := client.SendWebsocketMessage(wsResp) @@ -873,7 +873,7 @@ func wsGetOrderbook(client *websocketClient, data interface{}) error { } return err } - ob, err := exch.FetchOrderbook(p, a) + ob, err := exch.FetchOrderbook(context.TODO(), p, a) if err != nil { wsResp.Error = err.Error() sendErr := client.SendWebsocketMessage(wsResp) diff --git a/engine/datahistory_manager.go b/engine/datahistory_manager.go index cd0e087d..7f81908e 100644 --- a/engine/datahistory_manager.go +++ b/engine/datahistory_manager.go @@ -1,6 +1,7 @@ package engine import ( + "context" "database/sql" "errors" "fmt" @@ -699,7 +700,12 @@ func (m *DataHistoryManager) processCandleData(job *DataHistoryJob, exch exchang Status: dataHistoryStatusComplete, Date: time.Now(), } - candles, err := exch.GetHistoricCandlesExtended(job.Pair, job.Asset, startRange, endRange, job.Interval) + candles, err := exch.GetHistoricCandlesExtended(context.TODO(), + job.Pair, + job.Asset, + startRange, + endRange, + job.Interval) if err != nil { r.Result += "could not get candles: " + err.Error() + ". " r.Status = dataHistoryStatusFailed @@ -744,7 +750,11 @@ func (m *DataHistoryManager) processTradeData(job *DataHistoryJob, exch exchange Status: dataHistoryStatusComplete, Date: time.Now(), } - trades, err := exch.GetHistoricTrades(job.Pair, job.Asset, startRange, endRange) + trades, err := exch.GetHistoricTrades(context.TODO(), + job.Pair, + job.Asset, + startRange, + endRange) if err != nil { r.Result += "could not get trades: " + err.Error() + ". " r.Status = dataHistoryStatusFailed @@ -893,7 +903,12 @@ func (m *DataHistoryManager) validateCandles(job *DataHistoryJob, exch exchange. Date: time.Now(), } - apiCandles, err := exch.GetHistoricCandlesExtended(job.Pair, job.Asset, startRange, endRange, job.Interval) + apiCandles, err := exch.GetHistoricCandlesExtended(context.TODO(), + job.Pair, + job.Asset, + startRange, + endRange, + job.Interval) if err != nil { r.Result = "could not get API candles: " + err.Error() r.Status = dataHistoryStatusFailed diff --git a/engine/datahistory_manager_test.go b/engine/datahistory_manager_test.go index 82025bc6..6a884bdc 100644 --- a/engine/datahistory_manager_test.go +++ b/engine/datahistory_manager_test.go @@ -1,6 +1,7 @@ package engine import ( + "context" "database/sql" "errors" "strings" @@ -1542,7 +1543,7 @@ type dhmExchange struct { exchange.IBotExchange } -func (f dhmExchange) GetHistoricCandlesExtended(p currency.Pair, a asset.Item, timeStart, _ time.Time, interval kline.Interval) (kline.Item, error) { +func (f dhmExchange) GetHistoricCandlesExtended(ctx context.Context, p currency.Pair, a asset.Item, timeStart, _ time.Time, interval kline.Interval) (kline.Item, error) { return kline.Item{ Exchange: testExchange, Pair: p, @@ -1577,7 +1578,7 @@ func (f dhmExchange) GetHistoricCandlesExtended(p currency.Pair, a asset.Item, t }, nil } -func (f dhmExchange) GetHistoricTrades(p currency.Pair, a asset.Item, startTime, endTime time.Time) ([]trade.Data, error) { +func (f dhmExchange) GetHistoricTrades(ctx context.Context, p currency.Pair, a asset.Item, startTime, endTime time.Time) ([]trade.Data, error) { return []trade.Data{ { Exchange: testExchange, diff --git a/engine/engine.go b/engine/engine.go index 81b52484..1ef68651 100644 --- a/engine/engine.go +++ b/engine/engine.go @@ -1,6 +1,7 @@ package engine import ( + "context" "errors" "fmt" "log" @@ -210,10 +211,22 @@ func validateSettings(b *Engine, s *Settings, flagSet map[string]bool) { if b.Settings.GlobalHTTPTimeout <= 0 { b.Settings.GlobalHTTPTimeout = b.Config.GlobalHTTPTimeout } - common.SetHTTPClientWithTimeout(b.Settings.GlobalHTTPTimeout) + + err := common.SetHTTPClientWithTimeout(b.Settings.GlobalHTTPTimeout) + if err != nil { + gctlog.Errorf(gctlog.Global, + "Could not set new HTTP Client with timeout %s error: %v", + b.Settings.GlobalHTTPTimeout, + err) + } if b.Settings.GlobalHTTPUserAgent != "" { - common.HTTPUserAgent = b.Settings.GlobalHTTPUserAgent + err = common.SetHTTPUserAgent(b.Settings.GlobalHTTPUserAgent) + if err != nil { + gctlog.Errorf(gctlog.Global, "Could not set HTTP User Agent for %s error: %v", + b.Settings.GlobalHTTPUserAgent, + err) + } } } @@ -809,7 +822,7 @@ func (bot *Engine) LoadExchange(name string, wg *sync.WaitGroup) error { useAsset = assetTypes[a] break } - err = exch.ValidateCredentials(useAsset) + err = exch.ValidateCredentials(context.TODO(), useAsset) if err != nil { gctlog.Warnf(gctlog.ExchangeSys, "%s: Cannot validate credentials, authenticated support has been disabled, Error: %s\n", diff --git a/engine/event_manager_test.go b/engine/event_manager_test.go index bbe9a584..e1bcc5ed 100644 --- a/engine/event_manager_test.go +++ b/engine/event_manager_test.go @@ -1,6 +1,7 @@ package engine import ( + "context" "errors" "strings" "sync/atomic" @@ -284,7 +285,8 @@ func TestCheckEventCondition(t *testing.T) { t.Error("expected error") } m.m.Unlock() - _, err = exch.FetchTicker(currency.NewPair(currency.BTC, currency.USD), asset.Spot) + _, err = exch.FetchTicker(context.Background(), + currency.NewPair(currency.BTC, currency.USD), asset.Spot) if !errors.Is(err, nil) { t.Errorf("error '%v', expected '%v'", err, nil) } @@ -308,7 +310,8 @@ func TestCheckEventCondition(t *testing.T) { } m.m.Unlock() - _, err = exch.FetchOrderbook(currency.NewPair(currency.BTC, currency.USD), asset.Spot) + _, err = exch.FetchOrderbook(context.Background(), + currency.NewPair(currency.BTC, currency.USD), asset.Spot) if !errors.Is(err, nil) { t.Errorf("error '%v', expected '%v'", err, nil) } diff --git a/engine/helpers.go b/engine/helpers.go index 91a41c37..83bb0a58 100644 --- a/engine/helpers.go +++ b/engine/helpers.go @@ -1,6 +1,7 @@ package engine import ( + "context" "crypto/ecdsa" "crypto/elliptic" "crypto/rand" @@ -542,22 +543,22 @@ func GetRelatableCurrencies(p currency.Pair, incOrig, incUSDT bool) currency.Pai // GetSpecificOrderbook returns a specific orderbook given the currency, // exchangeName and assetType -func (bot *Engine) GetSpecificOrderbook(p currency.Pair, exchangeName string, assetType asset.Item) (*orderbook.Base, error) { +func (bot *Engine) GetSpecificOrderbook(ctx context.Context, p currency.Pair, exchangeName string, assetType asset.Item) (*orderbook.Base, error) { exch, err := bot.GetExchangeByName(exchangeName) if err != nil { return nil, err } - return exch.FetchOrderbook(p, assetType) + return exch.FetchOrderbook(ctx, p, assetType) } // GetSpecificTicker returns a specific ticker given the currency, // exchangeName and assetType -func (bot *Engine) GetSpecificTicker(p currency.Pair, exchangeName string, assetType asset.Item) (*ticker.Price, error) { +func (bot *Engine) GetSpecificTicker(ctx context.Context, p currency.Pair, exchangeName string, assetType asset.Item) (*ticker.Price, error) { exch, err := bot.GetExchangeByName(exchangeName) if err != nil { return nil, err } - return exch.FetchTicker(p, assetType) + return exch.FetchTicker(ctx, p, assetType) } // GetCollatedExchangeAccountInfoByCoin collates individual exchange account @@ -668,7 +669,7 @@ func (bot *Engine) GetCryptocurrencyDepositAddressesByExchange(exchName string) // GetExchangeCryptocurrencyDepositAddress returns the cryptocurrency deposit address for a particular // exchange -func (bot *Engine) GetExchangeCryptocurrencyDepositAddress(exchName, accountID string, item currency.Code) (string, error) { +func (bot *Engine) GetExchangeCryptocurrencyDepositAddress(ctx context.Context, exchName, accountID string, item currency.Code) (string, error) { if bot.DepositAddressManager != nil { return bot.DepositAddressManager.GetDepositAddressByExchangeAndCurrency(exchName, item) } @@ -677,7 +678,7 @@ func (bot *Engine) GetExchangeCryptocurrencyDepositAddress(exchName, accountID s if err != nil { return "", err } - return exch.GetDepositAddress(item, accountID) + return exch.GetDepositAddress(ctx, item, accountID) } // GetExchangeCryptocurrencyDepositAddresses obtains an exchanges deposit cryptocurrency list @@ -702,7 +703,9 @@ func (bot *Engine) GetExchangeCryptocurrencyDepositAddresses() map[string]map[st cryptoAddr := make(map[string]string) for y := range cryptoCurrencies { cryptocurrency := cryptoCurrencies[y] - depositAddr, err := exchanges[x].GetDepositAddress(currency.NewCode(cryptocurrency), "") + depositAddr, err := exchanges[x].GetDepositAddress(context.TODO(), + currency.NewCode(cryptocurrency), + "") if err != nil { log.Errorf(log.Global, "%s failed to get cryptocurrency deposit addresses. Err: %s\n", exchName, err) continue @@ -727,7 +730,7 @@ func (bot *Engine) GetExchangeNames(enabledOnly bool) []string { } // GetAllActiveTickers returns all enabled exchange tickers -func (bot *Engine) GetAllActiveTickers() []EnabledExchangeCurrencies { +func (bot *Engine) GetAllActiveTickers(ctx context.Context) []EnabledExchangeCurrencies { var tickerData []EnabledExchangeCurrencies exchanges := bot.GetExchanges() for x := range exchanges { @@ -746,7 +749,7 @@ func (bot *Engine) GetAllActiveTickers() []EnabledExchangeCurrencies { continue } for z := range currencies { - tp, err := exchanges[x].FetchTicker(currencies[z], assets[y]) + tp, err := exchanges[x].FetchTicker(ctx, currencies[z], assets[y]) if err != nil { log.Errorf(log.ExchangeSys, "Exchange %s failed to retrieve %s ticker. Err: %s\n", exchName, currencies[z].String(), diff --git a/engine/helpers_test.go b/engine/helpers_test.go index f86261af..eaa101a0 100644 --- a/engine/helpers_test.go +++ b/engine/helpers_test.go @@ -1,6 +1,7 @@ package engine import ( + "context" "crypto/ecdsa" "crypto/elliptic" "crypto/rand" @@ -773,7 +774,8 @@ func TestGetSpecificOrderbook(t *testing.T) { t.Fatal(err) } - ob, err := e.GetSpecificOrderbook(btsusd, testExchange, asset.Spot) + ob, err := e.GetSpecificOrderbook(context.Background(), + btsusd, testExchange, asset.Spot) if err != nil { t.Fatal(err) } @@ -787,7 +789,8 @@ func TestGetSpecificOrderbook(t *testing.T) { t.Fatal(err) } - _, err = e.GetSpecificOrderbook(ethltc, testExchange, asset.Spot) + _, err = e.GetSpecificOrderbook(context.Background(), + ethltc, testExchange, asset.Spot) if err == nil { t.Fatal("Unexpected result") } @@ -815,7 +818,8 @@ func TestGetSpecificTicker(t *testing.T) { t.Fatal("ProcessTicker error", err) } - tick, err := e.GetSpecificTicker(p, testExchange, asset.Spot) + tick, err := e.GetSpecificTicker(context.Background(), + p, testExchange, asset.Spot) if err != nil { t.Fatal(err) } @@ -829,7 +833,8 @@ func TestGetSpecificTicker(t *testing.T) { t.Fatal(err) } - _, err = e.GetSpecificTicker(ethltc, testExchange, asset.Spot) + _, err = e.GetSpecificTicker(context.Background(), + ethltc, testExchange, asset.Spot) if err == nil { t.Fatal("Unexpected result") } diff --git a/engine/order_manager.go b/engine/order_manager.go index af2696a7..2aa5cd79 100644 --- a/engine/order_manager.go +++ b/engine/order_manager.go @@ -1,6 +1,7 @@ package engine import ( + "context" "errors" "fmt" "strings" @@ -86,7 +87,8 @@ func (m *OrderManager) Stop() error { func (m *OrderManager) gracefulShutdown() { if m.cfg.CancelOrdersOnShutdown { log.Debugln(log.OrderMgr, "Order manager: Cancelling any open orders...") - m.CancelAllOrders(m.orderStore.exchangeManager.GetExchanges()) + m.CancelAllOrders(context.TODO(), + m.orderStore.exchangeManager.GetExchanges()) } } @@ -113,7 +115,7 @@ func (m *OrderManager) run() { } // CancelAllOrders iterates and cancels all orders for each exchange provided -func (m *OrderManager) CancelAllOrders(exchangeNames []exchange.IBotExchange) { +func (m *OrderManager) CancelAllOrders(ctx context.Context, exchangeNames []exchange.IBotExchange) { if m == nil || atomic.LoadInt32(&m.started) == 0 { return } @@ -130,7 +132,7 @@ func (m *OrderManager) CancelAllOrders(exchangeNames []exchange.IBotExchange) { } for j := range exchangeOrders { log.Debugf(log.OrderMgr, "Order manager: Cancelling order(s) for exchange %s.", exchangeNames[i].GetName()) - err := m.Cancel(&order.Cancel{ + err := m.Cancel(ctx, &order.Cancel{ Exchange: exchangeOrders[j].Exchange, ID: exchangeOrders[j].ID, AccountID: exchangeOrders[j].AccountID, @@ -150,7 +152,7 @@ func (m *OrderManager) CancelAllOrders(exchangeNames []exchange.IBotExchange) { // Cancel will find the order in the OrderManager, send a cancel request // to the exchange and if successful, update the status of the order -func (m *OrderManager) Cancel(cancel *order.Cancel) error { +func (m *OrderManager) Cancel(ctx context.Context, cancel *order.Cancel) error { if m == nil { return fmt.Errorf("order manager %w", ErrNilSubsystem) } @@ -193,7 +195,7 @@ func (m *OrderManager) Cancel(cancel *order.Cancel) error { log.Debugf(log.OrderMgr, "Order manager: Cancelling order ID %v [%+v]", cancel.ID, cancel) - err = exch.CancelOrder(cancel) + err = exch.CancelOrder(ctx, cancel) if err != nil { err = fmt.Errorf("%v - Failed to cancel order: %w", cancel.Exchange, err) return err @@ -219,7 +221,7 @@ func (m *OrderManager) Cancel(cancel *order.Cancel) error { // GetOrderInfo calls the exchange's wrapper GetOrderInfo function // and stores the result in the order manager -func (m *OrderManager) GetOrderInfo(exchangeName, orderID string, cp currency.Pair, a asset.Item) (order.Detail, error) { +func (m *OrderManager) GetOrderInfo(ctx context.Context, exchangeName, orderID string, cp currency.Pair, a asset.Item) (order.Detail, error) { if m == nil { return order.Detail{}, fmt.Errorf("order manager %w", ErrNilSubsystem) } @@ -235,7 +237,7 @@ func (m *OrderManager) GetOrderInfo(exchangeName, orderID string, cp currency.Pa if err != nil { return order.Detail{}, err } - result, err := exch.GetOrderInfo(orderID, cp, a) + result, err := exch.GetOrderInfo(ctx, orderID, cp, a) if err != nil { return order.Detail{}, err } @@ -285,7 +287,7 @@ func (m *OrderManager) validate(newOrder *order.Submit) error { // Modify depends on the order.Modify.ID and order.Modify.Exchange fields to uniquely // identify an order to modify. -func (m *OrderManager) Modify(mod *order.Modify) (*order.ModifyResponse, error) { +func (m *OrderManager) Modify(ctx context.Context, mod *order.Modify) (*order.ModifyResponse, error) { if m == nil { return nil, fmt.Errorf("order manager %w", ErrNilSubsystem) } @@ -320,7 +322,7 @@ func (m *OrderManager) Modify(mod *order.Modify) (*order.ModifyResponse, error) if err != nil { return nil, err } - res, err := exch.ModifyOrder(mod) + res, err := exch.ModifyOrder(ctx, mod) if err != nil { message := fmt.Sprintf( "Order manager: Exchange %s order ID=%v: failed to modify", @@ -356,7 +358,7 @@ func (m *OrderManager) Modify(mod *order.Modify) (*order.ModifyResponse, error) // Submit will take in an order struct, send it to the exchange and // populate it in the OrderManager if successful -func (m *OrderManager) Submit(newOrder *order.Submit) (*OrderSubmitResponse, error) { +func (m *OrderManager) Submit(ctx context.Context, newOrder *order.Submit) (*OrderSubmitResponse, error) { if m == nil { return nil, fmt.Errorf("order manager %w", ErrNilSubsystem) } @@ -386,7 +388,7 @@ func (m *OrderManager) Submit(newOrder *order.Submit) (*OrderSubmitResponse, err err) } - result, err := exch.SubmitOrder(newOrder) + result, err := exch.SubmitOrder(ctx, newOrder) if err != nil { return nil, err } @@ -589,7 +591,7 @@ func (m *OrderManager) processOrders() { Pairs: pairs, AssetType: supportedAssets[y], } - result, err := exchanges[i].GetActiveOrders(&req) + result, err := exchanges[i].GetActiveOrders(context.TODO(), &req) if err != nil { log.Warnf(log.OrderMgr, "Order manager: Unable to get active orders for %s and asset type %s: %s", diff --git a/engine/order_manager_test.go b/engine/order_manager_test.go index 26fb525c..5c5de616 100644 --- a/engine/order_manager_test.go +++ b/engine/order_manager_test.go @@ -1,6 +1,7 @@ package engine import ( + "context" "errors" "sync" "testing" @@ -20,14 +21,14 @@ type omfExchange struct { // CancelOrder overrides testExchange's cancel order function // to do the bare minimum required with no API calls or credentials required -func (f omfExchange) CancelOrder(o *order.Cancel) error { +func (f omfExchange) CancelOrder(ctx context.Context, o *order.Cancel) error { o.Status = order.Cancelled return nil } // GetOrderInfo overrides testExchange's get order function // to do the bare minimum required with no API calls or credentials required -func (f omfExchange) GetOrderInfo(orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { +func (f omfExchange) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { if orderID == "" { return order.Detail{}, errors.New("") } @@ -40,7 +41,7 @@ func (f omfExchange) GetOrderInfo(orderID string, pair currency.Pair, assetType }, nil } -func (f omfExchange) ModifyOrder(action *order.Modify) (order.Modify, error) { +func (f omfExchange) ModifyOrder(ctx context.Context, action *order.Modify) (order.Modify, error) { ans := *action ans.ID = "modified_order_id" return ans, nil @@ -391,35 +392,36 @@ func TestStore_modifyOrder(t *testing.T) { func TestCancelOrder(t *testing.T) { m := OrdersSetup(t) - err := m.Cancel(nil) + err := m.Cancel(context.Background(), nil) if err == nil { t.Error("Expected error due to empty order") } - err = m.Cancel(&order.Cancel{}) + err = m.Cancel(context.Background(), &order.Cancel{}) if err == nil { t.Error("Expected error due to empty order") } - err = m.Cancel(&order.Cancel{ + err = m.Cancel(context.Background(), &order.Cancel{ Exchange: testExchange, }) if err == nil { t.Error("Expected error due to no order ID") } - err = m.Cancel(&order.Cancel{ + err = m.Cancel(context.Background(), &order.Cancel{ ID: "ID", }) if err == nil { t.Error("Expected error due to no Exchange") } - err = m.Cancel(&order.Cancel{ - ID: "ID", - Exchange: testExchange, - AssetType: asset.Binary, - }) + err = m.Cancel(context.Background(), + &order.Cancel{ + ID: "ID", + Exchange: testExchange, + AssetType: asset.Binary, + }) if err == nil { t.Error("Expected error due to bad asset type") } @@ -434,11 +436,12 @@ func TestCancelOrder(t *testing.T) { t.Error(err) } - err = m.Cancel(&order.Cancel{ - ID: "Unknown", - Exchange: testExchange, - AssetType: asset.Spot, - }) + err = m.Cancel(context.Background(), + &order.Cancel{ + ID: "Unknown", + Exchange: testExchange, + AssetType: asset.Spot, + }) if err == nil { t.Error("Expected error due to no order found") } @@ -457,7 +460,7 @@ func TestCancelOrder(t *testing.T) { Date: time.Now(), Pair: pair, } - err = m.Cancel(cancel) + err = m.Cancel(context.Background(), cancel) if !errors.Is(err, nil) { t.Errorf("error '%v', expected '%v'", err, nil) } @@ -469,13 +472,14 @@ func TestCancelOrder(t *testing.T) { func TestGetOrderInfo(t *testing.T) { m := OrdersSetup(t) - _, err := m.GetOrderInfo("", "", currency.Pair{}, "") + _, err := m.GetOrderInfo(context.Background(), "", "", currency.Pair{}, "") if err == nil { t.Error("Expected error due to empty order") } var result order.Detail - result, err = m.GetOrderInfo(testExchange, "1337", currency.Pair{}, "") + result, err = m.GetOrderInfo(context.Background(), + testExchange, "1337", currency.Pair{}, "") if err != nil { t.Error(err) } @@ -483,7 +487,8 @@ func TestGetOrderInfo(t *testing.T) { t.Error("unexpected order returned") } - result, err = m.GetOrderInfo(testExchange, "1337", currency.Pair{}, "") + result, err = m.GetOrderInfo(context.Background(), + testExchange, "1337", currency.Pair{}, "") if err != nil { t.Error(err) } @@ -504,7 +509,7 @@ func TestCancelAllOrders(t *testing.T) { t.Error(err) } - m.CancelAllOrders([]exchange.IBotExchange{}) + m.CancelAllOrders(context.Background(), []exchange.IBotExchange{}) if o.Status == order.Cancelled { t.Error("Order should not be cancelled") } @@ -514,13 +519,13 @@ func TestCancelAllOrders(t *testing.T) { t.Fatal(err) } - m.CancelAllOrders([]exchange.IBotExchange{exch}) + m.CancelAllOrders(context.Background(), []exchange.IBotExchange{exch}) if o.Status != order.Cancelled { t.Error("Order should be cancelled") } o.Status = order.New - m.CancelAllOrders(nil) + m.CancelAllOrders(context.Background(), nil) if o.Status != order.New { t.Error("Order should not be cancelled") } @@ -528,7 +533,7 @@ func TestCancelAllOrders(t *testing.T) { func TestSubmit(t *testing.T) { m := OrdersSetup(t) - _, err := m.Submit(nil) + _, err := m.Submit(context.Background(), nil) if err == nil { t.Error("Expected error from nil order") } @@ -539,13 +544,13 @@ func TestSubmit(t *testing.T) { Status: order.New, Type: order.Market, } - _, err = m.Submit(o) + _, err = m.Submit(context.Background(), o) if err == nil { t.Error("Expected error from empty exchange") } o.Exchange = testExchange - _, err = m.Submit(o) + _, err = m.Submit(context.Background(), o) if err == nil { t.Error("Expected error from validation") } @@ -562,20 +567,20 @@ func TestSubmit(t *testing.T) { o.Side = order.Buy o.Amount = 1 o.Price = 1 - _, err = m.Submit(o) + _, err = m.Submit(context.Background(), o) if err == nil { t.Error("Expected fail due to order market type is not allowed") } m.cfg.AllowMarketOrders = true m.cfg.LimitAmount = 1 o.Amount = 2 - _, err = m.Submit(o) + _, err = m.Submit(context.Background(), o) if err == nil { t.Error("Expected fail due to order limit exceeds allowed limit") } m.cfg.LimitAmount = 0 m.cfg.AllowedExchanges = []string{"fake"} - _, err = m.Submit(o) + _, err = m.Submit(context.Background(), o) if err == nil { t.Error("Expected fail due to order exchange not found in allowed list") } @@ -587,13 +592,13 @@ func TestSubmit(t *testing.T) { m.cfg.AllowedExchanges = nil m.cfg.AllowedPairs = currency.Pairs{failPair} - _, err = m.Submit(o) + _, err = m.Submit(context.Background(), o) if err == nil { t.Error("Expected fail due to order pair not found in allowed list") } m.cfg.AllowedPairs = nil - _, err = m.Submit(o) + _, err = m.Submit(context.Background(), o) if !errors.Is(err, exchange.ErrAuthenticatedRequestWithoutCredentialsSet) { t.Errorf("error '%v', expected '%v'", err, exchange.ErrAuthenticatedRequestWithoutCredentialsSet) } @@ -629,15 +634,14 @@ func TestOrderManager_Modify(t *testing.T) { AssetType: asset.Spot, Pair: pair, ID: "fake_order_id", - // - Price: 8, - Amount: 128, + Price: 8, + Amount: 128, }) if err != nil { t.Error(err) } - resp, err := m.Modify(&mod) + resp, err := m.Modify(context.Background(), &mod) if expectError { if err == nil { t.Fatal("Expected error") diff --git a/engine/portfolio_manager.go b/engine/portfolio_manager.go index 4568cbf0..2292f3cb 100644 --- a/engine/portfolio_manager.go +++ b/engine/portfolio_manager.go @@ -1,6 +1,7 @@ package engine import ( + "context" "fmt" "sync" "sync/atomic" @@ -246,7 +247,7 @@ func (m *portfolioManager) getExchangeAccountInfo(exchanges []exchange.IBotExcha assetTypes := exchanges[x].GetAssetTypes(false) // left as available for now, to sync the full spectrum var exchangeHoldings account.Holdings for y := range assetTypes { - accountHoldings, err := exchanges[x].FetchAccountInfo(assetTypes[y]) + accountHoldings, err := exchanges[x].FetchAccountInfo(context.TODO(), assetTypes[y]) if err != nil { log.Errorf(log.PortfolioMgr, "Error encountered retrieving exchange account info for %s. Error %s\n", diff --git a/engine/rpcserver.go b/engine/rpcserver.go index fc4f9a88..eae2f369 100644 --- a/engine/rpcserver.go +++ b/engine/rpcserver.go @@ -343,7 +343,7 @@ func (s *RPCServer) GetExchangeInfo(_ context.Context, r *gctrpc.GenericExchange // GetTicker returns the ticker for a specified exchange, currency pair and // asset type -func (s *RPCServer) GetTicker(_ context.Context, r *gctrpc.GetTickerRequest) (*gctrpc.TickerResponse, error) { +func (s *RPCServer) GetTicker(ctx context.Context, r *gctrpc.GetTickerRequest) (*gctrpc.TickerResponse, error) { a, err := asset.New(r.AssetType) if err != nil { return nil, err @@ -363,11 +363,12 @@ func (s *RPCServer) GetTicker(_ context.Context, r *gctrpc.GetTickerRequest) (*g return nil, err } - t, err := s.GetSpecificTicker(currency.Pair{ - Delimiter: r.Pair.Delimiter, - Base: currency.NewCode(r.Pair.Base), - Quote: currency.NewCode(r.Pair.Quote), - }, + t, err := s.GetSpecificTicker(ctx, + currency.Pair{ + Delimiter: r.Pair.Delimiter, + Base: currency.NewCode(r.Pair.Base), + Quote: currency.NewCode(r.Pair.Quote), + }, r.Exchange, a, ) @@ -392,8 +393,8 @@ func (s *RPCServer) GetTicker(_ context.Context, r *gctrpc.GetTickerRequest) (*g // GetTickers returns a list of tickers for all enabled exchanges and all // enabled currency pairs -func (s *RPCServer) GetTickers(_ context.Context, _ *gctrpc.GetTickersRequest) (*gctrpc.GetTickersResponse, error) { - activeTickers := s.GetAllActiveTickers() +func (s *RPCServer) GetTickers(ctx context.Context, _ *gctrpc.GetTickersRequest) (*gctrpc.GetTickersResponse, error) { + activeTickers := s.GetAllActiveTickers(ctx) var tickers []*gctrpc.Tickers for x := range activeTickers { @@ -426,17 +427,18 @@ func (s *RPCServer) GetTickers(_ context.Context, _ *gctrpc.GetTickersRequest) ( // GetOrderbook returns an orderbook for a specific exchange, currency pair // and asset type -func (s *RPCServer) GetOrderbook(_ context.Context, r *gctrpc.GetOrderbookRequest) (*gctrpc.OrderbookResponse, error) { +func (s *RPCServer) GetOrderbook(ctx context.Context, r *gctrpc.GetOrderbookRequest) (*gctrpc.OrderbookResponse, error) { a, err := asset.New(r.AssetType) if err != nil { return nil, err } - ob, err := s.GetSpecificOrderbook(currency.Pair{ - Delimiter: r.Pair.Delimiter, - Base: currency.NewCode(r.Pair.Base), - Quote: currency.NewCode(r.Pair.Quote), - }, + ob, err := s.GetSpecificOrderbook(ctx, + currency.Pair{ + Delimiter: r.Pair.Delimiter, + Base: currency.NewCode(r.Pair.Base), + Quote: currency.NewCode(r.Pair.Quote), + }, r.Exchange, a, ) @@ -479,7 +481,7 @@ func (s *RPCServer) GetOrderbook(_ context.Context, r *gctrpc.GetOrderbookReques // GetOrderbooks returns a list of orderbooks for all enabled exchanges and all // enabled currency pairs -func (s *RPCServer) GetOrderbooks(_ context.Context, _ *gctrpc.GetOrderbooksRequest) (*gctrpc.GetOrderbooksResponse, error) { +func (s *RPCServer) GetOrderbooks(ctx context.Context, _ *gctrpc.GetOrderbooksRequest) (*gctrpc.GetOrderbooksResponse, error) { exchanges := s.ExchangeManager.GetExchanges() var obResponse []*gctrpc.Orderbooks var obs []*gctrpc.OrderbookResponse @@ -499,7 +501,7 @@ func (s *RPCServer) GetOrderbooks(_ context.Context, _ *gctrpc.GetOrderbooksRequ continue } for z := range currencies { - resp, err := exchanges[x].FetchOrderbook(currencies[z], assets[y]) + resp, err := exchanges[x].FetchOrderbook(ctx, currencies[z], assets[y]) if err != nil { log.Errorf(log.RESTSys, "Exchange %s failed to retrieve %s orderbook. Err: %s\n", exchName, @@ -542,7 +544,7 @@ func (s *RPCServer) GetOrderbooks(_ context.Context, _ *gctrpc.GetOrderbooksRequ } // GetAccountInfo returns an account balance for a specific exchange -func (s *RPCServer) GetAccountInfo(_ context.Context, r *gctrpc.GetAccountInfoRequest) (*gctrpc.GetAccountInfoResponse, error) { +func (s *RPCServer) GetAccountInfo(ctx context.Context, r *gctrpc.GetAccountInfoRequest) (*gctrpc.GetAccountInfoResponse, error) { assetType, err := asset.New(r.AssetType) if err != nil { return nil, err @@ -558,7 +560,7 @@ func (s *RPCServer) GetAccountInfo(_ context.Context, r *gctrpc.GetAccountInfoRe return nil, err } - resp, err := exch.FetchAccountInfo(assetType) + resp, err := exch.FetchAccountInfo(ctx, assetType) if err != nil { return nil, err } @@ -567,7 +569,7 @@ func (s *RPCServer) GetAccountInfo(_ context.Context, r *gctrpc.GetAccountInfoRe } // UpdateAccountInfo forces an update of the account info -func (s *RPCServer) UpdateAccountInfo(_ context.Context, r *gctrpc.GetAccountInfoRequest) (*gctrpc.GetAccountInfoResponse, error) { +func (s *RPCServer) UpdateAccountInfo(ctx context.Context, r *gctrpc.GetAccountInfoRequest) (*gctrpc.GetAccountInfoResponse, error) { assetType, err := asset.New(r.AssetType) if err != nil { return nil, err @@ -583,7 +585,7 @@ func (s *RPCServer) UpdateAccountInfo(_ context.Context, r *gctrpc.GetAccountInf return nil, err } - resp, err := exch.UpdateAccountInfo(assetType) + resp, err := exch.UpdateAccountInfo(ctx, assetType) if err != nil { return nil, err } @@ -626,7 +628,7 @@ func (s *RPCServer) GetAccountInfoStream(r *gctrpc.GetAccountInfoRequest, stream return err } - initAcc, err := exch.FetchAccountInfo(assetType) + initAcc, err := exch.FetchAccountInfo(stream.Context(), assetType) if err != nil { return err } @@ -863,7 +865,7 @@ func (s *RPCServer) GetForexRates(_ context.Context, _ *gctrpc.GetForexRatesRequ // GetOrders returns all open orders, filtered by exchange, currency pair or // asset type between optional dates -func (s *RPCServer) GetOrders(_ context.Context, r *gctrpc.GetOrdersRequest) (*gctrpc.GetOrdersResponse, error) { +func (s *RPCServer) GetOrders(ctx context.Context, r *gctrpc.GetOrdersRequest) (*gctrpc.GetOrdersResponse, error) { if r == nil { return nil, errInvalidArguments } @@ -921,7 +923,7 @@ func (s *RPCServer) GetOrders(_ context.Context, r *gctrpc.GetOrdersRequest) (*g } var resp []order.Detail - resp, err = exch.GetActiveOrders(request) + resp, err = exch.GetActiveOrders(ctx, request) if err != nil { return nil, err } @@ -1064,7 +1066,7 @@ func (s *RPCServer) GetManagedOrders(_ context.Context, r *gctrpc.GetOrdersReque } // GetOrder returns order information based on exchange and order ID -func (s *RPCServer) GetOrder(_ context.Context, r *gctrpc.GetOrderRequest) (*gctrpc.OrderDetails, error) { +func (s *RPCServer) GetOrder(ctx context.Context, r *gctrpc.GetOrderRequest) (*gctrpc.OrderDetails, error) { if r == nil { return nil, errInvalidArguments } @@ -1094,7 +1096,11 @@ func (s *RPCServer) GetOrder(_ context.Context, r *gctrpc.GetOrderRequest) (*gct return nil, err } - result, err := s.OrderManager.GetOrderInfo(r.Exchange, r.OrderId, pair, a) + result, err := s.OrderManager.GetOrderInfo(ctx, + r.Exchange, + r.OrderId, + pair, + a) if err != nil { return nil, fmt.Errorf("error whilst trying to retrieve info for order %s: %w", r.OrderId, err) } @@ -1144,7 +1150,7 @@ func (s *RPCServer) GetOrder(_ context.Context, r *gctrpc.GetOrderRequest) (*gct // SubmitOrder submits an order specified by exchange, currency pair and asset // type -func (s *RPCServer) SubmitOrder(_ context.Context, r *gctrpc.SubmitOrderRequest) (*gctrpc.SubmitOrderResponse, error) { +func (s *RPCServer) SubmitOrder(ctx context.Context, r *gctrpc.SubmitOrderRequest) (*gctrpc.SubmitOrderResponse, error) { a, err := asset.New(r.AssetType) if err != nil { return nil, err @@ -1182,7 +1188,7 @@ func (s *RPCServer) SubmitOrder(_ context.Context, r *gctrpc.SubmitOrderRequest) AssetType: a, } - resp, err := s.OrderManager.Submit(submission) + resp, err := s.OrderManager.Submit(ctx, submission) if err != nil { return &gctrpc.SubmitOrderResponse{}, err } @@ -1206,7 +1212,7 @@ func (s *RPCServer) SubmitOrder(_ context.Context, r *gctrpc.SubmitOrderRequest) // SimulateOrder simulates an order specified by exchange, currency pair and asset // type -func (s *RPCServer) SimulateOrder(_ context.Context, r *gctrpc.SimulateOrderRequest) (*gctrpc.SimulateOrderResponse, error) { +func (s *RPCServer) SimulateOrder(ctx context.Context, r *gctrpc.SimulateOrderRequest) (*gctrpc.SimulateOrderResponse, error) { if r.Pair == nil { return nil, errCurrencyPairUnset } @@ -1227,7 +1233,7 @@ func (s *RPCServer) SimulateOrder(_ context.Context, r *gctrpc.SimulateOrderRequ return nil, err } - o, err := exch.FetchOrderbook(p, asset.Spot) + o, err := exch.FetchOrderbook(ctx, p, asset.Spot) if err != nil { return nil, err } @@ -1257,7 +1263,7 @@ func (s *RPCServer) SimulateOrder(_ context.Context, r *gctrpc.SimulateOrderRequ // WhaleBomb finds the amount required to reach a specific price target for a given exchange, pair // and asset type -func (s *RPCServer) WhaleBomb(_ context.Context, r *gctrpc.WhaleBombRequest) (*gctrpc.SimulateOrderResponse, error) { +func (s *RPCServer) WhaleBomb(ctx context.Context, r *gctrpc.WhaleBombRequest) (*gctrpc.SimulateOrderResponse, error) { if r.Pair == nil { return nil, errCurrencyPairUnset } @@ -1278,7 +1284,7 @@ func (s *RPCServer) WhaleBomb(_ context.Context, r *gctrpc.WhaleBombRequest) (*g return nil, err } - o, err := exch.FetchOrderbook(p, asset.Spot) + o, err := exch.FetchOrderbook(ctx, p, asset.Spot) if err != nil { return nil, err } @@ -1311,7 +1317,7 @@ func (s *RPCServer) WhaleBomb(_ context.Context, r *gctrpc.WhaleBombRequest) (*g // CancelOrder cancels an order specified by exchange, currency pair and asset // type -func (s *RPCServer) CancelOrder(_ context.Context, r *gctrpc.CancelOrderRequest) (*gctrpc.GenericResponse, error) { +func (s *RPCServer) CancelOrder(ctx context.Context, r *gctrpc.CancelOrderRequest) (*gctrpc.GenericResponse, error) { if r.Pair == nil { return nil, errCurrencyPairUnset } @@ -1337,15 +1343,16 @@ func (s *RPCServer) CancelOrder(_ context.Context, r *gctrpc.CancelOrderRequest) return nil, err } - err = s.OrderManager.Cancel(&order.Cancel{ - Exchange: r.Exchange, - AccountID: r.AccountId, - ID: r.OrderId, - Side: order.Side(r.Side), - WalletAddress: r.WalletAddress, - Pair: p, - AssetType: a, - }) + err = s.OrderManager.Cancel(ctx, + &order.Cancel{ + Exchange: r.Exchange, + AccountID: r.AccountId, + ID: r.OrderId, + Side: order.Side(r.Side), + WalletAddress: r.WalletAddress, + Pair: p, + AssetType: a, + }) if err != nil { return nil, err } @@ -1354,7 +1361,7 @@ func (s *RPCServer) CancelOrder(_ context.Context, r *gctrpc.CancelOrderRequest) } // CancelBatchOrders cancels an orders specified by exchange, currency pair and asset type -func (s *RPCServer) CancelBatchOrders(_ context.Context, r *gctrpc.CancelBatchOrdersRequest) (*gctrpc.CancelBatchOrdersResponse, error) { +func (s *RPCServer) CancelBatchOrders(ctx context.Context, r *gctrpc.CancelBatchOrdersRequest) (*gctrpc.CancelBatchOrdersResponse, error) { pair := currency.Pair{ Delimiter: r.Pair.Delimiter, Base: currency.NewCode(r.Pair.Base), @@ -1391,7 +1398,8 @@ func (s *RPCServer) CancelBatchOrders(_ context.Context, r *gctrpc.CancelBatchOr }) } - _, err = exch.CancelBatchOrders(request) + // TODO: Change to order manager + _, err = exch.CancelBatchOrders(ctx, request) if err != nil { return nil, err } @@ -1404,13 +1412,14 @@ func (s *RPCServer) CancelBatchOrders(_ context.Context, r *gctrpc.CancelBatchOr } // CancelAllOrders cancels all orders, filterable by exchange -func (s *RPCServer) CancelAllOrders(_ context.Context, r *gctrpc.CancelAllOrdersRequest) (*gctrpc.CancelAllOrdersResponse, error) { +func (s *RPCServer) CancelAllOrders(ctx context.Context, r *gctrpc.CancelAllOrdersRequest) (*gctrpc.CancelAllOrdersResponse, error) { exch, err := s.GetExchangeByName(r.Exchange) if err != nil { return nil, err } - resp, err := exch.CancelAllOrders(nil) + // TODO: Change to order manager + resp, err := exch.CancelAllOrders(ctx, nil) if err != nil { return &gctrpc.CancelAllOrdersResponse{}, err } @@ -1420,7 +1429,7 @@ func (s *RPCServer) CancelAllOrders(_ context.Context, r *gctrpc.CancelAllOrders }, nil } -func (s *RPCServer) ModifyOrder(_ context.Context, r *gctrpc.ModifyOrderRequest) (*gctrpc.ModifyOrderResponse, error) { +func (s *RPCServer) ModifyOrder(ctx context.Context, r *gctrpc.ModifyOrderRequest) (*gctrpc.ModifyOrderResponse, error) { assetType, err := asset.New(r.Asset) if err != nil { return nil, err @@ -1450,7 +1459,7 @@ func (s *RPCServer) ModifyOrder(_ context.Context, r *gctrpc.ModifyOrderRequest) Amount: r.Amount, Price: r.Price, } - resp, err := s.OrderManager.Modify(&mod) + resp, err := s.OrderManager.Modify(ctx, &mod) if err != nil { return nil, err } @@ -1501,7 +1510,7 @@ func (s *RPCServer) AddEvent(_ context.Context, r *gctrpc.AddEventRequest) (*gct } // RemoveEvent removes an event, specified by an event ID -func (s *RPCServer) RemoveEvent(_ context.Context, r *gctrpc.RemoveEventRequest) (*gctrpc.GenericResponse, error) { +func (s *RPCServer) RemoveEvent(ctx context.Context, r *gctrpc.RemoveEventRequest) (*gctrpc.GenericResponse, error) { if !s.eventManager.Remove(r.Id) { return nil, fmt.Errorf("event %d not removed", r.Id) } @@ -1511,7 +1520,7 @@ func (s *RPCServer) RemoveEvent(_ context.Context, r *gctrpc.RemoveEventRequest) // GetCryptocurrencyDepositAddresses returns a list of cryptocurrency deposit // addresses specified by an exchange -func (s *RPCServer) GetCryptocurrencyDepositAddresses(_ context.Context, r *gctrpc.GetCryptocurrencyDepositAddressesRequest) (*gctrpc.GetCryptocurrencyDepositAddressesResponse, error) { +func (s *RPCServer) GetCryptocurrencyDepositAddresses(ctx context.Context, r *gctrpc.GetCryptocurrencyDepositAddressesRequest) (*gctrpc.GetCryptocurrencyDepositAddressesResponse, error) { _, err := s.GetExchangeByName(r.Exchange) if err != nil { return nil, err @@ -1523,19 +1532,22 @@ func (s *RPCServer) GetCryptocurrencyDepositAddresses(_ context.Context, r *gctr // GetCryptocurrencyDepositAddress returns a cryptocurrency deposit address // specified by exchange and cryptocurrency -func (s *RPCServer) GetCryptocurrencyDepositAddress(_ context.Context, r *gctrpc.GetCryptocurrencyDepositAddressRequest) (*gctrpc.GetCryptocurrencyDepositAddressResponse, error) { +func (s *RPCServer) GetCryptocurrencyDepositAddress(ctx context.Context, r *gctrpc.GetCryptocurrencyDepositAddressRequest) (*gctrpc.GetCryptocurrencyDepositAddressResponse, error) { _, err := s.GetExchangeByName(r.Exchange) if err != nil { return nil, err } - addr, err := s.GetExchangeCryptocurrencyDepositAddress(r.Exchange, "", currency.NewCode(r.Cryptocurrency)) + addr, err := s.GetExchangeCryptocurrencyDepositAddress(ctx, + r.Exchange, + "", + currency.NewCode(r.Cryptocurrency)) return &gctrpc.GetCryptocurrencyDepositAddressResponse{Address: addr}, err } // WithdrawCryptocurrencyFunds withdraws cryptocurrency funds specified by // exchange -func (s *RPCServer) WithdrawCryptocurrencyFunds(_ context.Context, r *gctrpc.WithdrawCryptoRequest) (*gctrpc.WithdrawResponse, error) { +func (s *RPCServer) WithdrawCryptocurrencyFunds(ctx context.Context, r *gctrpc.WithdrawCryptoRequest) (*gctrpc.WithdrawResponse, error) { _, err := s.GetExchangeByName(r.Exchange) if err != nil { return nil, err @@ -1554,7 +1566,7 @@ func (s *RPCServer) WithdrawCryptocurrencyFunds(_ context.Context, r *gctrpc.Wit }, } - resp, err := s.Engine.WithdrawManager.SubmitWithdrawal(request) + resp, err := s.Engine.WithdrawManager.SubmitWithdrawal(ctx, request) if err != nil { return nil, err } @@ -1566,7 +1578,7 @@ func (s *RPCServer) WithdrawCryptocurrencyFunds(_ context.Context, r *gctrpc.Wit } // WithdrawFiatFunds withdraws fiat funds specified by exchange -func (s *RPCServer) WithdrawFiatFunds(_ context.Context, r *gctrpc.WithdrawFiatRequest) (*gctrpc.WithdrawResponse, error) { +func (s *RPCServer) WithdrawFiatFunds(ctx context.Context, r *gctrpc.WithdrawFiatRequest) (*gctrpc.WithdrawResponse, error) { exch, err := s.GetExchangeByName(r.Exchange) if err != nil { return nil, err @@ -1578,7 +1590,8 @@ func (s *RPCServer) WithdrawFiatFunds(_ context.Context, r *gctrpc.WithdrawFiatR if base == nil { return nil, errExchangeBaseNotFound } - bankAccount, err = base.GetExchangeBankAccounts(r.BankAccountId, r.Currency) + bankAccount, err = base.GetExchangeBankAccounts(r.BankAccountId, + r.Currency) if err != nil { return nil, err } @@ -1595,7 +1608,7 @@ func (s *RPCServer) WithdrawFiatFunds(_ context.Context, r *gctrpc.WithdrawFiatR }, } - resp, err := s.Engine.WithdrawManager.SubmitWithdrawal(request) + resp, err := s.Engine.WithdrawManager.SubmitWithdrawal(ctx, request) if err != nil { return nil, err } @@ -1667,7 +1680,7 @@ func (s *RPCServer) WithdrawalEventByID(_ context.Context, r *gctrpc.WithdrawalE } // WithdrawalEventsByExchange returns previous withdrawal request details by exchange -func (s *RPCServer) WithdrawalEventsByExchange(_ context.Context, r *gctrpc.WithdrawalEventsByExchangeRequest) (*gctrpc.WithdrawalEventsByExchangeResponse, error) { +func (s *RPCServer) WithdrawalEventsByExchange(ctx context.Context, r *gctrpc.WithdrawalEventsByExchangeRequest) (*gctrpc.WithdrawalEventsByExchangeResponse, error) { if !s.Config.Database.Enabled { if r.Id == "" { exch, err := s.GetExchangeByName(r.Exchange) @@ -1676,7 +1689,7 @@ func (s *RPCServer) WithdrawalEventsByExchange(_ context.Context, r *gctrpc.With } c := currency.NewCode(strings.ToUpper(r.Currency)) - ret, err := exch.GetWithdrawalsHistory(c) + ret, err := exch.GetWithdrawalsHistory(ctx, c) if err != nil { return nil, err } @@ -2154,7 +2167,7 @@ func (s *RPCServer) GetAuditEvent(_ context.Context, r *gctrpc.GetAuditEventRequ } // GetHistoricCandles returns historical candles for a given exchange -func (s *RPCServer) GetHistoricCandles(_ context.Context, r *gctrpc.GetHistoricCandlesRequest) (*gctrpc.GetHistoricCandlesResponse, error) { +func (s *RPCServer) GetHistoricCandles(ctx context.Context, r *gctrpc.GetHistoricCandlesRequest) (*gctrpc.GetHistoricCandlesResponse, error) { start, err := time.Parse(common.SimpleTimeFormat, r.Start) if err != nil { return nil, fmt.Errorf("%w cannot parse start time %v", errInvalidTimes, err) @@ -2214,13 +2227,15 @@ func (s *RPCServer) GetHistoricCandles(_ context.Context, r *gctrpc.GetHistoricC } } else { if r.ExRequest { - klineItem, err = exch.GetHistoricCandlesExtended(pair, + klineItem, err = exch.GetHistoricCandlesExtended(ctx, + pair, a, start, end, interval) } else { - klineItem, err = exch.GetHistoricCandles(pair, + klineItem, err = exch.GetHistoricCandles(ctx, + pair, a, start, end, @@ -2702,7 +2717,7 @@ func (s *RPCServer) SetAllExchangePairs(_ context.Context, r *gctrpc.SetExchange // UpdateExchangeSupportedPairs forces an update of the supported pairs which // will update the available pairs list and remove any assets that are disabled // by the exchange -func (s *RPCServer) UpdateExchangeSupportedPairs(_ context.Context, r *gctrpc.UpdateExchangeSupportedPairsRequest) (*gctrpc.GenericResponse, error) { +func (s *RPCServer) UpdateExchangeSupportedPairs(ctx context.Context, r *gctrpc.UpdateExchangeSupportedPairsRequest) (*gctrpc.GenericResponse, error) { exch, err := s.GetExchangeByName(r.Exchange) if err != nil { return nil, err @@ -2718,7 +2733,7 @@ func (s *RPCServer) UpdateExchangeSupportedPairs(_ context.Context, r *gctrpc.Up errors.New("cannot auto pair update for exchange, a manual update is needed") } - err = exch.UpdateTradablePairs(false) + err = exch.UpdateTradablePairs(ctx, false) if err != nil { return nil, err } @@ -3280,7 +3295,7 @@ func (s *RPCServer) GetHistoricTrades(r *gctrpc.GetSavedTradesRequest, stream gc for iterateStartTime := start; iterateStartTime.Before(end); iterateStartTime = iterateStartTime.Add(time.Hour) { iterateEndTime := iterateStartTime.Add(time.Hour) - trades, err = exch.GetHistoricTrades(cp, a, iterateStartTime, iterateEndTime) + trades, err = exch.GetHistoricTrades(stream.Context(), cp, a, iterateStartTime, iterateEndTime) if err != nil { return err } @@ -3315,7 +3330,7 @@ func (s *RPCServer) GetHistoricTrades(r *gctrpc.GetSavedTradesRequest, stream gc } // GetRecentTrades returns trades -func (s *RPCServer) GetRecentTrades(_ context.Context, r *gctrpc.GetSavedTradesRequest) (*gctrpc.SavedTradesResponse, error) { +func (s *RPCServer) GetRecentTrades(ctx context.Context, r *gctrpc.GetSavedTradesRequest) (*gctrpc.SavedTradesResponse, error) { if r.Exchange == "" || r.Pair == nil || r.AssetType == "" || r.Pair.String() == "" { return nil, errInvalidArguments } @@ -3340,7 +3355,7 @@ func (s *RPCServer) GetRecentTrades(_ context.Context, r *gctrpc.GetSavedTradesR return nil, err } var trades []trade.Data - trades, err = exch.GetRecentTrades(cp, asset.Item(r.AssetType)) + trades, err = exch.GetRecentTrades(ctx, cp, asset.Item(r.AssetType)) if err != nil { return nil, err } diff --git a/engine/rpcserver_test.go b/engine/rpcserver_test.go index 283dc5da..2ee65162 100644 --- a/engine/rpcserver_test.go +++ b/engine/rpcserver_test.go @@ -36,6 +36,7 @@ import ( "github.com/thrasher-corp/gocryptotrader/portfolio/banking" "github.com/thrasher-corp/gocryptotrader/portfolio/withdraw" "github.com/thrasher-corp/goose" + "google.golang.org/grpc/metadata" ) const ( @@ -50,7 +51,7 @@ type fExchange struct { exchange.IBotExchange } -func (f fExchange) GetHistoricCandles(p currency.Pair, a asset.Item, timeStart, _ time.Time, interval kline.Interval) (kline.Item, error) { +func (f fExchange) GetHistoricCandles(ctx context.Context, p currency.Pair, a asset.Item, timeStart, _ time.Time, interval kline.Interval) (kline.Item, error) { return kline.Item{ Exchange: "fake", Pair: p, @@ -69,7 +70,7 @@ func (f fExchange) GetHistoricCandles(p currency.Pair, a asset.Item, timeStart, }, nil } -func (f fExchange) GetHistoricCandlesExtended(p currency.Pair, a asset.Item, timeStart, _ time.Time, interval kline.Interval) (kline.Item, error) { +func (f fExchange) GetHistoricCandlesExtended(ctx context.Context, p currency.Pair, a asset.Item, timeStart, _ time.Time, interval kline.Interval) (kline.Item, error) { return kline.Item{ Exchange: "fake", Pair: p, @@ -90,7 +91,7 @@ func (f fExchange) GetHistoricCandlesExtended(p currency.Pair, a asset.Item, tim // FetchAccountInfo overrides testExchange's fetch account info function // to do the bare minimum required with no API calls or credentials required -func (f fExchange) FetchAccountInfo(a asset.Item) (account.Holdings, error) { +func (f fExchange) FetchAccountInfo(ctx context.Context, a asset.Item) (account.Holdings, error) { return account.Holdings{ Exchange: f.GetName(), Accounts: []account.SubAccount{ @@ -105,7 +106,7 @@ func (f fExchange) FetchAccountInfo(a asset.Item) (account.Holdings, error) { // UpdateAccountInfo overrides testExchange's update account info function // to do the bare minimum required with no API calls or credentials required -func (f fExchange) UpdateAccountInfo(a asset.Item) (account.Holdings, error) { +func (f fExchange) UpdateAccountInfo(ctx context.Context, a asset.Item) (account.Holdings, error) { if a == asset.Futures { return account.Holdings{}, errAssetTypeDisabled } @@ -875,6 +876,18 @@ func TestGetRecentTrades(t *testing.T) { } } +// dummyServer implements a basic RPC server interface for deployment in a test +// when streaming occurs, so we can deliver a context value. +type dummyServer struct{} + +func (d *dummyServer) Send(*gctrpc.SavedTradesResponse) error { return nil } +func (d *dummyServer) SetHeader(metadata.MD) error { return nil } +func (d *dummyServer) SendHeader(metadata.MD) error { return nil } +func (d *dummyServer) SetTrailer(metadata.MD) {} +func (d *dummyServer) Context() context.Context { return context.Background() } +func (d *dummyServer) SendMsg(m interface{}) error { return nil } +func (d *dummyServer) RecvMsg(m interface{}) error { return nil } + func TestGetHistoricTrades(t *testing.T) { engerino := RPCTestSetup(t) defer CleanRPCTest(t, engerino) @@ -907,7 +920,7 @@ func TestGetHistoricTrades(t *testing.T) { AssetType: asset.Spot.String(), Start: time.Date(2020, 0, 0, 0, 0, 0, 0, time.UTC).Format(common.SimpleTimeFormat), End: time.Date(2020, 0, 0, 1, 0, 0, 0, time.UTC).Format(common.SimpleTimeFormat), - }, nil) + }, &dummyServer{}) if err != common.ErrFunctionNotSupported { t.Error(err) } diff --git a/engine/subsystem_types.go b/engine/subsystem_types.go index 7d6c5337..978d2653 100644 --- a/engine/subsystem_types.go +++ b/engine/subsystem_types.go @@ -1,6 +1,7 @@ package engine import ( + "context" "errors" "github.com/thrasher-corp/gocryptotrader/communications/base" @@ -54,7 +55,7 @@ type iCommsManager interface { type iOrderManager interface { Exists(*order.Detail) bool Add(*order.Detail) error - Cancel(*order.Cancel) error + Cancel(context.Context, *order.Cancel) error GetByExchangeAndID(string, string) (*order.Detail, error) UpdateExistingOrder(*order.Detail) error } diff --git a/engine/sync_manager.go b/engine/sync_manager.go index bc681e08..2ea58c3b 100644 --- a/engine/sync_manager.go +++ b/engine/sync_manager.go @@ -1,6 +1,7 @@ package engine import ( + "context" "errors" "fmt" "strconv" @@ -561,7 +562,9 @@ func (m *syncManager) worker() { } m.setProcessing(c.Exchange, c.Pair, c.AssetType, SyncItemOrderbook, true) - result, err := exchanges[x].UpdateOrderbook(c.Pair, c.AssetType) + result, err := exchanges[x].UpdateOrderbook(context.TODO(), + c.Pair, + c.AssetType) m.PrintOrderbookSummary(result, "REST", err) if err == nil { if m.remoteConfig.WebsocketRPC.Enabled { @@ -621,9 +624,9 @@ func (m *syncManager) worker() { if m.config.Verbose { log.Debugf(log.SyncMgr, "Initialising %s REST ticker batching", exchangeName) } - err = exchanges[x].UpdateTickers(c.AssetType) + err = exchanges[x].UpdateTickers(context.TODO(), c.AssetType) if err == nil { - result, err = exchanges[x].FetchTicker(c.Pair, c.AssetType) + result, err = exchanges[x].FetchTicker(context.TODO(), c.Pair, c.AssetType) } m.tickerBatchLastRequested[exchangeName] = time.Now() m.mux.Unlock() @@ -631,10 +634,14 @@ func (m *syncManager) worker() { if m.config.Verbose { log.Debugf(log.SyncMgr, "%s Using recent batching cache", exchangeName) } - result, err = exchanges[x].FetchTicker(c.Pair, c.AssetType) + result, err = exchanges[x].FetchTicker(context.TODO(), + c.Pair, + c.AssetType) } } else { - result, err = exchanges[x].UpdateTicker(c.Pair, c.AssetType) + result, err = exchanges[x].UpdateTicker(context.TODO(), + c.Pair, + c.AssetType) } m.PrintTickerSummary(result, "REST", err) if err == nil { diff --git a/engine/withdraw_manager.go b/engine/withdraw_manager.go index 27e834b9..2e3b655a 100644 --- a/engine/withdraw_manager.go +++ b/engine/withdraw_manager.go @@ -1,6 +1,7 @@ package engine import ( + "context" "errors" "fmt" "time" @@ -24,7 +25,7 @@ func SetupWithdrawManager(em iExchangeManager, pm iPortfolioManager, isDryRun bo // SubmitWithdrawal performs validation and submits a new withdraw request to // exchange -func (m *WithdrawManager) SubmitWithdrawal(req *withdraw.Request) (*withdraw.Response, error) { +func (m *WithdrawManager) SubmitWithdrawal(ctx context.Context, req *withdraw.Request) (*withdraw.Response, error) { if m == nil { return nil, ErrNilSubsystem } @@ -60,7 +61,7 @@ func (m *WithdrawManager) SubmitWithdrawal(req *withdraw.Request) (*withdraw.Res } } if req.Type == withdraw.Fiat { - ret, err = exch.WithdrawFiatFunds(req) + ret, err = exch.WithdrawFiatFunds(ctx, req) if err != nil { resp.Exchange.Status = err.Error() } else { @@ -68,7 +69,7 @@ func (m *WithdrawManager) SubmitWithdrawal(req *withdraw.Request) (*withdraw.Res resp.Exchange.ID = ret.ID } } else if req.Type == withdraw.Crypto { - ret, err = exch.WithdrawCryptocurrencyFunds(req) + ret, err = exch.WithdrawCryptocurrencyFunds(ctx, req) if err != nil { resp.Exchange.Status = err.Error() } else { diff --git a/engine/withdraw_manager_test.go b/engine/withdraw_manager_test.go index 695a3449..ed0364e4 100644 --- a/engine/withdraw_manager_test.go +++ b/engine/withdraw_manager_test.go @@ -1,6 +1,7 @@ package engine import ( + "context" "errors" "sync" "testing" @@ -69,7 +70,7 @@ func TestSubmitWithdrawal(t *testing.T) { Bank: bank, }, } - _, err = m.SubmitWithdrawal(req) + _, err = m.SubmitWithdrawal(context.Background(), req) if !errors.Is(err, common.ErrFunctionNotSupported) { t.Errorf("received %v, expected %v", err, common.ErrFunctionNotSupported) } @@ -77,7 +78,7 @@ func TestSubmitWithdrawal(t *testing.T) { req.Type = withdraw.Crypto req.Currency = currency.BTC req.Crypto.Address = "1337" - _, err = m.SubmitWithdrawal(req) + _, err = m.SubmitWithdrawal(context.Background(), req) if !errors.Is(err, withdraw.ErrStrAddressNotWhiteListed) { t.Errorf("received %v, expected %v", err, withdraw.ErrStrAddressNotWhiteListed) } @@ -95,24 +96,24 @@ func TestSubmitWithdrawal(t *testing.T) { if !errors.Is(err, nil) { t.Errorf("received %v, expected %v", err, nil) } - _, err = m.SubmitWithdrawal(req) + _, err = m.SubmitWithdrawal(context.Background(), req) if !errors.Is(err, withdraw.ErrStrExchangeNotSupportedByAddress) { t.Errorf("received %v, expected %v", err, withdraw.ErrStrExchangeNotSupportedByAddress) } adds[0].SupportedExchanges = exchangeName - _, err = m.SubmitWithdrawal(req) + _, err = m.SubmitWithdrawal(context.Background(), req) if !errors.Is(err, exchange.ErrAuthenticatedRequestWithoutCredentialsSet) { t.Errorf("received %v, expected %v", err, exchange.ErrAuthenticatedRequestWithoutCredentialsSet) } - _, err = m.SubmitWithdrawal(nil) + _, err = m.SubmitWithdrawal(context.Background(), nil) if !errors.Is(err, withdraw.ErrRequestCannotBeNil) { t.Errorf("received %v, expected %v", err, withdraw.ErrRequestCannotBeNil) } m.isDryRun = true - _, err = m.SubmitWithdrawal(req) + _, err = m.SubmitWithdrawal(context.Background(), req) if !errors.Is(err, nil) { t.Errorf("received %v, expected %v", err, nil) } diff --git a/exchanges/alphapoint/alphapoint.go b/exchanges/alphapoint/alphapoint.go index 68e1d490..485879f1 100644 --- a/exchanges/alphapoint/alphapoint.go +++ b/exchanges/alphapoint/alphapoint.go @@ -53,12 +53,17 @@ type Alphapoint struct { // GetTicker returns current ticker information from Alphapoint for a selected // currency pair ie "BTCUSD" -func (a *Alphapoint) GetTicker(currencyPair string) (Ticker, error) { +func (a *Alphapoint) GetTicker(ctx context.Context, currencyPair string) (Ticker, error) { req := make(map[string]interface{}) req["productPair"] = currencyPair response := Ticker{} - err := a.SendHTTPRequest(exchange.RestSpot, http.MethodPost, alphapointTicker, req, &response) + err := a.SendHTTPRequest(ctx, + exchange.RestSpot, + http.MethodPost, + alphapointTicker, + req, + &response) if err != nil { return response, err } @@ -74,14 +79,15 @@ func (a *Alphapoint) GetTicker(currencyPair string) (Ticker, error) { // AlphaPoint Exchange. To begin from the most recent trade, set startIndex to // 0 (default: 0) // Count: specifies the number of trades to return (default: 10) -func (a *Alphapoint) GetTrades(currencyPair string, startIndex, count int) (Trades, error) { +func (a *Alphapoint) GetTrades(ctx context.Context, currencyPair string, startIndex, count int) (Trades, error) { req := make(map[string]interface{}) req["ins"] = currencyPair req["startIndex"] = startIndex req["Count"] = count response := Trades{} - err := a.SendHTTPRequest(exchange.RestSpot, http.MethodPost, alphapointTrades, req, &response) + err := a.SendHTTPRequest(ctx, + exchange.RestSpot, http.MethodPost, alphapointTrades, req, &response) if err != nil { return response, err } @@ -95,14 +101,19 @@ func (a *Alphapoint) GetTrades(currencyPair string, startIndex, count int) (Trad // CurrencyPair - instrument code (ex: “BTCUSD”) // StartDate - specifies the starting time in epoch time, type is long // EndDate - specifies the end time in epoch time, type is long -func (a *Alphapoint) GetTradesByDate(currencyPair string, startDate, endDate int64) (Trades, error) { +func (a *Alphapoint) GetTradesByDate(ctx context.Context, currencyPair string, startDate, endDate int64) (Trades, error) { req := make(map[string]interface{}) req["ins"] = currencyPair req["startDate"] = startDate req["endDate"] = endDate response := Trades{} - err := a.SendHTTPRequest(exchange.RestSpot, http.MethodPost, alphapointTradesByDate, req, &response) + err := a.SendHTTPRequest(ctx, + exchange.RestSpot, + http.MethodPost, + alphapointTradesByDate, + req, + &response) if err != nil { return response, err } @@ -114,12 +125,13 @@ func (a *Alphapoint) GetTradesByDate(currencyPair string, startDate, endDate int // GetOrderbook fetches the current orderbook for a given currency pair // CurrencyPair - trade pair (ex: “BTCUSD”) -func (a *Alphapoint) GetOrderbook(currencyPair string) (Orderbook, error) { +func (a *Alphapoint) GetOrderbook(ctx context.Context, currencyPair string) (Orderbook, error) { req := make(map[string]interface{}) req["productPair"] = currencyPair response := Orderbook{} - err := a.SendHTTPRequest(exchange.RestSpot, http.MethodPost, alphapointOrderbook, req, &response) + err := a.SendHTTPRequest(ctx, + exchange.RestSpot, http.MethodPost, alphapointOrderbook, req, &response) if err != nil { return response, err } @@ -130,10 +142,11 @@ func (a *Alphapoint) GetOrderbook(currencyPair string) (Orderbook, error) { } // GetProductPairs gets the currency pairs currently traded on alphapoint -func (a *Alphapoint) GetProductPairs() (ProductPairs, error) { +func (a *Alphapoint) GetProductPairs(ctx context.Context) (ProductPairs, error) { response := ProductPairs{} - err := a.SendHTTPRequest(exchange.RestSpot, http.MethodPost, alphapointProductPairs, nil, &response) + err := a.SendHTTPRequest(ctx, + exchange.RestSpot, http.MethodPost, alphapointProductPairs, nil, &response) if err != nil { return response, err } @@ -144,10 +157,11 @@ func (a *Alphapoint) GetProductPairs() (ProductPairs, error) { } // GetProducts gets the currency products currently supported on alphapoint -func (a *Alphapoint) GetProducts() (Products, error) { +func (a *Alphapoint) GetProducts(ctx context.Context) (Products, error) { response := Products{} - err := a.SendHTTPRequest(exchange.RestSpot, http.MethodPost, alphapointProducts, nil, &response) + err := a.SendHTTPRequest(ctx, + exchange.RestSpot, http.MethodPost, alphapointProducts, nil, &response) if err != nil { return response, err } @@ -163,7 +177,7 @@ func (a *Alphapoint) GetProducts() (Products, error) { // Email - Email address // Phone - Phone number (ex: “+12223334444”) // Password - Minimum 8 characters -func (a *Alphapoint) CreateAccount(firstName, lastName, email, phone, password string) error { +func (a *Alphapoint) CreateAccount(ctx context.Context, firstName, lastName, email, phone, password string) error { if len(password) < 8 { return errors.New( "alphapoint Error - Create account - Password must be 8 characters or more", @@ -178,7 +192,8 @@ func (a *Alphapoint) CreateAccount(firstName, lastName, email, phone, password s req["password"] = password response := Response{} - err := a.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, alphapointCreateAccount, req, &response) + err := a.SendAuthenticatedHTTPRequest(ctx, + exchange.RestSpot, http.MethodPost, alphapointCreateAccount, req, &response) if err != nil { return fmt.Errorf("unable to create account. Reason: %s", err) } @@ -189,10 +204,15 @@ func (a *Alphapoint) CreateAccount(firstName, lastName, email, phone, password s } // GetUserInfo returns current account user information -func (a *Alphapoint) GetUserInfo() (UserInfo, error) { +func (a *Alphapoint) GetUserInfo(ctx context.Context) (UserInfo, error) { response := UserInfo{} - err := a.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, alphapointUserInfo, map[string]interface{}{}, &response) + err := a.SendAuthenticatedHTTPRequest(ctx, + exchange.RestSpot, + http.MethodPost, + alphapointUserInfo, + map[string]interface{}{}, + &response) if err != nil { return UserInfo{}, err } @@ -211,7 +231,7 @@ func (a *Alphapoint) GetUserInfo() (UserInfo, error) { // Cell2FAValue - Cell phone number, required for Authentication // Use2FAForWithdraw - “true” or “false” set to true for using 2FA for // withdrawals -func (a *Alphapoint) SetUserInfo(firstName, lastName, cell2FACountryCode, cell2FAValue string, useAuthy2FA, use2FAForWithdraw bool) (UserInfoSet, error) { +func (a *Alphapoint) SetUserInfo(ctx context.Context, firstName, lastName, cell2FACountryCode, cell2FAValue string, useAuthy2FA, use2FAForWithdraw bool) (UserInfoSet, error) { response := UserInfoSet{} var userInfoKVPs = []UserInfoKVP{ @@ -244,7 +264,7 @@ func (a *Alphapoint) SetUserInfo(firstName, lastName, cell2FACountryCode, cell2F req := make(map[string]interface{}) req["userInfoKVP"] = userInfoKVPs - err := a.SendAuthenticatedHTTPRequest( + err := a.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, alphapointUserInfo, @@ -261,10 +281,10 @@ func (a *Alphapoint) SetUserInfo(firstName, lastName, cell2FACountryCode, cell2F } // GetAccountInformation returns account info -func (a *Alphapoint) GetAccountInformation() (AccountInfo, error) { +func (a *Alphapoint) GetAccountInformation(ctx context.Context) (AccountInfo, error) { response := AccountInfo{} - err := a.SendAuthenticatedHTTPRequest( + err := a.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, alphapointAccountInfo, @@ -284,14 +304,14 @@ func (a *Alphapoint) GetAccountInformation() (AccountInfo, error) { // CurrencyPair - Instrument code (ex: “BTCUSD”) // StartIndex - Starting index, if less than 0 then start from the beginning // Count - Returns last trade, (Default: 30) -func (a *Alphapoint) GetAccountTrades(currencyPair string, startIndex, count int) (Trades, error) { +func (a *Alphapoint) GetAccountTrades(ctx context.Context, currencyPair string, startIndex, count int) (Trades, error) { req := make(map[string]interface{}) req["ins"] = currencyPair req["startIndex"] = startIndex req["count"] = count response := Trades{} - err := a.SendAuthenticatedHTTPRequest( + err := a.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, alphapointAccountTrades, @@ -308,11 +328,15 @@ func (a *Alphapoint) GetAccountTrades(currencyPair string, startIndex, count int } // GetDepositAddresses generates a deposit address -func (a *Alphapoint) GetDepositAddresses() ([]DepositAddresses, error) { +func (a *Alphapoint) GetDepositAddresses(ctx context.Context) ([]DepositAddresses, error) { response := Response{} - err := a.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, alphapointDepositAddresses, - map[string]interface{}{}, &response, + err := a.SendAuthenticatedHTTPRequest(ctx, + exchange.RestSpot, + http.MethodPost, + alphapointDepositAddresses, + map[string]interface{}{}, + &response, ) if err != nil { return nil, err @@ -328,7 +352,7 @@ func (a *Alphapoint) GetDepositAddresses() ([]DepositAddresses, error) { // product - Currency name (ex: “BTC”) // amount - Amount (ex: “.011”) // address - Withdraw address -func (a *Alphapoint) WithdrawCoins(symbol, product, address string, amount float64) error { +func (a *Alphapoint) WithdrawCoins(ctx context.Context, symbol, product, address string, amount float64) error { req := make(map[string]interface{}) req["ins"] = symbol req["product"] = product @@ -336,7 +360,7 @@ func (a *Alphapoint) WithdrawCoins(symbol, product, address string, amount float req["sendToAddress"] = address response := Response{} - err := a.SendAuthenticatedHTTPRequest( + err := a.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, alphapointWithdraw, @@ -366,7 +390,7 @@ func (a *Alphapoint) convertOrderTypeToOrderTypeNumber(orderType string) (orderT // orderType - “1” for market orders, “0” for limit orders // quantity - Quantity // price - Price in USD -func (a *Alphapoint) CreateOrder(symbol, side, orderType string, quantity, price float64) (int64, error) { +func (a *Alphapoint) CreateOrder(ctx context.Context, symbol, side, orderType string, quantity, price float64) (int64, error) { orderTypeNumber := a.convertOrderTypeToOrderTypeNumber(orderType) req := make(map[string]interface{}) req["ins"] = symbol @@ -376,7 +400,7 @@ func (a *Alphapoint) CreateOrder(symbol, side, orderType string, quantity, price req["px"] = strconv.FormatFloat(price, 'f', -1, 64) response := Response{} - err := a.SendAuthenticatedHTTPRequest( + err := a.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, alphapointCreateOrder, @@ -400,14 +424,14 @@ func (a *Alphapoint) CreateOrder(symbol, side, orderType string, quantity, price // book. A buy order will be modified to the highest bid and a sell order will // be modified to the lowest ask price. “1” means "Execute now", which will // convert a limit order into a market order. -func (a *Alphapoint) ModifyExistingOrder(symbol string, orderID, action int64) (int64, error) { +func (a *Alphapoint) ModifyExistingOrder(ctx context.Context, symbol string, orderID, action int64) (int64, error) { req := make(map[string]interface{}) req["ins"] = symbol req["serverOrderId"] = orderID req["modifyAction"] = action response := Response{} - err := a.SendAuthenticatedHTTPRequest( + err := a.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, alphapointModifyOrder, @@ -426,13 +450,13 @@ func (a *Alphapoint) ModifyExistingOrder(symbol string, orderID, action int64) ( // CancelExistingOrder cancels an order that has not been executed. // symbol - Instrument code (ex: “BTCUSD”) // OrderId - Order id (ex: 1000) -func (a *Alphapoint) CancelExistingOrder(orderID int64, omsid string) (int64, error) { +func (a *Alphapoint) CancelExistingOrder(ctx context.Context, orderID int64, omsid string) (int64, error) { req := make(map[string]interface{}) req["OrderId"] = orderID req["OMSId"] = omsid response := Response{} - err := a.SendAuthenticatedHTTPRequest( + err := a.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, alphapointCancelOrder, @@ -450,12 +474,12 @@ func (a *Alphapoint) CancelExistingOrder(orderID int64, omsid string) (int64, er // CancelAllExistingOrders cancels all open orders by symbol // symbol - Instrument code (ex: “BTCUSD”) -func (a *Alphapoint) CancelAllExistingOrders(omsid string) error { +func (a *Alphapoint) CancelAllExistingOrders(ctx context.Context, omsid string) error { req := make(map[string]interface{}) req["OMSId"] = omsid response := Response{} - err := a.SendAuthenticatedHTTPRequest( + err := a.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, alphapointCancelAllOrders, @@ -472,10 +496,10 @@ func (a *Alphapoint) CancelAllExistingOrders(omsid string) error { } // GetOrders returns all current open orders -func (a *Alphapoint) GetOrders() ([]OpenOrders, error) { +func (a *Alphapoint) GetOrders(ctx context.Context) ([]OpenOrders, error) { response := OrderInfo{} - err := a.SendAuthenticatedHTTPRequest( + err := a.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, alphapointOpenOrders, @@ -496,7 +520,7 @@ func (a *Alphapoint) GetOrders() ([]OpenOrders, error) { // side - “buy” or “sell” // quantity - Quantity // price - Price in USD -func (a *Alphapoint) GetOrderFee(symbol, side string, quantity, price float64) (float64, error) { +func (a *Alphapoint) GetOrderFee(ctx context.Context, symbol, side string, quantity, price float64) (float64, error) { req := make(map[string]interface{}) req["ins"] = symbol req["side"] = side @@ -504,7 +528,7 @@ func (a *Alphapoint) GetOrderFee(symbol, side string, quantity, price float64) ( req["px"] = strconv.FormatFloat(price, 'f', -1, 64) response := Response{} - err := a.SendAuthenticatedHTTPRequest( + err := a.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, alphapointOrderFee, @@ -521,7 +545,7 @@ func (a *Alphapoint) GetOrderFee(symbol, side string, quantity, price float64) ( } // SendHTTPRequest sends an unauthenticated HTTP request -func (a *Alphapoint) SendHTTPRequest(ep exchange.URL, method, path string, data map[string]interface{}, result interface{}) error { +func (a *Alphapoint) SendHTTPRequest(ctx context.Context, ep exchange.URL, method, path string, data map[string]interface{}, result interface{}) error { endpoint, err := a.API.Endpoints.GetURL(ep) if err != nil { return err @@ -551,7 +575,7 @@ func (a *Alphapoint) SendHTTPRequest(ep exchange.URL, method, path string, data } // SendAuthenticatedHTTPRequest sends an authenticated request -func (a *Alphapoint) SendAuthenticatedHTTPRequest(ep exchange.URL, method, path string, data map[string]interface{}, result interface{}) error { +func (a *Alphapoint) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, method, path string, data map[string]interface{}, result interface{}) error { if !a.AllowAuthenticatedRequest() { return fmt.Errorf("%s %w", a.Name, exchange.ErrAuthenticatedRequestWithoutCredentialsSet) } diff --git a/exchanges/alphapoint/alphapoint_test.go b/exchanges/alphapoint/alphapoint_test.go index 84bb3bf2..a2a34d4f 100644 --- a/exchanges/alphapoint/alphapoint_test.go +++ b/exchanges/alphapoint/alphapoint_test.go @@ -1,6 +1,7 @@ package alphapoint import ( + "context" "encoding/json" "os" "testing" @@ -41,12 +42,12 @@ func TestGetTicker(t *testing.T) { var ticker Ticker var err error if onlineTest { - ticker, err = a.GetTicker("BTCUSD") + ticker, err = a.GetTicker(context.Background(), "BTCUSD") if err != nil { t.Fatal("Alphapoint GetTicker init error: ", err) } - _, err = a.GetTicker("wigwham") + _, err = a.GetTicker(context.Background(), "wigwham") if err == nil { t.Error("Alphapoint GetTicker Expected error") } @@ -75,12 +76,12 @@ func TestGetTrades(t *testing.T) { var trades Trades var err error if onlineTest { - trades, err = a.GetTrades("BTCUSD", 0, 10) + trades, err = a.GetTrades(context.Background(), "BTCUSD", 0, 10) if err != nil { t.Fatalf("Init error: %s", err) } - _, err = a.GetTrades("wigwham", 0, 10) + _, err = a.GetTrades(context.Background(), "wigwham", 0, 10) if err == nil { t.Fatal("GetTrades Expected error") } @@ -113,11 +114,13 @@ func TestGetTradesByDate(t *testing.T) { var trades Trades var err error if onlineTest { - trades, err = a.GetTradesByDate("BTCUSD", 1414799400, 1414800000) + trades, err = a.GetTradesByDate(context.Background(), + "BTCUSD", 1414799400, 1414800000) if err != nil { t.Errorf("Init error: %s", err) } - _, err = a.GetTradesByDate("wigwham", 1414799400, 1414800000) + _, err = a.GetTradesByDate(context.Background(), + "wigwham", 1414799400, 1414800000) if err == nil { t.Error("GetTradesByDate Expected error") } @@ -157,12 +160,12 @@ func TestGetOrderbook(t *testing.T) { var orderBook Orderbook var err error if onlineTest { - orderBook, err = a.GetOrderbook("BTCUSD") + orderBook, err = a.GetOrderbook(context.Background(), "BTCUSD") if err != nil { t.Errorf("Init error: %s", err) } - _, err = a.GetOrderbook("wigwham") + _, err = a.GetOrderbook(context.Background(), "wigwham") if err == nil { t.Error("GetOrderbook() Expected error") } @@ -200,7 +203,7 @@ func TestGetProductPairs(t *testing.T) { var err error if onlineTest { - products, err = a.GetProductPairs() + products, err = a.GetProductPairs(context.Background()) if err != nil { t.Errorf("Init error: %s", err) } @@ -238,7 +241,7 @@ func TestGetProducts(t *testing.T) { var err error if onlineTest { - products, err = a.GetProducts() + products, err = a.GetProducts(context.Background()) if err != nil { t.Errorf("Init error: %s", err) } @@ -276,15 +279,17 @@ func TestCreateAccount(t *testing.T) { t.Skip("API keys not set, skipping") } - err := a.CreateAccount("test", "account", "something@something.com", "0292383745", "lolcat123") + err := a.CreateAccount(context.Background(), + "test", "account", "something@something.com", "0292383745", "lolcat123") if err != nil { t.Errorf("Init error: %s", err) } - err = a.CreateAccount("test", "account", "something@something.com", "0292383745", "bla") + err = a.CreateAccount(context.Background(), + "test", "account", "something@something.com", "0292383745", "bla") if err == nil { t.Errorf("CreateAccount() Expected error") } - err = a.CreateAccount("", "", "", "", "lolcat123") + err = a.CreateAccount(context.Background(), "", "", "", "", "lolcat123") if err == nil { t.Errorf("CreateAccount() Expected error") } @@ -296,7 +301,7 @@ func TestGetUserInfo(t *testing.T) { t.Skip("API keys not set, skipping") } - _, err := a.GetUserInfo() + _, err := a.GetUserInfo(context.Background()) if err == nil { t.Error("GetUserInfo() Expected error") } @@ -308,7 +313,8 @@ func TestSetUserInfo(t *testing.T) { t.Skip("API keys not set, skipping") } - _, err := a.SetUserInfo("bla", "bla", "1", "meh", true, true) + _, err := a.SetUserInfo(context.Background(), + "bla", "bla", "1", "meh", true, true) if err == nil { t.Error("GetUserInfo() Expected error") } @@ -320,7 +326,7 @@ func TestGetAccountInfo(t *testing.T) { t.Skip("API keys not set, skipping") } - _, err := a.UpdateAccountInfo(asset.Spot) + _, err := a.UpdateAccountInfo(context.Background(), asset.Spot) if err == nil { t.Error("GetUserInfo() Expected error") } @@ -332,7 +338,7 @@ func TestGetAccountTrades(t *testing.T) { t.Skip("API keys not set, skipping") } - _, err := a.GetAccountTrades("", 1, 2) + _, err := a.GetAccountTrades(context.Background(), "", 1, 2) if err == nil { t.Error("GetUserInfo() Expected error") } @@ -344,7 +350,7 @@ func TestGetDepositAddresses(t *testing.T) { t.Skip("API keys not set, skipping") } - _, err := a.GetDepositAddresses() + _, err := a.GetDepositAddresses(context.Background()) if err == nil { t.Error("GetUserInfo() Expected error") } @@ -356,7 +362,7 @@ func TestWithdrawCoins(t *testing.T) { t.Skip("API keys not set, skipping") } - err := a.WithdrawCoins("", "", "", 0.01) + err := a.WithdrawCoins(context.Background(), "", "", "", 0.01) if err == nil { t.Error("GetUserInfo() Expected error") } @@ -368,7 +374,8 @@ func TestCreateOrder(t *testing.T) { t.Skip("API keys not set, skipping") } - _, err := a.CreateOrder("", "", order.Limit.String(), 0.01, 0) + _, err := a.CreateOrder(context.Background(), + "", "", order.Limit.String(), 0.01, 0) if err == nil { t.Error("GetUserInfo() Expected error") } @@ -380,7 +387,7 @@ func TestModifyExistingOrder(t *testing.T) { t.Skip("API keys not set, skipping") } - _, err := a.ModifyExistingOrder("", 1, 1) + _, err := a.ModifyExistingOrder(context.Background(), "", 1, 1) if err == nil { t.Error("GetUserInfo() Expected error") } @@ -392,7 +399,7 @@ func TestCancelAllExistingOrders(t *testing.T) { t.Skip("API keys not set, skipping") } - err := a.CancelAllExistingOrders("") + err := a.CancelAllExistingOrders(context.Background(), "") if err == nil { t.Error("GetUserInfo() Expected error") } @@ -404,7 +411,7 @@ func TestGetOrders(t *testing.T) { t.Skip("API keys not set, skipping") } - _, err := a.GetOrders() + _, err := a.GetOrders(context.Background()) if err == nil { t.Error("GetUserInfo() Expected error") } @@ -416,7 +423,7 @@ func TestGetOrderFee(t *testing.T) { t.Skip("API keys not set, skipping") } - _, err := a.GetOrderFee("", "", 1, 1) + _, err := a.GetOrderFee(context.Background(), "", "", 1, 1) if err == nil { t.Error("GetUserInfo() Expected error") } @@ -438,7 +445,7 @@ func TestGetActiveOrders(t *testing.T) { AssetType: asset.Spot, } - _, err := a.GetActiveOrders(&getOrdersRequest) + _, err := a.GetActiveOrders(context.Background(), &getOrdersRequest) if areTestAPIKeysSet() && err != nil { t.Errorf("Could not get open orders: %s", err) } else if !areTestAPIKeysSet() && err == nil { @@ -453,7 +460,7 @@ func TestGetOrderHistory(t *testing.T) { AssetType: asset.Spot, } - _, err := a.GetOrderHistory(&getOrdersRequest) + _, err := a.GetOrderHistory(context.Background(), &getOrdersRequest) if areTestAPIKeysSet() && err != nil { t.Errorf("Could not get order history: %s", err) } else if !areTestAPIKeysSet() && err == nil { @@ -484,7 +491,7 @@ func TestSubmitOrder(t *testing.T) { AssetType: asset.Spot, } - response, err := a.SubmitOrder(orderSubmission) + response, err := a.SubmitOrder(context.Background(), orderSubmission) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") } @@ -512,7 +519,7 @@ func TestCancelExchangeOrder(t *testing.T) { AssetType: asset.Spot, } - err := a.CancelOrder(orderCancellation) + err := a.CancelOrder(context.Background(), orderCancellation) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") } @@ -536,7 +543,7 @@ func TestCancelAllExchangeOrders(t *testing.T) { AssetType: asset.Spot, } - resp, err := a.CancelAllOrders(orderCancellation) + resp, err := a.CancelAllOrders(context.Background(), orderCancellation) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") } @@ -562,7 +569,8 @@ func TestModifyOrder(t *testing.T) { func TestWithdraw(t *testing.T) { t.Parallel() - _, err := a.WithdrawCryptocurrencyFunds(&withdraw.Request{}) + _, err := a.WithdrawCryptocurrencyFunds(context.Background(), + &withdraw.Request{}) if err != common.ErrNotYetImplemented { t.Errorf("Expected 'Not implemented', received %v", err) } @@ -574,7 +582,8 @@ func TestWithdrawFiat(t *testing.T) { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - _, err := a.WithdrawFiatFunds(&withdraw.Request{}) + _, err := a.WithdrawFiatFunds(context.Background(), + &withdraw.Request{}) if err != common.ErrNotYetImplemented { t.Errorf("Expected '%v', received: '%v'", common.ErrNotYetImplemented, err) } @@ -610,7 +619,8 @@ func TestGetHistoricTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = a.GetHistoricTrades(currencyPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) + _, err = a.GetHistoricTrades(context.Background(), + currencyPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) if err != nil && err != common.ErrNotYetImplemented { t.Error(err) } diff --git a/exchanges/alphapoint/alphapoint_wrapper.go b/exchanges/alphapoint/alphapoint_wrapper.go index 2a06c750..331b39fc 100644 --- a/exchanges/alphapoint/alphapoint_wrapper.go +++ b/exchanges/alphapoint/alphapoint_wrapper.go @@ -1,6 +1,7 @@ package alphapoint import ( + "context" "errors" "strconv" "time" @@ -77,22 +78,22 @@ func (a *Alphapoint) SetDefaults() { } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (a *Alphapoint) FetchTradablePairs(asset asset.Item) ([]string, error) { +func (a *Alphapoint) FetchTradablePairs(ctx context.Context, asset asset.Item) ([]string, error) { return nil, common.ErrFunctionNotSupported } // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (a *Alphapoint) UpdateTradablePairs(forceUpdate bool) error { +func (a *Alphapoint) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { return common.ErrFunctionNotSupported } // UpdateAccountInfo retrieves balances for all enabled currencies on the // Alphapoint exchange -func (a *Alphapoint) UpdateAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (a *Alphapoint) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { var response account.Holdings response.Exchange = a.Name - acc, err := a.GetAccountInformation() + acc, err := a.GetAccountInformation(ctx) if err != nil { return response, err } @@ -121,10 +122,10 @@ func (a *Alphapoint) UpdateAccountInfo(assetType asset.Item) (account.Holdings, // FetchAccountInfo retrieves balances for all enabled currencies on the // Alphapoint exchange -func (a *Alphapoint) FetchAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (a *Alphapoint) FetchAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { acc, err := account.GetHoldings(a.Name, assetType) if err != nil { - return a.UpdateAccountInfo(assetType) + return a.UpdateAccountInfo(ctx, assetType) } return acc, nil @@ -136,8 +137,8 @@ func (a *Alphapoint) UpdateTickers(assetType asset.Item) error { } // UpdateTicker updates and returns the ticker for a currency pair -func (a *Alphapoint) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) { - tick, err := a.GetTicker(p.String()) +func (a *Alphapoint) UpdateTicker(ctx context.Context, p currency.Pair, assetType asset.Item) (*ticker.Price, error) { + tick, err := a.GetTicker(ctx, p.String()) if err != nil { return nil, err } @@ -161,18 +162,18 @@ func (a *Alphapoint) UpdateTicker(p currency.Pair, assetType asset.Item) (*ticke } // FetchTicker returns the ticker for a currency pair -func (a *Alphapoint) FetchTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) { +func (a *Alphapoint) FetchTicker(ctx context.Context, p currency.Pair, assetType asset.Item) (*ticker.Price, error) { tick, err := ticker.GetTicker(a.Name, p, assetType) if err != nil { - return a.UpdateTicker(p, assetType) + return a.UpdateTicker(ctx, p, assetType) } return tick, nil } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (a *Alphapoint) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (a *Alphapoint) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { orderBook := new(orderbook.Base) - orderbookNew, err := a.GetOrderbook(p.String()) + orderbookNew, err := a.GetOrderbook(ctx, p.String()) if err != nil { return orderBook, err } @@ -204,23 +205,23 @@ func (a *Alphapoint) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*or } // FetchOrderbook returns the orderbook for a currency pair -func (a *Alphapoint) FetchOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (a *Alphapoint) FetchOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { ob, err := orderbook.Get(a.Name, p, assetType) if err != nil { - return a.UpdateOrderbook(p, assetType) + return a.UpdateOrderbook(ctx, p, assetType) } return ob, nil } // GetFundingHistory returns funding history, deposits and // withdrawals -func (a *Alphapoint) GetFundingHistory() ([]exchange.FundHistory, error) { +func (a *Alphapoint) GetFundingHistory(ctx context.Context) ([]exchange.FundHistory, error) { // https://alphapoint.github.io/slate/#generatetreasuryactivityreport return nil, common.ErrNotYetImplemented } // GetWithdrawalsHistory returns previous withdrawals data -func (a *Alphapoint) GetWithdrawalsHistory(c currency.Code) (resp []exchange.WithdrawalHistory, err error) { +func (a *Alphapoint) GetWithdrawalsHistory(ctx context.Context, c currency.Code) (resp []exchange.WithdrawalHistory, err error) { return nil, common.ErrNotYetImplemented } @@ -230,13 +231,13 @@ func (a *Alphapoint) GetRecentTrades(_ currency.Pair, _ asset.Item) ([]trade.Dat } // GetHistoricTrades returns historic trade data within the timeframe provided -func (a *Alphapoint) GetHistoricTrades(_ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { +func (a *Alphapoint) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { return nil, common.ErrNotYetImplemented } // SubmitOrder submits a new order and returns a true value when // successfully submitted -func (a *Alphapoint) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { +func (a *Alphapoint) SubmitOrder(ctx context.Context, s *order.Submit) (order.SubmitResponse, error) { var submitOrderResponse order.SubmitResponse if err := s.Validate(); err != nil { return submitOrderResponse, err @@ -247,7 +248,8 @@ func (a *Alphapoint) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) return submitOrderResponse, err } - response, err := a.CreateOrder(fPair.String(), + response, err := a.CreateOrder(ctx, + fPair.String(), s.Side.String(), s.Type.String(), s.Amount, @@ -273,7 +275,7 @@ func (a *Alphapoint) ModifyOrder(_ *order.Modify) (order.Modify, error) { } // CancelOrder cancels an order by its corresponding ID number -func (a *Alphapoint) CancelOrder(o *order.Cancel) error { +func (a *Alphapoint) CancelOrder(ctx context.Context, o *order.Cancel) error { if err := o.Validate(o.StandardCancel()); err != nil { return err } @@ -281,27 +283,27 @@ func (a *Alphapoint) CancelOrder(o *order.Cancel) error { if err != nil { return err } - _, err = a.CancelExistingOrder(orderIDInt, o.AccountID) + _, err = a.CancelExistingOrder(ctx, orderIDInt, o.AccountID) return err } // CancelBatchOrders cancels an orders by their corresponding ID numbers -func (a *Alphapoint) CancelBatchOrders(o []order.Cancel) (order.CancelBatchResponse, error) { +func (a *Alphapoint) CancelBatchOrders(ctx context.Context, o []order.Cancel) (order.CancelBatchResponse, error) { return order.CancelBatchResponse{}, common.ErrNotYetImplemented } // CancelAllOrders cancels all orders for a given account -func (a *Alphapoint) CancelAllOrders(orderCancellation *order.Cancel) (order.CancelAllResponse, error) { +func (a *Alphapoint) CancelAllOrders(ctx context.Context, orderCancellation *order.Cancel) (order.CancelAllResponse, error) { if err := orderCancellation.Validate(); err != nil { return order.CancelAllResponse{}, err } return order.CancelAllResponse{}, - a.CancelAllExistingOrders(orderCancellation.AccountID) + a.CancelAllExistingOrders(ctx, orderCancellation.AccountID) } // GetOrderInfo returns order information based on order ID -func (a *Alphapoint) GetOrderInfo(orderID string, pair currency.Pair, assetType asset.Item) (float64, error) { - orders, err := a.GetOrders() +func (a *Alphapoint) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (float64, error) { + orders, err := a.GetOrders(ctx) if err != nil { return 0, err } @@ -317,8 +319,8 @@ func (a *Alphapoint) GetOrderInfo(orderID string, pair currency.Pair, assetType } // GetDepositAddress returns a deposit address for a specified currency -func (a *Alphapoint) GetDepositAddress(cryptocurrency currency.Code, _ string) (string, error) { - addreses, err := a.GetDepositAddresses() +func (a *Alphapoint) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _ string) (string, error) { + addreses, err := a.GetDepositAddresses(ctx) if err != nil { return "", err } @@ -333,12 +335,12 @@ func (a *Alphapoint) GetDepositAddress(cryptocurrency currency.Code, _ string) ( // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is // submitted -func (a *Alphapoint) WithdrawCryptocurrencyFunds(_ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (a *Alphapoint) WithdrawCryptocurrencyFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrNotYetImplemented } // WithdrawFiatFunds returns a withdrawal ID when a withdrawal is submitted -func (a *Alphapoint) WithdrawFiatFunds(_ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (a *Alphapoint) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrNotYetImplemented } @@ -355,11 +357,11 @@ func (a *Alphapoint) GetFeeByType(_ *exchange.FeeBuilder) (float64, error) { // GetActiveOrders retrieves any orders that are active/open // This function is not concurrency safe due to orderSide/orderType maps -func (a *Alphapoint) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, error) { +func (a *Alphapoint) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) { if err := req.Validate(); err != nil { return nil, err } - resp, err := a.GetOrders() + resp, err := a.GetOrders(ctx) if err != nil { return nil, err } @@ -400,12 +402,12 @@ func (a *Alphapoint) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detai // GetOrderHistory retrieves account order information // Can Limit response to specific order status // This function is not concurrency safe due to orderSide/orderType maps -func (a *Alphapoint) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, error) { +func (a *Alphapoint) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) { if err := req.Validate(); err != nil { return nil, err } - resp, err := a.GetOrders() + resp, err := a.GetOrders(ctx) if err != nil { return nil, err } @@ -445,7 +447,7 @@ func (a *Alphapoint) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detai // ValidateCredentials validates current credentials used for wrapper // functionality -func (a *Alphapoint) ValidateCredentials(assetType asset.Item) error { - _, err := a.UpdateAccountInfo(assetType) +func (a *Alphapoint) ValidateCredentials(ctx context.Context, assetType asset.Item) error { + _, err := a.UpdateAccountInfo(ctx, assetType) return a.CheckTransientError(err) } diff --git a/exchanges/binance/binance.go b/exchanges/binance/binance.go index 2b13f33b..193a6538 100644 --- a/exchanges/binance/binance.go +++ b/exchanges/binance/binance.go @@ -75,34 +75,39 @@ const ( ) // GetInterestHistory gets interest history for currency/currencies provided -func (b *Binance) GetInterestHistory() (MarginInfoData, error) { +func (b *Binance) GetInterestHistory(ctx context.Context) (MarginInfoData, error) { var resp MarginInfoData - if err := b.SendHTTPRequest(exchange.EdgeCase1, undocumentedInterestHistory, spotDefaultRate, &resp); err != nil { + if err := b.SendHTTPRequest(ctx, exchange.EdgeCase1, undocumentedInterestHistory, spotDefaultRate, &resp); err != nil { return resp, err } return resp, nil } // GetCrossMarginInterestHistory gets cross-margin interest history for currency/currencies provided -func (b *Binance) GetCrossMarginInterestHistory() (CrossMarginInterestData, error) { +func (b *Binance) GetCrossMarginInterestHistory(ctx context.Context) (CrossMarginInterestData, error) { var resp CrossMarginInterestData - if err := b.SendHTTPRequest(exchange.EdgeCase1, undocumentedCrossMarginInterestHistory, spotDefaultRate, &resp); err != nil { + if err := b.SendHTTPRequest(ctx, + exchange.EdgeCase1, + undocumentedCrossMarginInterestHistory, + spotDefaultRate, &resp); err != nil { return resp, err } return resp, nil } // GetMarginMarkets returns exchange information. Check binance_types for more information -func (b *Binance) GetMarginMarkets() (PerpsExchangeInfo, error) { +func (b *Binance) GetMarginMarkets(ctx context.Context) (PerpsExchangeInfo, error) { var resp PerpsExchangeInfo - return resp, b.SendHTTPRequest(exchange.RestSpot, perpExchangeInfo, spotDefaultRate, &resp) + return resp, b.SendHTTPRequest(ctx, + exchange.RestSpot, perpExchangeInfo, spotDefaultRate, &resp) } // GetExchangeInfo returns exchange information. Check binance_types for more // information -func (b *Binance) GetExchangeInfo() (ExchangeInfo, error) { +func (b *Binance) GetExchangeInfo(ctx context.Context) (ExchangeInfo, error) { var resp ExchangeInfo - return resp, b.SendHTTPRequest(exchange.RestSpotSupplementary, exchangeInfo, spotExchangeInfo, &resp) + return resp, b.SendHTTPRequest(ctx, + exchange.RestSpotSupplementary, exchangeInfo, spotExchangeInfo, &resp) } // GetOrderBook returns full orderbook information @@ -110,7 +115,7 @@ func (b *Binance) GetExchangeInfo() (ExchangeInfo, error) { // OrderBookDataRequestParams contains the following members // symbol: string of currency pair // limit: returned limit amount -func (b *Binance) GetOrderBook(obd OrderBookDataRequestParams) (OrderBook, error) { +func (b *Binance) GetOrderBook(ctx context.Context, obd OrderBookDataRequestParams) (OrderBook, error) { var orderbook OrderBook if err := b.CheckLimit(obd.Limit); err != nil { return orderbook, err @@ -125,7 +130,10 @@ func (b *Binance) GetOrderBook(obd OrderBookDataRequestParams) (OrderBook, error params.Set("limit", fmt.Sprintf("%d", obd.Limit)) var resp OrderBookData - if err := b.SendHTTPRequest(exchange.RestSpotSupplementary, orderBookDepth+"?"+params.Encode(), orderbookLimit(obd.Limit), &resp); err != nil { + if err := b.SendHTTPRequest(ctx, + exchange.RestSpotSupplementary, + orderBookDepth+"?"+params.Encode(), + orderbookLimit(obd.Limit), &resp); err != nil { return orderbook, err } @@ -169,7 +177,7 @@ func (b *Binance) GetOrderBook(obd OrderBookDataRequestParams) (OrderBook, error // GetMostRecentTrades returns recent trade activity // limit: Up to 500 results returned -func (b *Binance) GetMostRecentTrades(rtr RecentTradeRequestParams) ([]RecentTrade, error) { +func (b *Binance) GetMostRecentTrades(ctx context.Context, rtr RecentTradeRequestParams) ([]RecentTrade, error) { var resp []RecentTrade params := url.Values{} @@ -182,7 +190,8 @@ func (b *Binance) GetMostRecentTrades(rtr RecentTradeRequestParams) ([]RecentTra path := recentTrades + "?" + params.Encode() - return resp, b.SendHTTPRequest(exchange.RestSpotSupplementary, path, spotDefaultRate, &resp) + return resp, b.SendHTTPRequest(ctx, + exchange.RestSpotSupplementary, path, spotDefaultRate, &resp) } // GetHistoricalTrades returns historical trade activity @@ -190,7 +199,7 @@ func (b *Binance) GetMostRecentTrades(rtr RecentTradeRequestParams) ([]RecentTra // symbol: string of currency pair // limit: Optional. Default 500; max 1000. // fromID: -func (b *Binance) GetHistoricalTrades(symbol string, limit int, fromID int64) ([]HistoricalTrade, error) { +func (b *Binance) GetHistoricalTrades(ctx context.Context, symbol string, limit int, fromID int64) ([]HistoricalTrade, error) { var resp []HistoricalTrade params := url.Values{} @@ -202,14 +211,15 @@ func (b *Binance) GetHistoricalTrades(symbol string, limit int, fromID int64) ([ } path := historicalTrades + "?" + params.Encode() - return resp, b.SendAPIKeyHTTPRequest(exchange.RestSpotSupplementary, path, spotDefaultRate, &resp) + return resp, + b.SendAPIKeyHTTPRequest(ctx, exchange.RestSpotSupplementary, path, spotDefaultRate, &resp) } // GetAggregatedTrades returns aggregated trade activity. // If more than one hour of data is requested or asked limit is not supported by exchange // then the trades are collected with multiple backend requests. // https://binance-docs.github.io/apidocs/spot/en/#compressed-aggregate-trades-list -func (b *Binance) GetAggregatedTrades(arg *AggregatedTradeRequestParams) ([]AggregatedTrade, error) { +func (b *Binance) GetAggregatedTrades(ctx context.Context, arg *AggregatedTradeRequestParams) ([]AggregatedTrade, error) { params := url.Values{} symbol, err := b.FormatSymbol(arg.Symbol, asset.Spot) if err != nil { @@ -245,7 +255,7 @@ func (b *Binance) GetAggregatedTrades(arg *AggregatedTradeRequestParams) ([]Aggr canBatch := arg.FromID == 0 != arg.StartTime.IsZero() if canBatch { // Split the request into multiple - return b.batchAggregateTrades(arg, params) + return b.batchAggregateTrades(ctx, arg, params) } // Can't handle this request locally or remotely @@ -254,13 +264,14 @@ func (b *Binance) GetAggregatedTrades(arg *AggregatedTradeRequestParams) ([]Aggr } var resp []AggregatedTrade path := aggregatedTrades + "?" + params.Encode() - return resp, b.SendHTTPRequest(exchange.RestSpotSupplementary, path, spotDefaultRate, &resp) + return resp, b.SendHTTPRequest(ctx, + exchange.RestSpotSupplementary, path, spotDefaultRate, &resp) } // batchAggregateTrades fetches trades in multiple requests // first phase, hourly requests until the first trade (or end time) is reached // second phase, limit requests from previous trade until end time (or limit) is reached -func (b *Binance) batchAggregateTrades(arg *AggregatedTradeRequestParams, params url.Values) ([]AggregatedTrade, error) { +func (b *Binance) batchAggregateTrades(ctx context.Context, arg *AggregatedTradeRequestParams, params url.Values) ([]AggregatedTrade, error) { var resp []AggregatedTrade // prepare first request with only first hour and max limit if arg.Limit == 0 || arg.Limit > 1000 { @@ -283,7 +294,8 @@ func (b *Binance) batchAggregateTrades(arg *AggregatedTradeRequestParams, params params.Set("startTime", timeString(start)) params.Set("endTime", timeString(start.Add(increment))) path := aggregatedTrades + "?" + params.Encode() - err := b.SendHTTPRequest(exchange.RestSpotSupplementary, path, spotDefaultRate, &resp) + err := b.SendHTTPRequest(ctx, + exchange.RestSpotSupplementary, path, spotDefaultRate, &resp) if err != nil { log.Warn(log.ExchangeSys, err.Error()) return resp, err @@ -301,7 +313,11 @@ func (b *Binance) batchAggregateTrades(arg *AggregatedTradeRequestParams, params params.Set("fromId", strconv.FormatInt(fromID, 10)) path := aggregatedTrades + "?" + params.Encode() var additionalTrades []AggregatedTrade - err := b.SendHTTPRequest(exchange.RestSpotSupplementary, path, spotDefaultRate, &additionalTrades) + err := b.SendHTTPRequest(ctx, + exchange.RestSpotSupplementary, + path, + spotDefaultRate, + &additionalTrades) if err != nil { return resp, err } @@ -335,7 +351,7 @@ func (b *Binance) batchAggregateTrades(arg *AggregatedTradeRequestParams, params // interval: the interval time for the data // startTime: startTime filter for kline data // endTime: endTime filter for the kline data -func (b *Binance) GetSpotKline(arg *KlinesRequestParams) ([]CandleStick, error) { +func (b *Binance) GetSpotKline(ctx context.Context, arg *KlinesRequestParams) ([]CandleStick, error) { var resp interface{} var klineData []CandleStick @@ -358,7 +374,11 @@ func (b *Binance) GetSpotKline(arg *KlinesRequestParams) ([]CandleStick, error) path := candleStick + "?" + params.Encode() - if err := b.SendHTTPRequest(exchange.RestSpotSupplementary, path, spotDefaultRate, &resp); err != nil { + if err := b.SendHTTPRequest(ctx, + exchange.RestSpotSupplementary, + path, + spotDefaultRate, + &resp); err != nil { return klineData, err } @@ -408,7 +428,7 @@ 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 currency.Pair) (AveragePrice, error) { +func (b *Binance) GetAveragePrice(ctx context.Context, symbol currency.Pair) (AveragePrice, error) { resp := AveragePrice{} params := url.Values{} symbolValue, err := b.FormatSymbol(symbol, asset.Spot) @@ -419,13 +439,14 @@ func (b *Binance) GetAveragePrice(symbol currency.Pair) (AveragePrice, error) { path := averagePrice + "?" + params.Encode() - return resp, b.SendHTTPRequest(exchange.RestSpotSupplementary, path, spotDefaultRate, &resp) + return resp, b.SendHTTPRequest(ctx, + exchange.RestSpotSupplementary, path, spotDefaultRate, &resp) } // GetPriceChangeStats returns price change statistics for the last 24 hours // // symbol: string of currency pair -func (b *Binance) GetPriceChangeStats(symbol currency.Pair) (PriceChangeStats, error) { +func (b *Binance) GetPriceChangeStats(ctx context.Context, symbol currency.Pair) (PriceChangeStats, error) { resp := PriceChangeStats{} params := url.Values{} rateLimit := spotPriceChangeAllRate @@ -439,19 +460,21 @@ func (b *Binance) GetPriceChangeStats(symbol currency.Pair) (PriceChangeStats, e } path := priceChange + "?" + params.Encode() - return resp, b.SendHTTPRequest(exchange.RestSpotSupplementary, path, rateLimit, &resp) + return resp, b.SendHTTPRequest(ctx, + exchange.RestSpotSupplementary, path, rateLimit, &resp) } // GetTickers returns the ticker data for the last 24 hrs -func (b *Binance) GetTickers() ([]PriceChangeStats, error) { +func (b *Binance) GetTickers(ctx context.Context) ([]PriceChangeStats, error) { var resp []PriceChangeStats - return resp, b.SendHTTPRequest(exchange.RestSpotSupplementary, priceChange, spotPriceChangeAllRate, &resp) + return resp, b.SendHTTPRequest(ctx, + exchange.RestSpotSupplementary, priceChange, spotPriceChangeAllRate, &resp) } // GetLatestSpotPrice returns latest spot price of symbol // // symbol: string of currency pair -func (b *Binance) GetLatestSpotPrice(symbol currency.Pair) (SymbolPrice, error) { +func (b *Binance) GetLatestSpotPrice(ctx context.Context, symbol currency.Pair) (SymbolPrice, error) { resp := SymbolPrice{} params := url.Values{} rateLimit := spotSymbolPriceAllRate @@ -465,13 +488,14 @@ func (b *Binance) GetLatestSpotPrice(symbol currency.Pair) (SymbolPrice, error) } path := symbolPrice + "?" + params.Encode() - return resp, b.SendHTTPRequest(exchange.RestSpotSupplementary, path, rateLimit, &resp) + return resp, + b.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, path, rateLimit, &resp) } // GetBestPrice returns the latest best price for symbol // // symbol: string of currency pair -func (b *Binance) GetBestPrice(symbol currency.Pair) (BestPrice, error) { +func (b *Binance) GetBestPrice(ctx context.Context, symbol currency.Pair) (BestPrice, error) { resp := BestPrice{} params := url.Values{} rateLimit := spotOrderbookTickerAllRate @@ -485,13 +509,14 @@ func (b *Binance) GetBestPrice(symbol currency.Pair) (BestPrice, error) { } path := bestPrice + "?" + params.Encode() - return resp, b.SendHTTPRequest(exchange.RestSpotSupplementary, path, rateLimit, &resp) + return resp, + b.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, path, rateLimit, &resp) } // NewOrder sends a new order to Binance -func (b *Binance) NewOrder(o *NewOrderRequest) (NewOrderResponse, error) { +func (b *Binance) NewOrder(ctx context.Context, o *NewOrderRequest) (NewOrderResponse, error) { var resp NewOrderResponse - if err := b.newOrder(orderEndpoint, o, &resp); err != nil { + if err := b.newOrder(ctx, orderEndpoint, o, &resp); err != nil { return resp, err } @@ -503,12 +528,12 @@ func (b *Binance) NewOrder(o *NewOrderRequest) (NewOrderResponse, error) { } // NewOrderTest sends a new test order to Binance -func (b *Binance) NewOrderTest(o *NewOrderRequest) error { +func (b *Binance) NewOrderTest(ctx context.Context, o *NewOrderRequest) error { var resp NewOrderResponse - return b.newOrder(newOrderTest, o, &resp) + return b.newOrder(ctx, newOrderTest, o, &resp) } -func (b *Binance) newOrder(api string, o *NewOrderRequest, resp *NewOrderResponse) error { +func (b *Binance) newOrder(ctx context.Context, api string, o *NewOrderRequest, resp *NewOrderResponse) error { params := url.Values{} symbol, err := b.FormatSymbol(o.Symbol, asset.Spot) if err != nil { @@ -544,11 +569,11 @@ func (b *Binance) newOrder(api string, o *NewOrderRequest, resp *NewOrderRespons if o.NewOrderRespType != "" { params.Set("newOrderRespType", o.NewOrderRespType) } - return b.SendAuthHTTPRequest(exchange.RestSpotSupplementary, http.MethodPost, api, params, spotOrderRate, resp) + return b.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodPost, api, params, spotOrderRate, resp) } // CancelExistingOrder sends a cancel order to Binance -func (b *Binance) CancelExistingOrder(symbol currency.Pair, orderID int64, origClientOrderID string) (CancelOrderResponse, error) { +func (b *Binance) CancelExistingOrder(ctx context.Context, symbol currency.Pair, orderID int64, origClientOrderID string) (CancelOrderResponse, error) { var resp CancelOrderResponse symbolValue, err := b.FormatSymbol(symbol, asset.Spot) @@ -565,13 +590,13 @@ func (b *Binance) CancelExistingOrder(symbol currency.Pair, orderID int64, origC if origClientOrderID != "" { params.Set("origClientOrderId", origClientOrderID) } - return resp, b.SendAuthHTTPRequest(exchange.RestSpotSupplementary, http.MethodDelete, orderEndpoint, params, spotOrderRate, &resp) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodDelete, orderEndpoint, params, spotOrderRate, &resp) } // 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(pair currency.Pair) ([]QueryOrderData, error) { +func (b *Binance) OpenOrders(ctx context.Context, pair currency.Pair) ([]QueryOrderData, error) { var resp []QueryOrderData params := url.Values{} var p string @@ -587,7 +612,13 @@ func (b *Binance) OpenOrders(pair currency.Pair) ([]QueryOrderData, error) { // error params.Set("recvWindow", "10000") } - if err := b.SendAuthHTTPRequest(exchange.RestSpotSupplementary, http.MethodGet, openOrders, params, openOrdersLimit(p), &resp); err != nil { + if err := b.SendAuthHTTPRequest(ctx, + exchange.RestSpotSupplementary, + http.MethodGet, + openOrders, + params, + openOrdersLimit(p), + &resp); err != nil { return resp, err } @@ -597,7 +628,7 @@ func (b *Binance) OpenOrders(pair currency.Pair) ([]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 currency.Pair, orderID, limit string) ([]QueryOrderData, error) { +func (b *Binance) AllOrders(ctx context.Context, symbol currency.Pair, orderID, limit string) ([]QueryOrderData, error) { var resp []QueryOrderData params := url.Values{} @@ -612,14 +643,20 @@ func (b *Binance) AllOrders(symbol currency.Pair, orderID, limit string) ([]Quer if limit != "" { params.Set("limit", limit) } - if err := b.SendAuthHTTPRequest(exchange.RestSpotSupplementary, http.MethodGet, allOrders, params, spotAllOrdersRate, &resp); err != nil { + if err := b.SendAuthHTTPRequest(ctx, + exchange.RestSpotSupplementary, + http.MethodGet, + allOrders, + params, + spotAllOrdersRate, + &resp); err != nil { return resp, err } return resp, nil } // QueryOrder returns information on a past order -func (b *Binance) QueryOrder(symbol currency.Pair, origClientOrderID string, orderID int64) (QueryOrderData, error) { +func (b *Binance) QueryOrder(ctx context.Context, symbol currency.Pair, origClientOrderID string, orderID int64) (QueryOrderData, error) { var resp QueryOrderData params := url.Values{} @@ -635,7 +672,11 @@ func (b *Binance) QueryOrder(symbol currency.Pair, origClientOrderID string, ord params.Set("orderId", strconv.FormatInt(orderID, 10)) } - if err := b.SendAuthHTTPRequest(exchange.RestSpotSupplementary, http.MethodGet, orderEndpoint, params, spotOrderQueryRate, &resp); err != nil { + if err := b.SendAuthHTTPRequest(ctx, + exchange.RestSpotSupplementary, + http.MethodGet, orderEndpoint, + params, spotOrderQueryRate, + &resp); err != nil { return resp, err } @@ -646,7 +687,7 @@ func (b *Binance) QueryOrder(symbol currency.Pair, origClientOrderID string, ord } // GetAccount returns binance user accounts -func (b *Binance) GetAccount() (*Account, error) { +func (b *Binance) GetAccount(ctx context.Context) (*Account, error) { type response struct { Response Account @@ -655,7 +696,11 @@ func (b *Binance) GetAccount() (*Account, error) { var resp response params := url.Values{} - if err := b.SendAuthHTTPRequest(exchange.RestSpotSupplementary, http.MethodGet, accountInfo, params, spotAccountInformationRate, &resp); err != nil { + if err := b.SendAuthHTTPRequest(ctx, + exchange.RestSpotSupplementary, + http.MethodGet, accountInfo, + params, spotAccountInformationRate, + &resp); err != nil { return &resp.Account, err } @@ -667,11 +712,15 @@ func (b *Binance) GetAccount() (*Account, error) { } // GetMarginAccount returns account information for margin accounts -func (b *Binance) GetMarginAccount() (*MarginAccount, error) { +func (b *Binance) GetMarginAccount(ctx context.Context) (*MarginAccount, error) { var resp MarginAccount params := url.Values{} - if err := b.SendAuthHTTPRequest(exchange.RestSpotSupplementary, http.MethodGet, marginAccountInfo, params, spotAccountInformationRate, &resp); err != nil { + if err := b.SendAuthHTTPRequest(ctx, + exchange.RestSpotSupplementary, + http.MethodGet, marginAccountInfo, + params, spotAccountInformationRate, + &resp); err != nil { return &resp, err } @@ -679,7 +728,7 @@ func (b *Binance) GetMarginAccount() (*MarginAccount, error) { } // SendHTTPRequest sends an unauthenticated request -func (b *Binance) SendHTTPRequest(ePath exchange.URL, path string, f request.EndpointLimit, result interface{}) error { +func (b *Binance) SendHTTPRequest(ctx context.Context, ePath exchange.URL, path string, f request.EndpointLimit, result interface{}) error { endpointPath, err := b.API.Endpoints.GetURL(ePath) if err != nil { return err @@ -692,14 +741,14 @@ func (b *Binance) SendHTTPRequest(ePath exchange.URL, path string, f request.End HTTPDebugging: b.HTTPDebugging, HTTPRecording: b.HTTPRecording} - return b.SendPayload(context.Background(), f, func() (*request.Item, error) { + return b.SendPayload(ctx, f, func() (*request.Item, error) { return item, nil }) } // SendAPIKeyHTTPRequest is a special API request where the api key is // appended to the headers without a secret -func (b *Binance) SendAPIKeyHTTPRequest(ePath exchange.URL, path string, f request.EndpointLimit, result interface{}) error { +func (b *Binance) SendAPIKeyHTTPRequest(ctx context.Context, ePath exchange.URL, path string, f request.EndpointLimit, result interface{}) error { endpointPath, err := b.API.Endpoints.GetURL(ePath) if err != nil { return err @@ -715,13 +764,13 @@ func (b *Binance) SendAPIKeyHTTPRequest(ePath exchange.URL, path string, f reque HTTPDebugging: b.HTTPDebugging, HTTPRecording: b.HTTPRecording} - return b.SendPayload(context.Background(), f, func() (*request.Item, error) { + return b.SendPayload(ctx, f, func() (*request.Item, error) { return item, nil }) } // SendAuthHTTPRequest sends an authenticated HTTP request -func (b *Binance) SendAuthHTTPRequest(ePath exchange.URL, method, path string, params url.Values, f request.EndpointLimit, result interface{}) error { +func (b *Binance) SendAuthHTTPRequest(ctx context.Context, ePath exchange.URL, method, path string, params url.Values, f request.EndpointLimit, result interface{}) error { if !b.AllowAuthenticatedRequest() { return fmt.Errorf("%s %w", b.Name, exchange.ErrAuthenticatedRequestWithoutCredentialsSet) } @@ -739,7 +788,7 @@ func (b *Binance) SendAuthHTTPRequest(ePath exchange.URL, method, path string, p } interim := json.RawMessage{} - err = b.SendPayload(context.Background(), f, func() (*request.Item, error) { + err = b.SendPayload(ctx, f, func() (*request.Item, error) { fullPath := endpointPath + path params.Set("timestamp", strconv.FormatInt(time.Now().Unix()*1000, 10)) signature := params.Encode() @@ -798,12 +847,12 @@ func (b *Binance) SetValues() { } // GetFee returns an estimate of fee based on type of transaction -func (b *Binance) GetFee(feeBuilder *exchange.FeeBuilder) (float64, error) { +func (b *Binance) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { var fee float64 switch feeBuilder.FeeType { case exchange.CryptocurrencyTradeFee: - multiplier, err := b.getMultiplier(feeBuilder.IsMaker) + multiplier, err := b.getMultiplier(ctx, feeBuilder.IsMaker) if err != nil { return 0, err } @@ -825,9 +874,9 @@ func getOfflineTradeFee(price, amount float64) float64 { } // getMultiplier retrieves account based taker/maker fees -func (b *Binance) getMultiplier(isMaker bool) (float64, error) { +func (b *Binance) getMultiplier(ctx context.Context, isMaker bool) (float64, error) { var multiplier float64 - account, err := b.GetAccount() + account, err := b.GetAccount(ctx) if err != nil { return 0, err } @@ -850,7 +899,7 @@ func getCryptocurrencyWithdrawalFee(c currency.Code) float64 { } // WithdrawCrypto sends cryptocurrency to the address of your choosing -func (b *Binance) WithdrawCrypto(asset, address, addressTag, name, amount string) (string, error) { +func (b *Binance) WithdrawCrypto(ctx context.Context, asset, address, addressTag, name, amount string) (string, error) { var resp WithdrawResponse params := url.Values{} @@ -864,7 +913,10 @@ func (b *Binance) WithdrawCrypto(asset, address, addressTag, name, amount string params.Set("addressTag", addressTag) } - if err := b.SendAuthHTTPRequest(exchange.RestSpotSupplementary, http.MethodPost, withdrawEndpoint, params, spotDefaultRate, &resp); err != nil { + if err := b.SendAuthHTTPRequest(ctx, + exchange.RestSpotSupplementary, + http.MethodPost, withdrawEndpoint, + params, spotDefaultRate, &resp); err != nil { return "", err } @@ -877,7 +929,7 @@ func (b *Binance) WithdrawCrypto(asset, address, addressTag, name, amount string // WithdrawStatus gets the status of recent withdrawals // status `param` used as string to prevent default value 0 (for int) interpreting as EmailSent status -func (b *Binance) WithdrawStatus(c currency.Code, status string, startTime, endTime int64) ([]WithdrawStatusResponse, error) { +func (b *Binance) WithdrawStatus(ctx context.Context, c currency.Code, status string, startTime, endTime int64) ([]WithdrawStatusResponse, error) { var response struct { Success bool `json:"success"` WithdrawList []WithdrawStatusResponse `json:"withdrawList"` @@ -909,7 +961,11 @@ func (b *Binance) WithdrawStatus(c currency.Code, status string, startTime, endT params.Set("endTime", strconv.FormatInt(endTime, 10)) } - if err := b.SendAuthHTTPRequest(exchange.RestSpotSupplementary, http.MethodGet, withdrawalHistory, params, spotDefaultRate, &response); err != nil { + if err := b.SendAuthHTTPRequest(ctx, + exchange.RestSpotSupplementary, + http.MethodGet, withdrawalHistory, + params, spotDefaultRate, + &response); err != nil { return response.WithdrawList, err } @@ -917,7 +973,7 @@ func (b *Binance) WithdrawStatus(c currency.Code, status string, startTime, endT } // GetDepositAddressForCurrency retrieves the wallet address for a given currency -func (b *Binance) GetDepositAddressForCurrency(currency string) (string, error) { +func (b *Binance) GetDepositAddressForCurrency(ctx context.Context, currency string) (string, error) { resp := struct { Address string `json:"address"` Success bool `json:"success"` @@ -930,11 +986,14 @@ func (b *Binance) GetDepositAddressForCurrency(currency string) (string, error) params.Set("recvWindow", "10000") return resp.Address, - b.SendAuthHTTPRequest(exchange.RestSpotSupplementary, http.MethodGet, depositAddress, params, spotDefaultRate, &resp) + b.SendAuthHTTPRequest(ctx, + exchange.RestSpotSupplementary, + http.MethodGet, depositAddress, + params, spotDefaultRate, &resp) } // GetWsAuthStreamKey will retrieve a key to use for authorised WS streaming -func (b *Binance) GetWsAuthStreamKey() (string, error) { +func (b *Binance) GetWsAuthStreamKey(ctx context.Context) (string, error) { endpointPath, err := b.API.Endpoints.GetURL(exchange.RestSpotSupplementary) if err != nil { return "", err @@ -954,7 +1013,7 @@ func (b *Binance) GetWsAuthStreamKey() (string, error) { HTTPRecording: b.HTTPRecording, } - err = b.SendPayload(context.Background(), request.Unset, func() (*request.Item, error) { + err = b.SendPayload(ctx, request.Unset, func() (*request.Item, error) { return item, nil }) if err != nil { @@ -964,13 +1023,13 @@ func (b *Binance) GetWsAuthStreamKey() (string, error) { } // MaintainWsAuthStreamKey will keep the key alive -func (b *Binance) MaintainWsAuthStreamKey() error { +func (b *Binance) MaintainWsAuthStreamKey(ctx context.Context) error { endpointPath, err := b.API.Endpoints.GetURL(exchange.RestSpotSupplementary) if err != nil { return err } if listenKey == "" { - listenKey, err = b.GetWsAuthStreamKey() + listenKey, err = b.GetWsAuthStreamKey(ctx) return err } path := endpointPath + userAccountStream @@ -989,15 +1048,15 @@ func (b *Binance) MaintainWsAuthStreamKey() error { HTTPRecording: b.HTTPRecording, } - return b.SendPayload(context.Background(), request.Unset, func() (*request.Item, error) { + return b.SendPayload(ctx, request.Unset, func() (*request.Item, error) { return item, nil }) } // FetchSpotExchangeLimits fetches spot order execution limits -func (b *Binance) FetchSpotExchangeLimits() ([]order.MinMaxLevel, error) { +func (b *Binance) FetchSpotExchangeLimits(ctx context.Context) ([]order.MinMaxLevel, error) { var limits []order.MinMaxLevel - spot, err := b.GetExchangeInfo() + spot, err := b.GetExchangeInfo(ctx) if err != nil { return nil, err } diff --git a/exchanges/binance/binance_cfutures.go b/exchanges/binance/binance_cfutures.go index 881b6624..f42f3111 100644 --- a/exchanges/binance/binance_cfutures.go +++ b/exchanges/binance/binance_cfutures.go @@ -1,6 +1,7 @@ package binance import ( + "context" "encoding/json" "errors" "fmt" @@ -67,13 +68,13 @@ const ( ) // FuturesExchangeInfo stores CoinMarginedFutures, data -func (b *Binance) FuturesExchangeInfo() (CExchangeInfo, error) { +func (b *Binance) FuturesExchangeInfo(ctx context.Context) (CExchangeInfo, error) { var resp CExchangeInfo - return resp, b.SendHTTPRequest(exchange.RestCoinMargined, cfuturesExchangeInfo, cFuturesDefaultRate, &resp) + return resp, b.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesExchangeInfo, cFuturesDefaultRate, &resp) } // GetFuturesOrderbook gets orderbook data for CoinMarginedFutures, -func (b *Binance) GetFuturesOrderbook(symbol currency.Pair, limit int64) (OrderBook, error) { +func (b *Binance) GetFuturesOrderbook(ctx context.Context, symbol currency.Pair, limit int64) (OrderBook, error) { var resp OrderBook var data OrderbookData params := url.Values{} @@ -96,7 +97,7 @@ func (b *Binance) GetFuturesOrderbook(symbol currency.Pair, limit int64) (OrderB if limit > 0 && limit <= 1000 { params.Set("limit", strconv.FormatInt(limit, 10)) } - err = b.SendHTTPRequest(exchange.RestCoinMargined, cfuturesOrderbook+params.Encode(), rateBudget, &data) + err = b.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesOrderbook+params.Encode(), rateBudget, &data) if err != nil { return resp, err } @@ -133,7 +134,7 @@ func (b *Binance) GetFuturesOrderbook(symbol currency.Pair, limit int64) (OrderB } // GetFuturesPublicTrades gets recent public trades for CoinMarginedFutures, -func (b *Binance) GetFuturesPublicTrades(symbol currency.Pair, limit int64) ([]FuturesPublicTradesData, error) { +func (b *Binance) GetFuturesPublicTrades(ctx context.Context, symbol currency.Pair, limit int64) ([]FuturesPublicTradesData, error) { var resp []FuturesPublicTradesData params := url.Values{} symbolValue, err := b.FormatSymbol(symbol, asset.CoinMarginedFutures) @@ -144,11 +145,11 @@ func (b *Binance) GetFuturesPublicTrades(symbol currency.Pair, limit int64) ([]F if limit > 0 && limit <= 1000 { params.Set("limit", strconv.FormatInt(limit, 10)) } - return resp, b.SendHTTPRequest(exchange.RestCoinMargined, cfuturesRecentTrades+params.Encode(), cFuturesDefaultRate, &resp) + return resp, b.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesRecentTrades+params.Encode(), cFuturesDefaultRate, &resp) } // GetFuturesHistoricalTrades gets historical public trades for CoinMarginedFutures, -func (b *Binance) GetFuturesHistoricalTrades(symbol currency.Pair, fromID string, limit int64) ([]UPublicTradesData, error) { +func (b *Binance) GetFuturesHistoricalTrades(ctx context.Context, symbol currency.Pair, fromID string, limit int64) ([]UPublicTradesData, error) { var resp []UPublicTradesData params := url.Values{} symbolValue, err := b.FormatSymbol(symbol, asset.CoinMarginedFutures) @@ -162,11 +163,11 @@ func (b *Binance) GetFuturesHistoricalTrades(symbol currency.Pair, fromID string if limit > 0 && limit < 1000 { params.Set("limit", strconv.FormatInt(limit, 10)) } - return resp, b.SendAuthHTTPRequest(exchange.RestCoinMargined, http.MethodGet, cfuturesHistoricalTrades, params, cFuturesHistoricalTradesRate, &resp) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodGet, cfuturesHistoricalTrades, params, cFuturesHistoricalTradesRate, &resp) } // GetPastPublicTrades gets past public trades for CoinMarginedFutures, -func (b *Binance) GetPastPublicTrades(symbol currency.Pair, limit, fromID int64) ([]FuturesPublicTradesData, error) { +func (b *Binance) GetPastPublicTrades(ctx context.Context, symbol currency.Pair, limit, fromID int64) ([]FuturesPublicTradesData, error) { var resp []FuturesPublicTradesData params := url.Values{} symbolValue, err := b.FormatSymbol(symbol, asset.CoinMarginedFutures) @@ -180,11 +181,11 @@ func (b *Binance) GetPastPublicTrades(symbol currency.Pair, limit, fromID int64) if fromID != 0 { params.Set("fromID", strconv.FormatInt(fromID, 10)) } - return resp, b.SendHTTPRequest(exchange.RestCoinMargined, cfuturesRecentTrades+params.Encode(), cFuturesDefaultRate, &resp) + return resp, b.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesRecentTrades+params.Encode(), cFuturesDefaultRate, &resp) } // GetFuturesAggregatedTradesList gets aggregated trades list for CoinMarginedFutures, -func (b *Binance) GetFuturesAggregatedTradesList(symbol currency.Pair, fromID, limit int64, startTime, endTime time.Time) ([]AggregatedTrade, error) { +func (b *Binance) GetFuturesAggregatedTradesList(ctx context.Context, symbol currency.Pair, fromID, limit int64, startTime, endTime time.Time) ([]AggregatedTrade, error) { var resp []AggregatedTrade params := url.Values{} symbolValue, err := b.FormatSymbol(symbol, asset.CoinMarginedFutures) @@ -205,11 +206,11 @@ func (b *Binance) GetFuturesAggregatedTradesList(symbol currency.Pair, fromID, l params.Set("start_time", strconv.FormatInt(startTime.Unix(), 10)) params.Set("end_time", strconv.FormatInt(endTime.Unix(), 10)) } - return resp, b.SendHTTPRequest(exchange.RestCoinMargined, cfuturesCompressedTrades+params.Encode(), cFuturesHistoricalTradesRate, &resp) + return resp, b.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesCompressedTrades+params.Encode(), cFuturesHistoricalTradesRate, &resp) } // GetIndexAndMarkPrice gets index and mark prices for CoinMarginedFutures, -func (b *Binance) GetIndexAndMarkPrice(symbol, pair string) ([]IndexMarkPrice, error) { +func (b *Binance) GetIndexAndMarkPrice(ctx context.Context, symbol, pair string) ([]IndexMarkPrice, error) { var resp []IndexMarkPrice params := url.Values{} if symbol != "" { @@ -218,11 +219,11 @@ func (b *Binance) GetIndexAndMarkPrice(symbol, pair string) ([]IndexMarkPrice, e if pair != "" { params.Set("pair", pair) } - return resp, b.SendHTTPRequest(exchange.RestCoinMargined, cfuturesMarkPrice+params.Encode(), cFuturesIndexMarkPriceRate, &resp) + return resp, b.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesMarkPrice+params.Encode(), cFuturesIndexMarkPriceRate, &resp) } // GetFuturesKlineData gets futures kline data for CoinMarginedFutures, -func (b *Binance) GetFuturesKlineData(symbol currency.Pair, interval string, limit int64, startTime, endTime time.Time) ([]FuturesCandleStick, error) { +func (b *Binance) GetFuturesKlineData(ctx context.Context, symbol currency.Pair, interval string, limit int64, startTime, endTime time.Time) ([]FuturesCandleStick, error) { var data [][10]interface{} var resp []FuturesCandleStick params := url.Values{} @@ -248,7 +249,7 @@ func (b *Binance) GetFuturesKlineData(symbol currency.Pair, interval string, lim params.Set("end_time", strconv.FormatInt(endTime.Unix(), 10)) } rateBudget := getKlineRateBudget(limit) - err := b.SendHTTPRequest(exchange.RestCoinMargined, cfuturesKlineData+params.Encode(), rateBudget, &data) + err := b.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesKlineData+params.Encode(), rateBudget, &data) if err != nil { return resp, err } @@ -341,7 +342,7 @@ func (b *Binance) GetFuturesKlineData(symbol currency.Pair, interval string, lim } // GetContinuousKlineData gets continuous kline data -func (b *Binance) GetContinuousKlineData(pair, contractType, interval string, limit int64, startTime, endTime time.Time) ([]FuturesCandleStick, error) { +func (b *Binance) GetContinuousKlineData(ctx context.Context, pair, contractType, interval string, limit int64, startTime, endTime time.Time) ([]FuturesCandleStick, error) { var data [][10]interface{} var resp []FuturesCandleStick params := url.Values{} @@ -366,7 +367,7 @@ func (b *Binance) GetContinuousKlineData(pair, contractType, interval string, li } rateBudget := getKlineRateBudget(limit) - err := b.SendHTTPRequest(exchange.RestCoinMargined, cfuturesContinuousKline+params.Encode(), rateBudget, &data) + err := b.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesContinuousKline+params.Encode(), rateBudget, &data) if err != nil { return resp, err } @@ -459,7 +460,7 @@ func (b *Binance) GetContinuousKlineData(pair, contractType, interval string, li } // GetIndexPriceKlines gets continuous kline data -func (b *Binance) GetIndexPriceKlines(pair, interval string, limit int64, startTime, endTime time.Time) ([]FuturesCandleStick, error) { +func (b *Binance) GetIndexPriceKlines(ctx context.Context, pair, interval string, limit int64, startTime, endTime time.Time) ([]FuturesCandleStick, error) { var data [][10]interface{} var resp []FuturesCandleStick params := url.Values{} @@ -479,7 +480,7 @@ func (b *Binance) GetIndexPriceKlines(pair, interval string, limit int64, startT params.Set("end_time", strconv.FormatInt(endTime.Unix(), 10)) } rateBudget := getKlineRateBudget(limit) - err := b.SendHTTPRequest(exchange.RestCoinMargined, cfuturesIndexKline+params.Encode(), rateBudget, &data) + err := b.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesIndexKline+params.Encode(), rateBudget, &data) if err != nil { return resp, err } @@ -572,7 +573,7 @@ func (b *Binance) GetIndexPriceKlines(pair, interval string, limit int64, startT } // GetMarkPriceKline gets mark price kline data -func (b *Binance) GetMarkPriceKline(symbol currency.Pair, interval string, limit int64, startTime, endTime time.Time) ([]FuturesCandleStick, error) { +func (b *Binance) GetMarkPriceKline(ctx context.Context, symbol currency.Pair, interval string, limit int64, startTime, endTime time.Time) ([]FuturesCandleStick, error) { var data [][10]interface{} var resp []FuturesCandleStick params := url.Values{} @@ -596,7 +597,7 @@ func (b *Binance) GetMarkPriceKline(symbol currency.Pair, interval string, limit params.Set("end_time", strconv.FormatInt(endTime.Unix(), 10)) } rateBudget := getKlineRateBudget(limit) - err = b.SendHTTPRequest(exchange.RestCoinMargined, cfuturesMarkPriceKline+params.Encode(), rateBudget, &data) + err = b.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesMarkPriceKline+params.Encode(), rateBudget, &data) if err != nil { return resp, err } @@ -704,7 +705,7 @@ func getKlineRateBudget(limit int64) request.EndpointLimit { } // GetFuturesSwapTickerChangeStats gets 24hr ticker change stats for CoinMarginedFutures, -func (b *Binance) GetFuturesSwapTickerChangeStats(symbol currency.Pair, pair string) ([]PriceChangeStats, error) { +func (b *Binance) GetFuturesSwapTickerChangeStats(ctx context.Context, symbol currency.Pair, pair string) ([]PriceChangeStats, error) { var resp []PriceChangeStats params := url.Values{} rateLimit := cFuturesTickerPriceHistoryRate @@ -719,11 +720,11 @@ func (b *Binance) GetFuturesSwapTickerChangeStats(symbol currency.Pair, pair str if pair != "" { params.Set("pair", pair) } - return resp, b.SendHTTPRequest(exchange.RestCoinMargined, cfuturesTickerPriceStats+params.Encode(), rateLimit, &resp) + return resp, b.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesTickerPriceStats+params.Encode(), rateLimit, &resp) } // FuturesGetFundingHistory gets funding history for CoinMarginedFutures, -func (b *Binance) FuturesGetFundingHistory(symbol currency.Pair, limit int64, startTime, endTime time.Time) ([]FundingRateHistory, error) { +func (b *Binance) FuturesGetFundingHistory(ctx context.Context, symbol currency.Pair, limit int64, startTime, endTime time.Time) ([]FundingRateHistory, error) { var resp []FundingRateHistory params := url.Values{} if !symbol.IsEmpty() { @@ -743,11 +744,11 @@ func (b *Binance) FuturesGetFundingHistory(symbol currency.Pair, limit int64, st params.Set("start_time", strconv.FormatInt(startTime.Unix(), 10)) params.Set("end_time", strconv.FormatInt(endTime.Unix(), 10)) } - return resp, b.SendHTTPRequest(exchange.RestCoinMargined, cfuturesFundingRateHistory+params.Encode(), cFuturesDefaultRate, &resp) + return resp, b.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesFundingRateHistory+params.Encode(), cFuturesDefaultRate, &resp) } // GetFuturesSymbolPriceTicker gets price ticker for symbol -func (b *Binance) GetFuturesSymbolPriceTicker(symbol currency.Pair, pair string) ([]SymbolPriceTicker, error) { +func (b *Binance) GetFuturesSymbolPriceTicker(ctx context.Context, symbol currency.Pair, pair string) ([]SymbolPriceTicker, error) { var resp []SymbolPriceTicker params := url.Values{} rateLimit := cFuturesOrderbookTickerAllRate @@ -762,11 +763,11 @@ func (b *Binance) GetFuturesSymbolPriceTicker(symbol currency.Pair, pair string) if pair != "" { params.Set("pair", pair) } - return resp, b.SendHTTPRequest(exchange.RestCoinMargined, cfuturesSymbolPriceTicker+params.Encode(), rateLimit, &resp) + return resp, b.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesSymbolPriceTicker+params.Encode(), rateLimit, &resp) } // GetFuturesOrderbookTicker gets orderbook ticker for symbol -func (b *Binance) GetFuturesOrderbookTicker(symbol currency.Pair, pair string) ([]SymbolOrderBookTicker, error) { +func (b *Binance) GetFuturesOrderbookTicker(ctx context.Context, symbol currency.Pair, pair string) ([]SymbolOrderBookTicker, error) { var resp []SymbolOrderBookTicker params := url.Values{} rateLimit := cFuturesOrderbookTickerAllRate @@ -781,11 +782,11 @@ func (b *Binance) GetFuturesOrderbookTicker(symbol currency.Pair, pair string) ( if pair != "" { params.Set("pair", pair) } - return resp, b.SendHTTPRequest(exchange.RestCoinMargined, cfuturesSymbolOrderbook+params.Encode(), rateLimit, &resp) + return resp, b.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesSymbolOrderbook+params.Encode(), rateLimit, &resp) } // GetFuturesLiquidationOrders gets forced liquidation orders -func (b *Binance) GetFuturesLiquidationOrders(symbol currency.Pair, pair string, limit int64, startTime, endTime time.Time) ([]AllLiquidationOrders, error) { +func (b *Binance) GetFuturesLiquidationOrders(ctx context.Context, symbol currency.Pair, pair string, limit int64, startTime, endTime time.Time) ([]AllLiquidationOrders, error) { var resp []AllLiquidationOrders params := url.Values{} rateLimit := cFuturesAllForceOrdersRate @@ -810,11 +811,11 @@ func (b *Binance) GetFuturesLiquidationOrders(symbol currency.Pair, pair string, params.Set("start_time", strconv.FormatInt(startTime.Unix(), 10)) params.Set("end_time", strconv.FormatInt(endTime.Unix(), 10)) } - return resp, b.SendHTTPRequest(exchange.RestCoinMargined, cfuturesLiquidationOrders+params.Encode(), rateLimit, &resp) + return resp, b.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesLiquidationOrders+params.Encode(), rateLimit, &resp) } // GetOpenInterest gets open interest data for a symbol -func (b *Binance) GetOpenInterest(symbol currency.Pair) (OpenInterestData, error) { +func (b *Binance) GetOpenInterest(ctx context.Context, symbol currency.Pair) (OpenInterestData, error) { var resp OpenInterestData params := url.Values{} symbolValue, err := b.FormatSymbol(symbol, asset.CoinMarginedFutures) @@ -822,11 +823,11 @@ func (b *Binance) GetOpenInterest(symbol currency.Pair) (OpenInterestData, error return resp, err } params.Set("symbol", symbolValue) - return resp, b.SendHTTPRequest(exchange.RestCoinMargined, cfuturesOpenInterest+params.Encode(), cFuturesDefaultRate, &resp) + return resp, b.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesOpenInterest+params.Encode(), cFuturesDefaultRate, &resp) } // GetOpenInterestStats gets open interest stats for a symbol -func (b *Binance) GetOpenInterestStats(pair, contractType, period string, limit int64, startTime, endTime time.Time) ([]OpenInterestStats, error) { +func (b *Binance) GetOpenInterestStats(ctx context.Context, pair, contractType, period string, limit int64, startTime, endTime time.Time) ([]OpenInterestStats, error) { var resp []OpenInterestStats params := url.Values{} if pair != "" { @@ -850,11 +851,11 @@ func (b *Binance) GetOpenInterestStats(pair, contractType, period string, limit params.Set("start_time", strconv.FormatInt(startTime.Unix(), 10)) params.Set("end_time", strconv.FormatInt(endTime.Unix(), 10)) } - return resp, b.SendHTTPRequest(exchange.RestCoinMargined, cfuturesOpenInterestStats+params.Encode(), cFuturesDefaultRate, &resp) + return resp, b.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesOpenInterestStats+params.Encode(), cFuturesDefaultRate, &resp) } // GetTraderFuturesAccountRatio gets a traders futures account long/short ratio -func (b *Binance) GetTraderFuturesAccountRatio(pair, period string, limit int64, startTime, endTime time.Time) ([]TopTraderAccountRatio, error) { +func (b *Binance) GetTraderFuturesAccountRatio(ctx context.Context, pair, period string, limit int64, startTime, endTime time.Time) ([]TopTraderAccountRatio, error) { var resp []TopTraderAccountRatio params := url.Values{} params.Set("pair", pair) @@ -872,11 +873,11 @@ func (b *Binance) GetTraderFuturesAccountRatio(pair, period string, limit int64, params.Set("start_time", strconv.FormatInt(startTime.Unix(), 10)) params.Set("end_time", strconv.FormatInt(endTime.Unix(), 10)) } - return resp, b.SendHTTPRequest(exchange.RestCoinMargined, cfuturesTopAccountsRatio+params.Encode(), cFuturesDefaultRate, &resp) + return resp, b.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesTopAccountsRatio+params.Encode(), cFuturesDefaultRate, &resp) } // GetTraderFuturesPositionsRatio gets a traders futures positions' long/short ratio -func (b *Binance) GetTraderFuturesPositionsRatio(pair, period string, limit int64, startTime, endTime time.Time) ([]TopTraderPositionRatio, error) { +func (b *Binance) GetTraderFuturesPositionsRatio(ctx context.Context, pair, period string, limit int64, startTime, endTime time.Time) ([]TopTraderPositionRatio, error) { var resp []TopTraderPositionRatio params := url.Values{} params.Set("pair", pair) @@ -894,11 +895,11 @@ func (b *Binance) GetTraderFuturesPositionsRatio(pair, period string, limit int6 params.Set("start_time", strconv.FormatInt(startTime.Unix(), 10)) params.Set("end_time", strconv.FormatInt(endTime.Unix(), 10)) } - return resp, b.SendHTTPRequest(exchange.RestCoinMargined, cfuturesTopPositionsRatio+params.Encode(), cFuturesDefaultRate, &resp) + return resp, b.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesTopPositionsRatio+params.Encode(), cFuturesDefaultRate, &resp) } // GetMarketRatio gets global long/short ratio -func (b *Binance) GetMarketRatio(pair, period string, limit int64, startTime, endTime time.Time) ([]TopTraderPositionRatio, error) { +func (b *Binance) GetMarketRatio(ctx context.Context, pair, period string, limit int64, startTime, endTime time.Time) ([]TopTraderPositionRatio, error) { var resp []TopTraderPositionRatio params := url.Values{} params.Set("pair", pair) @@ -916,11 +917,11 @@ func (b *Binance) GetMarketRatio(pair, period string, limit int64, startTime, en params.Set("start_time", strconv.FormatInt(startTime.Unix(), 10)) params.Set("end_time", strconv.FormatInt(endTime.Unix(), 10)) } - return resp, b.SendHTTPRequest(exchange.RestCoinMargined, cfuturesLongShortRatio+params.Encode(), cFuturesDefaultRate, &resp) + return resp, b.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesLongShortRatio+params.Encode(), cFuturesDefaultRate, &resp) } // GetFuturesTakerVolume gets futures taker buy/sell volumes -func (b *Binance) GetFuturesTakerVolume(pair, contractType, period string, limit int64, startTime, endTime time.Time) ([]TakerBuySellVolume, error) { +func (b *Binance) GetFuturesTakerVolume(ctx context.Context, pair, contractType, period string, limit int64, startTime, endTime time.Time) ([]TakerBuySellVolume, error) { var resp []TakerBuySellVolume params := url.Values{} params.Set("pair", pair) @@ -942,11 +943,11 @@ func (b *Binance) GetFuturesTakerVolume(pair, contractType, period string, limit params.Set("start_time", strconv.FormatInt(startTime.Unix(), 10)) params.Set("end_time", strconv.FormatInt(endTime.Unix(), 10)) } - return resp, b.SendHTTPRequest(exchange.RestCoinMargined, cfuturesBuySellVolume+params.Encode(), cFuturesDefaultRate, &resp) + return resp, b.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesBuySellVolume+params.Encode(), cFuturesDefaultRate, &resp) } // GetFuturesBasisData gets futures basis data -func (b *Binance) GetFuturesBasisData(pair, contractType, period string, limit int64, startTime, endTime time.Time) ([]FuturesBasisData, error) { +func (b *Binance) GetFuturesBasisData(ctx context.Context, pair, contractType, period string, limit int64, startTime, endTime time.Time) ([]FuturesBasisData, error) { var resp []FuturesBasisData params := url.Values{} params.Set("pair", pair) @@ -968,11 +969,11 @@ func (b *Binance) GetFuturesBasisData(pair, contractType, period string, limit i params.Set("start_time", strconv.FormatInt(startTime.Unix(), 10)) params.Set("end_time", strconv.FormatInt(endTime.Unix(), 10)) } - return resp, b.SendHTTPRequest(exchange.RestCoinMargined, cfuturesBasis+params.Encode(), cFuturesDefaultRate, &resp) + return resp, b.SendHTTPRequest(ctx, exchange.RestCoinMargined, cfuturesBasis+params.Encode(), cFuturesDefaultRate, &resp) } // FuturesNewOrder sends a new futures order to the exchange -func (b *Binance) FuturesNewOrder(symbol currency.Pair, side, positionSide, orderType, timeInForce, +func (b *Binance) FuturesNewOrder(ctx context.Context, symbol currency.Pair, side, positionSide, orderType, timeInForce, newClientOrderID, closePosition, workingType, newOrderRespType string, quantity, price, stopPrice, activationPrice, callbackRate float64, reduceOnly bool) (FuturesOrderPlaceData, error) { var resp FuturesOrderPlaceData @@ -1027,11 +1028,11 @@ func (b *Binance) FuturesNewOrder(symbol currency.Pair, side, positionSide, orde if callbackRate != 0 { params.Set("callbackRate", strconv.FormatFloat(callbackRate, 'f', -1, 64)) } - return resp, b.SendAuthHTTPRequest(exchange.RestCoinMargined, http.MethodPost, cfuturesOrder, params, cFuturesOrdersDefaultRate, &resp) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodPost, cfuturesOrder, params, cFuturesOrdersDefaultRate, &resp) } // FuturesBatchOrder sends a batch order request -func (b *Binance) FuturesBatchOrder(data []PlaceBatchOrderData) ([]FuturesOrderPlaceData, error) { +func (b *Binance) FuturesBatchOrder(ctx context.Context, data []PlaceBatchOrderData) ([]FuturesOrderPlaceData, error) { var resp []FuturesOrderPlaceData params := url.Values{} for x := range data { @@ -1065,11 +1066,11 @@ func (b *Binance) FuturesBatchOrder(data []PlaceBatchOrderData) ([]FuturesOrderP return resp, err } params.Set("batchOrders", string(jsonData)) - return resp, b.SendAuthHTTPRequest(exchange.RestCoinMargined, http.MethodPost, cfuturesBatchOrder, params, cFuturesBatchOrdersRate, &resp) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodPost, cfuturesBatchOrder, params, cFuturesBatchOrdersRate, &resp) } // FuturesBatchCancelOrders sends a batch request to cancel orders -func (b *Binance) FuturesBatchCancelOrders(symbol currency.Pair, orderList, origClientOrderIDList []string) ([]BatchCancelOrderData, error) { +func (b *Binance) FuturesBatchCancelOrders(ctx context.Context, symbol currency.Pair, orderList, origClientOrderIDList []string) ([]BatchCancelOrderData, error) { var resp []BatchCancelOrderData params := url.Values{} symbolValue, err := b.FormatSymbol(symbol, asset.CoinMarginedFutures) @@ -1091,11 +1092,11 @@ func (b *Binance) FuturesBatchCancelOrders(symbol currency.Pair, orderList, orig } params.Set("origClientOrderIdList", string(jsonCliOrdIDList)) } - return resp, b.SendAuthHTTPRequest(exchange.RestCoinMargined, http.MethodDelete, cfuturesBatchOrder, params, cFuturesOrdersDefaultRate, &resp) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodDelete, cfuturesBatchOrder, params, cFuturesOrdersDefaultRate, &resp) } // FuturesGetOrderData gets futures order data -func (b *Binance) FuturesGetOrderData(symbol currency.Pair, orderID, origClientOrderID string) (FuturesOrderGetData, error) { +func (b *Binance) FuturesGetOrderData(ctx context.Context, symbol currency.Pair, orderID, origClientOrderID string) (FuturesOrderGetData, error) { var resp FuturesOrderGetData params := url.Values{} symbolValue, err := b.FormatSymbol(symbol, asset.CoinMarginedFutures) @@ -1109,11 +1110,11 @@ func (b *Binance) FuturesGetOrderData(symbol currency.Pair, orderID, origClientO if origClientOrderID != "" { params.Set("origClientOrderId", origClientOrderID) } - return resp, b.SendAuthHTTPRequest(exchange.RestCoinMargined, http.MethodGet, cfuturesOrder, params, cFuturesOrdersDefaultRate, &resp) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodGet, cfuturesOrder, params, cFuturesOrdersDefaultRate, &resp) } // FuturesCancelOrder cancels a futures order -func (b *Binance) FuturesCancelOrder(symbol currency.Pair, orderID, origClientOrderID string) (FuturesOrderGetData, error) { +func (b *Binance) FuturesCancelOrder(ctx context.Context, symbol currency.Pair, orderID, origClientOrderID string) (FuturesOrderGetData, error) { var resp FuturesOrderGetData params := url.Values{} symbolValue, err := b.FormatSymbol(symbol, asset.CoinMarginedFutures) @@ -1127,11 +1128,11 @@ func (b *Binance) FuturesCancelOrder(symbol currency.Pair, orderID, origClientOr if origClientOrderID != "" { params.Set("origClientOrderId", origClientOrderID) } - return resp, b.SendAuthHTTPRequest(exchange.RestCoinMargined, http.MethodDelete, cfuturesOrder, params, cFuturesOrdersDefaultRate, &resp) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodDelete, cfuturesOrder, params, cFuturesOrdersDefaultRate, &resp) } // FuturesCancelAllOpenOrders cancels a futures order -func (b *Binance) FuturesCancelAllOpenOrders(symbol currency.Pair) (GenericAuthResponse, error) { +func (b *Binance) FuturesCancelAllOpenOrders(ctx context.Context, symbol currency.Pair) (GenericAuthResponse, error) { var resp GenericAuthResponse params := url.Values{} symbolValue, err := b.FormatSymbol(symbol, asset.CoinMarginedFutures) @@ -1139,12 +1140,12 @@ func (b *Binance) FuturesCancelAllOpenOrders(symbol currency.Pair) (GenericAuthR return resp, err } params.Set("symbol", symbolValue) - return resp, b.SendAuthHTTPRequest(exchange.RestCoinMargined, http.MethodDelete, cfuturesCancelAllOrders, params, cFuturesOrdersDefaultRate, &resp) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodDelete, cfuturesCancelAllOrders, params, cFuturesOrdersDefaultRate, &resp) } // AutoCancelAllOpenOrders cancels all open futures orders // countdownTime 1000 = 1s, example - to cancel all orders after 30s (countdownTime: 30000) -func (b *Binance) AutoCancelAllOpenOrders(symbol currency.Pair, countdownTime int64) (AutoCancelAllOrdersData, error) { +func (b *Binance) AutoCancelAllOpenOrders(ctx context.Context, symbol currency.Pair, countdownTime int64) (AutoCancelAllOrdersData, error) { var resp AutoCancelAllOrdersData params := url.Values{} symbolValue, err := b.FormatSymbol(symbol, asset.CoinMarginedFutures) @@ -1153,11 +1154,11 @@ func (b *Binance) AutoCancelAllOpenOrders(symbol currency.Pair, countdownTime in } params.Set("symbol", symbolValue) params.Set("countdownTime", strconv.FormatInt(countdownTime, 10)) - return resp, b.SendAuthHTTPRequest(exchange.RestCoinMargined, http.MethodPost, cfuturesCountdownCancel, params, cFuturesCancelAllOrdersRate, &resp) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodPost, cfuturesCountdownCancel, params, cFuturesCancelAllOrdersRate, &resp) } // FuturesOpenOrderData gets open order data for CoinMarginedFutures, -func (b *Binance) FuturesOpenOrderData(symbol currency.Pair, orderID, origClientOrderID string) (FuturesOrderGetData, error) { +func (b *Binance) FuturesOpenOrderData(ctx context.Context, symbol currency.Pair, orderID, origClientOrderID string) (FuturesOrderGetData, error) { var resp FuturesOrderGetData params := url.Values{} symbolValue, err := b.FormatSymbol(symbol, asset.CoinMarginedFutures) @@ -1171,11 +1172,11 @@ func (b *Binance) FuturesOpenOrderData(symbol currency.Pair, orderID, origClient if origClientOrderID != "" { params.Set("origClientOrderId", origClientOrderID) } - return resp, b.SendAuthHTTPRequest(exchange.RestCoinMargined, http.MethodGet, cfuturesOpenOrder, params, cFuturesOrdersDefaultRate, &resp) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodGet, cfuturesOpenOrder, params, cFuturesOrdersDefaultRate, &resp) } // GetFuturesAllOpenOrders gets all open orders data for CoinMarginedFutures, -func (b *Binance) GetFuturesAllOpenOrders(symbol currency.Pair, pair string) ([]FuturesOrderData, error) { +func (b *Binance) GetFuturesAllOpenOrders(ctx context.Context, symbol currency.Pair, pair string) ([]FuturesOrderData, error) { var resp []FuturesOrderData params := url.Values{} var p string @@ -1195,11 +1196,11 @@ func (b *Binance) GetFuturesAllOpenOrders(symbol currency.Pair, pair string) ([] if pair != "" { params.Set("pair", pair) } - return resp, b.SendAuthHTTPRequest(exchange.RestCoinMargined, http.MethodGet, cfuturesAllOpenOrders, params, rateLimit, &resp) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodGet, cfuturesAllOpenOrders, params, rateLimit, &resp) } // GetAllFuturesOrders gets all orders active cancelled or filled -func (b *Binance) GetAllFuturesOrders(symbol currency.Pair, pair string, startTime, endTime time.Time, orderID, limit int64) ([]FuturesOrderData, error) { +func (b *Binance) GetAllFuturesOrders(ctx context.Context, symbol currency.Pair, pair string, startTime, endTime time.Time, orderID, limit int64) ([]FuturesOrderData, error) { var resp []FuturesOrderData params := url.Values{} rateLimit := cFuturesPairOrdersRate @@ -1227,23 +1228,23 @@ func (b *Binance) GetAllFuturesOrders(symbol currency.Pair, pair string, startTi params.Set("start_time", strconv.FormatInt(startTime.Unix(), 10)) params.Set("end_time", strconv.FormatInt(endTime.Unix(), 10)) } - return resp, b.SendAuthHTTPRequest(exchange.RestCoinMargined, http.MethodGet, cfuturesAllOrders, params, rateLimit, &resp) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodGet, cfuturesAllOrders, params, rateLimit, &resp) } // GetFuturesAccountBalance gets account balance data for CoinMarginedFutures, account -func (b *Binance) GetFuturesAccountBalance() ([]FuturesAccountBalanceData, error) { +func (b *Binance) GetFuturesAccountBalance(ctx context.Context) ([]FuturesAccountBalanceData, error) { var resp []FuturesAccountBalanceData - return resp, b.SendAuthHTTPRequest(exchange.RestCoinMargined, http.MethodGet, cfuturesAccountBalance, nil, cFuturesDefaultRate, &resp) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodGet, cfuturesAccountBalance, nil, cFuturesDefaultRate, &resp) } // GetFuturesAccountInfo gets account info data for CoinMarginedFutures, account -func (b *Binance) GetFuturesAccountInfo() (FuturesAccountInformation, error) { +func (b *Binance) GetFuturesAccountInfo(ctx context.Context) (FuturesAccountInformation, error) { var resp FuturesAccountInformation - return resp, b.SendAuthHTTPRequest(exchange.RestCoinMargined, http.MethodGet, cfuturesAccountInfo, nil, cFuturesAccountInformationRate, &resp) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodGet, cfuturesAccountInfo, nil, cFuturesAccountInformationRate, &resp) } // FuturesChangeInitialLeverage changes initial leverage for the account -func (b *Binance) FuturesChangeInitialLeverage(symbol currency.Pair, leverage int64) (FuturesLeverageData, error) { +func (b *Binance) FuturesChangeInitialLeverage(ctx context.Context, symbol currency.Pair, leverage int64) (FuturesLeverageData, error) { var resp FuturesLeverageData params := url.Values{} symbolValue, err := b.FormatSymbol(symbol, asset.CoinMarginedFutures) @@ -1255,11 +1256,11 @@ func (b *Binance) FuturesChangeInitialLeverage(symbol currency.Pair, leverage in return resp, errors.New("invalid leverage") } params.Set("leverage", strconv.FormatInt(leverage, 10)) - return resp, b.SendAuthHTTPRequest(exchange.RestCoinMargined, http.MethodPost, cfuturesChangeInitialLeverage, params, cFuturesDefaultRate, &resp) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodPost, cfuturesChangeInitialLeverage, params, cFuturesDefaultRate, &resp) } // FuturesChangeMarginType changes margin type -func (b *Binance) FuturesChangeMarginType(symbol currency.Pair, marginType string) (GenericAuthResponse, error) { +func (b *Binance) FuturesChangeMarginType(ctx context.Context, symbol currency.Pair, marginType string) (GenericAuthResponse, error) { var resp GenericAuthResponse params := url.Values{} symbolValue, err := b.FormatSymbol(symbol, asset.CoinMarginedFutures) @@ -1271,11 +1272,11 @@ func (b *Binance) FuturesChangeMarginType(symbol currency.Pair, marginType strin return resp, errors.New("invalid marginType") } params.Set("marginType", marginType) - return resp, b.SendAuthHTTPRequest(exchange.RestCoinMargined, http.MethodPost, cfuturesChangeMarginType, params, cFuturesDefaultRate, &resp) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodPost, cfuturesChangeMarginType, params, cFuturesDefaultRate, &resp) } // ModifyIsolatedPositionMargin changes margin for an isolated position -func (b *Binance) ModifyIsolatedPositionMargin(symbol currency.Pair, positionSide, changeType string, amount float64) (GenericAuthResponse, error) { +func (b *Binance) ModifyIsolatedPositionMargin(ctx context.Context, symbol currency.Pair, positionSide, changeType string, amount float64) (GenericAuthResponse, error) { var resp GenericAuthResponse params := url.Values{} symbolValue, err := b.FormatSymbol(symbol, asset.CoinMarginedFutures) @@ -1293,11 +1294,11 @@ func (b *Binance) ModifyIsolatedPositionMargin(symbol currency.Pair, positionSid } params.Set("type", strconv.FormatInt(cType, 10)) params.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) - return resp, b.SendAuthHTTPRequest(exchange.RestCoinMargined, http.MethodPost, cfuturesModifyMargin, params, cFuturesDefaultRate, &resp) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodPost, cfuturesModifyMargin, params, cFuturesDefaultRate, &resp) } // FuturesMarginChangeHistory gets past margin changes for positions -func (b *Binance) FuturesMarginChangeHistory(symbol currency.Pair, changeType string, startTime, endTime time.Time, limit int64) ([]GetPositionMarginChangeHistoryData, error) { +func (b *Binance) FuturesMarginChangeHistory(ctx context.Context, symbol currency.Pair, changeType string, startTime, endTime time.Time, limit int64) ([]GetPositionMarginChangeHistoryData, error) { var resp []GetPositionMarginChangeHistoryData params := url.Values{} symbolValue, err := b.FormatSymbol(symbol, asset.CoinMarginedFutures) @@ -1320,11 +1321,11 @@ func (b *Binance) FuturesMarginChangeHistory(symbol currency.Pair, changeType st if limit != 0 { params.Set("limit", strconv.FormatInt(limit, 10)) } - return resp, b.SendAuthHTTPRequest(exchange.RestCoinMargined, http.MethodGet, cfuturesMarginChangeHistory, params, cFuturesDefaultRate, &resp) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodGet, cfuturesMarginChangeHistory, params, cFuturesDefaultRate, &resp) } // FuturesPositionsInfo gets futures positions info -func (b *Binance) FuturesPositionsInfo(marginAsset, pair string) ([]FuturesPositionInformation, error) { +func (b *Binance) FuturesPositionsInfo(ctx context.Context, marginAsset, pair string) ([]FuturesPositionInformation, error) { var resp []FuturesPositionInformation params := url.Values{} if marginAsset != "" { @@ -1333,11 +1334,11 @@ func (b *Binance) FuturesPositionsInfo(marginAsset, pair string) ([]FuturesPosit if pair != "" { params.Set("pair", pair) } - return resp, b.SendAuthHTTPRequest(exchange.RestCoinMargined, http.MethodGet, cfuturesPositionInfo, params, cFuturesDefaultRate, &resp) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodGet, cfuturesPositionInfo, params, cFuturesDefaultRate, &resp) } // FuturesTradeHistory gets trade history for CoinMarginedFutures, account -func (b *Binance) FuturesTradeHistory(symbol currency.Pair, pair string, startTime, endTime time.Time, limit, fromID int64) ([]FuturesAccountTradeList, error) { +func (b *Binance) FuturesTradeHistory(ctx context.Context, symbol currency.Pair, pair string, startTime, endTime time.Time, limit, fromID int64) ([]FuturesAccountTradeList, error) { var resp []FuturesAccountTradeList params := url.Values{} rateLimit := cFuturesPairOrdersRate @@ -1365,11 +1366,11 @@ func (b *Binance) FuturesTradeHistory(symbol currency.Pair, pair string, startTi if fromID != 0 { params.Set("fromId", strconv.FormatInt(fromID, 10)) } - return resp, b.SendAuthHTTPRequest(exchange.RestCoinMargined, http.MethodGet, cfuturesAccountTradeList, params, rateLimit, &resp) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodGet, cfuturesAccountTradeList, params, rateLimit, &resp) } // FuturesIncomeHistory gets income history for CoinMarginedFutures, -func (b *Binance) FuturesIncomeHistory(symbol currency.Pair, incomeType string, startTime, endTime time.Time, limit int64) ([]FuturesIncomeHistoryData, error) { +func (b *Binance) FuturesIncomeHistory(ctx context.Context, symbol currency.Pair, incomeType string, startTime, endTime time.Time, limit int64) ([]FuturesIncomeHistoryData, error) { var resp []FuturesIncomeHistoryData params := url.Values{} if !symbol.IsEmpty() { @@ -1395,21 +1396,21 @@ func (b *Binance) FuturesIncomeHistory(symbol currency.Pair, incomeType string, if limit != 0 { params.Set("limit", strconv.FormatInt(limit, 10)) } - return resp, b.SendAuthHTTPRequest(exchange.RestCoinMargined, http.MethodGet, cfuturesIncomeHistory, params, cFuturesIncomeHistoryRate, &resp) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodGet, cfuturesIncomeHistory, params, cFuturesIncomeHistoryRate, &resp) } // FuturesNotionalBracket gets futures notional bracket -func (b *Binance) FuturesNotionalBracket(pair string) ([]NotionalBracketData, error) { +func (b *Binance) FuturesNotionalBracket(ctx context.Context, pair string) ([]NotionalBracketData, error) { var resp []NotionalBracketData params := url.Values{} if pair != "" { params.Set("pair", pair) } - return resp, b.SendAuthHTTPRequest(exchange.RestCoinMargined, http.MethodGet, cfuturesNotionalBracket, params, cFuturesDefaultRate, &resp) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodGet, cfuturesNotionalBracket, params, cFuturesDefaultRate, &resp) } // FuturesForceOrders gets futures forced orders -func (b *Binance) FuturesForceOrders(symbol currency.Pair, autoCloseType string, startTime, endTime time.Time) ([]ForcedOrdersData, error) { +func (b *Binance) FuturesForceOrders(ctx context.Context, symbol currency.Pair, autoCloseType string, startTime, endTime time.Time) ([]ForcedOrdersData, error) { var resp []ForcedOrdersData params := url.Values{} if !symbol.IsEmpty() { @@ -1432,11 +1433,11 @@ func (b *Binance) FuturesForceOrders(symbol currency.Pair, autoCloseType string, params.Set("start_time", strconv.FormatInt(startTime.Unix(), 10)) params.Set("end_time", strconv.FormatInt(endTime.Unix(), 10)) } - return resp, b.SendAuthHTTPRequest(exchange.RestCoinMargined, http.MethodGet, cfuturesUsersForceOrders, params, cFuturesDefaultRate, &resp) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodGet, cfuturesUsersForceOrders, params, cFuturesDefaultRate, &resp) } // FuturesPositionsADLEstimate estimates ADL on positions -func (b *Binance) FuturesPositionsADLEstimate(symbol currency.Pair) ([]ADLEstimateData, error) { +func (b *Binance) FuturesPositionsADLEstimate(ctx context.Context, symbol currency.Pair) ([]ADLEstimateData, error) { var resp []ADLEstimateData params := url.Values{} if !symbol.IsEmpty() { @@ -1446,13 +1447,13 @@ func (b *Binance) FuturesPositionsADLEstimate(symbol currency.Pair) ([]ADLEstima } params.Set("symbol", symbolValue) } - return resp, b.SendAuthHTTPRequest(exchange.RestCoinMargined, http.MethodGet, cfuturesADLQuantile, params, cFuturesAccountInformationRate, &resp) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestCoinMargined, http.MethodGet, cfuturesADLQuantile, params, cFuturesAccountInformationRate, &resp) } // FetchCoinMarginExchangeLimits fetches coin margined order execution limits -func (b *Binance) FetchCoinMarginExchangeLimits() ([]order.MinMaxLevel, error) { +func (b *Binance) FetchCoinMarginExchangeLimits(ctx context.Context) ([]order.MinMaxLevel, error) { var limits []order.MinMaxLevel - coinFutures, err := b.FuturesExchangeInfo() + coinFutures, err := b.FuturesExchangeInfo(ctx) if err != nil { return nil, err } diff --git a/exchanges/binance/binance_test.go b/exchanges/binance/binance_test.go index 325e5f46..c49a52bc 100644 --- a/exchanges/binance/binance_test.go +++ b/exchanges/binance/binance_test.go @@ -1,6 +1,7 @@ package binance import ( + "context" "encoding/json" "errors" "fmt" @@ -46,7 +47,7 @@ func setFeeBuilder() *exchange.FeeBuilder { func TestUServerTime(t *testing.T) { t.Parallel() - _, err := b.UServerTime() + _, err := b.UServerTime(context.Background()) if err != nil { t.Error(err) } @@ -54,7 +55,7 @@ func TestUServerTime(t *testing.T) { func TestUpdateTicker(t *testing.T) { t.Parallel() - spotPairs, err := b.FetchTradablePairs(asset.Spot) + spotPairs, err := b.FetchTradablePairs(context.Background(), asset.Spot) if err != nil { t.Error(err) } @@ -65,11 +66,11 @@ func TestUpdateTicker(t *testing.T) { if err != nil { t.Error(err) } - _, err = b.UpdateTicker(spotCP, asset.Spot) + _, err = b.UpdateTicker(context.Background(), spotCP, asset.Spot) if err != nil { t.Error(err) } - tradablePairs, err := b.FetchTradablePairs(asset.CoinMarginedFutures) + tradablePairs, err := b.FetchTradablePairs(context.Background(), asset.CoinMarginedFutures) if err != nil { t.Error(err) } @@ -80,12 +81,12 @@ func TestUpdateTicker(t *testing.T) { if err != nil { t.Error(err) } - _, err = b.UpdateTicker(cp, asset.CoinMarginedFutures) + _, err = b.UpdateTicker(context.Background(), cp, asset.CoinMarginedFutures) if err != nil { t.Error(err) } - usdtMarginedPairs, err := b.FetchTradablePairs(asset.USDTMarginedFutures) + usdtMarginedPairs, err := b.FetchTradablePairs(context.Background(), asset.USDTMarginedFutures) if err != nil { t.Error(err) } @@ -96,24 +97,24 @@ func TestUpdateTicker(t *testing.T) { if err != nil { t.Error(err) } - _, err = b.UpdateTicker(ucp, asset.USDTMarginedFutures) + _, err = b.UpdateTicker(context.Background(), ucp, asset.USDTMarginedFutures) if err != nil { t.Error(err) } } func TestUpdateTickers(t *testing.T) { - err := b.UpdateTickers(asset.Spot) + err := b.UpdateTickers(context.Background(), asset.Spot) if err != nil { t.Error(err) } - err = b.UpdateTickers(asset.CoinMarginedFutures) + err = b.UpdateTickers(context.Background(), asset.CoinMarginedFutures) if err != nil { t.Error(err) } - err = b.UpdateTickers(asset.USDTMarginedFutures) + err = b.UpdateTickers(context.Background(), asset.USDTMarginedFutures) if err != nil { t.Error(err) } @@ -125,15 +126,15 @@ func TestUpdateOrderbook(t *testing.T) { if err != nil { t.Error(err) } - _, err = b.UpdateOrderbook(cp, asset.Spot) + _, err = b.UpdateOrderbook(context.Background(), cp, asset.Spot) if err != nil { t.Error(err) } - _, err = b.UpdateOrderbook(cp, asset.Margin) + _, err = b.UpdateOrderbook(context.Background(), cp, asset.Margin) if err != nil { t.Error(err) } - _, err = b.UpdateOrderbook(cp, asset.USDTMarginedFutures) + _, err = b.UpdateOrderbook(context.Background(), cp, asset.USDTMarginedFutures) if err != nil { t.Error(err) } @@ -141,7 +142,7 @@ func TestUpdateOrderbook(t *testing.T) { if err != nil { t.Error(err) } - _, err = b.UpdateOrderbook(cp2, asset.CoinMarginedFutures) + _, err = b.UpdateOrderbook(context.Background(), cp2, asset.CoinMarginedFutures) if err != nil { t.Error(err) } @@ -151,7 +152,7 @@ func TestUpdateOrderbook(t *testing.T) { func TestUExchangeInfo(t *testing.T) { t.Parallel() - _, err := b.UExchangeInfo() + _, err := b.UExchangeInfo(context.Background()) if err != nil { t.Error(err) } @@ -159,7 +160,7 @@ func TestUExchangeInfo(t *testing.T) { func TestUFuturesOrderbook(t *testing.T) { t.Parallel() - _, err := b.UFuturesOrderbook(currency.Pair{Delimiter: "_", Base: currency.BTC, Quote: currency.USDT}, 1000) + _, err := b.UFuturesOrderbook(context.Background(), currency.Pair{Delimiter: "_", Base: currency.BTC, Quote: currency.USDT}, 1000) if err != nil { t.Error(err) } @@ -167,7 +168,7 @@ func TestUFuturesOrderbook(t *testing.T) { func TestURecentTrades(t *testing.T) { t.Parallel() - _, err := b.URecentTrades(currency.NewPair(currency.BTC, currency.USDT), "", 5) + _, err := b.URecentTrades(context.Background(), currency.NewPair(currency.BTC, currency.USDT), "", 5) if err != nil { t.Error(err) } @@ -175,11 +176,11 @@ func TestURecentTrades(t *testing.T) { func TestUCompressedTrades(t *testing.T) { t.Parallel() - _, err := b.UCompressedTrades(currency.NewPair(currency.BTC, currency.USDT), "", 5, time.Time{}, time.Time{}) + _, err := b.UCompressedTrades(context.Background(), currency.NewPair(currency.BTC, currency.USDT), "", 5, time.Time{}, time.Time{}) if err != nil { t.Error(err) } - _, err = b.UCompressedTrades(currency.NewPair(currency.LTC, currency.USDT), "", 0, time.Unix(1577836800, 0), time.Unix(1580515200, 0)) + _, err = b.UCompressedTrades(context.Background(), currency.NewPair(currency.LTC, currency.USDT), "", 0, time.Unix(1577836800, 0), time.Unix(1580515200, 0)) if err != nil { t.Error(err) } @@ -187,11 +188,11 @@ func TestUCompressedTrades(t *testing.T) { func TestUKlineData(t *testing.T) { t.Parallel() - _, err := b.UKlineData(currency.NewPair(currency.BTC, currency.USDT), "1d", 5, time.Time{}, time.Time{}) + _, err := b.UKlineData(context.Background(), currency.NewPair(currency.BTC, currency.USDT), "1d", 5, time.Time{}, time.Time{}) if err != nil { t.Error(err) } - _, err = b.UKlineData(currency.NewPair(currency.LTC, currency.USDT), "5m", 0, time.Unix(1577836800, 0), time.Unix(1580515200, 0)) + _, err = b.UKlineData(context.Background(), currency.NewPair(currency.LTC, currency.USDT), "5m", 0, time.Unix(1577836800, 0), time.Unix(1580515200, 0)) if err != nil { t.Error(err) } @@ -199,11 +200,11 @@ func TestUKlineData(t *testing.T) { func TestUGetMarkPrice(t *testing.T) { t.Parallel() - _, err := b.UGetMarkPrice(currency.NewPair(currency.BTC, currency.USDT)) + _, err := b.UGetMarkPrice(context.Background(), currency.NewPair(currency.BTC, currency.USDT)) if err != nil { t.Error(err) } - _, err = b.UGetMarkPrice(currency.Pair{}) + _, err = b.UGetMarkPrice(context.Background(), currency.Pair{}) if err != nil { t.Error(err) } @@ -211,11 +212,11 @@ func TestUGetMarkPrice(t *testing.T) { func TestUGetFundingHistory(t *testing.T) { t.Parallel() - _, err := b.UGetFundingHistory(currency.NewPair(currency.BTC, currency.USDT), 1, time.Time{}, time.Time{}) + _, err := b.UGetFundingHistory(context.Background(), currency.NewPair(currency.BTC, currency.USDT), 1, time.Time{}, time.Time{}) if err != nil { t.Error(err) } - _, err = b.UGetFundingHistory(currency.NewPair(currency.LTC, currency.USDT), 1, time.Unix(1577836800, 0), time.Unix(1580515200, 0)) + _, err = b.UGetFundingHistory(context.Background(), currency.NewPair(currency.LTC, currency.USDT), 1, time.Unix(1577836800, 0), time.Unix(1580515200, 0)) if err != nil { t.Error(err) } @@ -223,11 +224,11 @@ func TestUGetFundingHistory(t *testing.T) { func TestU24HTickerPriceChangeStats(t *testing.T) { t.Parallel() - _, err := b.U24HTickerPriceChangeStats(currency.NewPair(currency.BTC, currency.USDT)) + _, err := b.U24HTickerPriceChangeStats(context.Background(), currency.NewPair(currency.BTC, currency.USDT)) if err != nil { t.Error(err) } - _, err = b.U24HTickerPriceChangeStats(currency.Pair{}) + _, err = b.U24HTickerPriceChangeStats(context.Background(), currency.Pair{}) if err != nil { t.Error(err) } @@ -235,11 +236,11 @@ func TestU24HTickerPriceChangeStats(t *testing.T) { func TestUSymbolPriceTicker(t *testing.T) { t.Parallel() - _, err := b.USymbolPriceTicker(currency.NewPair(currency.BTC, currency.USDT)) + _, err := b.USymbolPriceTicker(context.Background(), currency.NewPair(currency.BTC, currency.USDT)) if err != nil { t.Error(err) } - _, err = b.USymbolPriceTicker(currency.Pair{}) + _, err = b.USymbolPriceTicker(context.Background(), currency.Pair{}) if err != nil { t.Error(err) } @@ -247,11 +248,11 @@ func TestUSymbolPriceTicker(t *testing.T) { func TestUSymbolOrderbookTicker(t *testing.T) { t.Parallel() - _, err := b.USymbolOrderbookTicker(currency.NewPair(currency.BTC, currency.USDT)) + _, err := b.USymbolOrderbookTicker(context.Background(), currency.NewPair(currency.BTC, currency.USDT)) if err != nil { t.Error(err) } - _, err = b.USymbolOrderbookTicker(currency.Pair{}) + _, err = b.USymbolOrderbookTicker(context.Background(), currency.Pair{}) if err != nil { t.Error(err) } @@ -259,11 +260,11 @@ func TestUSymbolOrderbookTicker(t *testing.T) { func TestULiquidationOrders(t *testing.T) { t.Parallel() - _, err := b.ULiquidationOrders(currency.NewPair(currency.BTC, currency.USDT), 0, time.Time{}, time.Time{}) + _, err := b.ULiquidationOrders(context.Background(), currency.NewPair(currency.BTC, currency.USDT), 0, time.Time{}, time.Time{}) if err != nil { t.Error(err) } - _, err = b.ULiquidationOrders(currency.NewPair(currency.LTC, currency.USDT), 5, time.Unix(1577836800, 0), time.Unix(1580515200, 0)) + _, err = b.ULiquidationOrders(context.Background(), currency.NewPair(currency.LTC, currency.USDT), 5, time.Unix(1577836800, 0), time.Unix(1580515200, 0)) if err != nil { t.Error(err) } @@ -271,7 +272,7 @@ func TestULiquidationOrders(t *testing.T) { func TestUOpenInterest(t *testing.T) { t.Parallel() - _, err := b.UOpenInterest(currency.NewPair(currency.BTC, currency.USDT)) + _, err := b.UOpenInterest(context.Background(), currency.NewPair(currency.BTC, currency.USDT)) if err != nil { t.Error(err) } @@ -279,11 +280,11 @@ func TestUOpenInterest(t *testing.T) { func TestUOpenInterestStats(t *testing.T) { t.Parallel() - _, err := b.UOpenInterestStats(currency.NewPair(currency.BTC, currency.USDT), "5m", 1, time.Time{}, time.Time{}) + _, err := b.UOpenInterestStats(context.Background(), currency.NewPair(currency.BTC, currency.USDT), "5m", 1, time.Time{}, time.Time{}) if err != nil { t.Error(err) } - _, err = b.UOpenInterestStats(currency.NewPair(currency.LTC, currency.USDT), "1d", 10, time.Unix(1577836800, 0), time.Unix(1580515200, 0)) + _, err = b.UOpenInterestStats(context.Background(), currency.NewPair(currency.LTC, currency.USDT), "1d", 10, time.Unix(1577836800, 0), time.Unix(1580515200, 0)) if err != nil { t.Error(err) } @@ -291,11 +292,11 @@ func TestUOpenInterestStats(t *testing.T) { func TestUTopAcccountsLongShortRatio(t *testing.T) { t.Parallel() - _, err := b.UTopAcccountsLongShortRatio(currency.NewPair(currency.BTC, currency.USDT), "5m", 2, time.Time{}, time.Time{}) + _, err := b.UTopAcccountsLongShortRatio(context.Background(), currency.NewPair(currency.BTC, currency.USDT), "5m", 2, time.Time{}, time.Time{}) if err != nil { t.Error(err) } - _, err = b.UTopAcccountsLongShortRatio(currency.NewPair(currency.BTC, currency.USDT), "5m", 2, time.Unix(1577836800, 0), time.Unix(1580515200, 0)) + _, err = b.UTopAcccountsLongShortRatio(context.Background(), currency.NewPair(currency.BTC, currency.USDT), "5m", 2, time.Unix(1577836800, 0), time.Unix(1580515200, 0)) if err != nil { t.Error(err) } @@ -303,11 +304,11 @@ func TestUTopAcccountsLongShortRatio(t *testing.T) { func TestUTopPostionsLongShortRatio(t *testing.T) { t.Parallel() - _, err := b.UTopPostionsLongShortRatio(currency.NewPair(currency.BTC, currency.USDT), "5m", 3, time.Time{}, time.Time{}) + _, err := b.UTopPostionsLongShortRatio(context.Background(), currency.NewPair(currency.BTC, currency.USDT), "5m", 3, time.Time{}, time.Time{}) if err != nil { t.Error(err) } - _, err = b.UTopPostionsLongShortRatio(currency.NewPair(currency.BTC, currency.USDT), "1d", 0, time.Unix(1577836800, 0), time.Unix(1580515200, 0)) + _, err = b.UTopPostionsLongShortRatio(context.Background(), currency.NewPair(currency.BTC, currency.USDT), "1d", 0, time.Unix(1577836800, 0), time.Unix(1580515200, 0)) if err != nil { t.Error(err) } @@ -315,11 +316,11 @@ func TestUTopPostionsLongShortRatio(t *testing.T) { func TestUGlobalLongShortRatio(t *testing.T) { t.Parallel() - _, err := b.UGlobalLongShortRatio(currency.NewPair(currency.BTC, currency.USDT), "5m", 3, time.Time{}, time.Time{}) + _, err := b.UGlobalLongShortRatio(context.Background(), currency.NewPair(currency.BTC, currency.USDT), "5m", 3, time.Time{}, time.Time{}) if err != nil { t.Error(err) } - _, err = b.UGlobalLongShortRatio(currency.NewPair(currency.BTC, currency.USDT), "4h", 0, time.Unix(1577836800, 0), time.Unix(1580515200, 0)) + _, err = b.UGlobalLongShortRatio(context.Background(), currency.NewPair(currency.BTC, currency.USDT), "4h", 0, time.Unix(1577836800, 0), time.Unix(1580515200, 0)) if err != nil { t.Error(err) } @@ -327,7 +328,7 @@ func TestUGlobalLongShortRatio(t *testing.T) { func TestUTakerBuySellVol(t *testing.T) { t.Parallel() - _, err := b.UTakerBuySellVol(currency.NewPair(currency.BTC, currency.USDT), "5m", 10, time.Unix(1577836800, 0), time.Unix(1580515200, 0)) + _, err := b.UTakerBuySellVol(context.Background(), currency.NewPair(currency.BTC, currency.USDT), "5m", 10, time.Unix(1577836800, 0), time.Unix(1580515200, 0)) if err != nil { t.Error(err) } @@ -339,11 +340,11 @@ func TestUCompositeIndexInfo(t *testing.T) { if err != nil { t.Error(err) } - _, err = b.UCompositeIndexInfo(cp) + _, err = b.UCompositeIndexInfo(context.Background(), cp) if err != nil { t.Error(err) } - _, err = b.UCompositeIndexInfo(currency.Pair{}) + _, err = b.UCompositeIndexInfo(context.Background(), currency.Pair{}) if err != nil { t.Error(err) } @@ -354,7 +355,7 @@ func TestUFuturesNewOrder(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test: api keys not set or canManipulateRealOrders set to false") } - _, err := b.UFuturesNewOrder(currency.NewPair(currency.BTC, currency.USDT), "BUY", "", "LIMIT", "GTC", "", "", "", "", 1, 1, 0, 0, 0, false) + _, err := b.UFuturesNewOrder(context.Background(), currency.NewPair(currency.BTC, currency.USDT), "BUY", "", "LIMIT", "GTC", "", "", "", "", 1, 1, 0, 0, 0, false) if err != nil { t.Error(err) } @@ -374,7 +375,7 @@ func TestUPlaceBatchOrders(t *testing.T) { tempData.Price = 1 tempData.TimeInForce = "GTC" data = append(data, tempData) - _, err := b.UPlaceBatchOrders(data) + _, err := b.UPlaceBatchOrders(context.Background(), data) if err != nil { t.Error(err) } @@ -385,7 +386,7 @@ func TestUGetOrderData(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("skipping test: api keys not set") } - _, err := b.UGetOrderData(currency.NewPair(currency.BTC, currency.USDT), "123", "") + _, err := b.UGetOrderData(context.Background(), currency.NewPair(currency.BTC, currency.USDT), "123", "") if err != nil { t.Error(err) } @@ -396,7 +397,7 @@ func TestUCancelOrder(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test: api keys not set or canManipulateRealOrders set to false") } - _, err := b.UCancelOrder(currency.NewPair(currency.BTC, currency.USDT), "123", "") + _, err := b.UCancelOrder(context.Background(), currency.NewPair(currency.BTC, currency.USDT), "123", "") if err != nil { t.Error(err) } @@ -407,7 +408,7 @@ func TestUCancelAllOpenOrders(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test: api keys not set or canManipulateRealOrders set to false") } - _, err := b.UCancelAllOpenOrders(currency.NewPair(currency.BTC, currency.USDT)) + _, err := b.UCancelAllOpenOrders(context.Background(), currency.NewPair(currency.BTC, currency.USDT)) if err != nil { t.Error(err) } @@ -418,7 +419,7 @@ func TestUCancelBatchOrders(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test: api keys not set or canManipulateRealOrders set to false") } - _, err := b.UCancelBatchOrders(currency.NewPair(currency.BTC, currency.USDT), []string{"123"}, []string{}) + _, err := b.UCancelBatchOrders(context.Background(), currency.NewPair(currency.BTC, currency.USDT), []string{"123"}, []string{}) if err != nil { t.Error(err) } @@ -429,7 +430,7 @@ func TestUAutoCancelAllOpenOrders(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test: api keys not set or canManipulateRealOrders set to false") } - _, err := b.UAutoCancelAllOpenOrders(currency.NewPair(currency.BTC, currency.USDT), 30) + _, err := b.UAutoCancelAllOpenOrders(context.Background(), currency.NewPair(currency.BTC, currency.USDT), 30) if err != nil { t.Error(err) } @@ -440,7 +441,7 @@ func TestUFetchOpenOrder(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("skipping test: api keys not set") } - _, err := b.UFetchOpenOrder(currency.NewPair(currency.BTC, currency.USDT), "123", "") + _, err := b.UFetchOpenOrder(context.Background(), currency.NewPair(currency.BTC, currency.USDT), "123", "") if err != nil { t.Error(err) } @@ -451,7 +452,7 @@ func TestUAllAccountOpenOrders(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("skipping test: api keys not set") } - _, err := b.UAllAccountOpenOrders(currency.NewPair(currency.BTC, currency.USDT)) + _, err := b.UAllAccountOpenOrders(context.Background(), currency.NewPair(currency.BTC, currency.USDT)) if err != nil { t.Error(err) } @@ -462,11 +463,11 @@ func TestUAllAccountOrders(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("skipping test: api keys not set") } - _, err := b.UAllAccountOrders(currency.Pair{}, 0, 0, time.Time{}, time.Time{}) + _, err := b.UAllAccountOrders(context.Background(), currency.Pair{}, 0, 0, time.Time{}, time.Time{}) if err != nil { t.Error(err) } - _, err = b.UAllAccountOrders(currency.NewPair(currency.BTC, currency.USDT), 0, 5, time.Now().Add(-time.Hour*4), time.Now()) + _, err = b.UAllAccountOrders(context.Background(), currency.NewPair(currency.BTC, currency.USDT), 0, 5, time.Now().Add(-time.Hour*4), time.Now()) if err != nil { t.Error(err) } @@ -477,7 +478,7 @@ func TestUAccountBalanceV2(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("skipping test: api keys not set") } - _, err := b.UAccountBalanceV2() + _, err := b.UAccountBalanceV2(context.Background()) if err != nil { t.Error(err) } @@ -488,7 +489,7 @@ func TestUAccountInformationV2(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("skipping test: api keys not set") } - _, err := b.UAccountInformationV2() + _, err := b.UAccountInformationV2(context.Background()) if err != nil { t.Error(err) } @@ -499,7 +500,7 @@ func TestUChangeInitialLeverageRequest(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test: api keys not set or canManipulateRealOrders set to false") } - _, err := b.UChangeInitialLeverageRequest(currency.NewPair(currency.BTC, currency.USDT), 2) + _, err := b.UChangeInitialLeverageRequest(context.Background(), currency.NewPair(currency.BTC, currency.USDT), 2) if err != nil { t.Error(err) } @@ -510,7 +511,7 @@ func TestUChangeInitialMarginType(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test: api keys not set or canManipulateRealOrders set to false") } - err := b.UChangeInitialMarginType(currency.NewPair(currency.BTC, currency.USDT), "ISOLATED") + err := b.UChangeInitialMarginType(context.Background(), currency.NewPair(currency.BTC, currency.USDT), "ISOLATED") if err != nil { t.Error(err) } @@ -521,7 +522,7 @@ func TestUModifyIsolatedPositionMarginReq(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test: api keys not set or canManipulateRealOrders set to false") } - _, err := b.UModifyIsolatedPositionMarginReq(currency.NewPair(currency.BTC, currency.USDT), "LONG", "add", 5) + _, err := b.UModifyIsolatedPositionMarginReq(context.Background(), currency.NewPair(currency.BTC, currency.USDT), "LONG", "add", 5) if err != nil { t.Error(err) } @@ -532,7 +533,7 @@ func TestUPositionMarginChangeHistory(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("skipping test: api keys not set") } - _, err := b.UPositionMarginChangeHistory(currency.NewPair(currency.BTC, currency.USDT), "add", 5, time.Time{}, time.Time{}) + _, err := b.UPositionMarginChangeHistory(context.Background(), currency.NewPair(currency.BTC, currency.USDT), "add", 5, time.Time{}, time.Time{}) if err != nil { t.Error(err) } @@ -543,7 +544,7 @@ func TestUPositionsInfoV2(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("skipping test: api keys not set") } - _, err := b.UPositionsInfoV2(currency.NewPair(currency.BTC, currency.USDT)) + _, err := b.UPositionsInfoV2(context.Background(), currency.NewPair(currency.BTC, currency.USDT)) if err != nil { t.Error(err) } @@ -554,7 +555,7 @@ func TestUAccountTradesHistory(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("skipping test: api keys not set") } - _, err := b.UAccountTradesHistory(currency.NewPair(currency.BTC, currency.USDT), "", 5, time.Time{}, time.Time{}) + _, err := b.UAccountTradesHistory(context.Background(), currency.NewPair(currency.BTC, currency.USDT), "", 5, time.Time{}, time.Time{}) if err != nil { t.Error(err) } @@ -565,7 +566,7 @@ func TestUAccountIncomeHistory(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("skipping test: api keys not set") } - _, err := b.UAccountIncomeHistory(currency.Pair{}, "", 5, time.Now().Add(-time.Hour*48), time.Now()) + _, err := b.UAccountIncomeHistory(context.Background(), currency.Pair{}, "", 5, time.Now().Add(-time.Hour*48), time.Now()) if err != nil { t.Error(err) } @@ -576,7 +577,7 @@ func TestUGetNotionalAndLeverageBrackets(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("skipping test: api keys not set") } - _, err := b.UGetNotionalAndLeverageBrackets(currency.NewPair(currency.BTC, currency.USDT)) + _, err := b.UGetNotionalAndLeverageBrackets(context.Background(), currency.NewPair(currency.BTC, currency.USDT)) if err != nil { t.Error(err) } @@ -587,7 +588,7 @@ func TestUPositionsADLEstimate(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("skipping test: api keys not set") } - _, err := b.UPositionsADLEstimate(currency.NewPair(currency.BTC, currency.USDT)) + _, err := b.UPositionsADLEstimate(context.Background(), currency.NewPair(currency.BTC, currency.USDT)) if err != nil { t.Error(err) } @@ -598,7 +599,7 @@ func TestUAccountForcedOrders(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("skipping test: api keys not set") } - _, err := b.UAccountForcedOrders(currency.NewPair(currency.BTC, currency.USDT), "ADL", 5, time.Time{}, time.Time{}) + _, err := b.UAccountForcedOrders(context.Background(), currency.NewPair(currency.BTC, currency.USDT), "ADL", 5, time.Time{}, time.Time{}) if err != nil { t.Error(err) } @@ -608,7 +609,7 @@ func TestUAccountForcedOrders(t *testing.T) { func TestGetFuturesExchangeInfo(t *testing.T) { t.Parallel() - _, err := b.FuturesExchangeInfo() + _, err := b.FuturesExchangeInfo(context.Background()) if err != nil { t.Error(err) } @@ -616,7 +617,7 @@ func TestGetFuturesExchangeInfo(t *testing.T) { func TestGetInterestHistory(t *testing.T) { t.Parallel() - _, err := b.GetInterestHistory() + _, err := b.GetInterestHistory(context.Background()) if err != nil { t.Error(err) } @@ -624,7 +625,7 @@ func TestGetInterestHistory(t *testing.T) { func TestGetCrossMarginInterestHistory(t *testing.T) { t.Parallel() - _, err := b.GetCrossMarginInterestHistory() + _, err := b.GetCrossMarginInterestHistory(context.Background()) if err != nil { t.Error(err) } @@ -632,11 +633,11 @@ func TestGetCrossMarginInterestHistory(t *testing.T) { func TestGetFundingRates(t *testing.T) { t.Parallel() - _, err := b.GetFundingRates(currency.NewPair(currency.BTC, currency.USDT), "", time.Time{}, time.Time{}) + _, err := b.GetFundingRates(context.Background(), currency.NewPair(currency.BTC, currency.USDT), "", time.Time{}, time.Time{}) if err != nil { t.Error(err) } - _, err = b.GetFundingRates(currency.NewPair(currency.BTC, currency.USDT), "2", time.Unix(1577836800, 0), time.Unix(1580515200, 0)) + _, err = b.GetFundingRates(context.Background(), currency.NewPair(currency.BTC, currency.USDT), "2", time.Unix(1577836800, 0), time.Unix(1580515200, 0)) if err != nil { t.Error(err) } @@ -644,7 +645,7 @@ func TestGetFundingRates(t *testing.T) { func TestGetFuturesOrderbook(t *testing.T) { t.Parallel() - _, err := b.GetFuturesOrderbook(currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), 1000) + _, err := b.GetFuturesOrderbook(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), 1000) if err != nil { t.Error(err) } @@ -652,7 +653,7 @@ func TestGetFuturesOrderbook(t *testing.T) { func TestGetFuturesPublicTrades(t *testing.T) { t.Parallel() - _, err := b.GetFuturesPublicTrades(currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), 5) + _, err := b.GetFuturesPublicTrades(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), 5) if err != nil { t.Error(err) } @@ -660,7 +661,7 @@ func TestGetFuturesPublicTrades(t *testing.T) { func TestGetPastPublicTrades(t *testing.T) { t.Parallel() - _, err := b.GetPastPublicTrades(currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), 5, 0) + _, err := b.GetPastPublicTrades(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), 5, 0) if err != nil { t.Error(err) } @@ -668,7 +669,7 @@ func TestGetPastPublicTrades(t *testing.T) { func TestGetAggregatedTradesList(t *testing.T) { t.Parallel() - _, err := b.GetFuturesAggregatedTradesList(currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), 0, 5, time.Time{}, time.Time{}) + _, err := b.GetFuturesAggregatedTradesList(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), 0, 5, time.Time{}, time.Time{}) if err != nil { t.Error(err) } @@ -676,7 +677,7 @@ func TestGetAggregatedTradesList(t *testing.T) { func TestGetPerpsExchangeInfo(t *testing.T) { t.Parallel() - _, err := b.GetPerpMarkets() + _, err := b.GetPerpMarkets(context.Background()) if err != nil { t.Error(err) } @@ -684,7 +685,7 @@ func TestGetPerpsExchangeInfo(t *testing.T) { func TestGetIndexAndMarkPrice(t *testing.T) { t.Parallel() - _, err := b.GetIndexAndMarkPrice("", "BTCUSD") + _, err := b.GetIndexAndMarkPrice(context.Background(), "", "BTCUSD") if err != nil { t.Error(err) } @@ -692,12 +693,12 @@ func TestGetIndexAndMarkPrice(t *testing.T) { func TestGetFuturesKlineData(t *testing.T) { t.Parallel() - _, err := b.GetFuturesKlineData(currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "1M", 5, time.Time{}, time.Time{}) + _, err := b.GetFuturesKlineData(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "1M", 5, time.Time{}, time.Time{}) if err != nil { t.Error(err) } - _, err = b.GetFuturesKlineData(currency.NewPairWithDelimiter("LTCUSD", "PERP", "_"), "5m", 5, time.Unix(1577836800, 0), time.Unix(1580515200, 0)) + _, err = b.GetFuturesKlineData(context.Background(), currency.NewPairWithDelimiter("LTCUSD", "PERP", "_"), "5m", 5, time.Unix(1577836800, 0), time.Unix(1580515200, 0)) if err != nil { t.Error(err) } @@ -705,11 +706,11 @@ func TestGetFuturesKlineData(t *testing.T) { func TestGetContinuousKlineData(t *testing.T) { t.Parallel() - _, err := b.GetContinuousKlineData("BTCUSD", "CURRENT_QUARTER", "1M", 5, time.Time{}, time.Time{}) + _, err := b.GetContinuousKlineData(context.Background(), "BTCUSD", "CURRENT_QUARTER", "1M", 5, time.Time{}, time.Time{}) if err != nil { t.Error(err) } - _, err = b.GetContinuousKlineData("BTCUSD", "CURRENT_QUARTER", "1M", 5, time.Unix(1577836800, 0), time.Unix(1580515200, 0)) + _, err = b.GetContinuousKlineData(context.Background(), "BTCUSD", "CURRENT_QUARTER", "1M", 5, time.Unix(1577836800, 0), time.Unix(1580515200, 0)) if err != nil { t.Error(err) } @@ -717,11 +718,11 @@ func TestGetContinuousKlineData(t *testing.T) { func TestGetIndexPriceKlines(t *testing.T) { t.Parallel() - _, err := b.GetIndexPriceKlines("BTCUSD", "1M", 5, time.Time{}, time.Time{}) + _, err := b.GetIndexPriceKlines(context.Background(), "BTCUSD", "1M", 5, time.Time{}, time.Time{}) if err != nil { t.Error(err) } - _, err = b.GetIndexPriceKlines("BTCUSD", "1M", 5, time.Unix(1577836800, 0), time.Unix(1580515200, 0)) + _, err = b.GetIndexPriceKlines(context.Background(), "BTCUSD", "1M", 5, time.Unix(1577836800, 0), time.Unix(1580515200, 0)) if err != nil { t.Error(err) } @@ -729,15 +730,15 @@ func TestGetIndexPriceKlines(t *testing.T) { func TestGetFuturesSwapTickerChangeStats(t *testing.T) { t.Parallel() - _, err := b.GetFuturesSwapTickerChangeStats(currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "") + _, err := b.GetFuturesSwapTickerChangeStats(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "") if err != nil { t.Error(err) } - _, err = b.GetFuturesSwapTickerChangeStats(currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "") + _, err = b.GetFuturesSwapTickerChangeStats(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "") if err != nil { t.Error(err) } - _, err = b.GetFuturesSwapTickerChangeStats(currency.Pair{}, "") + _, err = b.GetFuturesSwapTickerChangeStats(context.Background(), currency.Pair{}, "") if err != nil { t.Error(err) } @@ -748,11 +749,11 @@ func TestFuturesGetFundingHistory(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("skipping test: api keys") } - _, err := b.FuturesGetFundingHistory(currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), 5, time.Time{}, time.Time{}) + _, err := b.FuturesGetFundingHistory(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), 5, time.Time{}, time.Time{}) if err != nil { t.Error(err) } - _, err = b.FuturesGetFundingHistory(currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), 50, time.Unix(1577836800, 0), time.Unix(1580515200, 0)) + _, err = b.FuturesGetFundingHistory(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), 50, time.Unix(1577836800, 0), time.Unix(1580515200, 0)) if err != nil { t.Error(err) } @@ -763,11 +764,11 @@ func TestGetFuturesHistoricalTrades(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("skipping test: api keys not set") } - _, err := b.GetFuturesHistoricalTrades(currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "", 5) + _, err := b.GetFuturesHistoricalTrades(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "", 5) if err != nil { t.Error(err) } - _, err = b.GetFuturesHistoricalTrades(currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "", 0) + _, err = b.GetFuturesHistoricalTrades(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "", 0) if err != nil { t.Error(err) } @@ -775,7 +776,7 @@ func TestGetFuturesHistoricalTrades(t *testing.T) { func TestGetFuturesSymbolPriceTicker(t *testing.T) { t.Parallel() - _, err := b.GetFuturesSymbolPriceTicker(currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "") + _, err := b.GetFuturesSymbolPriceTicker(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "") if err != nil { t.Error(err) } @@ -783,11 +784,11 @@ func TestGetFuturesSymbolPriceTicker(t *testing.T) { func TestGetFuturesOrderbookTicker(t *testing.T) { t.Parallel() - _, err := b.GetFuturesOrderbookTicker(currency.Pair{}, "") + _, err := b.GetFuturesOrderbookTicker(context.Background(), currency.Pair{}, "") if err != nil { t.Error(err) } - _, err = b.GetFuturesOrderbookTicker(currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "") + _, err = b.GetFuturesOrderbookTicker(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "") if err != nil { t.Error(err) } @@ -795,11 +796,11 @@ func TestGetFuturesOrderbookTicker(t *testing.T) { func TestGetFuturesLiquidationOrders(t *testing.T) { t.Parallel() - _, err := b.GetFuturesLiquidationOrders(currency.Pair{}, "", 0, time.Time{}, time.Time{}) + _, err := b.GetFuturesLiquidationOrders(context.Background(), currency.Pair{}, "", 0, time.Time{}, time.Time{}) if err != nil { t.Error(err) } - _, err = b.GetFuturesLiquidationOrders(currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "", 0, time.Unix(1577836800, 0), time.Unix(1580515200, 0)) + _, err = b.GetFuturesLiquidationOrders(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "", 0, time.Unix(1577836800, 0), time.Unix(1580515200, 0)) if err != nil { t.Error(err) } @@ -807,7 +808,7 @@ func TestGetFuturesLiquidationOrders(t *testing.T) { func TestGetOpenInterest(t *testing.T) { t.Parallel() - _, err := b.GetOpenInterest(currency.NewPairWithDelimiter("BTCUSD", "PERP", "_")) + _, err := b.GetOpenInterest(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_")) if err != nil { t.Error(err) } @@ -815,11 +816,11 @@ func TestGetOpenInterest(t *testing.T) { func TestGetOpenInterestStats(t *testing.T) { t.Parallel() - _, err := b.GetOpenInterestStats("BTCUSD", "CURRENT_QUARTER", "5m", 0, time.Time{}, time.Time{}) + _, err := b.GetOpenInterestStats(context.Background(), "BTCUSD", "CURRENT_QUARTER", "5m", 0, time.Time{}, time.Time{}) if err != nil { t.Error(err) } - _, err = b.GetOpenInterestStats("BTCUSD", "CURRENT_QUARTER", "5m", 0, time.Unix(1577836800, 0), time.Unix(1580515200, 0)) + _, err = b.GetOpenInterestStats(context.Background(), "BTCUSD", "CURRENT_QUARTER", "5m", 0, time.Unix(1577836800, 0), time.Unix(1580515200, 0)) if err != nil { t.Error(err) } @@ -827,11 +828,11 @@ func TestGetOpenInterestStats(t *testing.T) { func TestGetTraderFuturesAccountRatio(t *testing.T) { t.Parallel() - _, err := b.GetTraderFuturesAccountRatio("BTCUSD", "5m", 0, time.Time{}, time.Time{}) + _, err := b.GetTraderFuturesAccountRatio(context.Background(), "BTCUSD", "5m", 0, time.Time{}, time.Time{}) if err != nil { t.Error(err) } - _, err = b.GetTraderFuturesAccountRatio("BTCUSD", "5m", 0, time.Unix(1577836800, 0), time.Unix(1580515200, 0)) + _, err = b.GetTraderFuturesAccountRatio(context.Background(), "BTCUSD", "5m", 0, time.Unix(1577836800, 0), time.Unix(1580515200, 0)) if err != nil { t.Error(err) } @@ -839,11 +840,11 @@ func TestGetTraderFuturesAccountRatio(t *testing.T) { func TestGetTraderFuturesPositionsRatio(t *testing.T) { t.Parallel() - _, err := b.GetTraderFuturesPositionsRatio("BTCUSD", "5m", 0, time.Time{}, time.Time{}) + _, err := b.GetTraderFuturesPositionsRatio(context.Background(), "BTCUSD", "5m", 0, time.Time{}, time.Time{}) if err != nil { t.Error(err) } - _, err = b.GetTraderFuturesPositionsRatio("BTCUSD", "5m", 0, time.Unix(1577836800, 0), time.Unix(1580515200, 0)) + _, err = b.GetTraderFuturesPositionsRatio(context.Background(), "BTCUSD", "5m", 0, time.Unix(1577836800, 0), time.Unix(1580515200, 0)) if err != nil { t.Error(err) } @@ -851,11 +852,11 @@ func TestGetTraderFuturesPositionsRatio(t *testing.T) { func TestGetMarketRatio(t *testing.T) { t.Parallel() - _, err := b.GetMarketRatio("BTCUSD", "5m", 0, time.Time{}, time.Time{}) + _, err := b.GetMarketRatio(context.Background(), "BTCUSD", "5m", 0, time.Time{}, time.Time{}) if err != nil { t.Error(err) } - _, err = b.GetMarketRatio("BTCUSD", "5m", 0, time.Unix(1577836800, 0), time.Unix(1580515200, 0)) + _, err = b.GetMarketRatio(context.Background(), "BTCUSD", "5m", 0, time.Unix(1577836800, 0), time.Unix(1580515200, 0)) if err != nil { t.Error(err) } @@ -863,11 +864,11 @@ func TestGetMarketRatio(t *testing.T) { func TestGetFuturesTakerVolume(t *testing.T) { t.Parallel() - _, err := b.GetFuturesTakerVolume("BTCUSD", "ALL", "5m", 0, time.Time{}, time.Time{}) + _, err := b.GetFuturesTakerVolume(context.Background(), "BTCUSD", "ALL", "5m", 0, time.Time{}, time.Time{}) if err != nil { t.Error(err) } - _, err = b.GetFuturesTakerVolume("BTCUSD", "ALL", "5m", 0, time.Unix(1577836800, 0), time.Unix(1580515200, 0)) + _, err = b.GetFuturesTakerVolume(context.Background(), "BTCUSD", "ALL", "5m", 0, time.Unix(1577836800, 0), time.Unix(1580515200, 0)) if err != nil { t.Error(err) } @@ -875,11 +876,11 @@ func TestGetFuturesTakerVolume(t *testing.T) { func TestFuturesBasisData(t *testing.T) { t.Parallel() - _, err := b.GetFuturesBasisData("BTCUSD", "CURRENT_QUARTER", "5m", 0, time.Time{}, time.Time{}) + _, err := b.GetFuturesBasisData(context.Background(), "BTCUSD", "CURRENT_QUARTER", "5m", 0, time.Time{}, time.Time{}) if err != nil { t.Error(err) } - _, err = b.GetFuturesBasisData("BTCUSD", "CURRENT_QUARTER", "5m", 0, time.Unix(1577836800, 0), time.Unix(1580515200, 0)) + _, err = b.GetFuturesBasisData(context.Background(), "BTCUSD", "CURRENT_QUARTER", "5m", 0, time.Unix(1577836800, 0), time.Unix(1580515200, 0)) if err != nil { t.Error(err) } @@ -890,7 +891,7 @@ func TestFuturesNewOrder(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test: api keys not set or canManipulateRealOrders set to false") } - _, err := b.FuturesNewOrder(currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "BUY", "", "LIMIT", "GTC", "", "", "", "", 1, 1, 0, 0, 0, false) + _, err := b.FuturesNewOrder(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "BUY", "", "LIMIT", "GTC", "", "", "", "", 1, 1, 0, 0, 0, false) if err != nil { t.Error(err) } @@ -911,7 +912,7 @@ func TestFuturesBatchOrder(t *testing.T) { tempData.TimeInForce = "GTC" data = append(data, tempData) - _, err := b.FuturesBatchOrder(data) + _, err := b.FuturesBatchOrder(context.Background(), data) if err != nil { t.Error(err) } @@ -922,7 +923,7 @@ func TestFuturesBatchCancelOrders(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test: api keys not set or canManipulateRealOrders set to false") } - _, err := b.FuturesBatchCancelOrders(currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), []string{"123"}, []string{}) + _, err := b.FuturesBatchCancelOrders(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), []string{"123"}, []string{}) if err != nil { t.Error(err) } @@ -933,7 +934,7 @@ func TestFuturesGetOrderData(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("skipping test: api keys not set") } - _, err := b.FuturesGetOrderData(currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "123", "") + _, err := b.FuturesGetOrderData(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "123", "") if err != nil { t.Error(err) } @@ -944,7 +945,7 @@ func TestCancelAllOpenOrders(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test: api keys not set or canManipulateRealOrders set to false") } - _, err := b.FuturesCancelAllOpenOrders(currency.NewPairWithDelimiter("BTCUSD", "PERP", "_")) + _, err := b.FuturesCancelAllOpenOrders(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_")) if err != nil { t.Error(err) } @@ -955,7 +956,7 @@ func TestAutoCancelAllOpenOrders(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test: api keys not set or canManipulateRealOrders set to false") } - _, err := b.AutoCancelAllOpenOrders(currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), 30000) + _, err := b.AutoCancelAllOpenOrders(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), 30000) if err != nil { t.Error(err) } @@ -966,7 +967,7 @@ func TestFuturesOpenOrderData(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("skipping test: api keys not set") } - _, err := b.FuturesOpenOrderData(currency.NewPair(currency.BTC, currency.USDT), "", "") + _, err := b.FuturesOpenOrderData(context.Background(), currency.NewPair(currency.BTC, currency.USDT), "", "") if err != nil { t.Error(err) } @@ -977,7 +978,7 @@ func TestGetFuturesAllOpenOrders(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("skipping test: api keys not set") } - _, err := b.GetFuturesAllOpenOrders(currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "") + _, err := b.GetFuturesAllOpenOrders(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "") if err != nil { t.Error(err) } @@ -988,7 +989,7 @@ func TestGetAllFuturesOrders(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("skipping test: api keys not set") } - _, err := b.GetAllFuturesOrders(currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "", time.Time{}, time.Time{}, 0, 2) + _, err := b.GetAllFuturesOrders(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "", time.Time{}, time.Time{}, 0, 2) if err != nil { t.Error(err) } @@ -999,7 +1000,7 @@ func TestFuturesChangeMarginType(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test: api keys not set or canManipulateRealOrders set to false") } - _, err := b.FuturesChangeMarginType(currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "ISOLATED") + _, err := b.FuturesChangeMarginType(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "ISOLATED") if err != nil { t.Error(err) } @@ -1010,7 +1011,7 @@ func TestGetFuturesAccountBalance(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("skipping test: api keys not set") } - _, err := b.GetFuturesAccountBalance() + _, err := b.GetFuturesAccountBalance(context.Background()) if err != nil { t.Error(err) } @@ -1021,7 +1022,7 @@ func TestGetFuturesAccountInfo(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("skipping test: api keys not set") } - _, err := b.GetFuturesAccountInfo() + _, err := b.GetFuturesAccountInfo(context.Background()) if err != nil { t.Error(err) } @@ -1032,7 +1033,7 @@ func TestFuturesChangeInitialLeverage(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test: api keys not set or canManipulateRealOrders set to false") } - _, err := b.FuturesChangeInitialLeverage(currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), 5) + _, err := b.FuturesChangeInitialLeverage(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), 5) if err != nil { t.Error(err) } @@ -1043,7 +1044,7 @@ func TestModifyIsolatedPositionMargin(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test: api keys not set or canManipulateRealOrders set to false") } - _, err := b.ModifyIsolatedPositionMargin(currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "BOTH", "add", 5) + _, err := b.ModifyIsolatedPositionMargin(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "BOTH", "add", 5) if err != nil { t.Error(err) } @@ -1054,7 +1055,7 @@ func TestFuturesMarginChangeHistory(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("skipping test: api keys not set") } - _, err := b.FuturesMarginChangeHistory(currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "add", time.Time{}, time.Time{}, 10) + _, err := b.FuturesMarginChangeHistory(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "add", time.Time{}, time.Time{}, 10) if err != nil { t.Error(err) } @@ -1065,7 +1066,7 @@ func TestFuturesPositionsInfo(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("skipping test: api keys not set") } - _, err := b.FuturesPositionsInfo("BTCUSD_PERP", "") + _, err := b.FuturesPositionsInfo(context.Background(), "BTCUSD_PERP", "") if err != nil { t.Error(err) } @@ -1076,7 +1077,7 @@ func TestFuturesTradeHistory(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("skipping test: api keys not set") } - _, err := b.FuturesTradeHistory(currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "", time.Time{}, time.Time{}, 5, 0) + _, err := b.FuturesTradeHistory(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "", time.Time{}, time.Time{}, 5, 0) if err != nil { t.Error(err) } @@ -1087,7 +1088,7 @@ func TestFuturesIncomeHistory(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("skipping test: api keys not set") } - _, err := b.FuturesIncomeHistory(currency.Pair{}, "TRANSFER", time.Time{}, time.Time{}, 5) + _, err := b.FuturesIncomeHistory(context.Background(), currency.Pair{}, "TRANSFER", time.Time{}, time.Time{}, 5) if err != nil { t.Error(err) } @@ -1098,7 +1099,7 @@ func TestFuturesForceOrders(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("skipping test: api keys not set") } - _, err := b.FuturesForceOrders(currency.Pair{}, "ADL", time.Time{}, time.Time{}) + _, err := b.FuturesForceOrders(context.Background(), currency.Pair{}, "ADL", time.Time{}, time.Time{}) if err != nil { t.Error(err) } @@ -1109,11 +1110,11 @@ func TestUGetNotionalLeverage(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("skipping test: api keys not set") } - _, err := b.FuturesNotionalBracket("BTCUSD") + _, err := b.FuturesNotionalBracket(context.Background(), "BTCUSD") if err != nil { t.Error(err) } - _, err = b.FuturesNotionalBracket("") + _, err = b.FuturesNotionalBracket(context.Background(), "") if err != nil { t.Error(err) } @@ -1124,7 +1125,7 @@ func TestFuturesPositionsADLEstimate(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("skipping test: api keys not set") } - _, err := b.FuturesPositionsADLEstimate(currency.Pair{}) + _, err := b.FuturesPositionsADLEstimate(context.Background(), currency.Pair{}) if err != nil { t.Error(err) } @@ -1132,7 +1133,7 @@ func TestFuturesPositionsADLEstimate(t *testing.T) { func TestGetMarkPriceKline(t *testing.T) { t.Parallel() - _, err := b.GetMarkPriceKline(currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "1M", 5, time.Time{}, time.Time{}) + _, err := b.GetMarkPriceKline(context.Background(), currency.NewPairWithDelimiter("BTCUSD", "PERP", "_"), "1M", 5, time.Time{}, time.Time{}) if err != nil { t.Error(err) } @@ -1140,7 +1141,7 @@ func TestGetMarkPriceKline(t *testing.T) { func TestGetMarginExchangeInfo(t *testing.T) { t.Parallel() - _, err := b.GetMarginMarkets() + _, err := b.GetMarginMarkets(context.Background()) if err != nil { t.Error(err) } @@ -1148,7 +1149,7 @@ func TestGetMarginExchangeInfo(t *testing.T) { func TestGetExchangeInfo(t *testing.T) { t.Parallel() - info, err := b.GetExchangeInfo() + info, err := b.GetExchangeInfo(context.Background()) if err != nil { t.Error(err) } @@ -1162,17 +1163,17 @@ func TestGetExchangeInfo(t *testing.T) { func TestFetchTradablePairs(t *testing.T) { t.Parallel() - _, err := b.FetchTradablePairs(asset.Spot) + _, err := b.FetchTradablePairs(context.Background(), asset.Spot) if err != nil { t.Error("Binance FetchTradablePairs(asset asets.AssetType) error", err) } - _, err = b.FetchTradablePairs(asset.CoinMarginedFutures) + _, err = b.FetchTradablePairs(context.Background(), asset.CoinMarginedFutures) if err != nil { t.Error(err) } - _, err = b.FetchTradablePairs(asset.USDTMarginedFutures) + _, err = b.FetchTradablePairs(context.Background(), asset.USDTMarginedFutures) if err != nil { t.Error(err) } @@ -1180,10 +1181,11 @@ func TestFetchTradablePairs(t *testing.T) { func TestGetOrderBook(t *testing.T) { t.Parallel() - _, err := b.GetOrderBook(OrderBookDataRequestParams{ - Symbol: currency.NewPair(currency.BTC, currency.USDT), - Limit: 1000, - }) + _, err := b.GetOrderBook(context.Background(), + OrderBookDataRequestParams{ + Symbol: currency.NewPair(currency.BTC, currency.USDT), + Limit: 1000, + }) if err != nil { t.Error("Binance GetOrderBook() error", err) @@ -1192,10 +1194,11 @@ func TestGetOrderBook(t *testing.T) { func TestGetMostRecentTrades(t *testing.T) { t.Parallel() - _, err := b.GetMostRecentTrades(RecentTradeRequestParams{ - Symbol: currency.NewPair(currency.BTC, currency.USDT), - Limit: 15, - }) + _, err := b.GetMostRecentTrades(context.Background(), + RecentTradeRequestParams{ + Symbol: currency.NewPair(currency.BTC, currency.USDT), + Limit: 15, + }) if err != nil { t.Error("Binance GetMostRecentTrades() error", err) @@ -1205,7 +1208,7 @@ func TestGetMostRecentTrades(t *testing.T) { func TestGetHistoricalTrades(t *testing.T) { t.Parallel() - _, err := b.GetHistoricalTrades("BTCUSDT", 5, -1) + _, err := b.GetHistoricalTrades(context.Background(), "BTCUSDT", 5, -1) if err != nil { t.Errorf("Binance GetHistoricalTrades() error: %v", err) } @@ -1213,10 +1216,11 @@ func TestGetHistoricalTrades(t *testing.T) { func TestGetAggregatedTrades(t *testing.T) { t.Parallel() - _, err := b.GetAggregatedTrades(&AggregatedTradeRequestParams{ - Symbol: currency.NewPair(currency.BTC, currency.USDT), - Limit: 5, - }) + _, err := b.GetAggregatedTrades(context.Background(), + &AggregatedTradeRequestParams{ + Symbol: currency.NewPair(currency.BTC, currency.USDT), + Limit: 5, + }) if err != nil { t.Error("Binance GetAggregatedTrades() error", err) } @@ -1224,13 +1228,14 @@ func TestGetAggregatedTrades(t *testing.T) { func TestGetSpotKline(t *testing.T) { t.Parallel() - _, err := b.GetSpotKline(&KlinesRequestParams{ - Symbol: currency.NewPair(currency.BTC, currency.USDT), - Interval: kline.FiveMin.Short(), - Limit: 24, - StartTime: time.Unix(1577836800, 0), - EndTime: time.Unix(1580515200, 0), - }) + _, err := b.GetSpotKline(context.Background(), + &KlinesRequestParams{ + Symbol: currency.NewPair(currency.BTC, currency.USDT), + Interval: kline.FiveMin.Short(), + Limit: 24, + StartTime: time.Unix(1577836800, 0), + EndTime: time.Unix(1580515200, 0), + }) if err != nil { t.Error("Binance GetSpotKline() error", err) } @@ -1239,7 +1244,7 @@ func TestGetSpotKline(t *testing.T) { func TestGetAveragePrice(t *testing.T) { t.Parallel() - _, err := b.GetAveragePrice(currency.NewPair(currency.BTC, currency.USDT)) + _, err := b.GetAveragePrice(context.Background(), currency.NewPair(currency.BTC, currency.USDT)) if err != nil { t.Error("Binance GetAveragePrice() error", err) } @@ -1248,7 +1253,7 @@ func TestGetAveragePrice(t *testing.T) { func TestGetPriceChangeStats(t *testing.T) { t.Parallel() - _, err := b.GetPriceChangeStats(currency.NewPair(currency.BTC, currency.USDT)) + _, err := b.GetPriceChangeStats(context.Background(), currency.NewPair(currency.BTC, currency.USDT)) if err != nil { t.Error("Binance GetPriceChangeStats() error", err) } @@ -1257,7 +1262,7 @@ func TestGetPriceChangeStats(t *testing.T) { func TestGetTickers(t *testing.T) { t.Parallel() - _, err := b.GetTickers() + _, err := b.GetTickers(context.Background()) if err != nil { t.Error("Binance TestGetTickers error", err) } @@ -1266,7 +1271,7 @@ func TestGetTickers(t *testing.T) { func TestGetLatestSpotPrice(t *testing.T) { t.Parallel() - _, err := b.GetLatestSpotPrice(currency.NewPair(currency.BTC, currency.USDT)) + _, err := b.GetLatestSpotPrice(context.Background(), currency.NewPair(currency.BTC, currency.USDT)) if err != nil { t.Error("Binance GetLatestSpotPrice() error", err) } @@ -1275,7 +1280,7 @@ func TestGetLatestSpotPrice(t *testing.T) { func TestGetBestPrice(t *testing.T) { t.Parallel() - _, err := b.GetBestPrice(currency.NewPair(currency.BTC, currency.USDT)) + _, err := b.GetBestPrice(context.Background(), currency.NewPair(currency.BTC, currency.USDT)) if err != nil { t.Error("Binance GetBestPrice() error", err) } @@ -1284,7 +1289,7 @@ func TestGetBestPrice(t *testing.T) { func TestQueryOrder(t *testing.T) { t.Parallel() - _, err := b.QueryOrder(currency.NewPair(currency.BTC, currency.USDT), "", 1337) + _, err := b.QueryOrder(context.Background(), currency.NewPair(currency.BTC, currency.USDT), "", 1337) switch { case areTestAPIKeysSet() && err != nil: t.Error("QueryOrder() error", err) @@ -1300,13 +1305,13 @@ func TestOpenOrders(t *testing.T) { if !areTestAPIKeysSet() { t.Skip() } - _, err := b.OpenOrders(currency.Pair{}) + _, err := b.OpenOrders(context.Background(), currency.Pair{}) if err != nil { t.Error(err) } p := currency.NewPair(currency.BTC, currency.USDT) - _, err = b.OpenOrders(p) + _, err = b.OpenOrders(context.Background(), p) if err != nil { t.Error(err) } @@ -1315,7 +1320,7 @@ func TestOpenOrders(t *testing.T) { func TestAllOrders(t *testing.T) { t.Parallel() - _, err := b.AllOrders(currency.NewPair(currency.BTC, currency.USDT), "", "") + _, err := b.AllOrders(context.Background(), currency.NewPair(currency.BTC, currency.USDT), "", "") switch { case areTestAPIKeysSet() && err != nil: t.Error("AllOrders() error", err) @@ -1331,7 +1336,7 @@ func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { t.Parallel() var feeBuilder = setFeeBuilder() - _, err := b.GetFeeByType(feeBuilder) + _, err := b.GetFeeByType(context.Background(), feeBuilder) if err != nil { t.Fatal(err) } @@ -1353,7 +1358,7 @@ func TestGetFee(t *testing.T) { if areTestAPIKeysSet() && mockTests { // CryptocurrencyTradeFee Basic - if _, err := b.GetFee(feeBuilder); err != nil { + if _, err := b.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } @@ -1361,21 +1366,21 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.Amount = 1000 feeBuilder.PurchasePrice = 1000 - if _, err := b.GetFee(feeBuilder); err != nil { + if _, err := b.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyTradeFee IsMaker feeBuilder = setFeeBuilder() feeBuilder.IsMaker = true - if _, err := b.GetFee(feeBuilder); err != nil { + if _, err := b.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyTradeFee Negative purchase price feeBuilder = setFeeBuilder() feeBuilder.PurchasePrice = -1000 - if _, err := b.GetFee(feeBuilder); err != nil { + if _, err := b.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } } @@ -1383,14 +1388,14 @@ func TestGetFee(t *testing.T) { // CryptocurrencyWithdrawalFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee - if _, err := b.GetFee(feeBuilder); err != nil { + if _, err := b.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyDepositFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.CryptocurrencyDepositFee - if _, err := b.GetFee(feeBuilder); err != nil { + if _, err := b.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } @@ -1398,7 +1403,7 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankDepositFee feeBuilder.FiatCurrency = currency.HKD - if _, err := b.GetFee(feeBuilder); err != nil { + if _, err := b.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } @@ -1406,7 +1411,7 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee feeBuilder.FiatCurrency = currency.HKD - if _, err := b.GetFee(feeBuilder); err != nil { + if _, err := b.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } } @@ -1433,7 +1438,7 @@ func TestGetActiveOrders(t *testing.T) { AssetType: asset.Spot, } - _, err = b.GetActiveOrders(&getOrdersRequest) + _, err = b.GetActiveOrders(context.Background(), &getOrdersRequest) switch { case areTestAPIKeysSet() && err != nil: t.Error("GetActiveOrders() error", err) @@ -1452,7 +1457,7 @@ func TestGetOrderHistory(t *testing.T) { AssetType: asset.Spot, } - _, err := b.GetOrderHistory(&getOrdersRequest) + _, err := b.GetOrderHistory(context.Background(), &getOrdersRequest) if err == nil { t.Error("Expected: 'At least one currency is required to fetch order history'. received nil") } @@ -1461,7 +1466,7 @@ func TestGetOrderHistory(t *testing.T) { currency.NewPair(currency.LTC, currency.BTC)} - _, err = b.GetOrderHistory(&getOrdersRequest) + _, err = b.GetOrderHistory(context.Background(), &getOrdersRequest) switch { case areTestAPIKeysSet() && err != nil: t.Error("GetOrderHistory() error", err) @@ -1484,7 +1489,7 @@ func TestNewOrderTest(t *testing.T) { TimeInForce: BinanceRequestParamsTimeGTC, } - err := b.NewOrderTest(req) + err := b.NewOrderTest(context.Background(), req) switch { case areTestAPIKeysSet() && err != nil: t.Error("NewOrderTest() error", err) @@ -1502,7 +1507,7 @@ func TestNewOrderTest(t *testing.T) { QuoteOrderQty: 10, } - err = b.NewOrderTest(req) + err = b.NewOrderTest(context.Background(), req) switch { case areTestAPIKeysSet() && err != nil: t.Error("NewOrderTest() error", err) @@ -1523,7 +1528,8 @@ func TestGetHistoricTrades(t *testing.T) { if err != nil { t.Fatal(err) } - result, err := b.GetHistoricTrades(currencyPair, asset.Spot, start, start.Add(15*time.Minute)) + result, err := b.GetHistoricTrades(context.Background(), + currencyPair, asset.Spot, start, start.Add(15*time.Minute)) if err != nil { t.Error(err) } @@ -1619,7 +1625,7 @@ func TestGetAggregatedTradesBatched(t *testing.T) { if tt.mock != mockTests { t.Skip() } - result, err := b.GetAggregatedTrades(tt.args) + result, err := b.GetAggregatedTrades(context.Background(), tt.args) if err != nil { t.Error(err) } @@ -1671,7 +1677,7 @@ func TestGetAggregatedTradesErrors(t *testing.T) { for _, tt := range tests { tt := tt t.Run(tt.name, func(t *testing.T) { - _, err := b.GetAggregatedTrades(tt.args) + _, err := b.GetAggregatedTrades(context.Background(), tt.args) if err == nil { t.Errorf("Binance.GetAggregatedTrades() error = %v, wantErr true", err) return @@ -1704,7 +1710,7 @@ func TestSubmitOrder(t *testing.T) { AssetType: asset.Spot, } - _, err := b.SubmitOrder(orderSubmission) + _, err := b.SubmitOrder(context.Background(), orderSubmission) switch { case areTestAPIKeysSet() && err != nil: t.Error("SubmitOrder() error", err) @@ -1729,7 +1735,7 @@ func TestCancelExchangeOrder(t *testing.T) { AssetType: asset.Spot, } - err := b.CancelOrder(orderCancellation) + err := b.CancelOrder(context.Background(), orderCancellation) switch { case areTestAPIKeysSet() && err != nil: t.Error("CancelExchangeOrder() error", err) @@ -1754,7 +1760,7 @@ func TestCancelAllExchangeOrders(t *testing.T) { AssetType: asset.Spot, } - _, err := b.CancelAllOrders(orderCancellation) + _, err := b.CancelAllOrders(context.Background(), orderCancellation) switch { case areTestAPIKeysSet() && err != nil: t.Error("CancelAllExchangeOrders() error", err) @@ -1779,7 +1785,7 @@ func TestGetAccountInfo(t *testing.T) { for i := range items { assetType := items[i] t.Run(fmt.Sprintf("Update info of account [%s]", assetType.String()), func(t *testing.T) { - _, err := b.UpdateAccountInfo(assetType) + _, err := b.UpdateAccountInfo(context.Background(), assetType) if err != nil { t.Error(err) } @@ -1796,7 +1802,7 @@ func TestWrapperGetActiveOrders(t *testing.T) { if err != nil { t.Error(err) } - _, err = b.GetActiveOrders(&order.GetOrdersRequest{ + _, err = b.GetActiveOrders(context.Background(), &order.GetOrdersRequest{ Type: order.AnyType, Side: order.AnySide, Pairs: currency.Pairs{p}, @@ -1810,7 +1816,7 @@ func TestWrapperGetActiveOrders(t *testing.T) { if err != nil { t.Error(err) } - _, err = b.GetActiveOrders(&order.GetOrdersRequest{ + _, err = b.GetActiveOrders(context.Background(), &order.GetOrdersRequest{ Type: order.AnyType, Side: order.AnySide, Pairs: currency.Pairs{p2}, @@ -1830,7 +1836,7 @@ func TestWrapperGetOrderHistory(t *testing.T) { if err != nil { t.Error(err) } - _, err = b.GetOrderHistory(&order.GetOrdersRequest{ + _, err = b.GetOrderHistory(context.Background(), &order.GetOrdersRequest{ Type: order.AnyType, Side: order.AnySide, OrderID: "123", @@ -1845,7 +1851,7 @@ func TestWrapperGetOrderHistory(t *testing.T) { if err != nil { t.Error(err) } - _, err = b.GetOrderHistory(&order.GetOrdersRequest{ + _, err = b.GetOrderHistory(context.Background(), &order.GetOrdersRequest{ Type: order.AnyType, Side: order.AnySide, OrderID: "123", @@ -1856,7 +1862,7 @@ func TestWrapperGetOrderHistory(t *testing.T) { t.Error(err) } - _, err = b.GetOrderHistory(&order.GetOrdersRequest{ + _, err = b.GetOrderHistory(context.Background(), &order.GetOrdersRequest{ AssetType: asset.USDTMarginedFutures, }) if err == nil { @@ -1877,7 +1883,7 @@ func TestCancelOrder(t *testing.T) { if err != nil { t.Error(err) } - err = b.CancelOrder(&order.Cancel{ + err = b.CancelOrder(context.Background(), &order.Cancel{ AssetType: asset.CoinMarginedFutures, Pair: fpair, ID: "1234", @@ -1894,7 +1900,7 @@ func TestCancelOrder(t *testing.T) { if err != nil { t.Error(err) } - err = b.CancelOrder(&order.Cancel{ + err = b.CancelOrder(context.Background(), &order.Cancel{ AssetType: asset.USDTMarginedFutures, Pair: fpair2, ID: "1234", @@ -1909,7 +1915,8 @@ func TestGetOrderInfo(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("skipping test: api keys not set") } - tradablePairs, err := b.FetchTradablePairs(asset.CoinMarginedFutures) + tradablePairs, err := b.FetchTradablePairs(context.Background(), + asset.CoinMarginedFutures) if err != nil { t.Error(err) } @@ -1920,7 +1927,8 @@ func TestGetOrderInfo(t *testing.T) { if err != nil { t.Error(err) } - _, err = b.GetOrderInfo("123", cp, asset.CoinMarginedFutures) + _, err = b.GetOrderInfo(context.Background(), + "123", cp, asset.CoinMarginedFutures) if err != nil { t.Error(err) } @@ -1928,7 +1936,8 @@ func TestGetOrderInfo(t *testing.T) { func TestModifyOrder(t *testing.T) { t.Parallel() - _, err := b.ModifyOrder(&order.Modify{AssetType: asset.Spot}) + _, err := b.ModifyOrder(context.Background(), + &order.Modify{AssetType: asset.Spot}) if err == nil { t.Error("ModifyOrder() error cannot be nil") } @@ -1950,7 +1959,8 @@ func TestWithdraw(t *testing.T) { }, } - _, err := b.WithdrawCryptocurrencyFunds(&withdrawCryptoRequest) + _, err := b.WithdrawCryptocurrencyFunds(context.Background(), + &withdrawCryptoRequest) switch { case areTestAPIKeysSet() && err != nil: t.Error("Withdraw() error", err) @@ -1966,7 +1976,7 @@ func TestWithdrawHistory(t *testing.T) { if areTestAPIKeysSet() && !canManipulateRealOrders && !mockTests { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - _, err := b.GetWithdrawalsHistory(currency.XBT) + _, err := b.GetWithdrawalsHistory(context.Background(), currency.XBT) switch { case areTestAPIKeysSet() && err != nil: t.Error("GetWithdrawalsHistory() error", err) @@ -1977,7 +1987,8 @@ func TestWithdrawHistory(t *testing.T) { func TestWithdrawFiat(t *testing.T) { t.Parallel() - _, err := b.WithdrawFiatFunds(&withdraw.Request{}) + _, err := b.WithdrawFiatFunds(context.Background(), + &withdraw.Request{}) if err != common.ErrFunctionNotSupported { t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err) } @@ -1985,7 +1996,8 @@ func TestWithdrawFiat(t *testing.T) { func TestWithdrawInternationalBank(t *testing.T) { t.Parallel() - _, err := b.WithdrawFiatFundsToInternationalBank(&withdraw.Request{}) + _, err := b.WithdrawFiatFundsToInternationalBank(context.Background(), + &withdraw.Request{}) if err != common.ErrFunctionNotSupported { t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err) } @@ -1993,7 +2005,7 @@ func TestWithdrawInternationalBank(t *testing.T) { func TestGetDepositAddress(t *testing.T) { t.Parallel() - _, err := b.GetDepositAddress(currency.BTC, "") + _, err := b.GetDepositAddress(context.Background(), currency.BTC, "") switch { case areTestAPIKeysSet() && err != nil: t.Error("GetDepositAddress() error", err) @@ -2257,7 +2269,7 @@ func TestWsOCO(t *testing.T) { } func TestGetWsAuthStreamKey(t *testing.T) { - key, err := b.GetWsAuthStreamKey() + key, err := b.GetWsAuthStreamKey(context.Background()) switch { case mockTests && err != nil, !mockTests && areTestAPIKeysSet() && err != nil: @@ -2272,7 +2284,7 @@ func TestGetWsAuthStreamKey(t *testing.T) { } func TestMaintainWsAuthStreamKey(t *testing.T) { - err := b.MaintainWsAuthStreamKey() + err := b.MaintainWsAuthStreamKey(context.Background()) switch { case mockTests && err != nil, !mockTests && areTestAPIKeysSet() && err != nil: @@ -2312,12 +2324,14 @@ func TestGetHistoricCandles(t *testing.T) { } startTime := time.Unix(1546300800, 0) end := time.Unix(1577836799, 0) - _, err = b.GetHistoricCandles(currencyPair, asset.Spot, startTime, end, kline.OneDay) + _, err = b.GetHistoricCandles(context.Background(), + currencyPair, asset.Spot, startTime, end, kline.OneDay) if err != nil { t.Error(err) } - _, err = b.GetHistoricCandles(currencyPair, asset.Spot, startTime, end, kline.Interval(time.Hour*7)) + _, err = b.GetHistoricCandles(context.Background(), + currencyPair, asset.Spot, startTime, end, kline.Interval(time.Hour*7)) if err == nil { t.Fatal("unexpected result") } @@ -2331,12 +2345,14 @@ func TestGetHistoricCandlesExtended(t *testing.T) { startTime := time.Date(2020, 9, 1, 0, 0, 0, 0, time.UTC) end := time.Date(2021, 2, 15, 0, 0, 0, 0, time.UTC) - _, err = b.GetHistoricCandlesExtended(currencyPair, asset.Spot, startTime, end, kline.OneDay) + _, err = b.GetHistoricCandlesExtended(context.Background(), + currencyPair, asset.Spot, startTime, end, kline.OneDay) if err != nil { t.Error(err) } - _, err = b.GetHistoricCandlesExtended(currencyPair, asset.Spot, startTime, end, kline.Interval(time.Hour*7)) + _, err = b.GetHistoricCandlesExtended(context.Background(), + currencyPair, asset.Spot, startTime, end, kline.Interval(time.Hour*7)) if err == nil { t.Error("unexpected result") } @@ -2389,7 +2405,8 @@ func TestGetRecentTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = b.GetRecentTrades(currencyPair, asset.Spot) + _, err = b.GetRecentTrades(context.Background(), + currencyPair, asset.Spot) if err != nil { t.Error(err) } @@ -2397,7 +2414,7 @@ func TestGetRecentTrades(t *testing.T) { func TestSeedLocalCache(t *testing.T) { t.Parallel() - err := b.SeedLocalCache(currency.NewPair(currency.BTC, currency.USDT)) + err := b.SeedLocalCache(context.Background(), currency.NewPair(currency.BTC, currency.USDT)) if err != nil { t.Fatal(err) } @@ -2455,11 +2472,11 @@ func TestUFuturesHistoricalTrades(t *testing.T) { if err != nil { t.Error(err) } - _, err = b.UFuturesHistoricalTrades(cp, "", 5) + _, err = b.UFuturesHistoricalTrades(context.Background(), cp, "", 5) if err != nil { t.Error(err) } - _, err = b.UFuturesHistoricalTrades(cp, "", 0) + _, err = b.UFuturesHistoricalTrades(context.Background(), cp, "", 0) if err != nil { t.Error(err) } @@ -2467,21 +2484,21 @@ func TestUFuturesHistoricalTrades(t *testing.T) { func TestSetExchangeOrderExecutionLimits(t *testing.T) { t.Parallel() - err := b.UpdateOrderExecutionLimits(asset.Spot) + err := b.UpdateOrderExecutionLimits(context.Background(), asset.Spot) if err != nil { t.Fatal(err) } - err = b.UpdateOrderExecutionLimits(asset.CoinMarginedFutures) + err = b.UpdateOrderExecutionLimits(context.Background(), asset.CoinMarginedFutures) if err != nil { t.Fatal(err) } - err = b.UpdateOrderExecutionLimits(asset.USDTMarginedFutures) + err = b.UpdateOrderExecutionLimits(context.Background(), asset.USDTMarginedFutures) if err != nil { t.Fatal(err) } - err = b.UpdateOrderExecutionLimits(asset.Binary) + err = b.UpdateOrderExecutionLimits(context.Background(), asset.Binary) if err == nil { t.Fatal("expected unhandled case") } diff --git a/exchanges/binance/binance_ufutures.go b/exchanges/binance/binance_ufutures.go index ee235978..ad4879c3 100644 --- a/exchanges/binance/binance_ufutures.go +++ b/exchanges/binance/binance_ufutures.go @@ -1,6 +1,7 @@ package binance import ( + "context" "encoding/json" "errors" "fmt" @@ -65,11 +66,11 @@ const ( ) // UServerTime gets the server time -func (b *Binance) UServerTime() (time.Time, error) { +func (b *Binance) UServerTime(ctx context.Context) (time.Time, error) { var data struct { ServerTime int64 `json:"serverTime"` } - err := b.SendHTTPRequest(exchange.RestUSDTMargined, ufuturesServerTime, uFuturesDefaultRate, &data) + err := b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesServerTime, uFuturesDefaultRate, &data) if err != nil { return time.Time{}, err } @@ -77,13 +78,13 @@ func (b *Binance) UServerTime() (time.Time, error) { } // UExchangeInfo stores usdt margined futures data -func (b *Binance) UExchangeInfo() (UFuturesExchangeInfo, error) { +func (b *Binance) UExchangeInfo(ctx context.Context) (UFuturesExchangeInfo, error) { var resp UFuturesExchangeInfo - return resp, b.SendHTTPRequest(exchange.RestUSDTMargined, ufuturesExchangeInfo, uFuturesDefaultRate, &resp) + return resp, b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesExchangeInfo, uFuturesDefaultRate, &resp) } // UFuturesOrderbook gets orderbook data for usdt margined futures -func (b *Binance) UFuturesOrderbook(symbol currency.Pair, limit int64) (OrderBook, error) { +func (b *Binance) UFuturesOrderbook(ctx context.Context, symbol currency.Pair, limit int64) (OrderBook, error) { var resp OrderBook var data OrderbookData params := url.Values{} @@ -110,7 +111,7 @@ func (b *Binance) UFuturesOrderbook(symbol currency.Pair, limit int64) (OrderBoo case limit == 1000: rateBudget = uFuturesOrderbook1000Rate } - err = b.SendHTTPRequest(exchange.RestUSDTMargined, ufuturesOrderbook+params.Encode(), rateBudget, &data) + err = b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesOrderbook+params.Encode(), rateBudget, &data) if err != nil { return resp, err } @@ -149,7 +150,7 @@ func (b *Binance) UFuturesOrderbook(symbol currency.Pair, limit int64) (OrderBoo } // URecentTrades gets recent trades for usdt margined futures -func (b *Binance) URecentTrades(symbol currency.Pair, fromID string, limit int64) ([]UPublicTradesData, error) { +func (b *Binance) URecentTrades(ctx context.Context, symbol currency.Pair, fromID string, limit int64) ([]UPublicTradesData, error) { var resp []UPublicTradesData params := url.Values{} symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) @@ -163,11 +164,11 @@ func (b *Binance) URecentTrades(symbol currency.Pair, fromID string, limit int64 if limit > 0 && limit < 1000 { params.Set("limit", strconv.FormatInt(limit, 10)) } - return resp, b.SendHTTPRequest(exchange.RestUSDTMargined, ufuturesRecentTrades+params.Encode(), uFuturesDefaultRate, &resp) + return resp, b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesRecentTrades+params.Encode(), uFuturesDefaultRate, &resp) } // UFuturesHistoricalTrades gets historical public trades for USDTMarginedFutures -func (b *Binance) UFuturesHistoricalTrades(symbol currency.Pair, fromID string, limit int64) ([]interface{}, error) { +func (b *Binance) UFuturesHistoricalTrades(ctx context.Context, symbol currency.Pair, fromID string, limit int64) ([]interface{}, error) { var resp []interface{} params := url.Values{} symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) @@ -181,11 +182,11 @@ func (b *Binance) UFuturesHistoricalTrades(symbol currency.Pair, fromID string, if limit > 0 && limit < 1000 { params.Set("limit", strconv.FormatInt(limit, 10)) } - return resp, b.SendAuthHTTPRequest(exchange.RestUSDTMargined, http.MethodGet, ufuturesHistoricalTrades, params, uFuturesHistoricalTradesRate, &resp) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodGet, ufuturesHistoricalTrades, params, uFuturesHistoricalTradesRate, &resp) } // UCompressedTrades gets compressed public trades for usdt margined futures -func (b *Binance) UCompressedTrades(symbol currency.Pair, fromID string, limit int64, startTime, endTime time.Time) ([]UCompressedTradeData, error) { +func (b *Binance) UCompressedTrades(ctx context.Context, symbol currency.Pair, fromID string, limit int64, startTime, endTime time.Time) ([]UCompressedTradeData, error) { var resp []UCompressedTradeData params := url.Values{} symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) @@ -206,11 +207,11 @@ func (b *Binance) UCompressedTrades(symbol currency.Pair, fromID string, limit i params.Set("start_time", strconv.FormatInt(startTime.Unix(), 10)) params.Set("end_time", strconv.FormatInt(endTime.Unix(), 10)) } - return resp, b.SendHTTPRequest(exchange.RestUSDTMargined, ufuturesCompressedTrades+params.Encode(), uFuturesHistoricalTradesRate, &resp) + return resp, b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesCompressedTrades+params.Encode(), uFuturesHistoricalTradesRate, &resp) } // UKlineData gets kline data for usdt margined futures -func (b *Binance) UKlineData(symbol currency.Pair, interval string, limit int64, startTime, endTime time.Time) ([]FuturesCandleStick, error) { +func (b *Binance) UKlineData(ctx context.Context, symbol currency.Pair, interval string, limit int64, startTime, endTime time.Time) ([]FuturesCandleStick, error) { var data [][10]interface{} var resp []FuturesCandleStick params := url.Values{} @@ -244,7 +245,7 @@ func (b *Binance) UKlineData(symbol currency.Pair, interval string, limit int64, case limit > 1000: rateBudget = uFuturesKlineMaxRate } - err = b.SendHTTPRequest(exchange.RestUSDTMargined, ufuturesKlineData+params.Encode(), rateBudget, &data) + err = b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesKlineData+params.Encode(), rateBudget, &data) if err != nil { return resp, err } @@ -343,7 +344,7 @@ func (b *Binance) UKlineData(symbol currency.Pair, interval string, limit int64, } // UGetMarkPrice gets mark price data for USDTMarginedFutures -func (b *Binance) UGetMarkPrice(symbol currency.Pair) ([]UMarkPrice, error) { +func (b *Binance) UGetMarkPrice(ctx context.Context, symbol currency.Pair) ([]UMarkPrice, error) { params := url.Values{} if !symbol.IsEmpty() { symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) @@ -352,14 +353,14 @@ func (b *Binance) UGetMarkPrice(symbol currency.Pair) ([]UMarkPrice, error) { } params.Set("symbol", symbolValue) var tempResp UMarkPrice - err = b.SendHTTPRequest(exchange.RestUSDTMargined, ufuturesMarkPrice+params.Encode(), uFuturesDefaultRate, &tempResp) + err = b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesMarkPrice+params.Encode(), uFuturesDefaultRate, &tempResp) if err != nil { return nil, err } return []UMarkPrice{tempResp}, nil } var resp []UMarkPrice - err := b.SendHTTPRequest(exchange.RestUSDTMargined, ufuturesMarkPrice+params.Encode(), uFuturesDefaultRate, &resp) + err := b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesMarkPrice+params.Encode(), uFuturesDefaultRate, &resp) if err != nil { return nil, err } @@ -367,7 +368,7 @@ func (b *Binance) UGetMarkPrice(symbol currency.Pair) ([]UMarkPrice, error) { } // UGetFundingHistory gets funding history for USDTMarginedFutures -func (b *Binance) UGetFundingHistory(symbol currency.Pair, limit int64, startTime, endTime time.Time) ([]FundingRateHistory, error) { +func (b *Binance) UGetFundingHistory(ctx context.Context, symbol currency.Pair, limit int64, startTime, endTime time.Time) ([]FundingRateHistory, error) { var resp []FundingRateHistory params := url.Values{} if !symbol.IsEmpty() { @@ -387,11 +388,11 @@ func (b *Binance) UGetFundingHistory(symbol currency.Pair, limit int64, startTim params.Set("start_time", strconv.FormatInt(startTime.Unix(), 10)) params.Set("end_time", strconv.FormatInt(endTime.Unix(), 10)) } - return resp, b.SendHTTPRequest(exchange.RestUSDTMargined, ufuturesFundingRateHistory+params.Encode(), uFuturesDefaultRate, &resp) + return resp, b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesFundingRateHistory+params.Encode(), uFuturesDefaultRate, &resp) } // U24HTickerPriceChangeStats gets 24hr ticker price change stats for USDTMarginedFutures -func (b *Binance) U24HTickerPriceChangeStats(symbol currency.Pair) ([]U24HrPriceChangeStats, error) { +func (b *Binance) U24HTickerPriceChangeStats(ctx context.Context, symbol currency.Pair) ([]U24HrPriceChangeStats, error) { params := url.Values{} if !symbol.IsEmpty() { symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) @@ -400,19 +401,19 @@ func (b *Binance) U24HTickerPriceChangeStats(symbol currency.Pair) ([]U24HrPrice } params.Set("symbol", symbolValue) var tempResp U24HrPriceChangeStats - err = b.SendHTTPRequest(exchange.RestUSDTMargined, ufuturesTickerPriceStats+params.Encode(), uFuturesDefaultRate, &tempResp) + err = b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesTickerPriceStats+params.Encode(), uFuturesDefaultRate, &tempResp) if err != nil { return nil, err } return []U24HrPriceChangeStats{tempResp}, err } var resp []U24HrPriceChangeStats - err := b.SendHTTPRequest(exchange.RestUSDTMargined, ufuturesTickerPriceStats+params.Encode(), uFuturesTickerPriceHistoryRate, &resp) + err := b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesTickerPriceStats+params.Encode(), uFuturesTickerPriceHistoryRate, &resp) return resp, err } // USymbolPriceTicker gets symbol price ticker for USDTMarginedFutures -func (b *Binance) USymbolPriceTicker(symbol currency.Pair) ([]USymbolPriceTicker, error) { +func (b *Binance) USymbolPriceTicker(ctx context.Context, symbol currency.Pair) ([]USymbolPriceTicker, error) { params := url.Values{} if !symbol.IsEmpty() { symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) @@ -421,19 +422,19 @@ func (b *Binance) USymbolPriceTicker(symbol currency.Pair) ([]USymbolPriceTicker } params.Set("symbol", symbolValue) var tempResp USymbolPriceTicker - err = b.SendHTTPRequest(exchange.RestUSDTMargined, ufuturesSymbolPriceTicker+params.Encode(), uFuturesDefaultRate, &tempResp) + err = b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesSymbolPriceTicker+params.Encode(), uFuturesDefaultRate, &tempResp) if err != nil { return nil, err } return []USymbolPriceTicker{tempResp}, err } var resp []USymbolPriceTicker - err := b.SendHTTPRequest(exchange.RestUSDTMargined, ufuturesSymbolPriceTicker+params.Encode(), uFuturesOrderbookTickerAllRate, &resp) + err := b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesSymbolPriceTicker+params.Encode(), uFuturesOrderbookTickerAllRate, &resp) return resp, err } // USymbolOrderbookTicker gets symbol orderbook ticker -func (b *Binance) USymbolOrderbookTicker(symbol currency.Pair) ([]USymbolOrderbookTicker, error) { +func (b *Binance) USymbolOrderbookTicker(ctx context.Context, symbol currency.Pair) ([]USymbolOrderbookTicker, error) { params := url.Values{} if !symbol.IsEmpty() { symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) @@ -442,19 +443,19 @@ func (b *Binance) USymbolOrderbookTicker(symbol currency.Pair) ([]USymbolOrderbo } params.Set("symbol", symbolValue) var tempResp USymbolOrderbookTicker - err = b.SendHTTPRequest(exchange.RestUSDTMargined, ufuturesSymbolOrderbook+params.Encode(), uFuturesDefaultRate, &tempResp) + err = b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesSymbolOrderbook+params.Encode(), uFuturesDefaultRate, &tempResp) if err != nil { return nil, err } return []USymbolOrderbookTicker{tempResp}, err } var resp []USymbolOrderbookTicker - err := b.SendHTTPRequest(exchange.RestUSDTMargined, ufuturesTickerPriceStats+params.Encode(), uFuturesOrderbookTickerAllRate, &resp) + err := b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesTickerPriceStats+params.Encode(), uFuturesOrderbookTickerAllRate, &resp) return resp, err } // ULiquidationOrders gets public liquidation orders -func (b *Binance) ULiquidationOrders(symbol currency.Pair, limit int64, startTime, endTime time.Time) ([]ULiquidationOrdersData, error) { +func (b *Binance) ULiquidationOrders(ctx context.Context, symbol currency.Pair, limit int64, startTime, endTime time.Time) ([]ULiquidationOrdersData, error) { var resp []ULiquidationOrdersData params := url.Values{} rateLimit := uFuturesAllForceOrdersRate @@ -476,11 +477,11 @@ func (b *Binance) ULiquidationOrders(symbol currency.Pair, limit int64, startTim params.Set("start_time", strconv.FormatInt(startTime.Unix(), 10)) params.Set("end_time", strconv.FormatInt(endTime.Unix(), 10)) } - return resp, b.SendHTTPRequest(exchange.RestUSDTMargined, ufuturesLiquidationOrders+params.Encode(), rateLimit, &resp) + return resp, b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesLiquidationOrders+params.Encode(), rateLimit, &resp) } // UOpenInterest gets open interest data for USDTMarginedFutures -func (b *Binance) UOpenInterest(symbol currency.Pair) (UOpenInterestData, error) { +func (b *Binance) UOpenInterest(ctx context.Context, symbol currency.Pair) (UOpenInterestData, error) { var resp UOpenInterestData params := url.Values{} symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) @@ -488,11 +489,11 @@ func (b *Binance) UOpenInterest(symbol currency.Pair) (UOpenInterestData, error) return resp, err } params.Set("symbol", symbolValue) - return resp, b.SendHTTPRequest(exchange.RestUSDTMargined, ufuturesOpenInterest+params.Encode(), uFuturesDefaultRate, &resp) + return resp, b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesOpenInterest+params.Encode(), uFuturesDefaultRate, &resp) } // UOpenInterestStats gets open interest stats for USDTMarginedFutures -func (b *Binance) UOpenInterestStats(symbol currency.Pair, period string, limit int64, startTime, endTime time.Time) ([]UOpenInterestStats, error) { +func (b *Binance) UOpenInterestStats(ctx context.Context, symbol currency.Pair, period string, limit int64, startTime, endTime time.Time) ([]UOpenInterestStats, error) { var resp []UOpenInterestStats params := url.Values{} symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) @@ -514,11 +515,11 @@ func (b *Binance) UOpenInterestStats(symbol currency.Pair, period string, limit params.Set("start_time", strconv.FormatInt(startTime.Unix(), 10)) params.Set("end_time", strconv.FormatInt(endTime.Unix(), 10)) } - return resp, b.SendHTTPRequest(exchange.RestUSDTMargined, ufuturesOpenInterestStats+params.Encode(), uFuturesDefaultRate, &resp) + return resp, b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesOpenInterestStats+params.Encode(), uFuturesDefaultRate, &resp) } // UTopAcccountsLongShortRatio gets long/short ratio data for top trader accounts in ufutures -func (b *Binance) UTopAcccountsLongShortRatio(symbol currency.Pair, period string, limit int64, startTime, endTime time.Time) ([]ULongShortRatio, error) { +func (b *Binance) UTopAcccountsLongShortRatio(ctx context.Context, symbol currency.Pair, period string, limit int64, startTime, endTime time.Time) ([]ULongShortRatio, error) { var resp []ULongShortRatio params := url.Values{} symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) @@ -540,11 +541,11 @@ func (b *Binance) UTopAcccountsLongShortRatio(symbol currency.Pair, period strin params.Set("start_time", strconv.FormatInt(startTime.Unix(), 10)) params.Set("end_time", strconv.FormatInt(endTime.Unix(), 10)) } - return resp, b.SendHTTPRequest(exchange.RestUSDTMargined, ufuturesTopAccountsRatio+params.Encode(), uFuturesDefaultRate, &resp) + return resp, b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesTopAccountsRatio+params.Encode(), uFuturesDefaultRate, &resp) } // UTopPostionsLongShortRatio gets long/short ratio data for top positions' in ufutures -func (b *Binance) UTopPostionsLongShortRatio(symbol currency.Pair, period string, limit int64, startTime, endTime time.Time) ([]ULongShortRatio, error) { +func (b *Binance) UTopPostionsLongShortRatio(ctx context.Context, symbol currency.Pair, period string, limit int64, startTime, endTime time.Time) ([]ULongShortRatio, error) { var resp []ULongShortRatio params := url.Values{} symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) @@ -566,11 +567,11 @@ func (b *Binance) UTopPostionsLongShortRatio(symbol currency.Pair, period string params.Set("start_time", strconv.FormatInt(startTime.Unix(), 10)) params.Set("end_time", strconv.FormatInt(endTime.Unix(), 10)) } - return resp, b.SendHTTPRequest(exchange.RestUSDTMargined, ufuturesTopPositionsRatio+params.Encode(), uFuturesDefaultRate, &resp) + return resp, b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesTopPositionsRatio+params.Encode(), uFuturesDefaultRate, &resp) } // UGlobalLongShortRatio gets the global long/short ratio data for USDTMarginedFutures -func (b *Binance) UGlobalLongShortRatio(symbol currency.Pair, period string, limit int64, startTime, endTime time.Time) ([]ULongShortRatio, error) { +func (b *Binance) UGlobalLongShortRatio(ctx context.Context, symbol currency.Pair, period string, limit int64, startTime, endTime time.Time) ([]ULongShortRatio, error) { var resp []ULongShortRatio params := url.Values{} symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) @@ -592,11 +593,11 @@ func (b *Binance) UGlobalLongShortRatio(symbol currency.Pair, period string, lim params.Set("start_time", strconv.FormatInt(startTime.Unix(), 10)) params.Set("end_time", strconv.FormatInt(endTime.Unix(), 10)) } - return resp, b.SendHTTPRequest(exchange.RestUSDTMargined, ufuturesLongShortRatio+params.Encode(), uFuturesDefaultRate, &resp) + return resp, b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesLongShortRatio+params.Encode(), uFuturesDefaultRate, &resp) } // UTakerBuySellVol gets takers' buy/sell ratio for USDTMarginedFutures -func (b *Binance) UTakerBuySellVol(symbol currency.Pair, period string, limit int64, startTime, endTime time.Time) ([]UTakerVolumeData, error) { +func (b *Binance) UTakerBuySellVol(ctx context.Context, symbol currency.Pair, period string, limit int64, startTime, endTime time.Time) ([]UTakerVolumeData, error) { var resp []UTakerVolumeData params := url.Values{} symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) @@ -618,11 +619,11 @@ func (b *Binance) UTakerBuySellVol(symbol currency.Pair, period string, limit in params.Set("start_time", strconv.FormatInt(startTime.Unix(), 10)) params.Set("end_time", strconv.FormatInt(endTime.Unix(), 10)) } - return resp, b.SendHTTPRequest(exchange.RestUSDTMargined, ufuturesBuySellVolume+params.Encode(), uFuturesDefaultRate, &resp) + return resp, b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesBuySellVolume+params.Encode(), uFuturesDefaultRate, &resp) } // UCompositeIndexInfo stores composite indexs' info for usdt margined futures -func (b *Binance) UCompositeIndexInfo(symbol currency.Pair) ([]UCompositeIndexInfoData, error) { +func (b *Binance) UCompositeIndexInfo(ctx context.Context, symbol currency.Pair) ([]UCompositeIndexInfoData, error) { params := url.Values{} if !symbol.IsEmpty() { symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) @@ -631,18 +632,18 @@ func (b *Binance) UCompositeIndexInfo(symbol currency.Pair) ([]UCompositeIndexIn } params.Set("symbol", symbolValue) var tempResp UCompositeIndexInfoData - err = b.SendHTTPRequest(exchange.RestUSDTMargined, ufuturesCompositeIndexInfo+params.Encode(), uFuturesDefaultRate, &tempResp) + err = b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesCompositeIndexInfo+params.Encode(), uFuturesDefaultRate, &tempResp) if err != nil { return nil, err } return []UCompositeIndexInfoData{tempResp}, err } var resp []UCompositeIndexInfoData - return resp, b.SendHTTPRequest(exchange.RestUSDTMargined, ufuturesCompositeIndexInfo+params.Encode(), uFuturesDefaultRate, &resp) + return resp, b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, ufuturesCompositeIndexInfo+params.Encode(), uFuturesDefaultRate, &resp) } // UFuturesNewOrder sends a new order for USDTMarginedFutures -func (b *Binance) UFuturesNewOrder(symbol currency.Pair, side, positionSide, orderType, timeInForce, +func (b *Binance) UFuturesNewOrder(ctx context.Context, symbol currency.Pair, side, positionSide, orderType, timeInForce, newClientOrderID, closePosition, workingType, newOrderRespType string, quantity, price, stopPrice, activationPrice, callbackRate float64, reduceOnly bool) (UOrderData, error) { var resp UOrderData @@ -697,11 +698,11 @@ func (b *Binance) UFuturesNewOrder(symbol currency.Pair, side, positionSide, ord if callbackRate != 0 { params.Set("callbackRate", strconv.FormatFloat(callbackRate, 'f', -1, 64)) } - return resp, b.SendAuthHTTPRequest(exchange.RestUSDTMargined, http.MethodPost, ufuturesOrder, params, uFuturesOrdersDefaultRate, &resp) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodPost, ufuturesOrder, params, uFuturesOrdersDefaultRate, &resp) } // UPlaceBatchOrders places batch orders -func (b *Binance) UPlaceBatchOrders(data []PlaceBatchOrderData) ([]UOrderData, error) { +func (b *Binance) UPlaceBatchOrders(ctx context.Context, data []PlaceBatchOrderData) ([]UOrderData, error) { var resp []UOrderData params := url.Values{} for x := range data { @@ -735,11 +736,11 @@ func (b *Binance) UPlaceBatchOrders(data []PlaceBatchOrderData) ([]UOrderData, e return resp, err } params.Set("batchOrders", string(jsonData)) - return resp, b.SendAuthHTTPRequest(exchange.RestUSDTMargined, http.MethodPost, ufuturesBatchOrder, params, uFuturesBatchOrdersRate, &resp) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodPost, ufuturesBatchOrder, params, uFuturesBatchOrdersRate, &resp) } // UGetOrderData gets order data for USDTMarginedFutures -func (b *Binance) UGetOrderData(symbol currency.Pair, orderID, cliOrderID string) (UOrderData, error) { +func (b *Binance) UGetOrderData(ctx context.Context, symbol currency.Pair, orderID, cliOrderID string) (UOrderData, error) { var resp UOrderData params := url.Values{} symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) @@ -753,11 +754,11 @@ func (b *Binance) UGetOrderData(symbol currency.Pair, orderID, cliOrderID string if cliOrderID != "" { params.Set("origClientOrderId", cliOrderID) } - return resp, b.SendAuthHTTPRequest(exchange.RestUSDTMargined, http.MethodGet, ufuturesOrder, params, uFuturesOrdersDefaultRate, &resp) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodGet, ufuturesOrder, params, uFuturesOrdersDefaultRate, &resp) } // UCancelOrder cancel an order for USDTMarginedFutures -func (b *Binance) UCancelOrder(symbol currency.Pair, orderID, cliOrderID string) (UOrderData, error) { +func (b *Binance) UCancelOrder(ctx context.Context, symbol currency.Pair, orderID, cliOrderID string) (UOrderData, error) { var resp UOrderData params := url.Values{} symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) @@ -771,11 +772,11 @@ func (b *Binance) UCancelOrder(symbol currency.Pair, orderID, cliOrderID string) if cliOrderID != "" { params.Set("origClientOrderId", cliOrderID) } - return resp, b.SendAuthHTTPRequest(exchange.RestUSDTMargined, http.MethodDelete, ufuturesOrder, params, uFuturesOrdersDefaultRate, &resp) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodDelete, ufuturesOrder, params, uFuturesOrdersDefaultRate, &resp) } // UCancelAllOpenOrders cancels all open orders for a symbol ufutures -func (b *Binance) UCancelAllOpenOrders(symbol currency.Pair) (GenericAuthResponse, error) { +func (b *Binance) UCancelAllOpenOrders(ctx context.Context, symbol currency.Pair) (GenericAuthResponse, error) { var resp GenericAuthResponse params := url.Values{} symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) @@ -783,11 +784,11 @@ func (b *Binance) UCancelAllOpenOrders(symbol currency.Pair) (GenericAuthRespons return resp, err } params.Set("symbol", symbolValue) - return resp, b.SendAuthHTTPRequest(exchange.RestUSDTMargined, http.MethodDelete, ufuturesCancelAllOrders, params, uFuturesOrdersDefaultRate, &resp) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodDelete, ufuturesCancelAllOrders, params, uFuturesOrdersDefaultRate, &resp) } // UCancelBatchOrders cancel batch order for USDTMarginedFutures -func (b *Binance) UCancelBatchOrders(symbol currency.Pair, orderIDList, origCliOrdIDList []string) ([]UOrderData, error) { +func (b *Binance) UCancelBatchOrders(ctx context.Context, symbol currency.Pair, orderIDList, origCliOrdIDList []string) ([]UOrderData, error) { var resp []UOrderData params := url.Values{} symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) @@ -809,11 +810,11 @@ func (b *Binance) UCancelBatchOrders(symbol currency.Pair, orderIDList, origCliO } params.Set("origClientOrderIdList", string(jsonCliOrders)) } - return resp, b.SendAuthHTTPRequest(exchange.RestUSDTMargined, http.MethodDelete, ufuturesBatchOrder, params, uFuturesOrdersDefaultRate, &resp) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodDelete, ufuturesBatchOrder, params, uFuturesOrdersDefaultRate, &resp) } // UAutoCancelAllOpenOrders auto cancels all ufutures open orders for a symbol after the set countdown time -func (b *Binance) UAutoCancelAllOpenOrders(symbol currency.Pair, countdownTime int64) (AutoCancelAllOrdersData, error) { +func (b *Binance) UAutoCancelAllOpenOrders(ctx context.Context, symbol currency.Pair, countdownTime int64) (AutoCancelAllOrdersData, error) { var resp AutoCancelAllOrdersData params := url.Values{} symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) @@ -822,11 +823,11 @@ func (b *Binance) UAutoCancelAllOpenOrders(symbol currency.Pair, countdownTime i } params.Set("symbol", symbolValue) params.Set("countdownTime", strconv.FormatInt(countdownTime, 10)) - return resp, b.SendAuthHTTPRequest(exchange.RestUSDTMargined, http.MethodPost, ufuturesCountdownCancel, params, uFuturesCountdownCancelRate, &resp) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodPost, ufuturesCountdownCancel, params, uFuturesCountdownCancelRate, &resp) } // UFetchOpenOrder sends a request to fetch open order data for USDTMarginedFutures -func (b *Binance) UFetchOpenOrder(symbol currency.Pair, orderID, origClientOrderID string) (UOrderData, error) { +func (b *Binance) UFetchOpenOrder(ctx context.Context, symbol currency.Pair, orderID, origClientOrderID string) (UOrderData, error) { var resp UOrderData params := url.Values{} if !symbol.IsEmpty() { @@ -842,11 +843,11 @@ func (b *Binance) UFetchOpenOrder(symbol currency.Pair, orderID, origClientOrder if origClientOrderID != "" { params.Set("origClientOrderId", origClientOrderID) } - return resp, b.SendAuthHTTPRequest(exchange.RestUSDTMargined, http.MethodGet, ufuturesOpenOrder, params, uFuturesOrdersDefaultRate, &resp) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodGet, ufuturesOpenOrder, params, uFuturesOrdersDefaultRate, &resp) } // UAllAccountOpenOrders gets all account's orders for USDTMarginedFutures -func (b *Binance) UAllAccountOpenOrders(symbol currency.Pair) ([]UOrderData, error) { +func (b *Binance) UAllAccountOpenOrders(ctx context.Context, symbol currency.Pair) ([]UOrderData, error) { var resp []UOrderData params := url.Values{} rateLimit := uFuturesGetAllOpenOrdersRate @@ -861,11 +862,11 @@ func (b *Binance) UAllAccountOpenOrders(symbol currency.Pair) ([]UOrderData, err // extend the receive window when all currencies to prevent "recvwindow" error params.Set("recvWindow", "10000") } - return resp, b.SendAuthHTTPRequest(exchange.RestUSDTMargined, http.MethodGet, ufuturesAllOpenOrders, params, rateLimit, &resp) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodGet, ufuturesAllOpenOrders, params, rateLimit, &resp) } // UAllAccountOrders gets all account's orders for USDTMarginedFutures -func (b *Binance) UAllAccountOrders(symbol currency.Pair, orderID, limit int64, startTime, endTime time.Time) ([]UFuturesOrderData, error) { +func (b *Binance) UAllAccountOrders(ctx context.Context, symbol currency.Pair, orderID, limit int64, startTime, endTime time.Time) ([]UFuturesOrderData, error) { var resp []UFuturesOrderData params := url.Values{} symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) @@ -886,23 +887,23 @@ func (b *Binance) UAllAccountOrders(symbol currency.Pair, orderID, limit int64, params.Set("start_time", strconv.FormatInt(startTime.Unix(), 10)) params.Set("end_time", strconv.FormatInt(endTime.Unix(), 10)) } - return resp, b.SendAuthHTTPRequest(exchange.RestUSDTMargined, http.MethodGet, ufuturesAllOrders, params, uFuturesGetAllOrdersRate, &resp) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodGet, ufuturesAllOrders, params, uFuturesGetAllOrdersRate, &resp) } // UAccountBalanceV2 gets V2 account balance data -func (b *Binance) UAccountBalanceV2() ([]UAccountBalanceV2Data, error) { +func (b *Binance) UAccountBalanceV2(ctx context.Context) ([]UAccountBalanceV2Data, error) { var resp []UAccountBalanceV2Data - return resp, b.SendAuthHTTPRequest(exchange.RestUSDTMargined, http.MethodGet, ufuturesAccountBalance, nil, uFuturesOrdersDefaultRate, &resp) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodGet, ufuturesAccountBalance, nil, uFuturesOrdersDefaultRate, &resp) } // UAccountInformationV2 gets V2 account balance data -func (b *Binance) UAccountInformationV2() (UAccountInformationV2Data, error) { +func (b *Binance) UAccountInformationV2(ctx context.Context) (UAccountInformationV2Data, error) { var resp UAccountInformationV2Data - return resp, b.SendAuthHTTPRequest(exchange.RestUSDTMargined, http.MethodGet, ufuturesAccountInfo, nil, uFuturesAccountInformationRate, &resp) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodGet, ufuturesAccountInfo, nil, uFuturesAccountInformationRate, &resp) } // UChangeInitialLeverageRequest sends a request to change account's initial leverage -func (b *Binance) UChangeInitialLeverageRequest(symbol currency.Pair, leverage int64) (UChangeInitialLeverage, error) { +func (b *Binance) UChangeInitialLeverageRequest(ctx context.Context, symbol currency.Pair, leverage int64) (UChangeInitialLeverage, error) { var resp UChangeInitialLeverage params := url.Values{} symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) @@ -914,11 +915,11 @@ func (b *Binance) UChangeInitialLeverageRequest(symbol currency.Pair, leverage i return resp, errors.New("invalid leverage") } params.Set("leverage", strconv.FormatInt(leverage, 10)) - return resp, b.SendAuthHTTPRequest(exchange.RestUSDTMargined, http.MethodPost, ufuturesChangeInitialLeverage, params, uFuturesDefaultRate, &resp) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodPost, ufuturesChangeInitialLeverage, params, uFuturesDefaultRate, &resp) } // UChangeInitialMarginType sends a request to change account's initial margin type -func (b *Binance) UChangeInitialMarginType(symbol currency.Pair, marginType string) error { +func (b *Binance) UChangeInitialMarginType(ctx context.Context, symbol currency.Pair, marginType string) error { params := url.Values{} symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) if err != nil { @@ -929,11 +930,11 @@ func (b *Binance) UChangeInitialMarginType(symbol currency.Pair, marginType stri return errors.New("invalid marginType") } params.Set("marginType", marginType) - return b.SendAuthHTTPRequest(exchange.RestUSDTMargined, http.MethodPost, ufuturesChangeMarginType, params, uFuturesDefaultRate, nil) + return b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodPost, ufuturesChangeMarginType, params, uFuturesDefaultRate, nil) } // UModifyIsolatedPositionMarginReq sends a request to modify isolated margin for USDTMarginedFutures -func (b *Binance) UModifyIsolatedPositionMarginReq(symbol currency.Pair, positionSide, changeType string, amount float64) (UModifyIsolatedPosMargin, error) { +func (b *Binance) UModifyIsolatedPositionMarginReq(ctx context.Context, symbol currency.Pair, positionSide, changeType string, amount float64) (UModifyIsolatedPosMargin, error) { var resp UModifyIsolatedPosMargin params := url.Values{} symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) @@ -952,11 +953,11 @@ func (b *Binance) UModifyIsolatedPositionMarginReq(symbol currency.Pair, positio } params.Set("type", strconv.FormatInt(cType, 10)) params.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) - return resp, b.SendAuthHTTPRequest(exchange.RestUSDTMargined, http.MethodPost, ufuturesModifyMargin, params, uFuturesDefaultRate, &resp) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodPost, ufuturesModifyMargin, params, uFuturesDefaultRate, &resp) } // UPositionMarginChangeHistory gets margin change history for USDTMarginedFutures -func (b *Binance) UPositionMarginChangeHistory(symbol currency.Pair, changeType string, limit int64, startTime, endTime time.Time) ([]UPositionMarginChangeHistoryData, error) { +func (b *Binance) UPositionMarginChangeHistory(ctx context.Context, symbol currency.Pair, changeType string, limit int64, startTime, endTime time.Time) ([]UPositionMarginChangeHistoryData, error) { var resp []UPositionMarginChangeHistoryData params := url.Values{} symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) @@ -979,11 +980,11 @@ func (b *Binance) UPositionMarginChangeHistory(symbol currency.Pair, changeType params.Set("start_time", strconv.FormatInt(startTime.Unix(), 10)) params.Set("end_time", strconv.FormatInt(endTime.Unix(), 10)) } - return resp, b.SendAuthHTTPRequest(exchange.RestUSDTMargined, http.MethodGet, ufuturesMarginChangeHistory, params, uFuturesDefaultRate, &resp) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodGet, ufuturesMarginChangeHistory, params, uFuturesDefaultRate, &resp) } // UPositionsInfoV2 gets positions' info for USDTMarginedFutures -func (b *Binance) UPositionsInfoV2(symbol currency.Pair) ([]UPositionInformationV2, error) { +func (b *Binance) UPositionsInfoV2(ctx context.Context, symbol currency.Pair) ([]UPositionInformationV2, error) { var resp []UPositionInformationV2 params := url.Values{} if !symbol.IsEmpty() { @@ -993,11 +994,11 @@ func (b *Binance) UPositionsInfoV2(symbol currency.Pair) ([]UPositionInformation } params.Set("symbol", symbolValue) } - return resp, b.SendAuthHTTPRequest(exchange.RestUSDTMargined, http.MethodGet, ufuturesPositionInfo, params, uFuturesDefaultRate, &resp) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodGet, ufuturesPositionInfo, params, uFuturesDefaultRate, &resp) } // UAccountTradesHistory gets account's trade history data for USDTMarginedFutures -func (b *Binance) UAccountTradesHistory(symbol currency.Pair, fromID string, limit int64, startTime, endTime time.Time) ([]UAccountTradeHistory, error) { +func (b *Binance) UAccountTradesHistory(ctx context.Context, symbol currency.Pair, fromID string, limit int64, startTime, endTime time.Time) ([]UAccountTradeHistory, error) { var resp []UAccountTradeHistory params := url.Values{} symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) @@ -1018,11 +1019,11 @@ func (b *Binance) UAccountTradesHistory(symbol currency.Pair, fromID string, lim params.Set("start_time", strconv.FormatInt(startTime.Unix(), 10)) params.Set("end_time", strconv.FormatInt(endTime.Unix(), 10)) } - return resp, b.SendAuthHTTPRequest(exchange.RestUSDTMargined, http.MethodGet, ufuturesAccountTradeList, params, uFuturesAccountInformationRate, &resp) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodGet, ufuturesAccountTradeList, params, uFuturesAccountInformationRate, &resp) } // UAccountIncomeHistory gets account's income history data for USDTMarginedFutures -func (b *Binance) UAccountIncomeHistory(symbol currency.Pair, incomeType string, limit int64, startTime, endTime time.Time) ([]UAccountIncomeHistory, error) { +func (b *Binance) UAccountIncomeHistory(ctx context.Context, symbol currency.Pair, incomeType string, limit int64, startTime, endTime time.Time) ([]UAccountIncomeHistory, error) { var resp []UAccountIncomeHistory params := url.Values{} symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) @@ -1046,11 +1047,11 @@ func (b *Binance) UAccountIncomeHistory(symbol currency.Pair, incomeType string, params.Set("start_time", strconv.FormatInt(startTime.Unix(), 10)) params.Set("end_time", strconv.FormatInt(endTime.Unix(), 10)) } - return resp, b.SendAuthHTTPRequest(exchange.RestUSDTMargined, http.MethodGet, ufuturesIncomeHistory, params, uFuturesIncomeHistoryRate, &resp) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodGet, ufuturesIncomeHistory, params, uFuturesIncomeHistoryRate, &resp) } // UGetNotionalAndLeverageBrackets gets account's notional and leverage brackets for USDTMarginedFutures -func (b *Binance) UGetNotionalAndLeverageBrackets(symbol currency.Pair) ([]UNotionalLeverageAndBrakcetsData, error) { +func (b *Binance) UGetNotionalAndLeverageBrackets(ctx context.Context, symbol currency.Pair) ([]UNotionalLeverageAndBrakcetsData, error) { var resp []UNotionalLeverageAndBrakcetsData params := url.Values{} if !symbol.IsEmpty() { @@ -1060,11 +1061,11 @@ func (b *Binance) UGetNotionalAndLeverageBrackets(symbol currency.Pair) ([]UNoti } params.Set("symbol", symbolValue) } - return resp, b.SendAuthHTTPRequest(exchange.RestUSDTMargined, http.MethodGet, ufuturesNotionalBracket, params, uFuturesDefaultRate, &resp) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodGet, ufuturesNotionalBracket, params, uFuturesDefaultRate, &resp) } // UPositionsADLEstimate gets estimated ADL data for USDTMarginedFutures positions -func (b *Binance) UPositionsADLEstimate(symbol currency.Pair) (UPositionADLEstimationData, error) { +func (b *Binance) UPositionsADLEstimate(ctx context.Context, symbol currency.Pair) (UPositionADLEstimationData, error) { var resp UPositionADLEstimationData params := url.Values{} if !symbol.IsEmpty() { @@ -1074,11 +1075,11 @@ func (b *Binance) UPositionsADLEstimate(symbol currency.Pair) (UPositionADLEstim } params.Set("symbol", symbolValue) } - return resp, b.SendAuthHTTPRequest(exchange.RestUSDTMargined, http.MethodGet, ufuturesADLQuantile, params, uFuturesAccountInformationRate, &resp) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodGet, ufuturesADLQuantile, params, uFuturesAccountInformationRate, &resp) } // UAccountForcedOrders gets account's forced (liquidation) orders for USDTMarginedFutures -func (b *Binance) UAccountForcedOrders(symbol currency.Pair, autoCloseType string, limit int64, startTime, endTime time.Time) ([]UForceOrdersData, error) { +func (b *Binance) UAccountForcedOrders(ctx context.Context, symbol currency.Pair, autoCloseType string, limit int64, startTime, endTime time.Time) ([]UForceOrdersData, error) { var resp []UForceOrdersData params := url.Values{} rateLimit := uFuturesAllForceOrdersRate @@ -1106,17 +1107,17 @@ func (b *Binance) UAccountForcedOrders(symbol currency.Pair, autoCloseType strin params.Set("start_time", strconv.FormatInt(startTime.Unix(), 10)) params.Set("end_time", strconv.FormatInt(endTime.Unix(), 10)) } - return resp, b.SendAuthHTTPRequest(exchange.RestUSDTMargined, http.MethodGet, ufuturesUsersForceOrders, params, rateLimit, &resp) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestUSDTMargined, http.MethodGet, ufuturesUsersForceOrders, params, rateLimit, &resp) } // GetPerpMarkets returns exchange information. Check binance_types for more information -func (b *Binance) GetPerpMarkets() (PerpsExchangeInfo, error) { +func (b *Binance) GetPerpMarkets(ctx context.Context) (PerpsExchangeInfo, error) { var resp PerpsExchangeInfo - return resp, b.SendHTTPRequest(exchange.RestUSDTMargined, perpExchangeInfo, uFuturesDefaultRate, &resp) + return resp, b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, perpExchangeInfo, uFuturesDefaultRate, &resp) } // GetFundingRates gets funding rate history for perpetual contracts -func (b *Binance) GetFundingRates(symbol currency.Pair, limit string, startTime, endTime time.Time) ([]FundingRateData, error) { +func (b *Binance) GetFundingRates(ctx context.Context, symbol currency.Pair, limit string, startTime, endTime time.Time) ([]FundingRateData, error) { var resp []FundingRateData params := url.Values{} symbolValue, err := b.FormatSymbol(symbol, asset.USDTMarginedFutures) @@ -1133,13 +1134,13 @@ func (b *Binance) GetFundingRates(symbol currency.Pair, limit string, startTime, if !endTime.IsZero() { params.Set("endTime", strconv.FormatInt(endTime.UnixNano(), 10)) } - return resp, b.SendHTTPRequest(exchange.RestUSDTMargined, fundingRate+params.Encode(), uFuturesDefaultRate, &resp) + return resp, b.SendHTTPRequest(ctx, exchange.RestUSDTMargined, fundingRate+params.Encode(), uFuturesDefaultRate, &resp) } // FetchUSDTMarginExchangeLimits fetches USDT margined order execution limits -func (b *Binance) FetchUSDTMarginExchangeLimits() ([]order.MinMaxLevel, error) { +func (b *Binance) FetchUSDTMarginExchangeLimits(ctx context.Context) ([]order.MinMaxLevel, error) { var limits []order.MinMaxLevel - usdtFutures, err := b.UExchangeInfo() + usdtFutures, err := b.UExchangeInfo(ctx) if err != nil { return nil, err } diff --git a/exchanges/binance/binance_websocket.go b/exchanges/binance/binance_websocket.go index f030a066..bc313188 100644 --- a/exchanges/binance/binance_websocket.go +++ b/exchanges/binance/binance_websocket.go @@ -1,6 +1,7 @@ package binance import ( + "context" "encoding/json" "errors" "fmt" @@ -51,7 +52,7 @@ func (b *Binance) WsConnect() error { dialer.Proxy = http.ProxyFromEnvironment var err error if b.Websocket.CanUseAuthenticatedEndpoints() { - listenKey, err = b.GetWsAuthStreamKey() + listenKey, err = b.GetWsAuthStreamKey(context.TODO()) if err != nil { b.Websocket.SetCanUseAuthenticatedEndpoints(false) log.Errorf(log.ExchangeSys, @@ -130,7 +131,7 @@ func (b *Binance) KeepAuthKeyAlive() { ticks.Stop() return case <-ticks.C: - err := b.MaintainWsAuthStreamKey() + err := b.MaintainWsAuthStreamKey(context.TODO()) if err != nil { b.Websocket.DataHandler <- err log.Warnf(log.ExchangeSys, @@ -467,11 +468,12 @@ func stringToOrderStatus(status string) (order.Status, error) { } // SeedLocalCache seeds depth data -func (b *Binance) SeedLocalCache(p currency.Pair) error { - ob, err := b.GetOrderBook(OrderBookDataRequestParams{ - Symbol: p, - Limit: 1000, - }) +func (b *Binance) SeedLocalCache(ctx context.Context, p currency.Pair) error { + ob, err := b.GetOrderBook(ctx, + OrderBookDataRequestParams{ + Symbol: p, + Limit: 1000, + }) if err != nil { return err } @@ -759,7 +761,7 @@ func (b *Binance) SynchroniseWebsocketOrderbook() { // processJob fetches and processes orderbook updates func (b *Binance) processJob(p currency.Pair) error { - err := b.SeedLocalCache(p) + err := b.SeedLocalCache(context.TODO(), p) if err != nil { return fmt.Errorf("%s %s seeding local cache for orderbook error: %v", p, asset.Spot, err) diff --git a/exchanges/binance/binance_wrapper.go b/exchanges/binance/binance_wrapper.go index 95c57546..99f099cc 100644 --- a/exchanges/binance/binance_wrapper.go +++ b/exchanges/binance/binance_wrapper.go @@ -1,6 +1,7 @@ package binance import ( + "context" "errors" "fmt" "sort" @@ -41,7 +42,7 @@ func (b *Binance) GetDefaultConfig() (*config.ExchangeConfig, error) { } if b.Features.Supports.RESTCapabilities.AutoPairUpdates { - err = b.UpdateTradablePairs(true) + err = b.UpdateTradablePairs(context.TODO(), true) if err != nil { return nil, err } @@ -317,7 +318,7 @@ func (b *Binance) Run() { a := b.GetAssetTypes(true) for x := range a { - err = b.UpdateOrderExecutionLimits(a[x]) + err = b.UpdateOrderExecutionLimits(context.TODO(), a[x]) if err != nil { log.Errorf(log.ExchangeSys, "%s failed to set exchange order execution limits. Err: %v", @@ -329,7 +330,7 @@ func (b *Binance) Run() { if !b.GetEnabledFeatures().AutoPairUpdates && !forceUpdate { return } - err = b.UpdateTradablePairs(forceUpdate) + err = b.UpdateTradablePairs(context.TODO(), forceUpdate) if err != nil { log.Errorf(log.ExchangeSys, "%s failed to update tradable pairs. Err: %s", @@ -339,7 +340,7 @@ func (b *Binance) Run() { } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (b *Binance) FetchTradablePairs(a asset.Item) ([]string, error) { +func (b *Binance) FetchTradablePairs(ctx context.Context, a asset.Item) ([]string, error) { if !b.SupportsAsset(a) { return nil, fmt.Errorf("asset type of %s is not supported by %s", a, b.Name) } @@ -350,7 +351,7 @@ func (b *Binance) FetchTradablePairs(a asset.Item) ([]string, error) { var pairs []string switch a { case asset.Spot, asset.Margin: - info, err := b.GetExchangeInfo() + info, err := b.GetExchangeInfo(ctx) if err != nil { return nil, err } @@ -368,7 +369,7 @@ func (b *Binance) FetchTradablePairs(a asset.Item) ([]string, error) { } } case asset.CoinMarginedFutures: - cInfo, err := b.FuturesExchangeInfo() + cInfo, err := b.FuturesExchangeInfo(ctx) if err != nil { return pairs, nil } @@ -382,7 +383,7 @@ func (b *Binance) FetchTradablePairs(a asset.Item) ([]string, error) { } } case asset.USDTMarginedFutures: - uInfo, err := b.UExchangeInfo() + uInfo, err := b.UExchangeInfo(ctx) if err != nil { return pairs, nil } @@ -401,10 +402,10 @@ func (b *Binance) FetchTradablePairs(a asset.Item) ([]string, error) { // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (b *Binance) UpdateTradablePairs(forceUpdate bool) error { +func (b *Binance) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { assetTypes := b.GetAssetTypes(false) for i := range assetTypes { - p, err := b.FetchTradablePairs(assetTypes[i]) + p, err := b.FetchTradablePairs(ctx, assetTypes[i]) if err != nil { return err } @@ -423,10 +424,10 @@ func (b *Binance) UpdateTradablePairs(forceUpdate bool) error { } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (b *Binance) UpdateTickers(a asset.Item) error { +func (b *Binance) UpdateTickers(ctx context.Context, a asset.Item) error { switch a { case asset.Spot, asset.Margin: - tick, err := b.GetTickers() + tick, err := b.GetTickers(ctx) if err != nil { return err } @@ -454,7 +455,7 @@ func (b *Binance) UpdateTickers(a asset.Item) error { } } case asset.USDTMarginedFutures: - tick, err := b.U24HTickerPriceChangeStats(currency.Pair{}) + tick, err := b.U24HTickerPriceChangeStats(ctx, currency.Pair{}) if err != nil { return err } @@ -481,7 +482,7 @@ func (b *Binance) UpdateTickers(a asset.Item) error { } } case asset.CoinMarginedFutures: - tick, err := b.GetFuturesSwapTickerChangeStats(currency.Pair{}, "") + tick, err := b.GetFuturesSwapTickerChangeStats(ctx, currency.Pair{}, "") if err != nil { return err } @@ -514,10 +515,10 @@ func (b *Binance) UpdateTickers(a asset.Item) error { } // UpdateTicker updates and returns the ticker for a currency pair -func (b *Binance) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) { +func (b *Binance) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { switch a { case asset.Spot, asset.Margin: - tick, err := b.GetPriceChangeStats(p) + tick, err := b.GetPriceChangeStats(ctx, p) if err != nil { return nil, err } @@ -543,7 +544,7 @@ func (b *Binance) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, er return nil, err } case asset.USDTMarginedFutures: - tick, err := b.U24HTickerPriceChangeStats(p) + tick, err := b.U24HTickerPriceChangeStats(ctx, p) if err != nil { return nil, err } @@ -567,7 +568,7 @@ func (b *Binance) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, er return nil, err } case asset.CoinMarginedFutures: - tick, err := b.GetFuturesSwapTickerChangeStats(p, "") + tick, err := b.GetFuturesSwapTickerChangeStats(ctx, p, "") if err != nil { return nil, err } @@ -598,7 +599,7 @@ func (b *Binance) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, er } // FetchTicker returns the ticker for a currency pair -func (b *Binance) FetchTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) { +func (b *Binance) FetchTicker(ctx context.Context, p currency.Pair, assetType asset.Item) (*ticker.Price, error) { fPair, err := b.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err @@ -606,22 +607,22 @@ func (b *Binance) FetchTicker(p currency.Pair, assetType asset.Item) (*ticker.Pr tickerNew, err := ticker.GetTicker(b.Name, fPair, assetType) if err != nil { - return b.UpdateTicker(p, assetType) + return b.UpdateTicker(ctx, p, assetType) } return tickerNew, nil } // FetchOrderbook returns orderbook base on the currency pair -func (b *Binance) FetchOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (b *Binance) FetchOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { ob, err := orderbook.Get(b.Name, p, assetType) if err != nil { - return b.UpdateOrderbook(p, assetType) + return b.UpdateOrderbook(ctx, p, assetType) } return ob, nil } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (b *Binance) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (b *Binance) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { book := &orderbook.Base{ Exchange: b.Name, Pair: p, @@ -632,13 +633,14 @@ func (b *Binance) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*order var err error switch assetType { case asset.Spot, asset.Margin: - orderbookNew, err = b.GetOrderBook(OrderBookDataRequestParams{ - Symbol: p, - Limit: 1000}) + orderbookNew, err = b.GetOrderBook(ctx, + OrderBookDataRequestParams{ + Symbol: p, + Limit: 1000}) case asset.USDTMarginedFutures: - orderbookNew, err = b.UFuturesOrderbook(p, 1000) + orderbookNew, err = b.UFuturesOrderbook(ctx, p, 1000) case asset.CoinMarginedFutures: - orderbookNew, err = b.GetFuturesOrderbook(p, 1000) + orderbookNew, err = b.GetFuturesOrderbook(ctx, p, 1000) } if err != nil { return book, err @@ -665,13 +667,13 @@ func (b *Binance) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*order // UpdateAccountInfo retrieves balances for all enabled currencies for the // Binance exchange -func (b *Binance) UpdateAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (b *Binance) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { var info account.Holdings var acc account.SubAccount info.Exchange = b.Name switch assetType { case asset.Spot: - raw, err := b.GetAccount() + raw, err := b.GetAccount(ctx) if err != nil { return info, err } @@ -698,7 +700,7 @@ func (b *Binance) UpdateAccountInfo(assetType asset.Item) (account.Holdings, err acc.Currencies = currencyBalance case asset.CoinMarginedFutures: - accData, err := b.GetFuturesAccountInfo() + accData, err := b.GetFuturesAccountInfo(ctx) if err != nil { return info, err } @@ -714,7 +716,7 @@ func (b *Binance) UpdateAccountInfo(assetType asset.Item) (account.Holdings, err acc.Currencies = currencyDetails case asset.USDTMarginedFutures: - accData, err := b.UAccountBalanceV2() + accData, err := b.UAccountBalanceV2(ctx) if err != nil { return info, err } @@ -729,7 +731,7 @@ func (b *Binance) UpdateAccountInfo(assetType asset.Item) (account.Holdings, err acc.Currencies = currencyDetails case asset.Margin: - accData, err := b.GetMarginAccount() + accData, err := b.GetMarginAccount(ctx) if err != nil { return info, err } @@ -757,10 +759,10 @@ func (b *Binance) UpdateAccountInfo(assetType asset.Item) (account.Holdings, err } // FetchAccountInfo retrieves balances for all enabled currencies -func (b *Binance) FetchAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (b *Binance) FetchAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { acc, err := account.GetHoldings(b.Name, assetType) if err != nil { - return b.UpdateAccountInfo(assetType) + return b.UpdateAccountInfo(ctx, assetType) } return acc, nil @@ -768,13 +770,13 @@ func (b *Binance) FetchAccountInfo(assetType asset.Item) (account.Holdings, erro // GetFundingHistory returns funding history, deposits and // withdrawals -func (b *Binance) GetFundingHistory() ([]exchange.FundHistory, error) { +func (b *Binance) GetFundingHistory(ctx context.Context) ([]exchange.FundHistory, error) { return nil, common.ErrFunctionNotSupported } // GetWithdrawalsHistory returns previous withdrawals data -func (b *Binance) GetWithdrawalsHistory(c currency.Code) (resp []exchange.WithdrawalHistory, err error) { - w, err := b.WithdrawStatus(c, "", 0, 0) +func (b *Binance) GetWithdrawalsHistory(ctx context.Context, c currency.Code) (resp []exchange.WithdrawalHistory, err error) { + w, err := b.WithdrawStatus(ctx, c, "", 0, 0) if err != nil { return nil, err } @@ -796,10 +798,11 @@ 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) { +func (b *Binance) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { var resp []trade.Data limit := 1000 - tradeData, err := b.GetMostRecentTrades(RecentTradeRequestParams{p, limit}) + tradeData, err := b.GetMostRecentTrades(ctx, + RecentTradeRequestParams{p, limit}) if err != nil { return nil, err } @@ -826,13 +829,13 @@ 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) { +func (b *Binance) GetHistoricTrades(ctx context.Context, p currency.Pair, a asset.Item, from, to time.Time) ([]trade.Data, error) { req := AggregatedTradeRequestParams{ Symbol: p, StartTime: from, EndTime: to, } - trades, err := b.GetAggregatedTrades(&req) + trades, err := b.GetAggregatedTrades(ctx, &req) if err != nil { return nil, err } @@ -859,7 +862,7 @@ func (a *AggregatedTrade) toTradeData(p currency.Pair, exchange string, aType as } // SubmitOrder submits a new order -func (b *Binance) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { +func (b *Binance) SubmitOrder(ctx context.Context, s *order.Submit) (order.SubmitResponse, error) { var submitOrderResponse order.SubmitResponse if err := s.Validate(); err != nil { return submitOrderResponse, err @@ -895,7 +898,7 @@ func (b *Binance) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { TimeInForce: timeInForce, NewClientOrderID: s.ClientOrderID, } - response, err := b.NewOrder(&orderRequest) + response, err := b.NewOrder(ctx, &orderRequest) if err != nil { return submitOrderResponse, err } @@ -947,7 +950,8 @@ func (b *Binance) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { default: return submitOrderResponse, errors.New("invalid type, check api docs for updates") } - o, err := b.FuturesNewOrder(s.Pair, reqSide, + o, err := b.FuturesNewOrder(ctx, + s.Pair, reqSide, "", oType, "GTC", "", s.ClientOrderID, "", "", s.Amount, s.Price, 0, 0, 0, s.ReduceOnly) @@ -985,7 +989,8 @@ func (b *Binance) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { default: return submitOrderResponse, errors.New("invalid type, check api docs for updates") } - order, err := b.UFuturesNewOrder(s.Pair, reqSide, + order, err := b.UFuturesNewOrder(ctx, + s.Pair, reqSide, "", oType, "GTC", "", s.ClientOrderID, "", "", s.Amount, s.Price, 0, 0, 0, s.ReduceOnly) @@ -1003,12 +1008,12 @@ func (b *Binance) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (b *Binance) ModifyOrder(action *order.Modify) (order.Modify, error) { +func (b *Binance) ModifyOrder(ctx context.Context, action *order.Modify) (order.Modify, error) { return order.Modify{}, common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number -func (b *Binance) CancelOrder(o *order.Cancel) error { +func (b *Binance) CancelOrder(ctx context.Context, o *order.Cancel) error { if err := o.Validate(o.StandardCancel()); err != nil { return err } @@ -1018,19 +1023,20 @@ func (b *Binance) CancelOrder(o *order.Cancel) error { if err != nil { return err } - _, err = b.CancelExistingOrder(o.Pair, + _, err = b.CancelExistingOrder(ctx, + o.Pair, orderIDInt, o.AccountID) if err != nil { return err } case asset.CoinMarginedFutures: - _, err := b.FuturesCancelOrder(o.Pair, o.ID, "") + _, err := b.FuturesCancelOrder(ctx, o.Pair, o.ID, "") if err != nil { return err } case asset.USDTMarginedFutures: - _, err := b.UCancelOrder(o.Pair, o.ID, "") + _, err := b.UCancelOrder(ctx, o.Pair, o.ID, "") if err != nil { return err } @@ -1039,12 +1045,12 @@ func (b *Binance) CancelOrder(o *order.Cancel) error { } // CancelBatchOrders cancels an orders by their corresponding ID numbers -func (b *Binance) CancelBatchOrders(o []order.Cancel) (order.CancelBatchResponse, error) { +func (b *Binance) CancelBatchOrders(ctx context.Context, o []order.Cancel) (order.CancelBatchResponse, error) { return order.CancelBatchResponse{}, common.ErrNotYetImplemented } // CancelAllOrders cancels all orders associated with a currency pair -func (b *Binance) CancelAllOrders(req *order.Cancel) (order.CancelAllResponse, error) { +func (b *Binance) CancelAllOrders(ctx context.Context, req *order.Cancel) (order.CancelAllResponse, error) { if err := req.Validate(); err != nil { return order.CancelAllResponse{}, err } @@ -1052,12 +1058,13 @@ func (b *Binance) CancelAllOrders(req *order.Cancel) (order.CancelAllResponse, e cancelAllOrdersResponse.Status = make(map[string]string) switch req.AssetType { case asset.Spot, asset.Margin: - openOrders, err := b.OpenOrders(req.Pair) + openOrders, err := b.OpenOrders(ctx, req.Pair) if err != nil { return cancelAllOrdersResponse, err } for i := range openOrders { - _, err = b.CancelExistingOrder(req.Pair, + _, err = b.CancelExistingOrder(ctx, + req.Pair, openOrders[i].OrderID, "") if err != nil { @@ -1071,13 +1078,13 @@ func (b *Binance) CancelAllOrders(req *order.Cancel) (order.CancelAllResponse, e return cancelAllOrdersResponse, err } for i := range enabledPairs { - _, err = b.FuturesCancelAllOpenOrders(enabledPairs[i]) + _, err = b.FuturesCancelAllOpenOrders(ctx, enabledPairs[i]) if err != nil { return cancelAllOrdersResponse, err } } } else { - _, err := b.FuturesCancelAllOpenOrders(req.Pair) + _, err := b.FuturesCancelAllOpenOrders(ctx, req.Pair) if err != nil { return cancelAllOrdersResponse, err } @@ -1089,13 +1096,13 @@ func (b *Binance) CancelAllOrders(req *order.Cancel) (order.CancelAllResponse, e return cancelAllOrdersResponse, err } for i := range enabledPairs { - _, err = b.UCancelAllOpenOrders(enabledPairs[i]) + _, err = b.UCancelAllOpenOrders(ctx, enabledPairs[i]) if err != nil { return cancelAllOrdersResponse, err } } } else { - _, err := b.UCancelAllOpenOrders(req.Pair) + _, err := b.UCancelAllOpenOrders(ctx, req.Pair) if err != nil { return cancelAllOrdersResponse, err } @@ -1107,7 +1114,7 @@ func (b *Binance) CancelAllOrders(req *order.Cancel) (order.CancelAllResponse, e } // GetOrderInfo returns information on a current open order -func (b *Binance) GetOrderInfo(orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { +func (b *Binance) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { var respData order.Detail orderIDInt, err := strconv.ParseInt(orderID, 10, 64) if err != nil { @@ -1115,7 +1122,7 @@ func (b *Binance) GetOrderInfo(orderID string, pair currency.Pair, assetType ass } switch assetType { case asset.Spot: - resp, err := b.QueryOrder(pair, "", orderIDInt) + resp, err := b.QueryOrder(ctx, pair, "", orderIDInt) if err != nil { return respData, err } @@ -1146,7 +1153,7 @@ func (b *Binance) GetOrderInfo(orderID string, pair currency.Pair, assetType ass LastUpdated: resp.UpdateTime, }, nil case asset.CoinMarginedFutures: - orderData, err := b.FuturesOpenOrderData(pair, orderID, "") + orderData, err := b.FuturesOpenOrderData(ctx, pair, orderID, "") if err != nil { return respData, err } @@ -1154,7 +1161,7 @@ func (b *Binance) GetOrderInfo(orderID string, pair currency.Pair, assetType ass feeBuilder.Amount = orderData.ExecutedQuantity feeBuilder.PurchasePrice = orderData.AveragePrice feeBuilder.Pair = pair - fee, err := b.GetFee(&feeBuilder) + fee, err := b.GetFee(ctx, &feeBuilder) if err != nil { return respData, err } @@ -1175,7 +1182,7 @@ func (b *Binance) GetOrderInfo(orderID string, pair currency.Pair, assetType ass respData.Date = orderData.Time respData.LastUpdated = orderData.UpdateTime case asset.USDTMarginedFutures: - orderData, err := b.UGetOrderData(pair, orderID, "") + orderData, err := b.UGetOrderData(ctx, pair, orderID, "") if err != nil { return respData, err } @@ -1183,7 +1190,7 @@ func (b *Binance) GetOrderInfo(orderID string, pair currency.Pair, assetType ass feeBuilder.Amount = orderData.ExecutedQuantity feeBuilder.PurchasePrice = orderData.AveragePrice feeBuilder.Pair = pair - fee, err := b.GetFee(&feeBuilder) + fee, err := b.GetFee(ctx, &feeBuilder) if err != nil { return respData, err } @@ -1210,18 +1217,19 @@ func (b *Binance) GetOrderInfo(orderID string, pair currency.Pair, assetType ass } // GetDepositAddress returns a deposit address for a specified currency -func (b *Binance) GetDepositAddress(cryptocurrency currency.Code, _ string) (string, error) { - return b.GetDepositAddressForCurrency(cryptocurrency.String()) +func (b *Binance) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _ string) (string, error) { + return b.GetDepositAddressForCurrency(ctx, cryptocurrency.String()) } // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is // submitted -func (b *Binance) WithdrawCryptocurrencyFunds(withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (b *Binance) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } amountStr := strconv.FormatFloat(withdrawRequest.Amount, 'f', -1, 64) - v, err := b.WithdrawCrypto(withdrawRequest.Currency.String(), + v, err := b.WithdrawCrypto(ctx, + withdrawRequest.Currency.String(), withdrawRequest.Crypto.Address, withdrawRequest.Crypto.AddressTag, withdrawRequest.Description, amountStr) @@ -1235,27 +1243,27 @@ func (b *Binance) WithdrawCryptocurrencyFunds(withdrawRequest *withdraw.Request) // WithdrawFiatFunds returns a withdrawal ID when a // withdrawal is submitted -func (b *Binance) WithdrawFiatFunds(_ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (b *Binance) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a // withdrawal is submitted -func (b *Binance) WithdrawFiatFundsToInternationalBank(_ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (b *Binance) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // GetFeeByType returns an estimate of fee based on type of transaction -func (b *Binance) GetFeeByType(feeBuilder *exchange.FeeBuilder) (float64, error) { +func (b *Binance) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { if (!b.AllowAuthenticatedRequest() || b.SkipAuthCheck) && // Todo check connection status feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { feeBuilder.FeeType = exchange.OfflineTradeFee } - return b.GetFee(feeBuilder) + return b.GetFee(ctx, feeBuilder) } // GetActiveOrders retrieves any orders that are active/open -func (b *Binance) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, error) { +func (b *Binance) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) { if err := req.Validate(); err != nil { return nil, err } @@ -1267,7 +1275,7 @@ func (b *Binance) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, for i := range req.Pairs { switch req.AssetType { case asset.Spot, asset.Margin: - resp, err := b.OpenOrders(req.Pairs[i]) + resp, err := b.OpenOrders(ctx, req.Pairs[i]) if err != nil { return nil, err } @@ -1290,7 +1298,7 @@ func (b *Binance) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, }) } case asset.CoinMarginedFutures: - openOrders, err := b.GetFuturesAllOpenOrders(req.Pairs[i], "") + openOrders, err := b.GetFuturesAllOpenOrders(ctx, req.Pairs[i], "") if err != nil { return nil, err } @@ -1299,7 +1307,7 @@ func (b *Binance) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, feeBuilder.Amount = openOrders[y].ExecutedQty feeBuilder.PurchasePrice = openOrders[y].AvgPrice feeBuilder.Pair = req.Pairs[i] - fee, err := b.GetFee(&feeBuilder) + fee, err := b.GetFee(ctx, &feeBuilder) if err != nil { return orders, err } @@ -1323,7 +1331,7 @@ func (b *Binance) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, }) } case asset.USDTMarginedFutures: - openOrders, err := b.UAllAccountOpenOrders(req.Pairs[i]) + openOrders, err := b.UAllAccountOpenOrders(ctx, req.Pairs[i]) if err != nil { return nil, err } @@ -1332,7 +1340,7 @@ func (b *Binance) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, feeBuilder.Amount = openOrders[y].ExecutedQuantity feeBuilder.PurchasePrice = openOrders[y].AveragePrice feeBuilder.Pair = req.Pairs[i] - fee, err := b.GetFee(&feeBuilder) + fee, err := b.GetFee(ctx, &feeBuilder) if err != nil { return orders, err } @@ -1368,7 +1376,7 @@ func (b *Binance) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, // GetOrderHistory retrieves account order information // Can Limit response to specific order status -func (b *Binance) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, error) { +func (b *Binance) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) { if err := req.Validate(); err != nil { return nil, err } @@ -1379,7 +1387,8 @@ func (b *Binance) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, switch req.AssetType { case asset.Spot, asset.Margin: for x := range req.Pairs { - resp, err := b.AllOrders(req.Pairs[x], + resp, err := b.AllOrders(ctx, + req.Pairs[x], "", "1000") if err != nil { @@ -1423,7 +1432,8 @@ func (b *Binance) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, if time.Since(req.StartTime) > time.Hour*24*30 { return nil, fmt.Errorf("can only fetch orders 30 days out") } - orderHistory, err = b.GetAllFuturesOrders(req.Pairs[i], "", req.StartTime, req.EndTime, 0, 0) + orderHistory, err = b.GetAllFuturesOrders(ctx, + req.Pairs[i], "", req.StartTime, req.EndTime, 0, 0) if err != nil { return nil, err } @@ -1432,7 +1442,8 @@ func (b *Binance) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, if err != nil { return nil, err } - orderHistory, err = b.GetAllFuturesOrders(req.Pairs[i], "", time.Time{}, time.Time{}, fromID, 0) + orderHistory, err = b.GetAllFuturesOrders(ctx, + req.Pairs[i], "", time.Time{}, time.Time{}, fromID, 0) if err != nil { return nil, err } @@ -1444,7 +1455,7 @@ func (b *Binance) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, feeBuilder.Amount = orderHistory[y].ExecutedQty feeBuilder.PurchasePrice = orderHistory[y].AvgPrice feeBuilder.Pair = req.Pairs[i] - fee, err := b.GetFee(&feeBuilder) + fee, err := b.GetFee(ctx, &feeBuilder) if err != nil { return orders, err } @@ -1479,7 +1490,8 @@ func (b *Binance) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, if time.Since(req.StartTime) > time.Hour*24*7 { return nil, fmt.Errorf("can only fetch orders 7 days out") } - orderHistory, err = b.UAllAccountOrders(req.Pairs[i], 0, 0, req.StartTime, req.EndTime) + orderHistory, err = b.UAllAccountOrders(ctx, + req.Pairs[i], 0, 0, req.StartTime, req.EndTime) if err != nil { return nil, err } @@ -1488,7 +1500,8 @@ func (b *Binance) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, if err != nil { return nil, err } - orderHistory, err = b.UAllAccountOrders(req.Pairs[i], fromID, 0, time.Time{}, time.Time{}) + orderHistory, err = b.UAllAccountOrders(ctx, + req.Pairs[i], fromID, 0, time.Time{}, time.Time{}) if err != nil { return nil, err } @@ -1500,7 +1513,7 @@ func (b *Binance) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, feeBuilder.Amount = orderHistory[y].ExecutedQty feeBuilder.PurchasePrice = orderHistory[y].AvgPrice feeBuilder.Pair = req.Pairs[i] - fee, err := b.GetFee(&feeBuilder) + fee, err := b.GetFee(ctx, &feeBuilder) if err != nil { return orders, err } @@ -1534,8 +1547,8 @@ func (b *Binance) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, // ValidateCredentials validates current credentials used for wrapper // functionality -func (b *Binance) ValidateCredentials(assetType asset.Item) error { - _, err := b.UpdateAccountInfo(assetType) +func (b *Binance) ValidateCredentials(ctx context.Context, assetType asset.Item) error { + _, err := b.UpdateAccountInfo(ctx, assetType) return b.CheckTransientError(err) } @@ -1556,7 +1569,7 @@ func (b *Binance) FormatExchangeKlineInterval(interval kline.Interval) string { } // GetHistoricCandles returns candles between a time period for a set time interval -func (b *Binance) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (b *Binance) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { if err := b.ValidateKline(pair, a, interval); err != nil { return kline.Item{}, err } @@ -1577,7 +1590,7 @@ func (b *Binance) GetHistoricCandles(pair currency.Pair, a asset.Item, start, en Interval: interval, } - candles, err := b.GetSpotKline(&req) + candles, err := b.GetSpotKline(ctx, &req) if err != nil { return kline.Item{}, err } @@ -1596,7 +1609,7 @@ func (b *Binance) GetHistoricCandles(pair currency.Pair, a asset.Item, start, en } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (b *Binance) GetHistoricCandlesExtended(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (b *Binance) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { if err := b.ValidateKline(pair, a, interval); err != nil { return kline.Item{}, err } @@ -1621,7 +1634,7 @@ func (b *Binance) GetHistoricCandlesExtended(pair currency.Pair, a asset.Item, s Limit: int(b.Features.Enabled.Kline.ResultLimit), } - candles, err = b.GetSpotKline(&req) + candles, err = b.GetSpotKline(ctx, &req) if err != nil { return kline.Item{}, err } @@ -1698,19 +1711,19 @@ func compatibleOrderVars(side, status, orderType string) OrderVars { } // UpdateOrderExecutionLimits sets exchange executions for a required asset type -func (b *Binance) UpdateOrderExecutionLimits(a asset.Item) error { +func (b *Binance) UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) error { var limits []order.MinMaxLevel var err error switch a { case asset.Spot: - limits, err = b.FetchSpotExchangeLimits() + limits, err = b.FetchSpotExchangeLimits(ctx) case asset.USDTMarginedFutures: - limits, err = b.FetchUSDTMarginExchangeLimits() + limits, err = b.FetchUSDTMarginExchangeLimits(ctx) case asset.CoinMarginedFutures: - limits, err = b.FetchCoinMarginExchangeLimits() + limits, err = b.FetchCoinMarginExchangeLimits(ctx) case asset.Margin: if err = b.CurrencyPairs.IsAssetEnabled(asset.Spot); err != nil { - limits, err = b.FetchSpotExchangeLimits() + limits, err = b.FetchSpotExchangeLimits(ctx) } else { return nil } diff --git a/exchanges/bitfinex/bitfinex.go b/exchanges/bitfinex/bitfinex.go index e0c27c8e..443dc1a5 100644 --- a/exchanges/bitfinex/bitfinex.go +++ b/exchanges/bitfinex/bitfinex.go @@ -97,9 +97,9 @@ type Bitfinex struct { } // GetPlatformStatus returns the Bifinex platform status -func (b *Bitfinex) GetPlatformStatus() (int, error) { +func (b *Bitfinex) GetPlatformStatus(ctx context.Context) (int, error) { var response []int - err := b.SendHTTPRequest(exchange.RestSpot, + err := b.SendHTTPRequest(ctx, exchange.RestSpot, bitfinexAPIVersion2+ bitfinexPlatformStatus, &response, @@ -223,9 +223,10 @@ func defaultMarginV2Info(data []interface{}) (MarginInfoV2, error) { // GetV2MarginInfo gets v2 margin info for a symbol provided // symbol: base, sym_all, any other trading symbol example tBTCUSD -func (b *Bitfinex) GetV2MarginInfo(symbol string) ([]MarginInfoV2, error) { +func (b *Bitfinex) GetV2MarginInfo(ctx context.Context, symbol string) ([]MarginInfoV2, error) { var data []interface{} - err := b.SendAuthenticatedHTTPRequestV2(exchange.RestSpot, http.MethodPost, + err := b.SendAuthenticatedHTTPRequestV2(ctx, + exchange.RestSpot, http.MethodPost, bitfinexV2MarginInfo+symbol, nil, &data, @@ -254,14 +255,14 @@ func (b *Bitfinex) GetV2MarginInfo(symbol string) ([]MarginInfoV2, error) { } // GetV2MarginFunding gets borrowing rates for margin trading -func (b *Bitfinex) GetV2MarginFunding(symbol, amount string, period int32) (MarginV2FundingData, error) { +func (b *Bitfinex) GetV2MarginFunding(ctx context.Context, symbol, amount string, period int32) (MarginV2FundingData, error) { var resp []interface{} var response MarginV2FundingData params := make(map[string]interface{}) params["symbol"] = symbol params["period"] = period params["amount"] = amount - err := b.SendAuthenticatedHTTPRequestV2(exchange.RestSpot, http.MethodPost, + err := b.SendAuthenticatedHTTPRequestV2(ctx, exchange.RestSpot, http.MethodPost, bitfinexV2MarginFunding, params, &resp, @@ -287,10 +288,10 @@ func (b *Bitfinex) GetV2MarginFunding(symbol, amount string, period int32) (Marg } // GetV2FundingInfo gets funding info for margin pairs -func (b *Bitfinex) GetV2FundingInfo(key string) (MarginFundingDataV2, error) { +func (b *Bitfinex) GetV2FundingInfo(ctx context.Context, key string) (MarginFundingDataV2, error) { var resp []interface{} var response MarginFundingDataV2 - err := b.SendAuthenticatedHTTPRequestV2(exchange.RestSpot, http.MethodPost, + err := b.SendAuthenticatedHTTPRequestV2(ctx, exchange.RestSpot, http.MethodPost, fmt.Sprintf(bitfinexV2FundingInfo, key), nil, &resp, @@ -332,10 +333,10 @@ func (b *Bitfinex) GetV2FundingInfo(key string) (MarginFundingDataV2, error) { } // GetAccountInfoV2 gets V2 account data -func (b *Bitfinex) GetAccountInfoV2() (AccountV2Data, error) { +func (b *Bitfinex) GetAccountInfoV2(ctx context.Context) (AccountV2Data, error) { var resp AccountV2Data var data []interface{} - err := b.SendAuthenticatedHTTPRequestV2(exchange.RestSpot, http.MethodPost, + err := b.SendAuthenticatedHTTPRequestV2(ctx, exchange.RestSpot, http.MethodPost, bitfinexV2AccountInfo, nil, &data, @@ -377,10 +378,11 @@ func (b *Bitfinex) GetAccountInfoV2() (AccountV2Data, error) { } // GetV2Balances gets v2 balances -func (b *Bitfinex) GetV2Balances() ([]WalletDataV2, error) { +func (b *Bitfinex) GetV2Balances(ctx context.Context) ([]WalletDataV2, error) { var resp []WalletDataV2 var data [][4]interface{} - err := b.SendAuthenticatedHTTPRequestV2(exchange.RestSpot, http.MethodPost, + err := b.SendAuthenticatedHTTPRequestV2(ctx, + exchange.RestSpot, http.MethodPost, bitfinexV2Balances, nil, &data, @@ -416,10 +418,10 @@ func (b *Bitfinex) GetV2Balances() ([]WalletDataV2, error) { } // GetMarginPairs gets pairs that allow margin trading -func (b *Bitfinex) GetMarginPairs() ([]string, error) { +func (b *Bitfinex) GetMarginPairs(ctx context.Context) ([]string, error) { var resp [][]string path := bitfinexAPIVersion2 + bitfinexMarginPairs - err := b.SendHTTPRequest(exchange.RestSpot, path, &resp, status) + err := b.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp, status) if err != nil { return nil, err } @@ -430,7 +432,7 @@ func (b *Bitfinex) GetMarginPairs() ([]string, error) { } // GetDerivativeStatusInfo gets status data for the queried derivative -func (b *Bitfinex) GetDerivativeStatusInfo(keys, startTime, endTime string, sort, limit int64) ([]DerivativeDataResponse, error) { +func (b *Bitfinex) GetDerivativeStatusInfo(ctx context.Context, keys, startTime, endTime string, sort, limit int64) ([]DerivativeDataResponse, error) { var result [][]interface{} var finalResp []DerivativeDataResponse @@ -450,7 +452,7 @@ func (b *Bitfinex) GetDerivativeStatusInfo(keys, startTime, endTime string, sort } path := bitfinexAPIVersion2 + bitfinexDerivativeData + params.Encode() - err := b.SendHTTPRequest(exchange.RestSpot, path, &result, status) + err := b.SendHTTPRequest(ctx, exchange.RestSpot, path, &result, status) if err != nil { return finalResp, err } @@ -500,13 +502,13 @@ func (b *Bitfinex) GetDerivativeStatusInfo(keys, startTime, endTime string, sort } // GetTickerBatch returns all supported ticker information -func (b *Bitfinex) GetTickerBatch() (map[string]Ticker, error) { +func (b *Bitfinex) GetTickerBatch(ctx context.Context) (map[string]Ticker, error) { var response [][]interface{} path := bitfinexAPIVersion2 + bitfinexTickerBatch + "?symbols=ALL" - err := b.SendHTTPRequest(exchange.RestSpot, path, &response, tickerBatch) + err := b.SendHTTPRequest(ctx, exchange.RestSpot, path, &response, tickerBatch) if err != nil { return nil, err } @@ -549,12 +551,12 @@ func (b *Bitfinex) GetTickerBatch() (map[string]Ticker, error) { } // GetTicker returns ticker information for one symbol -func (b *Bitfinex) GetTicker(symbol string) (Ticker, error) { +func (b *Bitfinex) GetTicker(ctx context.Context, symbol string) (Ticker, error) { var response []interface{} path := bitfinexAPIVersion2 + bitfinexTicker + symbol - err := b.SendHTTPRequest(exchange.RestSpot, path, &response, tickerFunction) + err := b.SendHTTPRequest(ctx, exchange.RestSpot, path, &response, tickerFunction) if err != nil { return Ticker{}, err } @@ -597,7 +599,7 @@ func (b *Bitfinex) GetTicker(symbol string) (Ticker, error) { // timestampStart is a millisecond timestamp // timestampEnd is a millisecond timestamp // reOrderResp reorders the returned data. -func (b *Bitfinex) GetTrades(currencyPair string, limit, timestampStart, timestampEnd int64, reOrderResp bool) ([]Trade, error) { +func (b *Bitfinex) GetTrades(ctx context.Context, currencyPair string, limit, timestampStart, timestampEnd int64, reOrderResp bool) ([]Trade, error) { v := url.Values{} if limit > 0 { v.Set("limit", strconv.FormatInt(limit, 10)) @@ -619,7 +621,7 @@ func (b *Bitfinex) GetTrades(currencyPair string, limit, timestampStart, timesta path := bitfinexAPIVersion2 + bitfinexTrades + currencyPair + "/hist" + "?" + v.Encode() var resp [][]interface{} - err := b.SendHTTPRequest(exchange.RestSpot, path, &resp, tradeRateLimit) + err := b.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp, tradeRateLimit) if err != nil { return nil, err } @@ -663,14 +665,14 @@ func (b *Bitfinex) GetTrades(currencyPair string, limit, timestampStart, timesta // precision - P0,P1,P2,P3,R0 // Values can contain limit amounts for both the asks and bids - Example // "len" = 100 -func (b *Bitfinex) GetOrderbook(symbol, precision string, limit int64) (Orderbook, error) { +func (b *Bitfinex) GetOrderbook(ctx context.Context, symbol, precision string, limit int64) (Orderbook, error) { var u = url.Values{} if limit > 0 { u.Set("len", strconv.FormatInt(limit, 10)) } path := bitfinexAPIVersion2 + bitfinexOrderbook + symbol + "/" + precision + "?" + u.Encode() var response [][]interface{} - err := b.SendHTTPRequest(exchange.RestSpot, path, &response, orderbookFunction) + err := b.SendHTTPRequest(ctx, exchange.RestSpot, path, &response, orderbookFunction) if err != nil { return Orderbook{}, err } @@ -739,10 +741,10 @@ func (b *Bitfinex) GetOrderbook(symbol, precision string, limit int64) (Orderboo } // GetStats returns various statistics about the requested pair -func (b *Bitfinex) GetStats(symbol string) ([]Stat, error) { +func (b *Bitfinex) GetStats(ctx context.Context, symbol string) ([]Stat, error) { var response []Stat path := bitfinexAPIVersion + bitfinexStats + symbol - return response, b.SendHTTPRequest(exchange.RestSpot, path, &response, statsV1) + return response, b.SendHTTPRequest(ctx, exchange.RestSpot, path, &response, statsV1) } // GetFundingBook the entire margin funding book for both bids and asks sides @@ -750,11 +752,11 @@ func (b *Bitfinex) GetStats(symbol string) ([]Stat, error) { // symbol - example "USD" // WARNING: Orderbook now has this support, will be deprecated once a full // conversion to full V2 API update is done. -func (b *Bitfinex) GetFundingBook(symbol string) (FundingBook, error) { +func (b *Bitfinex) GetFundingBook(ctx context.Context, symbol string) (FundingBook, error) { response := FundingBook{} path := bitfinexAPIVersion + bitfinexLendbook + symbol - if err := b.SendHTTPRequest(exchange.RestSpot, path, &response, fundingbook); err != nil { + if err := b.SendHTTPRequest(ctx, exchange.RestSpot, path, &response, fundingbook); err != nil { return response, err } @@ -765,20 +767,20 @@ func (b *Bitfinex) GetFundingBook(symbol string) (FundingBook, error) { // currency: total amount provided and Flash Return Rate (in % by 365 days) // over time // Symbol - example "USD" -func (b *Bitfinex) GetLends(symbol string, values url.Values) ([]Lends, error) { +func (b *Bitfinex) GetLends(ctx context.Context, symbol string, values url.Values) ([]Lends, error) { var response []Lends path := common.EncodeURLValues(bitfinexAPIVersion+ bitfinexLends+ symbol, values) - return response, b.SendHTTPRequest(exchange.RestSpot, path, &response, lends) + return response, b.SendHTTPRequest(ctx, exchange.RestSpot, path, &response, lends) } // GetCandles returns candle chart data // timeFrame values: '1m', '5m', '15m', '30m', '1h', '3h', '6h', '12h', '1D', // '7D', '14D', '1M' // section values: last or hist -func (b *Bitfinex) GetCandles(symbol, timeFrame string, start, end int64, limit uint32, historic bool) ([]Candle, error) { +func (b *Bitfinex) GetCandles(ctx context.Context, symbol, timeFrame string, start, end int64, limit uint32, historic bool) ([]Candle, error) { var fundingPeriod string if symbol[0] == 'f' { fundingPeriod = ":p30" @@ -812,7 +814,7 @@ func (b *Bitfinex) GetCandles(symbol, timeFrame string, start, end int64, limit } var response [][]interface{} - err := b.SendHTTPRequest(exchange.RestSpot, path, &response, candle) + err := b.SendHTTPRequest(ctx, exchange.RestSpot, path, &response, candle) if err != nil { return nil, err } @@ -835,7 +837,7 @@ func (b *Bitfinex) GetCandles(symbol, timeFrame string, start, end int64, limit path += "/last" var response []interface{} - err := b.SendHTTPRequest(exchange.RestSpot, path, &response, candle) + err := b.SendHTTPRequest(ctx, exchange.RestSpot, path, &response, candle) if err != nil { return nil, err } @@ -879,7 +881,7 @@ func (b *Bitfinex) GetLiquidationFeed() error { // profit // Allowed time frames are 3h, 1w and 1M // Allowed symbols are trading pairs (e.g. tBTCUSD, tETHUSD and tGLOBAL:USD) -func (b *Bitfinex) GetLeaderboard(key, timeframe, symbol string, sort, limit int, start, end string) ([]LeaderboardEntry, error) { +func (b *Bitfinex) GetLeaderboard(ctx context.Context, key, timeframe, symbol string, sort, limit int, start, end string) ([]LeaderboardEntry, error) { validLeaderboardKey := func(input string) bool { switch input { case LeaderboardUnrealisedProfitPeriodDelta, @@ -915,7 +917,7 @@ func (b *Bitfinex) GetLeaderboard(key, timeframe, symbol string, sort, limit int } path = common.EncodeURLValues(path, vals) var resp []interface{} - if err := b.SendHTTPRequest(exchange.RestSpot, path, &resp, leaderBoardReqRate); err != nil { + if err := b.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp, leaderBoardReqRate); err != nil { return nil, err } @@ -953,9 +955,9 @@ func (b *Bitfinex) GetForeignExchangeRate() error { } // GetAccountFees returns information about your account trading fees -func (b *Bitfinex) GetAccountFees() ([]AccountInfo, error) { +func (b *Bitfinex) GetAccountFees(ctx context.Context) ([]AccountInfo, error) { var responses []AccountInfo - return responses, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return responses, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexAccountInfo, nil, &responses, @@ -963,9 +965,9 @@ func (b *Bitfinex) GetAccountFees() ([]AccountInfo, error) { } // GetWithdrawalFees - Gets all fee rates for withdrawals -func (b *Bitfinex) GetWithdrawalFees() (AccountFees, error) { +func (b *Bitfinex) GetWithdrawalFees(ctx context.Context) (AccountFees, error) { response := AccountFees{} - return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexAccountFees, nil, &response, @@ -974,10 +976,10 @@ func (b *Bitfinex) GetWithdrawalFees() (AccountFees, error) { // GetAccountSummary returns a 30-day summary of your trading volume and return // on margin funding -func (b *Bitfinex) GetAccountSummary() (AccountSummary, error) { +func (b *Bitfinex) GetAccountSummary(ctx context.Context) (AccountSummary, error) { response := AccountSummary{} - return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexAccountSummary, nil, &response, @@ -989,7 +991,7 @@ func (b *Bitfinex) GetAccountSummary() (AccountSummary, error) { // “tethers", "ethereumc", "zcash", "monero", "iota", "bcash" // WalletName - accepted: “trading”, “exchange”, “deposit” // renew - Default is 0. If set to 1, will return a new unused deposit address -func (b *Bitfinex) NewDeposit(method, walletName string, renew int) (DepositResponse, error) { +func (b *Bitfinex) NewDeposit(ctx context.Context, method, walletName string, renew int) (DepositResponse, error) { if !common.StringDataCompare(AcceptedWalletNames, walletName) { return DepositResponse{}, fmt.Errorf("walletname: [%s] is not allowed, supported: %s", @@ -1003,7 +1005,7 @@ func (b *Bitfinex) NewDeposit(method, walletName string, renew int) (DepositResp req["wallet_name"] = walletName req["renew"] = renew - return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexDeposit, req, &response, @@ -1012,9 +1014,9 @@ func (b *Bitfinex) NewDeposit(method, walletName string, renew int) (DepositResp // GetKeyPermissions checks the permissions of the key being used to generate // this request. -func (b *Bitfinex) GetKeyPermissions() (KeyPermissions, error) { +func (b *Bitfinex) GetKeyPermissions(ctx context.Context) (KeyPermissions, error) { response := KeyPermissions{} - return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexKeyPermissions, nil, &response, @@ -1022,9 +1024,9 @@ func (b *Bitfinex) GetKeyPermissions() (KeyPermissions, error) { } // GetMarginInfo shows your trading wallet information for margin trading -func (b *Bitfinex) GetMarginInfo() ([]MarginInfo, error) { +func (b *Bitfinex) GetMarginInfo(ctx context.Context) ([]MarginInfo, error) { var response []MarginInfo - return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexMarginInfo, nil, &response, @@ -1032,9 +1034,9 @@ func (b *Bitfinex) GetMarginInfo() ([]MarginInfo, error) { } // GetAccountBalance returns full wallet balance information -func (b *Bitfinex) GetAccountBalance() ([]Balance, error) { +func (b *Bitfinex) GetAccountBalance(ctx context.Context) ([]Balance, error) { var response []Balance - return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexBalances, nil, &response, @@ -1046,7 +1048,7 @@ func (b *Bitfinex) GetAccountBalance() ([]Balance, error) { // Currency - example "BTC" // WalletFrom - example "exchange" // WalletTo - example "deposit" -func (b *Bitfinex) WalletTransfer(amount float64, currency, walletFrom, walletTo string) (WalletTransfer, error) { +func (b *Bitfinex) WalletTransfer(ctx context.Context, amount float64, currency, walletFrom, walletTo string) (WalletTransfer, error) { var response []WalletTransfer req := make(map[string]interface{}) req["amount"] = strconv.FormatFloat(amount, 'f', -1, 64) @@ -1054,7 +1056,7 @@ func (b *Bitfinex) WalletTransfer(amount float64, currency, walletFrom, walletTo req["walletfrom"] = walletFrom req["walletto"] = walletTo - err := b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + err := b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexTransfer, req, &response, @@ -1071,7 +1073,7 @@ func (b *Bitfinex) WalletTransfer(amount float64, currency, walletFrom, walletTo // WithdrawCryptocurrency requests a withdrawal from one of your wallets. // For FIAT, use WithdrawFIAT -func (b *Bitfinex) WithdrawCryptocurrency(wallet, address, paymentID string, amount float64, c currency.Code) (Withdrawal, error) { +func (b *Bitfinex) WithdrawCryptocurrency(ctx context.Context, wallet, address, paymentID string, amount float64, c currency.Code) (Withdrawal, error) { var response []Withdrawal req := make(map[string]interface{}) req["withdraw_type"] = b.ConvertSymbolToWithdrawalType(c) @@ -1082,7 +1084,7 @@ func (b *Bitfinex) WithdrawCryptocurrency(wallet, address, paymentID string, amo req["payment_id"] = paymentID } - err := b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + err := b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexWithdrawal, req, &response, @@ -1099,7 +1101,7 @@ func (b *Bitfinex) WithdrawCryptocurrency(wallet, address, paymentID string, amo } // WithdrawFIAT Sends an authenticated request to withdraw FIAT currency -func (b *Bitfinex) WithdrawFIAT(withdrawalType, walletType string, withdrawRequest *withdraw.Request) (Withdrawal, error) { +func (b *Bitfinex) WithdrawFIAT(ctx context.Context, withdrawalType, walletType string, withdrawRequest *withdraw.Request) (Withdrawal, error) { var response []Withdrawal req := make(map[string]interface{}) @@ -1127,7 +1129,7 @@ func (b *Bitfinex) WithdrawFIAT(withdrawalType, walletType string, withdrawReque req["intermediary_bank_swift"] = withdrawRequest.Fiat.IntermediarySwiftCode } - err := b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + err := b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexWithdrawal, req, &response, @@ -1145,7 +1147,7 @@ func (b *Bitfinex) WithdrawFIAT(withdrawalType, walletType string, withdrawReque // NewOrder submits a new order and returns a order information // Major Upgrade needed on this function to include all query params -func (b *Bitfinex) NewOrder(currencyPair, orderType string, amount, price float64, buy, hidden bool) (Order, error) { +func (b *Bitfinex) NewOrder(ctx context.Context, currencyPair, orderType string, amount, price float64, buy, hidden bool) (Order, error) { if !common.StringDataCompare(AcceptedOrderType, orderType) { return Order{}, fmt.Errorf("order type %s not accepted", orderType) } @@ -1162,7 +1164,7 @@ func (b *Bitfinex) NewOrder(currencyPair, orderType string, amount, price float6 req["side"] = order.Buy.Lower() } - return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexOrderNew, req, &response, @@ -1170,12 +1172,12 @@ func (b *Bitfinex) NewOrder(currencyPair, orderType string, amount, price float6 } // NewOrderMulti allows several new orders at once -func (b *Bitfinex) NewOrderMulti(orders []PlaceOrder) (OrderMultiResponse, error) { +func (b *Bitfinex) NewOrderMulti(ctx context.Context, orders []PlaceOrder) (OrderMultiResponse, error) { response := OrderMultiResponse{} req := make(map[string]interface{}) req["orders"] = orders - return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexOrderNewMulti, req, &response, @@ -1183,12 +1185,12 @@ func (b *Bitfinex) NewOrderMulti(orders []PlaceOrder) (OrderMultiResponse, error } // CancelExistingOrder cancels a single order by OrderID -func (b *Bitfinex) CancelExistingOrder(orderID int64) (Order, error) { +func (b *Bitfinex) CancelExistingOrder(ctx context.Context, orderID int64) (Order, error) { response := Order{} req := make(map[string]interface{}) req["order_id"] = orderID - return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexOrderCancel, req, &response, @@ -1196,12 +1198,12 @@ func (b *Bitfinex) CancelExistingOrder(orderID int64) (Order, error) { } // CancelMultipleOrders cancels multiple orders -func (b *Bitfinex) CancelMultipleOrders(orderIDs []int64) (string, error) { +func (b *Bitfinex) CancelMultipleOrders(ctx context.Context, orderIDs []int64) (string, error) { response := GenericResponse{} req := make(map[string]interface{}) req["order_ids"] = orderIDs - return response.Result, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return response.Result, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexOrderCancelMulti, req, nil, @@ -1209,10 +1211,10 @@ func (b *Bitfinex) CancelMultipleOrders(orderIDs []int64) (string, error) { } // CancelAllExistingOrders cancels all active and open orders -func (b *Bitfinex) CancelAllExistingOrders() (string, error) { +func (b *Bitfinex) CancelAllExistingOrders(ctx context.Context) (string, error) { response := GenericResponse{} - return response.Result, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return response.Result, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexOrderCancelAll, nil, nil, @@ -1220,7 +1222,7 @@ func (b *Bitfinex) CancelAllExistingOrders() (string, error) { } // ReplaceOrder replaces an older order with a new order -func (b *Bitfinex) ReplaceOrder(orderID int64, symbol string, amount, price float64, buy bool, orderType string, hidden bool) (Order, error) { +func (b *Bitfinex) ReplaceOrder(ctx context.Context, orderID int64, symbol string, amount, price float64, buy bool, orderType string, hidden bool) (Order, error) { response := Order{} req := make(map[string]interface{}) req["order_id"] = orderID @@ -1237,7 +1239,7 @@ func (b *Bitfinex) ReplaceOrder(orderID int64, symbol string, amount, price floa req["side"] = order.Sell.Lower() } - return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexOrderCancelReplace, req, &response, @@ -1245,12 +1247,12 @@ func (b *Bitfinex) ReplaceOrder(orderID int64, symbol string, amount, price floa } // GetOrderStatus returns order status information -func (b *Bitfinex) GetOrderStatus(orderID int64) (Order, error) { +func (b *Bitfinex) GetOrderStatus(ctx context.Context, orderID int64) (Order, error) { orderStatus := Order{} req := make(map[string]interface{}) req["order_id"] = orderID - return orderStatus, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return orderStatus, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexOrderStatus, req, &orderStatus, @@ -1258,12 +1260,12 @@ func (b *Bitfinex) GetOrderStatus(orderID int64) (Order, error) { } // GetInactiveOrders returns order status information -func (b *Bitfinex) GetInactiveOrders() ([]Order, error) { +func (b *Bitfinex) GetInactiveOrders(ctx context.Context) ([]Order, error) { var response []Order req := make(map[string]interface{}) req["limit"] = "100" - return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexInactiveOrders, req, &response, @@ -1271,9 +1273,9 @@ func (b *Bitfinex) GetInactiveOrders() ([]Order, error) { } // GetOpenOrders returns all active orders and statuses -func (b *Bitfinex) GetOpenOrders() ([]Order, error) { +func (b *Bitfinex) GetOpenOrders(ctx context.Context) ([]Order, error) { var response []Order - return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexOrders, nil, &response, @@ -1281,10 +1283,10 @@ func (b *Bitfinex) GetOpenOrders() ([]Order, error) { } // GetActivePositions returns an array of active positions -func (b *Bitfinex) GetActivePositions() ([]Position, error) { +func (b *Bitfinex) GetActivePositions(ctx context.Context) ([]Position, error) { var response []Position - return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexPositions, nil, &response, @@ -1292,12 +1294,12 @@ func (b *Bitfinex) GetActivePositions() ([]Position, error) { } // ClaimPosition allows positions to be claimed -func (b *Bitfinex) ClaimPosition(positionID int) (Position, error) { +func (b *Bitfinex) ClaimPosition(ctx context.Context, positionID int) (Position, error) { response := Position{} req := make(map[string]interface{}) req["position_id"] = positionID - return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexClaimPosition, nil, nil, @@ -1305,7 +1307,7 @@ func (b *Bitfinex) ClaimPosition(positionID int) (Position, error) { } // GetBalanceHistory returns balance history for the account -func (b *Bitfinex) GetBalanceHistory(symbol string, timeSince, timeUntil time.Time, limit int, wallet string) ([]BalanceHistory, error) { +func (b *Bitfinex) GetBalanceHistory(ctx context.Context, symbol string, timeSince, timeUntil time.Time, limit int, wallet string) ([]BalanceHistory, error) { var response []BalanceHistory req := make(map[string]interface{}) req["currency"] = symbol @@ -1323,7 +1325,7 @@ func (b *Bitfinex) GetBalanceHistory(symbol string, timeSince, timeUntil time.Ti req["wallet"] = wallet } - return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexHistory, req, &response, @@ -1331,7 +1333,7 @@ func (b *Bitfinex) GetBalanceHistory(symbol string, timeSince, timeUntil time.Ti } // GetMovementHistory returns an array of past deposits and withdrawals -func (b *Bitfinex) GetMovementHistory(symbol, method string, timeSince, timeUntil time.Time, limit int) ([]MovementHistory, error) { +func (b *Bitfinex) GetMovementHistory(ctx context.Context, symbol, method string, timeSince, timeUntil time.Time, limit int) ([]MovementHistory, error) { var response []MovementHistory req := make(map[string]interface{}) req["currency"] = symbol @@ -1349,7 +1351,7 @@ func (b *Bitfinex) GetMovementHistory(symbol, method string, timeSince, timeUnti req["limit"] = limit } - return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexHistoryMovements, req, &response, @@ -1357,7 +1359,7 @@ func (b *Bitfinex) GetMovementHistory(symbol, method string, timeSince, timeUnti } // GetTradeHistory returns past executed trades -func (b *Bitfinex) GetTradeHistory(currencyPair string, timestamp, until time.Time, limit, reverse int) ([]TradeHistory, error) { +func (b *Bitfinex) GetTradeHistory(ctx context.Context, currencyPair string, timestamp, until time.Time, limit, reverse int) ([]TradeHistory, error) { var response []TradeHistory req := make(map[string]interface{}) req["currency"] = currencyPair @@ -1373,7 +1375,7 @@ func (b *Bitfinex) GetTradeHistory(currencyPair string, timestamp, until time.Ti req["reverse"] = reverse } - return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexTradeHistory, req, &response, @@ -1381,7 +1383,7 @@ func (b *Bitfinex) GetTradeHistory(currencyPair string, timestamp, until time.Ti } // NewOffer submits a new offer -func (b *Bitfinex) NewOffer(symbol string, amount, rate float64, period int64, direction string) (Offer, error) { +func (b *Bitfinex) NewOffer(ctx context.Context, symbol string, amount, rate float64, period int64, direction string) (Offer, error) { response := Offer{} req := make(map[string]interface{}) req["currency"] = symbol @@ -1390,7 +1392,7 @@ func (b *Bitfinex) NewOffer(symbol string, amount, rate float64, period int64, d req["period"] = period req["direction"] = direction - return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexOfferNew, req, &response, @@ -1398,12 +1400,12 @@ func (b *Bitfinex) NewOffer(symbol string, amount, rate float64, period int64, d } // CancelOffer cancels offer by offerID -func (b *Bitfinex) CancelOffer(offerID int64) (Offer, error) { +func (b *Bitfinex) CancelOffer(ctx context.Context, offerID int64) (Offer, error) { response := Offer{} req := make(map[string]interface{}) req["offer_id"] = offerID - return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexOfferCancel, req, &response, @@ -1412,12 +1414,12 @@ func (b *Bitfinex) CancelOffer(offerID int64) (Offer, error) { // GetOfferStatus checks offer status whether it has been cancelled, execute or // is still active -func (b *Bitfinex) GetOfferStatus(offerID int64) (Offer, error) { +func (b *Bitfinex) GetOfferStatus(ctx context.Context, offerID int64) (Offer, error) { response := Offer{} req := make(map[string]interface{}) req["offer_id"] = offerID - return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexOrderStatus, req, &response, @@ -1425,10 +1427,10 @@ func (b *Bitfinex) GetOfferStatus(offerID int64) (Offer, error) { } // GetActiveCredits returns all available credits -func (b *Bitfinex) GetActiveCredits() ([]Offer, error) { +func (b *Bitfinex) GetActiveCredits(ctx context.Context) ([]Offer, error) { var response []Offer - return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexActiveCredits, nil, &response, @@ -1436,10 +1438,10 @@ func (b *Bitfinex) GetActiveCredits() ([]Offer, error) { } // GetActiveOffers returns all current active offers -func (b *Bitfinex) GetActiveOffers() ([]Offer, error) { +func (b *Bitfinex) GetActiveOffers(ctx context.Context) ([]Offer, error) { var response []Offer - return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexOffers, nil, &response, @@ -1447,10 +1449,10 @@ func (b *Bitfinex) GetActiveOffers() ([]Offer, error) { } // GetActiveMarginFunding returns an array of active margin funds -func (b *Bitfinex) GetActiveMarginFunding() ([]MarginFunds, error) { +func (b *Bitfinex) GetActiveMarginFunding(ctx context.Context) ([]MarginFunds, error) { var response []MarginFunds - return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexMarginActiveFunds, nil, &response, @@ -1459,10 +1461,10 @@ func (b *Bitfinex) GetActiveMarginFunding() ([]MarginFunds, error) { // GetUnusedMarginFunds returns an array of funding borrowed but not currently // used -func (b *Bitfinex) GetUnusedMarginFunds() ([]MarginFunds, error) { +func (b *Bitfinex) GetUnusedMarginFunds(ctx context.Context) ([]MarginFunds, error) { var response []MarginFunds - return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexMarginUnusedFunds, nil, &response, @@ -1471,10 +1473,10 @@ func (b *Bitfinex) GetUnusedMarginFunds() ([]MarginFunds, error) { // GetMarginTotalTakenFunds returns an array of active funding used in a // position -func (b *Bitfinex) GetMarginTotalTakenFunds() ([]MarginTotalTakenFunds, error) { +func (b *Bitfinex) GetMarginTotalTakenFunds(ctx context.Context) ([]MarginTotalTakenFunds, error) { var response []MarginTotalTakenFunds - return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexMarginTotalFunds, nil, &response, @@ -1482,12 +1484,12 @@ func (b *Bitfinex) GetMarginTotalTakenFunds() ([]MarginTotalTakenFunds, error) { } // CloseMarginFunding closes an unused or used taken fund -func (b *Bitfinex) CloseMarginFunding(swapID int64) (Offer, error) { +func (b *Bitfinex) CloseMarginFunding(ctx context.Context, swapID int64) (Offer, error) { response := Offer{} req := make(map[string]interface{}) req["swap_id"] = swapID - return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return response, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitfinexMarginClose, req, &response, @@ -1495,7 +1497,7 @@ func (b *Bitfinex) CloseMarginFunding(swapID int64) (Offer, error) { } // SendHTTPRequest sends an unauthenticated request -func (b *Bitfinex) SendHTTPRequest(ep exchange.URL, path string, result interface{}, e request.EndpointLimit) error { +func (b *Bitfinex) SendHTTPRequest(ctx context.Context, ep exchange.URL, path string, result interface{}, e request.EndpointLimit) error { endpoint, err := b.API.Endpoints.GetURL(ep) if err != nil { return err @@ -1508,14 +1510,14 @@ func (b *Bitfinex) SendHTTPRequest(ep exchange.URL, path string, result interfac HTTPDebugging: b.HTTPDebugging, HTTPRecording: b.HTTPRecording} - return b.SendPayload(context.Background(), e, func() (*request.Item, error) { + return b.SendPayload(ctx, e, func() (*request.Item, error) { return item, nil }) } // SendAuthenticatedHTTPRequest sends an autheticated http request and json // unmarshals result to a supplied variable -func (b *Bitfinex) SendAuthenticatedHTTPRequest(ep exchange.URL, method, path string, params map[string]interface{}, result interface{}, endpoint request.EndpointLimit) error { +func (b *Bitfinex) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, method, path string, params map[string]interface{}, result interface{}, endpoint request.EndpointLimit) error { if !b.AllowAuthenticatedRequest() { return fmt.Errorf("%s %w", b.Name, exchange.ErrAuthenticatedRequestWithoutCredentialsSet) } @@ -1526,7 +1528,7 @@ func (b *Bitfinex) SendAuthenticatedHTTPRequest(ep exchange.URL, method, path st } fullPath := ePoint + bitfinexAPIVersion + path - return b.SendPayload(context.Background(), endpoint, func() (*request.Item, error) { + return b.SendPayload(ctx, endpoint, func() (*request.Item, error) { n := b.Requester.GetNonce(true) req := make(map[string]interface{}) req["request"] = bitfinexAPIVersion + path @@ -1568,7 +1570,7 @@ func (b *Bitfinex) SendAuthenticatedHTTPRequest(ep exchange.URL, method, path st // SendAuthenticatedHTTPRequestV2 sends an autheticated http request and json // unmarshals result to a supplied variable -func (b *Bitfinex) SendAuthenticatedHTTPRequestV2(ep exchange.URL, method, path string, params map[string]interface{}, result interface{}, endpoint request.EndpointLimit) error { +func (b *Bitfinex) SendAuthenticatedHTTPRequestV2(ctx context.Context, ep exchange.URL, method, path string, params map[string]interface{}, result interface{}, endpoint request.EndpointLimit) error { if !b.AllowAuthenticatedRequest() { return fmt.Errorf("%s %w", b.Name, exchange.ErrAuthenticatedRequestWithoutCredentialsSet) } @@ -1577,7 +1579,7 @@ func (b *Bitfinex) SendAuthenticatedHTTPRequestV2(ep exchange.URL, method, path return err } - return b.SendPayload(context.Background(), endpoint, func() (*request.Item, error) { + return b.SendPayload(ctx, endpoint, func() (*request.Item, error) { var body io.Reader var payload []byte if len(params) != 0 { @@ -1623,12 +1625,12 @@ func (b *Bitfinex) SendAuthenticatedHTTPRequestV2(ep exchange.URL, method, path } // GetFee returns an estimate of fee based on type of transaction -func (b *Bitfinex) GetFee(feeBuilder *exchange.FeeBuilder) (float64, error) { +func (b *Bitfinex) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { var fee float64 switch feeBuilder.FeeType { case exchange.CryptocurrencyTradeFee: - accountInfos, err := b.GetAccountFees() + accountInfos, err := b.GetAccountFees(ctx) if err != nil { return 0, err } @@ -1644,7 +1646,7 @@ func (b *Bitfinex) GetFee(feeBuilder *exchange.FeeBuilder) (float64, error) { //TODO: fee is charged when < $1000USD is transferred, need to infer value in some way fee = 0 case exchange.CryptocurrencyWithdrawalFee: - acc, err := b.GetWithdrawalFees() + acc, err := b.GetWithdrawalFees(ctx) if err != nil { return 0, err } @@ -1761,8 +1763,8 @@ func (b *Bitfinex) ConvertSymbolToWithdrawalType(c currency.Code) string { } // ConvertSymbolToDepositMethod returns a converted currency deposit method -func (b *Bitfinex) ConvertSymbolToDepositMethod(c currency.Code) (string, error) { - if err := b.PopulateAcceptableMethods(); err != nil { +func (b *Bitfinex) ConvertSymbolToDepositMethod(ctx context.Context, c currency.Code) (string, error) { + if err := b.PopulateAcceptableMethods(ctx); err != nil { return "", err } method, ok := AcceptableMethods[c.String()] @@ -1776,10 +1778,10 @@ func (b *Bitfinex) ConvertSymbolToDepositMethod(c currency.Code) (string, error) // PopulateAcceptableMethods retrieves all accepted currency strings and // populates a map to check -func (b *Bitfinex) PopulateAcceptableMethods() error { +func (b *Bitfinex) PopulateAcceptableMethods(ctx context.Context) error { if len(AcceptableMethods) == 0 { var response [][][2]string - err := b.SendHTTPRequest(exchange.RestSpot, + err := b.SendHTTPRequest(ctx, exchange.RestSpot, bitfinexAPIVersion2+bitfinexDepositMethod, &response, configs) diff --git a/exchanges/bitfinex/bitfinex_test.go b/exchanges/bitfinex/bitfinex_test.go index 47fa4ca7..49d6d2ce 100644 --- a/exchanges/bitfinex/bitfinex_test.go +++ b/exchanges/bitfinex/bitfinex_test.go @@ -1,6 +1,7 @@ package bitfinex import ( + "context" "log" "net/http" "os" @@ -65,7 +66,7 @@ func TestGetV2MarginFunding(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("api keys are not set or invalid") } - _, err := b.GetV2MarginFunding("fUSD", "2", 2) + _, err := b.GetV2MarginFunding(context.Background(), "fUSD", "2", 2) if err != nil { t.Error(err) } @@ -75,15 +76,15 @@ func TestGetV2MarginInfo(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("api keys are not set or invalid") } - _, err := b.GetV2MarginInfo("base") + _, err := b.GetV2MarginInfo(context.Background(), "base") if err != nil { t.Error(err) } - _, err = b.GetV2MarginInfo("tBTCUSD") + _, err = b.GetV2MarginInfo(context.Background(), "tBTCUSD") if err != nil { t.Error(err) } - _, err = b.GetV2MarginInfo("sym_all") + _, err = b.GetV2MarginInfo(context.Background(), "sym_all") if err != nil { t.Error(err) } @@ -94,7 +95,7 @@ func TestGetAccountInfoV2(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("api keys are not set or invalid") } - _, err := b.GetAccountInfoV2() + _, err := b.GetAccountInfoV2(context.Background()) if err != nil { t.Error(err) } @@ -104,7 +105,7 @@ func TestGetV2FundingInfo(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("api keys are not set or invalid") } - _, err := b.GetV2FundingInfo("fUST") + _, err := b.GetV2FundingInfo(context.Background(), "fUST") if err != nil { t.Error(err) } @@ -115,7 +116,7 @@ func TestGetV2Balances(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("api keys are not set or invalid") } - _, err := b.GetV2Balances() + _, err := b.GetV2Balances(context.Background()) if err != nil { t.Error(err) } @@ -123,7 +124,7 @@ func TestGetV2Balances(t *testing.T) { func TestGetDerivativeStatusInfo(t *testing.T) { t.Parallel() - _, err := b.GetDerivativeStatusInfo("ALL", "", "", 0, 0) + _, err := b.GetDerivativeStatusInfo(context.Background(), "ALL", "", "", 0, 0) if err != nil { t.Error(err) } @@ -131,7 +132,7 @@ func TestGetDerivativeStatusInfo(t *testing.T) { func TestGetMarginPairs(t *testing.T) { t.Parallel() - _, err := b.GetMarginPairs() + _, err := b.GetMarginPairs(context.Background()) if err != nil { t.Error(err) } @@ -162,7 +163,7 @@ func TestAppendOptionalDelimiter(t *testing.T) { func TestGetPlatformStatus(t *testing.T) { t.Parallel() - result, err := b.GetPlatformStatus() + result, err := b.GetPlatformStatus(context.Background()) if err != nil { t.Errorf("TestGetPlatformStatus error: %s", err) } @@ -174,7 +175,7 @@ func TestGetPlatformStatus(t *testing.T) { func TestGetTickerBatch(t *testing.T) { t.Parallel() - _, err := b.GetTickerBatch() + _, err := b.GetTickerBatch(context.Background()) if err != nil { t.Error(err) } @@ -182,12 +183,12 @@ func TestGetTickerBatch(t *testing.T) { func TestGetTicker(t *testing.T) { t.Parallel() - _, err := b.GetTicker("tBTCUSD") + _, err := b.GetTicker(context.Background(), "tBTCUSD") if err != nil { t.Error(err) } - _, err = b.GetTicker("fUSD") + _, err = b.GetTicker(context.Background(), "fUSD") if err != nil { t.Error(err) } @@ -196,7 +197,7 @@ func TestGetTicker(t *testing.T) { func TestGetTrades(t *testing.T) { t.Parallel() - _, err := b.GetTrades("tBTCUSD", 5, 0, 0, false) + _, err := b.GetTrades(context.Background(), "tBTCUSD", 5, 0, 0, false) if err != nil { t.Error(err) } @@ -204,27 +205,27 @@ func TestGetTrades(t *testing.T) { func TestGetOrderbook(t *testing.T) { t.Parallel() - _, err := b.GetOrderbook("tBTCUSD", "R0", 1) + _, err := b.GetOrderbook(context.Background(), "tBTCUSD", "R0", 1) if err != nil { t.Error(err) } - _, err = b.GetOrderbook("fUSD", "R0", 1) + _, err = b.GetOrderbook(context.Background(), "fUSD", "R0", 1) if err != nil { t.Error(err) } - _, err = b.GetOrderbook("tBTCUSD", "P0", 1) + _, err = b.GetOrderbook(context.Background(), "tBTCUSD", "P0", 1) if err != nil { t.Error(err) } - _, err = b.GetOrderbook("fUSD", "P0", 1) + _, err = b.GetOrderbook(context.Background(), "fUSD", "P0", 1) if err != nil { t.Error(err) } - _, err = b.GetOrderbook("tLINK:UST", "P0", 1) + _, err = b.GetOrderbook(context.Background(), "tLINK:UST", "P0", 1) if err != nil { t.Error(err) } @@ -232,7 +233,7 @@ func TestGetOrderbook(t *testing.T) { func TestGetStats(t *testing.T) { t.Parallel() - _, err := b.GetStats("btcusd") + _, err := b.GetStats(context.Background(), "btcusd") if err != nil { t.Error(err) } @@ -240,7 +241,7 @@ func TestGetStats(t *testing.T) { func TestGetFundingBook(t *testing.T) { t.Parallel() - _, err := b.GetFundingBook("usd") + _, err := b.GetFundingBook(context.Background(), "usd") if err != nil { t.Error(err) } @@ -248,7 +249,7 @@ func TestGetFundingBook(t *testing.T) { func TestGetLends(t *testing.T) { t.Parallel() - _, err := b.GetLends("usd", nil) + _, err := b.GetLends(context.Background(), "usd", nil) if err != nil { t.Error(err) } @@ -256,7 +257,7 @@ func TestGetLends(t *testing.T) { func TestGetCandles(t *testing.T) { t.Parallel() - _, err := b.GetCandles("fUSD", "1m", 0, 0, 10, true) + _, err := b.GetCandles(context.Background(), "fUSD", "1m", 0, 0, 10, true) if err != nil { t.Fatal(err) } @@ -265,12 +266,13 @@ func TestGetCandles(t *testing.T) { func TestGetLeaderboard(t *testing.T) { t.Parallel() // Test invalid key - _, err := b.GetLeaderboard("", "", "", 0, 0, "", "") + _, err := b.GetLeaderboard(context.Background(), "", "", "", 0, 0, "", "") if err == nil { t.Error("an error should have been thrown for an invalid key") } // Test default - _, err = b.GetLeaderboard(LeaderboardUnrealisedProfitInception, + _, err = b.GetLeaderboard(context.Background(), + LeaderboardUnrealisedProfitInception, "1M", "tGLOBAL:USD", 0, @@ -282,7 +284,8 @@ func TestGetLeaderboard(t *testing.T) { } // Test params var result []LeaderboardEntry - result, err = b.GetLeaderboard(LeaderboardUnrealisedProfitInception, + result, err = b.GetLeaderboard(context.Background(), + LeaderboardUnrealisedProfitInception, "1M", "tGLOBAL:USD", -1, @@ -303,7 +306,7 @@ func TestGetAccountFees(t *testing.T) { } t.Parallel() - _, err := b.UpdateAccountInfo(asset.Spot) + _, err := b.UpdateAccountInfo(context.Background(), asset.Spot) if err != nil { t.Error("GetAccountInfo error", err) } @@ -314,7 +317,7 @@ func TestGetWithdrawalFee(t *testing.T) { t.SkipNow() } t.Parallel() - _, err := b.GetWithdrawalFees() + _, err := b.GetWithdrawalFees(context.Background()) if err != nil { t.Error("GetAccountInfo error", err) } @@ -326,7 +329,7 @@ func TestGetAccountSummary(t *testing.T) { } t.Parallel() - _, err := b.GetAccountSummary() + _, err := b.GetAccountSummary(context.Background()) if err == nil { t.Error("GetAccountSummary() Expected error") } @@ -337,17 +340,17 @@ func TestNewDeposit(t *testing.T) { t.SkipNow() } t.Parallel() - _, err := b.NewDeposit("blabla", "testwallet", 0) + _, err := b.NewDeposit(context.Background(), "blabla", "testwallet", 0) if err == nil { t.Error("NewDeposit() Expected error") } - _, err = b.NewDeposit("bitcoin", "testwallet", 0) + _, err = b.NewDeposit(context.Background(), "bitcoin", "testwallet", 0) if err == nil { t.Error("NewDeposit() Expected error") } - _, err = b.NewDeposit("bitcoin", "exchange", 0) + _, err = b.NewDeposit(context.Background(), "bitcoin", "exchange", 0) if err != nil { t.Error(err) } @@ -359,7 +362,7 @@ func TestGetKeyPermissions(t *testing.T) { } t.Parallel() - _, err := b.GetKeyPermissions() + _, err := b.GetKeyPermissions(context.Background()) if err != nil { t.Error(err) } @@ -371,7 +374,7 @@ func TestGetMarginInfo(t *testing.T) { } t.Parallel() - _, err := b.GetMarginInfo() + _, err := b.GetMarginInfo(context.Background()) if err != nil { t.Error(err) } @@ -383,7 +386,7 @@ func TestGetAccountBalance(t *testing.T) { } t.Parallel() - _, err := b.GetAccountBalance() + _, err := b.GetAccountBalance(context.Background()) if err != nil { t.Error(err) } @@ -395,7 +398,7 @@ func TestGetAccountInfo(t *testing.T) { } t.Parallel() - _, err := b.FetchAccountInfo(asset.Spot) + _, err := b.FetchAccountInfo(context.Background(), asset.Spot) if err != nil { t.Error(err) } @@ -407,7 +410,7 @@ func TestWalletTransfer(t *testing.T) { } t.Parallel() - _, err := b.WalletTransfer(0.01, "btc", "bla", "bla") + _, err := b.WalletTransfer(context.Background(), 0.01, "btc", "bla", "bla") if err == nil { t.Error("error cannot be nil") } @@ -419,7 +422,8 @@ func TestNewOrder(t *testing.T) { } t.Parallel() - _, err := b.NewOrder("BTCUSD", + _, err := b.NewOrder(context.Background(), + "BTCUSD", order.Limit.Lower(), -1, 2, @@ -436,14 +440,14 @@ func TestUpdateTicker(t *testing.T) { t.Fatal(err) } - _, err = b.UpdateTicker(pair, asset.Spot) + _, err = b.UpdateTicker(context.Background(), pair, asset.Spot) if err != nil { t.Error(err) } } func TestUpdateTickers(t *testing.T) { - err := b.UpdateTickers(asset.Spot) + err := b.UpdateTickers(context.Background(), asset.Spot) if err != nil { t.Error(err) } @@ -466,7 +470,7 @@ func TestNewOrderMulti(t *testing.T) { }, } - _, err := b.NewOrderMulti(newOrder) + _, err := b.NewOrderMulti(context.Background(), newOrder) if err == nil { t.Error("NewOrderMulti() Expected error") } @@ -478,7 +482,7 @@ func TestCancelOrder(t *testing.T) { } t.Parallel() - _, err := b.CancelExistingOrder(1337) + _, err := b.CancelExistingOrder(context.Background(), 1337) if err == nil { t.Error("CancelExistingOrder() Expected error") } @@ -490,7 +494,7 @@ func TestCancelMultipleOrders(t *testing.T) { } t.Parallel() - _, err := b.CancelMultipleOrders([]int64{1337, 1336}) + _, err := b.CancelMultipleOrders(context.Background(), []int64{1337, 1336}) if err == nil { t.Error("CancelMultipleOrders() Expected error") } @@ -502,7 +506,7 @@ func TestCancelAllOrders(t *testing.T) { } t.Parallel() - _, err := b.CancelAllExistingOrders() + _, err := b.CancelAllExistingOrders(context.Background()) if err == nil { t.Error("CancelAllExistingOrders() Expected error") } @@ -514,7 +518,7 @@ func TestReplaceOrder(t *testing.T) { } t.Parallel() - _, err := b.ReplaceOrder(1337, "BTCUSD", + _, err := b.ReplaceOrder(context.Background(), 1337, "BTCUSD", 1, 1, true, order.Limit.Lower(), false) if err == nil { t.Error("ReplaceOrder() Expected error") @@ -527,7 +531,7 @@ func TestGetOrderStatus(t *testing.T) { } t.Parallel() - _, err := b.GetOrderStatus(1337) + _, err := b.GetOrderStatus(context.Background(), 1337) if err == nil { t.Error("GetOrderStatus() Expected error") } @@ -539,7 +543,7 @@ func TestGetOpenOrders(t *testing.T) { } t.Parallel() - _, err := b.GetOpenOrders() + _, err := b.GetOpenOrders(context.Background()) if err == nil { t.Error("GetOpenOrders() Expectederror") } @@ -551,7 +555,7 @@ func TestGetActivePositions(t *testing.T) { } t.Parallel() - _, err := b.GetActivePositions() + _, err := b.GetActivePositions(context.Background()) if err == nil { t.Error("GetActivePositions() Expected error") } @@ -563,7 +567,7 @@ func TestClaimPosition(t *testing.T) { } t.Parallel() - _, err := b.ClaimPosition(1337) + _, err := b.ClaimPosition(context.Background(), 1337) if err == nil { t.Error("ClaimPosition() Expected error") } @@ -574,7 +578,8 @@ func TestGetBalanceHistory(t *testing.T) { t.SkipNow() } t.Parallel() - _, err := b.GetBalanceHistory("USD", time.Time{}, time.Time{}, 1, "deposit") + _, err := b.GetBalanceHistory(context.Background(), + "USD", time.Time{}, time.Time{}, 1, "deposit") if err == nil { t.Error("GetBalanceHistory() Expected error") } @@ -586,7 +591,7 @@ func TestGetMovementHistory(t *testing.T) { } t.Parallel() - _, err := b.GetMovementHistory("USD", "bitcoin", time.Time{}, time.Time{}, 1) + _, err := b.GetMovementHistory(context.Background(), "USD", "bitcoin", time.Time{}, time.Time{}, 1) if err == nil { t.Error("GetMovementHistory() Expected error") } @@ -597,7 +602,8 @@ func TestGetTradeHistory(t *testing.T) { t.SkipNow() } t.Parallel() - _, err := b.GetTradeHistory("BTCUSD", time.Time{}, time.Time{}, 1, 0) + _, err := b.GetTradeHistory(context.Background(), + "BTCUSD", time.Time{}, time.Time{}, 1, 0) if err == nil { t.Error("GetTradeHistory() Expected error") } @@ -609,7 +615,7 @@ func TestNewOffer(t *testing.T) { } t.Parallel() - _, err := b.NewOffer("BTC", 1, 1, 1, "loan") + _, err := b.NewOffer(context.Background(), "BTC", 1, 1, 1, "loan") if err == nil { t.Error("NewOffer() Expected error") } @@ -621,7 +627,7 @@ func TestCancelOffer(t *testing.T) { } t.Parallel() - _, err := b.CancelOffer(1337) + _, err := b.CancelOffer(context.Background(), 1337) if err == nil { t.Error("CancelOffer() Expected error") } @@ -633,7 +639,7 @@ func TestGetOfferStatus(t *testing.T) { } t.Parallel() - _, err := b.GetOfferStatus(1337) + _, err := b.GetOfferStatus(context.Background(), 1337) if err == nil { t.Error("NewOffer() Expected error") } @@ -645,7 +651,7 @@ func TestGetActiveCredits(t *testing.T) { } t.Parallel() - _, err := b.GetActiveCredits() + _, err := b.GetActiveCredits(context.Background()) if err == nil { t.Error("GetActiveCredits() Expected error") } @@ -657,7 +663,7 @@ func TestGetActiveOffers(t *testing.T) { } t.Parallel() - _, err := b.GetActiveOffers() + _, err := b.GetActiveOffers(context.Background()) if err == nil { t.Error("GetActiveOffers() Expected error") } @@ -669,7 +675,7 @@ func TestGetActiveMarginFunding(t *testing.T) { } t.Parallel() - _, err := b.GetActiveMarginFunding() + _, err := b.GetActiveMarginFunding(context.Background()) if err == nil { t.Error("GetActiveMarginFunding() Expected error") } @@ -681,7 +687,7 @@ func TestGetUnusedMarginFunds(t *testing.T) { } t.Parallel() - _, err := b.GetUnusedMarginFunds() + _, err := b.GetUnusedMarginFunds(context.Background()) if err == nil { t.Error("GetUnusedMarginFunds() Expected error") } @@ -693,7 +699,7 @@ func TestGetMarginTotalTakenFunds(t *testing.T) { } t.Parallel() - _, err := b.GetMarginTotalTakenFunds() + _, err := b.GetMarginTotalTakenFunds(context.Background()) if err == nil { t.Error("GetMarginTotalTakenFunds() Expected error") } @@ -705,7 +711,7 @@ func TestCloseMarginFunding(t *testing.T) { } t.Parallel() - _, err := b.CloseMarginFunding(1337) + _, err := b.CloseMarginFunding(context.Background(), 1337) if err == nil { t.Error("CloseMarginFunding() Expected error") } @@ -723,7 +729,7 @@ func setFeeBuilder() *exchange.FeeBuilder { // TestGetFeeByTypeOfflineTradeFee logic test func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { var feeBuilder = setFeeBuilder() - _, err := b.GetFeeByType(feeBuilder) + _, err := b.GetFeeByType(context.Background(), feeBuilder) if err != nil { t.Fatal(err) } @@ -744,7 +750,7 @@ func TestGetFee(t *testing.T) { if areTestAPIKeysSet() { // CryptocurrencyTradeFee Basic - if _, err := b.GetFee(feeBuilder); err != nil { + if _, err := b.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } @@ -752,28 +758,28 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.Amount = 1000 feeBuilder.PurchasePrice = 1000 - if _, err := b.GetFee(feeBuilder); err != nil { + if _, err := b.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyTradeFee IsMaker feeBuilder = setFeeBuilder() feeBuilder.IsMaker = true - if _, err := b.GetFee(feeBuilder); err != nil { + if _, err := b.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyTradeFee Negative purchase price feeBuilder = setFeeBuilder() feeBuilder.PurchasePrice = -1000 - if _, err := b.GetFee(feeBuilder); err != nil { + if _, err := b.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyWithdrawalFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee - if _, err := b.GetFee(feeBuilder); err != nil { + if _, err := b.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } } @@ -781,7 +787,7 @@ func TestGetFee(t *testing.T) { // CryptocurrencyDepositFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.CryptocurrencyDepositFee - if _, err := b.GetFee(feeBuilder); err != nil { + if _, err := b.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } @@ -789,7 +795,7 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankDepositFee feeBuilder.FiatCurrency = currency.HKD - if _, err := b.GetFee(feeBuilder); err != nil { + if _, err := b.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } @@ -797,7 +803,7 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee feeBuilder.FiatCurrency = currency.HKD - if _, err := b.GetFee(feeBuilder); err != nil { + if _, err := b.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } } @@ -818,7 +824,7 @@ func TestGetActiveOrders(t *testing.T) { AssetType: asset.Spot, } - _, err := b.GetActiveOrders(&getOrdersRequest) + _, err := b.GetActiveOrders(context.Background(), &getOrdersRequest) if areTestAPIKeysSet() && err != nil { t.Errorf("Could not get open orders: %s", err) } else if !areTestAPIKeysSet() && err == nil { @@ -833,7 +839,7 @@ func TestGetOrderHistory(t *testing.T) { AssetType: asset.Spot, } - _, err := b.GetOrderHistory(&getOrdersRequest) + _, err := b.GetOrderHistory(context.Background(), &getOrdersRequest) if areTestAPIKeysSet() && err != nil { t.Errorf("Could not get order history: %s", err) } else if !areTestAPIKeysSet() && err == nil { @@ -865,7 +871,7 @@ func TestSubmitOrder(t *testing.T) { Amount: 20, ClientID: "meowOrder", } - response, err := b.SubmitOrder(orderSubmission) + response, err := b.SubmitOrder(context.Background(), orderSubmission) if areTestAPIKeysSet() && err != nil { t.Errorf("Could not place order: %v", err) @@ -893,7 +899,7 @@ func TestCancelExchangeOrder(t *testing.T) { AssetType: asset.Spot, } - err := b.CancelOrder(orderCancellation) + err := b.CancelOrder(context.Background(), orderCancellation) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") } @@ -917,7 +923,7 @@ func TestCancelAllExchangeOrdera(t *testing.T) { AssetType: asset.Spot, } - resp, err := b.CancelAllOrders(orderCancellation) + resp, err := b.CancelAllOrders(context.Background(), orderCancellation) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") @@ -936,7 +942,8 @@ func TestModifyOrder(t *testing.T) { if areTestAPIKeysSet() && !canManipulateRealOrders { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - _, err := b.ModifyOrder(&order.Modify{AssetType: asset.Spot}) + _, err := b.ModifyOrder(context.Background(), + &order.Modify{AssetType: asset.Spot}) if err == nil { t.Error("ModifyOrder() Expected error") } @@ -957,7 +964,8 @@ func TestWithdraw(t *testing.T) { }, } - _, err := b.WithdrawCryptocurrencyFunds(&withdrawCryptoRequest) + _, err := b.WithdrawCryptocurrencyFunds(context.Background(), + &withdrawCryptoRequest) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") } @@ -981,7 +989,7 @@ func TestWithdrawFiat(t *testing.T) { }, } - _, err := b.WithdrawFiatFunds(&withdrawFiatRequest) + _, err := b.WithdrawFiatFunds(context.Background(), &withdrawFiatRequest) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") } @@ -1013,7 +1021,8 @@ func TestWithdrawInternationalBank(t *testing.T) { }, } - _, err := b.WithdrawFiatFundsToInternationalBank(&withdrawFiatRequest) + _, err := b.WithdrawFiatFundsToInternationalBank(context.Background(), + &withdrawFiatRequest) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") } @@ -1025,12 +1034,14 @@ func TestWithdrawInternationalBank(t *testing.T) { func TestGetDepositAddress(t *testing.T) { t.Parallel() if areTestAPIKeysSet() { - _, err := b.GetDepositAddress(currency.BTC, "deposit") + _, err := b.GetDepositAddress(context.Background(), + currency.BTC, "deposit") if err != nil { t.Error("GetDepositAddress() error", err) } } else { - _, err := b.GetDepositAddress(currency.BTC, "deposit") + _, err := b.GetDepositAddress(context.Background(), + currency.BTC, "deposit") if err == nil { t.Error("GetDepositAddress() error cannot be nil") } @@ -1194,7 +1205,7 @@ func TestWsCancelOffer(t *testing.T) { } func TestConvertSymbolToDepositMethod(t *testing.T) { - s, err := b.ConvertSymbolToDepositMethod(currency.BTC) + s, err := b.ConvertSymbolToDepositMethod(context.Background(), currency.BTC) if err != nil { log.Fatal(err) } @@ -1202,14 +1213,15 @@ func TestConvertSymbolToDepositMethod(t *testing.T) { t.Errorf("expected bitcoin but received %s", s) } - _, err = b.ConvertSymbolToDepositMethod(currency.NewCode("CATS!")) + _, err = b.ConvertSymbolToDepositMethod(context.Background(), + currency.NewCode("CATS!")) if err == nil { log.Fatal("error cannot be nil") } } func TestUpdateTradablePairs(t *testing.T) { - err := b.UpdateTradablePairs(false) + err := b.UpdateTradablePairs(context.Background(), false) if err != nil { t.Error(err) } @@ -1322,12 +1334,14 @@ func TestGetHistoricCandles(t *testing.T) { } startTime := time.Now().Add(-time.Hour * 24) endTime := time.Now().Add(-time.Hour * 20) - _, err = b.GetHistoricCandles(currencyPair, asset.Spot, startTime, endTime, kline.OneHour) + _, err = b.GetHistoricCandles(context.Background(), + currencyPair, asset.Spot, startTime, endTime, kline.OneHour) if err != nil { t.Fatal(err) } - _, err = b.GetHistoricCandles(currencyPair, asset.Spot, startTime, time.Now(), kline.OneMin*1337) + _, err = b.GetHistoricCandles(context.Background(), + currencyPair, asset.Spot, startTime, time.Now(), kline.OneMin*1337) if err == nil { t.Fatal(err) } @@ -1340,12 +1354,14 @@ func TestGetHistoricCandlesExtended(t *testing.T) { } startTime := time.Now().Add(-time.Hour * 24) endTime := time.Now().Add(-time.Hour * 20) - _, err = b.GetHistoricCandlesExtended(currencyPair, asset.Spot, startTime, endTime, kline.OneHour) + _, err = b.GetHistoricCandlesExtended(context.Background(), + currencyPair, asset.Spot, startTime, endTime, kline.OneHour) if err != nil { t.Fatal(err) } - _, err = b.GetHistoricCandlesExtended(currencyPair, asset.Spot, startTime, endTime, kline.OneMin*1337) + _, err = b.GetHistoricCandlesExtended(context.Background(), + currencyPair, asset.Spot, startTime, endTime, kline.OneMin*1337) if err == nil { t.Fatal(err) } @@ -1525,7 +1541,7 @@ func TestGetRecentTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = b.GetRecentTrades(currencyPair, asset.Spot) + _, err = b.GetRecentTrades(context.Background(), currencyPair, asset.Spot) if err != nil { t.Error(err) } @@ -1534,7 +1550,7 @@ func TestGetRecentTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = b.GetRecentTrades(currencyPair, asset.Margin) + _, err = b.GetRecentTrades(context.Background(), currencyPair, asset.Margin) if err != nil { t.Error(err) } @@ -1546,13 +1562,17 @@ func TestGetHistoricTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = b.GetHistoricTrades(currencyPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) + _, err = b.GetHistoricTrades(context.Background(), + currencyPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) if err != nil { t.Error(err) } // longer term test - _, err = b.GetHistoricTrades(currencyPair, asset.Spot, time.Now().Add(-time.Hour*100), time.Now().Add(-time.Hour*99)) + _, err = b.GetHistoricTrades(context.Background(), + currencyPair, asset.Spot, + time.Now().Add(-time.Hour*100), + time.Now().Add(-time.Hour*99)) if err != nil { t.Error(err) } diff --git a/exchanges/bitfinex/bitfinex_wrapper.go b/exchanges/bitfinex/bitfinex_wrapper.go index 12053ca1..aa804176 100644 --- a/exchanges/bitfinex/bitfinex_wrapper.go +++ b/exchanges/bitfinex/bitfinex_wrapper.go @@ -1,6 +1,7 @@ package bitfinex import ( + "context" "errors" "fmt" "sort" @@ -42,7 +43,7 @@ func (b *Bitfinex) GetDefaultConfig() (*config.ExchangeConfig, error) { } if b.Features.Supports.RESTCapabilities.AutoPairUpdates { - err = b.UpdateTradablePairs(true) + err = b.UpdateTradablePairs(context.TODO(), true) if err != nil { return nil, err } @@ -254,7 +255,7 @@ func (b *Bitfinex) Run() { return } - err := b.UpdateTradablePairs(false) + err := b.UpdateTradablePairs(context.TODO(), false) if err != nil { log.Errorf(log.ExchangeSys, "%s failed to update tradable pairs. Err: %s", @@ -264,8 +265,8 @@ func (b *Bitfinex) Run() { } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (b *Bitfinex) FetchTradablePairs(a asset.Item) ([]string, error) { - items, err := b.GetTickerBatch() +func (b *Bitfinex) FetchTradablePairs(ctx context.Context, a asset.Item) ([]string, error) { + items, err := b.GetTickerBatch(ctx) if err != nil { return nil, err } @@ -302,10 +303,10 @@ func (b *Bitfinex) FetchTradablePairs(a asset.Item) ([]string, error) { // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (b *Bitfinex) UpdateTradablePairs(forceUpdate bool) error { +func (b *Bitfinex) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { assets := b.CurrencyPairs.GetAssetTypes(false) for i := range assets { - pairs, err := b.FetchTradablePairs(assets[i]) + pairs, err := b.FetchTradablePairs(ctx, assets[i]) if err != nil { return err } @@ -324,13 +325,13 @@ func (b *Bitfinex) UpdateTradablePairs(forceUpdate bool) error { } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (b *Bitfinex) UpdateTickers(a asset.Item) error { +func (b *Bitfinex) UpdateTickers(ctx context.Context, a asset.Item) error { enabledPairs, err := b.GetEnabledPairs(a) if err != nil { return err } - tickerNew, err := b.GetTickerBatch() + tickerNew, err := b.GetTickerBatch(ctx) if err != nil { return err } @@ -363,8 +364,8 @@ func (b *Bitfinex) UpdateTickers(a asset.Item) error { } // UpdateTicker updates and returns the ticker for a currency pair -func (b *Bitfinex) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) { - err := b.UpdateTickers(a) +func (b *Bitfinex) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { + err := b.UpdateTickers(ctx, a) if err != nil { return nil, err } @@ -372,7 +373,7 @@ func (b *Bitfinex) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, e } // FetchTicker returns the ticker for a currency pair -func (b *Bitfinex) FetchTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) { +func (b *Bitfinex) FetchTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { fPair, err := b.FormatExchangeCurrency(p, a) if err != nil { return nil, err @@ -381,13 +382,13 @@ func (b *Bitfinex) FetchTicker(p currency.Pair, a asset.Item) (*ticker.Price, er b.appendOptionalDelimiter(&fPair) tick, err := ticker.GetTicker(b.Name, fPair, asset.Spot) if err != nil { - return b.UpdateTicker(fPair, a) + return b.UpdateTicker(ctx, fPair, a) } return tick, nil } // FetchOrderbook returns the orderbook for a currency pair -func (b *Bitfinex) FetchOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (b *Bitfinex) FetchOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { fPair, err := b.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err @@ -396,13 +397,13 @@ func (b *Bitfinex) FetchOrderbook(p currency.Pair, assetType asset.Item) (*order b.appendOptionalDelimiter(&fPair) ob, err := orderbook.Get(b.Name, fPair, assetType) if err != nil { - return b.UpdateOrderbook(fPair, assetType) + return b.UpdateOrderbook(ctx, fPair, assetType) } return ob, nil } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (b *Bitfinex) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (b *Bitfinex) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { o := &orderbook.Base{ Exchange: b.Name, Pair: p, @@ -424,7 +425,7 @@ func (b *Bitfinex) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orde prefix = "f" } var orderbookNew Orderbook - orderbookNew, err = b.GetOrderbook(prefix+fPair.String(), "R0", 100) + orderbookNew, err = b.GetOrderbook(ctx, prefix+fPair.String(), "R0", 100) if err != nil { return nil, err } @@ -471,11 +472,11 @@ func (b *Bitfinex) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orde // UpdateAccountInfo retrieves balances for all enabled currencies on the // Bitfinex exchange -func (b *Bitfinex) UpdateAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (b *Bitfinex) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { var response account.Holdings response.Exchange = b.Name - accountBalance, err := b.GetAccountBalance() + accountBalance, err := b.GetAccountBalance(ctx) if err != nil { return response, err } @@ -511,10 +512,10 @@ func (b *Bitfinex) UpdateAccountInfo(assetType asset.Item) (account.Holdings, er } // FetchAccountInfo retrieves balances for all enabled currencies -func (b *Bitfinex) FetchAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (b *Bitfinex) FetchAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { acc, err := account.GetHoldings(b.Name, assetType) if err != nil { - return b.UpdateAccountInfo(assetType) + return b.UpdateAccountInfo(ctx, assetType) } return acc, nil @@ -522,22 +523,22 @@ func (b *Bitfinex) FetchAccountInfo(assetType asset.Item) (account.Holdings, err // GetFundingHistory returns funding history, deposits and // withdrawals -func (b *Bitfinex) GetFundingHistory() ([]exchange.FundHistory, error) { +func (b *Bitfinex) GetFundingHistory(ctx context.Context) ([]exchange.FundHistory, error) { return nil, common.ErrFunctionNotSupported } // GetWithdrawalsHistory returns previous withdrawals data -func (b *Bitfinex) GetWithdrawalsHistory(c currency.Code) (resp []exchange.WithdrawalHistory, err error) { +func (b *Bitfinex) GetWithdrawalsHistory(ctx context.Context, c currency.Code) (resp []exchange.WithdrawalHistory, err error) { return nil, common.ErrNotYetImplemented } // GetRecentTrades returns the most recent trades for a currency and asset -func (b *Bitfinex) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade.Data, error) { - return b.GetHistoricTrades(p, assetType, time.Now().Add(-time.Minute*15), time.Now()) +func (b *Bitfinex) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { + return b.GetHistoricTrades(ctx, p, assetType, time.Now().Add(-time.Minute*15), time.Now()) } // GetHistoricTrades returns historic trade data within the timeframe provided -func (b *Bitfinex) GetHistoricTrades(p currency.Pair, assetType asset.Item, timestampStart, timestampEnd time.Time) ([]trade.Data, error) { +func (b *Bitfinex) GetHistoricTrades(ctx context.Context, p currency.Pair, assetType asset.Item, timestampStart, timestampEnd time.Time) ([]trade.Data, error) { if assetType == asset.MarginFunding { return nil, fmt.Errorf("asset type '%v' not supported", assetType) } @@ -560,7 +561,8 @@ func (b *Bitfinex) GetHistoricTrades(p currency.Pair, assetType asset.Item, time allTrades: for { var tradeData []Trade - tradeData, err = b.GetTrades(currString, int64(limit), 0, ts.Unix()*1000, false) + tradeData, err = b.GetTrades(ctx, + currString, int64(limit), 0, ts.Unix()*1000, false) if err != nil { return nil, err } @@ -602,7 +604,7 @@ allTrades: } // SubmitOrder submits a new order -func (b *Bitfinex) SubmitOrder(o *order.Submit) (order.SubmitResponse, error) { +func (b *Bitfinex) SubmitOrder(ctx context.Context, o *order.Submit) (order.SubmitResponse, error) { var submitOrderResponse order.SubmitResponse err := o.Validate() if err != nil { @@ -633,7 +635,8 @@ func (b *Bitfinex) SubmitOrder(o *order.Submit) (order.SubmitResponse, error) { if o.AssetType == asset.Spot { orderType = "exchange " + orderType } - response, err = b.NewOrder(fpair.String(), + response, err = b.NewOrder(ctx, + fpair.String(), orderType, o.Amount, o.Price, @@ -656,7 +659,7 @@ func (b *Bitfinex) SubmitOrder(o *order.Submit) (order.SubmitResponse, error) { // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (b *Bitfinex) ModifyOrder(action *order.Modify) (order.Modify, error) { +func (b *Bitfinex) ModifyOrder(ctx context.Context, action *order.Modify) (order.Modify, error) { if err := action.Validate(); err != nil { return order.Modify{}, err } @@ -689,7 +692,7 @@ func (b *Bitfinex) ModifyOrder(action *order.Modify) (order.Modify, error) { } // CancelOrder cancels an order by its corresponding ID number -func (b *Bitfinex) CancelOrder(o *order.Cancel) error { +func (b *Bitfinex) CancelOrder(ctx context.Context, o *order.Cancel) error { if err := o.Validate(o.StandardCancel()); err != nil { return err } @@ -701,50 +704,50 @@ func (b *Bitfinex) CancelOrder(o *order.Cancel) error { if b.Websocket.CanUseAuthenticatedWebsocketForWrapper() { err = b.WsCancelOrder(orderIDInt) } else { - _, err = b.CancelExistingOrder(orderIDInt) + _, err = b.CancelExistingOrder(ctx, orderIDInt) } return err } // CancelBatchOrders cancels an orders by their corresponding ID numbers -func (b *Bitfinex) CancelBatchOrders(o []order.Cancel) (order.CancelBatchResponse, error) { +func (b *Bitfinex) CancelBatchOrders(ctx context.Context, o []order.Cancel) (order.CancelBatchResponse, error) { return order.CancelBatchResponse{}, common.ErrNotYetImplemented } // CancelAllOrders cancels all orders associated with a currency pair -func (b *Bitfinex) CancelAllOrders(_ *order.Cancel) (order.CancelAllResponse, error) { +func (b *Bitfinex) CancelAllOrders(ctx context.Context, _ *order.Cancel) (order.CancelAllResponse, error) { var err error if b.Websocket.CanUseAuthenticatedWebsocketForWrapper() { err = b.WsCancelAllOrders() } else { - _, err = b.CancelAllExistingOrders() + _, err = b.CancelAllExistingOrders(ctx) } return order.CancelAllResponse{}, err } // GetOrderInfo returns order information based on order ID -func (b *Bitfinex) GetOrderInfo(orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { +func (b *Bitfinex) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { var orderDetail order.Detail return orderDetail, common.ErrNotYetImplemented } // GetDepositAddress returns a deposit address for a specified currency -func (b *Bitfinex) GetDepositAddress(c currency.Code, accountID string) (string, error) { +func (b *Bitfinex) GetDepositAddress(ctx context.Context, c currency.Code, accountID string) (string, error) { if accountID == "" { accountID = "deposit" } - method, err := b.ConvertSymbolToDepositMethod(c) + method, err := b.ConvertSymbolToDepositMethod(ctx, c) if err != nil { return "", err } - resp, err := b.NewDeposit(method, accountID, 0) + resp, err := b.NewDeposit(ctx, method, accountID, 0) return resp.Address, err } // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is submitted -func (b *Bitfinex) WithdrawCryptocurrencyFunds(withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (b *Bitfinex) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } @@ -752,7 +755,8 @@ func (b *Bitfinex) WithdrawCryptocurrencyFunds(withdrawRequest *withdraw.Request // As this is for trading, I've made the wrapper default 'exchange' // TODO: Discover an automated way to make the decision for wallet type to withdraw from walletType := "exchange" - resp, err := b.WithdrawCryptocurrency(walletType, + resp, err := b.WithdrawCryptocurrency(ctx, + walletType, withdrawRequest.Crypto.Address, withdrawRequest.Description, withdrawRequest.Amount, @@ -769,7 +773,7 @@ func (b *Bitfinex) WithdrawCryptocurrencyFunds(withdrawRequest *withdraw.Request // WithdrawFiatFunds returns a withdrawal ID when a withdrawal is submitted // Returns comma delimited withdrawal IDs -func (b *Bitfinex) WithdrawFiatFunds(withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (b *Bitfinex) WithdrawFiatFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } @@ -778,7 +782,7 @@ func (b *Bitfinex) WithdrawFiatFunds(withdrawRequest *withdraw.Request) (*withdr // As this is for trading, I've made the wrapper default 'exchange' // TODO: Discover an automated way to make the decision for wallet type to withdraw from walletType := "exchange" - resp, err := b.WithdrawFIAT(withdrawalType, walletType, withdrawRequest) + resp, err := b.WithdrawFIAT(ctx, withdrawalType, walletType, withdrawRequest) if err != nil { return nil, err } @@ -791,11 +795,11 @@ func (b *Bitfinex) WithdrawFiatFunds(withdrawRequest *withdraw.Request) (*withdr // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a withdrawal is submitted // Returns comma delimited withdrawal IDs -func (b *Bitfinex) WithdrawFiatFundsToInternationalBank(withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (b *Bitfinex) WithdrawFiatFundsToInternationalBank(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } - v, err := b.WithdrawFiatFunds(withdrawRequest) + v, err := b.WithdrawFiatFunds(ctx, withdrawRequest) if err != nil { return nil, err } @@ -806,22 +810,22 @@ func (b *Bitfinex) WithdrawFiatFundsToInternationalBank(withdrawRequest *withdra } // GetFeeByType returns an estimate of fee based on type of transaction -func (b *Bitfinex) GetFeeByType(feeBuilder *exchange.FeeBuilder) (float64, error) { +func (b *Bitfinex) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { if !b.AllowAuthenticatedRequest() && // Todo check connection status feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { feeBuilder.FeeType = exchange.OfflineTradeFee } - return b.GetFee(feeBuilder) + return b.GetFee(ctx, feeBuilder) } // GetActiveOrders retrieves any orders that are active/open -func (b *Bitfinex) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, error) { +func (b *Bitfinex) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) { if err := req.Validate(); err != nil { return nil, err } var orders []order.Detail - resp, err := b.GetOpenOrders() + resp, err := b.GetOpenOrders(ctx) if err != nil { return nil, err } @@ -884,13 +888,13 @@ func (b *Bitfinex) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, // GetOrderHistory retrieves account order information // Can Limit response to specific order status -func (b *Bitfinex) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, error) { +func (b *Bitfinex) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) { if err := req.Validate(); err != nil { return nil, err } var orders []order.Detail - resp, err := b.GetInactiveOrders() + resp, err := b.GetInactiveOrders(ctx) if err != nil { return nil, err } @@ -954,7 +958,7 @@ func (b *Bitfinex) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, } // AuthenticateWebsocket sends an authentication message to the websocket -func (b *Bitfinex) AuthenticateWebsocket() error { +func (b *Bitfinex) AuthenticateWebsocket(_ context.Context) error { return b.WsSendAuth() } @@ -968,8 +972,8 @@ func (b *Bitfinex) appendOptionalDelimiter(p *currency.Pair) { // ValidateCredentials validates current credentials used for wrapper // functionality -func (b *Bitfinex) ValidateCredentials(assetType asset.Item) error { - _, err := b.UpdateAccountInfo(assetType) +func (b *Bitfinex) ValidateCredentials(ctx context.Context, assetType asset.Item) error { + _, err := b.UpdateAccountInfo(ctx, assetType) return b.CheckTransientError(err) } @@ -988,7 +992,7 @@ func (b *Bitfinex) FormatExchangeKlineInterval(in kline.Interval) string { } // GetHistoricCandles returns candles between a time period for a set time interval -func (b *Bitfinex) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (b *Bitfinex) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { if err := b.ValidateKline(pair, a, interval); err != nil { return kline.Item{}, err } @@ -1002,7 +1006,8 @@ func (b *Bitfinex) GetHistoricCandles(pair currency.Pair, a asset.Item, start, e return kline.Item{}, err } - candles, err := b.GetCandles(cf, b.FormatExchangeKlineInterval(interval), + candles, err := b.GetCandles(ctx, + cf, b.FormatExchangeKlineInterval(interval), start.Unix()*1000, end.Unix()*1000, b.Features.Enabled.Kline.ResultLimit, true) if err != nil { @@ -1031,7 +1036,7 @@ func (b *Bitfinex) GetHistoricCandles(pair currency.Pair, a asset.Item, start, e } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (b *Bitfinex) GetHistoricCandlesExtended(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (b *Bitfinex) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { if err := b.ValidateKline(pair, a, interval); err != nil { return kline.Item{}, err } @@ -1054,7 +1059,8 @@ func (b *Bitfinex) GetHistoricCandlesExtended(pair currency.Pair, a asset.Item, for x := range dates.Ranges { var candles []Candle - candles, err = b.GetCandles(cf, b.FormatExchangeKlineInterval(interval), + candles, err = b.GetCandles(ctx, + cf, b.FormatExchangeKlineInterval(interval), dates.Ranges[x].Start.Ticks*1000, dates.Ranges[x].End.Ticks*1000, b.Features.Enabled.Kline.ResultLimit, true) if err != nil { diff --git a/exchanges/bitflyer/bitflyer.go b/exchanges/bitflyer/bitflyer.go index 25747d47..1ec9a3f6 100644 --- a/exchanges/bitflyer/bitflyer.go +++ b/exchanges/bitflyer/bitflyer.go @@ -73,75 +73,75 @@ type Bitflyer struct { // GetLatestBlockCA returns the latest block information from bitflyer chain // analysis system -func (b *Bitflyer) GetLatestBlockCA() (ChainAnalysisBlock, error) { +func (b *Bitflyer) GetLatestBlockCA(ctx context.Context) (ChainAnalysisBlock, error) { var resp ChainAnalysisBlock - return resp, b.SendHTTPRequest(exchange.ChainAnalysis, latestBlock, &resp) + return resp, b.SendHTTPRequest(ctx, exchange.ChainAnalysis, latestBlock, &resp) } // GetBlockCA returns block information by blockhash from bitflyer chain // analysis system -func (b *Bitflyer) GetBlockCA(blockhash string) (ChainAnalysisBlock, error) { +func (b *Bitflyer) GetBlockCA(ctx context.Context, blockhash string) (ChainAnalysisBlock, error) { var resp ChainAnalysisBlock - return resp, b.SendHTTPRequest(exchange.ChainAnalysis, blockByBlockHash+blockhash, &resp) + return resp, b.SendHTTPRequest(ctx, exchange.ChainAnalysis, blockByBlockHash+blockhash, &resp) } // GetBlockbyHeightCA returns the block information by height from bitflyer chain // analysis system -func (b *Bitflyer) GetBlockbyHeightCA(height int64) (ChainAnalysisBlock, error) { +func (b *Bitflyer) GetBlockbyHeightCA(ctx context.Context, height int64) (ChainAnalysisBlock, error) { var resp ChainAnalysisBlock - return resp, b.SendHTTPRequest(exchange.ChainAnalysis, blockByBlockHeight+strconv.FormatInt(height, 10), &resp) + return resp, b.SendHTTPRequest(ctx, exchange.ChainAnalysis, blockByBlockHeight+strconv.FormatInt(height, 10), &resp) } // GetTransactionByHashCA returns transaction information by txHash from // bitflyer chain analysis system -func (b *Bitflyer) GetTransactionByHashCA(txHash string) (ChainAnalysisTransaction, error) { +func (b *Bitflyer) GetTransactionByHashCA(ctx context.Context, txHash string) (ChainAnalysisTransaction, error) { var resp ChainAnalysisTransaction - return resp, b.SendHTTPRequest(exchange.ChainAnalysis, transaction+txHash, &resp) + return resp, b.SendHTTPRequest(ctx, exchange.ChainAnalysis, transaction+txHash, &resp) } // GetAddressInfoCA returns balance information for address by addressln string // from bitflyer chain analysis system -func (b *Bitflyer) GetAddressInfoCA(addressln string) (ChainAnalysisAddress, error) { +func (b *Bitflyer) GetAddressInfoCA(ctx context.Context, addressln string) (ChainAnalysisAddress, error) { var resp ChainAnalysisAddress - return resp, b.SendHTTPRequest(exchange.ChainAnalysis, address+addressln, &resp) + return resp, b.SendHTTPRequest(ctx, exchange.ChainAnalysis, address+addressln, &resp) } // GetMarkets returns market information -func (b *Bitflyer) GetMarkets() ([]MarketInfo, error) { +func (b *Bitflyer) GetMarkets(ctx context.Context) ([]MarketInfo, error) { var resp []MarketInfo - return resp, b.SendHTTPRequest(exchange.RestSpot, pubGetMarkets, &resp) + return resp, b.SendHTTPRequest(ctx, exchange.RestSpot, pubGetMarkets, &resp) } // GetOrderBook returns market orderbook depth -func (b *Bitflyer) GetOrderBook(symbol string) (Orderbook, error) { +func (b *Bitflyer) GetOrderBook(ctx context.Context, symbol string) (Orderbook, error) { var resp Orderbook v := url.Values{} v.Set("product_code", symbol) - return resp, b.SendHTTPRequest(exchange.RestSpot, pubGetBoard+"?"+v.Encode(), &resp) + return resp, b.SendHTTPRequest(ctx, exchange.RestSpot, pubGetBoard+"?"+v.Encode(), &resp) } // GetTicker returns ticker information -func (b *Bitflyer) GetTicker(symbol string) (Ticker, error) { +func (b *Bitflyer) GetTicker(ctx context.Context, symbol string) (Ticker, error) { var resp Ticker v := url.Values{} v.Set("product_code", symbol) - return resp, b.SendHTTPRequest(exchange.RestSpot, pubGetTicker+"?"+v.Encode(), &resp) + return resp, b.SendHTTPRequest(ctx, exchange.RestSpot, pubGetTicker+"?"+v.Encode(), &resp) } // GetExecutionHistory returns past trades that were executed on the market -func (b *Bitflyer) GetExecutionHistory(symbol string) ([]ExecutedTrade, error) { +func (b *Bitflyer) GetExecutionHistory(ctx context.Context, symbol string) ([]ExecutedTrade, error) { var resp []ExecutedTrade v := url.Values{} v.Set("product_code", symbol) - return resp, b.SendHTTPRequest(exchange.RestSpot, pubGetExecutionHistory+"?"+v.Encode(), &resp) + return resp, b.SendHTTPRequest(ctx, exchange.RestSpot, pubGetExecutionHistory+"?"+v.Encode(), &resp) } // GetExchangeStatus returns exchange status information -func (b *Bitflyer) GetExchangeStatus() (string, error) { +func (b *Bitflyer) GetExchangeStatus(ctx context.Context) (string, error) { resp := make(map[string]string) - err := b.SendHTTPRequest(exchange.RestSpot, pubGetHealth, &resp) + err := b.SendHTTPRequest(ctx, exchange.RestSpot, pubGetHealth, &resp) if err != nil { return "", err } @@ -162,11 +162,11 @@ func (b *Bitflyer) GetExchangeStatus() (string, error) { // GetChats returns trollbox chat log // Note: returns vary from instant to infinty -func (b *Bitflyer) GetChats(fromDate string) ([]ChatLog, error) { +func (b *Bitflyer) GetChats(ctx context.Context, fromDate string) ([]ChatLog, error) { var resp []ChatLog v := url.Values{} v.Set("from_date", fromDate) - return resp, b.SendHTTPRequest(exchange.RestSpot, pubGetChats+"?"+v.Encode(), &resp) + return resp, b.SendHTTPRequest(ctx, exchange.RestSpot, pubGetChats+"?"+v.Encode(), &resp) } // GetPermissions returns current permissions for associated with your API @@ -286,7 +286,7 @@ func (b *Bitflyer) GetTradingCommission() { } // SendHTTPRequest sends an unauthenticated request -func (b *Bitflyer) SendHTTPRequest(ep exchange.URL, path string, result interface{}) error { +func (b *Bitflyer) SendHTTPRequest(ctx context.Context, ep exchange.URL, path string, result interface{}) error { endpoint, err := b.API.Endpoints.GetURL(ep) if err != nil { return err @@ -299,7 +299,7 @@ func (b *Bitflyer) SendHTTPRequest(ep exchange.URL, path string, result interfac HTTPDebugging: b.HTTPDebugging, HTTPRecording: b.HTTPRecording, } - return b.SendPayload(context.Background(), request.Unset, func() (*request.Item, error) { + return b.SendPayload(ctx, request.Unset, func() (*request.Item, error) { return item, nil }) } diff --git a/exchanges/bitflyer/bitflyer_test.go b/exchanges/bitflyer/bitflyer_test.go index e835d1bd..df2882d7 100644 --- a/exchanges/bitflyer/bitflyer_test.go +++ b/exchanges/bitflyer/bitflyer_test.go @@ -1,6 +1,7 @@ package bitflyer import ( + "context" "log" "os" "testing" @@ -50,7 +51,7 @@ func TestMain(m *testing.M) { func TestGetLatestBlockCA(t *testing.T) { t.Parallel() - _, err := b.GetLatestBlockCA() + _, err := b.GetLatestBlockCA(context.Background()) if err != nil { t.Error("Bitflyer - GetLatestBlockCA() error:", err) } @@ -58,7 +59,7 @@ func TestGetLatestBlockCA(t *testing.T) { func TestGetBlockCA(t *testing.T) { t.Parallel() - _, err := b.GetBlockCA("000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f") + _, err := b.GetBlockCA(context.Background(), "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f") if err != nil { t.Error("Bitflyer - GetBlockCA() error:", err) } @@ -66,7 +67,7 @@ func TestGetBlockCA(t *testing.T) { func TestGetBlockbyHeightCA(t *testing.T) { t.Parallel() - _, err := b.GetBlockbyHeightCA(0) + _, err := b.GetBlockbyHeightCA(context.Background(), 0) if err != nil { t.Error("Bitflyer - GetBlockbyHeightCA() error:", err) } @@ -74,7 +75,7 @@ func TestGetBlockbyHeightCA(t *testing.T) { func TestGetTransactionByHashCA(t *testing.T) { t.Parallel() - _, err := b.GetTransactionByHashCA("0562d1f063cd4127053d838b165630445af5e480ceb24e1fd9ecea52903cb772") + _, err := b.GetTransactionByHashCA(context.Background(), "0562d1f063cd4127053d838b165630445af5e480ceb24e1fd9ecea52903cb772") if err != nil { t.Error("Bitflyer - GetTransactionByHashCA() error:", err) } @@ -82,7 +83,7 @@ func TestGetTransactionByHashCA(t *testing.T) { func TestGetAddressInfoCA(t *testing.T) { t.Parallel() - v, err := b.GetAddressInfoCA(core.BitcoinDonationAddress) + v, err := b.GetAddressInfoCA(context.Background(), core.BitcoinDonationAddress) if err != nil { t.Error("Bitflyer - GetAddressInfoCA() error:", err) } @@ -93,7 +94,7 @@ func TestGetAddressInfoCA(t *testing.T) { func TestGetMarkets(t *testing.T) { t.Parallel() - markets, err := b.GetMarkets() + markets, err := b.GetMarkets(context.Background()) if err != nil { t.Error("Bitflyer - GetMarkets() error:", err) } @@ -109,7 +110,7 @@ func TestGetMarkets(t *testing.T) { func TestGetOrderBook(t *testing.T) { t.Parallel() - _, err := b.GetOrderBook("BTC_JPY") + _, err := b.GetOrderBook(context.Background(), "BTC_JPY") if err != nil { t.Error("Bitflyer - GetOrderBook() error:", err) } @@ -117,7 +118,7 @@ func TestGetOrderBook(t *testing.T) { func TestGetTicker(t *testing.T) { t.Parallel() - _, err := b.GetTicker("BTC_JPY") + _, err := b.GetTicker(context.Background(), "BTC_JPY") if err != nil { t.Error("Bitflyer - GetTicker() error:", err) } @@ -125,7 +126,7 @@ func TestGetTicker(t *testing.T) { func TestGetExecutionHistory(t *testing.T) { t.Parallel() - _, err := b.GetExecutionHistory("BTC_JPY") + _, err := b.GetExecutionHistory(context.Background(), "BTC_JPY") if err != nil { t.Error("Bitflyer - GetExecutionHistory() error:", err) } @@ -133,7 +134,7 @@ func TestGetExecutionHistory(t *testing.T) { func TestGetExchangeStatus(t *testing.T) { t.Parallel() - _, err := b.GetExchangeStatus() + _, err := b.GetExchangeStatus(context.Background()) if err != nil { t.Error("Bitflyer - GetExchangeStatus() error:", err) } @@ -167,7 +168,7 @@ func TestFetchTicker(t *testing.T) { } } - _, err = b.FetchTicker(p, asset.Spot) + _, err = b.FetchTicker(context.Background(), p, asset.Spot) if err != nil { t.Error("Bitflyer - FetchTicker() error", err) } @@ -187,7 +188,7 @@ func setFeeBuilder() *exchange.FeeBuilder { // TestGetFeeByTypeOfflineTradeFee logic test func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { var feeBuilder = setFeeBuilder() - _, err := b.GetFeeByType(feeBuilder) + _, err := b.GetFeeByType(context.Background(), feeBuilder) if err != nil { t.Fatal(err) } @@ -282,7 +283,7 @@ func TestGetActiveOrders(t *testing.T) { AssetType: asset.Spot, } - _, err := b.GetActiveOrders(&getOrdersRequest) + _, err := b.GetActiveOrders(context.Background(), &getOrdersRequest) if areTestAPIKeysSet() && err != nil { t.Errorf("Could not get open orders: %s", err) } else if !areTestAPIKeysSet() && err == nil { @@ -297,7 +298,7 @@ func TestGetOrderHistory(t *testing.T) { AssetType: asset.Spot, } - _, err := b.GetOrderHistory(&getOrdersRequest) + _, err := b.GetOrderHistory(context.Background(), &getOrdersRequest) if err != common.ErrNotYetImplemented { t.Errorf("Expected '%v', received '%v'", common.ErrNotYetImplemented, err) } @@ -327,7 +328,7 @@ func TestSubmitOrder(t *testing.T) { ClientID: "meowOrder", AssetType: asset.Spot, } - _, err := b.SubmitOrder(orderSubmission) + _, err := b.SubmitOrder(context.Background(), orderSubmission) if err != common.ErrNotYetImplemented { t.Errorf("Expected 'Not Yet Implemented', received %v", err) } @@ -348,7 +349,7 @@ func TestCancelExchangeOrder(t *testing.T) { AssetType: asset.Spot, } - err := b.CancelOrder(orderCancellation) + err := b.CancelOrder(context.Background(), orderCancellation) if err != common.ErrNotYetImplemented { t.Errorf("Expected 'Not Yet Implemented', received %v", err) @@ -370,7 +371,7 @@ func TestCancelAllExchangeOrders(t *testing.T) { AssetType: asset.Spot, } - _, err := b.CancelAllOrders(orderCancellation) + _, err := b.CancelAllOrders(context.Background(), orderCancellation) if err != common.ErrNotYetImplemented { t.Errorf("Expected 'Not Yet Implemented', received %v", err) @@ -392,7 +393,8 @@ func TestWithdraw(t *testing.T) { }, } - _, err := b.WithdrawCryptocurrencyFunds(&withdrawCryptoRequest) + _, err := b.WithdrawCryptocurrencyFunds(context.Background(), + &withdrawCryptoRequest) if err != common.ErrNotYetImplemented { t.Errorf("Expected 'Not Yet Implemented', received %v", err) } @@ -403,7 +405,8 @@ func TestModifyOrder(t *testing.T) { if areTestAPIKeysSet() && !canManipulateRealOrders { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - _, err := b.ModifyOrder(&order.Modify{AssetType: asset.Spot}) + _, err := b.ModifyOrder(context.Background(), + &order.Modify{AssetType: asset.Spot}) if err == nil { t.Error("ModifyOrder() Expected error") } @@ -417,7 +420,7 @@ func TestWithdrawFiat(t *testing.T) { var withdrawFiatRequest = withdraw.Request{} - _, err := b.WithdrawFiatFunds(&withdrawFiatRequest) + _, err := b.WithdrawFiatFunds(context.Background(), &withdrawFiatRequest) if err != common.ErrNotYetImplemented { t.Errorf("Expected '%v', received: '%v'", common.ErrNotYetImplemented, err) } @@ -431,7 +434,8 @@ func TestWithdrawInternationalBank(t *testing.T) { var withdrawFiatRequest = withdraw.Request{} - _, err := b.WithdrawFiatFundsToInternationalBank(&withdrawFiatRequest) + _, err := b.WithdrawFiatFundsToInternationalBank(context.Background(), + &withdrawFiatRequest) if err != common.ErrNotYetImplemented { t.Errorf("Expected '%v', received: '%v'", common.ErrNotYetImplemented, err) } @@ -443,7 +447,7 @@ func TestGetRecentTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = b.GetRecentTrades(currencyPair, asset.Spot) + _, err = b.GetRecentTrades(context.Background(), currencyPair, asset.Spot) if err != nil { t.Error(err) } @@ -455,7 +459,8 @@ func TestGetHistoricTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = b.GetHistoricTrades(currencyPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) + _, err = b.GetHistoricTrades(context.Background(), + currencyPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) if err != nil && err != common.ErrFunctionNotSupported { t.Fatal(err) } diff --git a/exchanges/bitflyer/bitflyer_wrapper.go b/exchanges/bitflyer/bitflyer_wrapper.go index b5cc77a0..ac99f672 100644 --- a/exchanges/bitflyer/bitflyer_wrapper.go +++ b/exchanges/bitflyer/bitflyer_wrapper.go @@ -1,6 +1,7 @@ package bitflyer import ( + "context" "sort" "strconv" "strings" @@ -38,7 +39,7 @@ func (b *Bitflyer) GetDefaultConfig() (*config.ExchangeConfig, error) { } if b.Features.Supports.RESTCapabilities.AutoPairUpdates { - err = b.UpdateTradablePairs(true) + err = b.UpdateTradablePairs(context.TODO(), true) if err != nil { return nil, err } @@ -132,15 +133,15 @@ func (b *Bitflyer) Run() { return } - err := b.UpdateTradablePairs(false) + err := b.UpdateTradablePairs(context.TODO(), false) if err != nil { log.Errorf(log.ExchangeSys, "%s failed to update tradable pairs. Err: %s", b.Name, err) } } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (b *Bitflyer) FetchTradablePairs(a asset.Item) ([]string, error) { - pairs, err := b.GetMarkets() +func (b *Bitflyer) FetchTradablePairs(ctx context.Context, a asset.Item) ([]string, error) { + pairs, err := b.GetMarkets(ctx) if err != nil { return nil, err } @@ -166,10 +167,10 @@ func (b *Bitflyer) FetchTradablePairs(a asset.Item) ([]string, error) { // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (b *Bitflyer) UpdateTradablePairs(forceUpdate bool) error { +func (b *Bitflyer) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { assets := b.CurrencyPairs.GetAssetTypes(false) for x := range assets { - pairs, err := b.FetchTradablePairs(assets[x]) + pairs, err := b.FetchTradablePairs(ctx, assets[x]) if err != nil { return err } @@ -188,18 +189,18 @@ func (b *Bitflyer) UpdateTradablePairs(forceUpdate bool) error { } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (b *Bitflyer) UpdateTickers(a asset.Item) error { +func (b *Bitflyer) UpdateTickers(ctx context.Context, a asset.Item) error { return common.ErrFunctionNotSupported } // UpdateTicker updates and returns the ticker for a currency pair -func (b *Bitflyer) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) { +func (b *Bitflyer) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { fPair, err := b.FormatExchangeCurrency(p, a) if err != nil { return nil, err } - tickerNew, err := b.GetTicker(b.CheckFXString(fPair).String()) + tickerNew, err := b.GetTicker(ctx, b.CheckFXString(fPair).String()) if err != nil { return nil, err } @@ -220,7 +221,7 @@ func (b *Bitflyer) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, e } // FetchTicker returns the ticker for a currency pair -func (b *Bitflyer) FetchTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) { +func (b *Bitflyer) FetchTicker(ctx context.Context, p currency.Pair, assetType asset.Item) (*ticker.Price, error) { fPair, err := b.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err @@ -228,7 +229,7 @@ func (b *Bitflyer) FetchTicker(p currency.Pair, assetType asset.Item) (*ticker.P tick, err := ticker.GetTicker(b.Name, fPair, assetType) if err != nil { - return b.UpdateTicker(fPair, assetType) + return b.UpdateTicker(ctx, fPair, assetType) } return tick, nil } @@ -243,7 +244,7 @@ func (b *Bitflyer) CheckFXString(p currency.Pair) currency.Pair { } // FetchOrderbook returns the orderbook for a currency pair -func (b *Bitflyer) FetchOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (b *Bitflyer) FetchOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { fPair, err := b.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err @@ -251,13 +252,13 @@ func (b *Bitflyer) FetchOrderbook(p currency.Pair, assetType asset.Item) (*order ob, err := orderbook.Get(b.Name, fPair, assetType) if err != nil { - return b.UpdateOrderbook(fPair, assetType) + return b.UpdateOrderbook(ctx, fPair, assetType) } return ob, nil } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (b *Bitflyer) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (b *Bitflyer) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { book := &orderbook.Base{ Exchange: b.Name, Pair: p, @@ -270,7 +271,7 @@ func (b *Bitflyer) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orde return book, err } - orderbookNew, err := b.GetOrderBook(b.CheckFXString(fPair).String()) + orderbookNew, err := b.GetOrderBook(ctx, b.CheckFXString(fPair).String()) if err != nil { return book, err } @@ -297,15 +298,15 @@ func (b *Bitflyer) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orde // UpdateAccountInfo retrieves balances for all enabled currencies on the // Bitflyer exchange -func (b *Bitflyer) UpdateAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (b *Bitflyer) UpdateAccountInfo(_ context.Context, _ asset.Item) (account.Holdings, error) { return account.Holdings{}, common.ErrNotYetImplemented } // FetchAccountInfo retrieves balances for all enabled currencies -func (b *Bitflyer) FetchAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (b *Bitflyer) FetchAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { acc, err := account.GetHoldings(b.Name, assetType) if err != nil { - return b.UpdateAccountInfo(assetType) + return b.UpdateAccountInfo(ctx, assetType) } return acc, nil @@ -313,23 +314,23 @@ func (b *Bitflyer) FetchAccountInfo(assetType asset.Item) (account.Holdings, err // GetFundingHistory returns funding history, deposits and // withdrawals -func (b *Bitflyer) GetFundingHistory() ([]exchange.FundHistory, error) { +func (b *Bitflyer) GetFundingHistory(_ context.Context) ([]exchange.FundHistory, error) { return nil, common.ErrFunctionNotSupported } // GetWithdrawalsHistory returns previous withdrawals data -func (b *Bitflyer) GetWithdrawalsHistory(c currency.Code) (resp []exchange.WithdrawalHistory, err error) { +func (b *Bitflyer) GetWithdrawalsHistory(_ context.Context, _ currency.Code) (resp []exchange.WithdrawalHistory, err error) { return nil, common.ErrNotYetImplemented } // GetRecentTrades returns recent historic trades -func (b *Bitflyer) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade.Data, error) { +func (b *Bitflyer) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { var err error p, err = b.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err } - tradeData, err := b.GetExecutionHistory(p.String()) + tradeData, err := b.GetExecutionHistory(ctx, p.String()) if err != nil { return nil, err } @@ -367,80 +368,80 @@ func (b *Bitflyer) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]tra } // GetHistoricTrades returns historic trade data within the timeframe provided -func (b *Bitflyer) GetHistoricTrades(_ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { +func (b *Bitflyer) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { return nil, common.ErrFunctionNotSupported } // SubmitOrder submits a new order -func (b *Bitflyer) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { +func (b *Bitflyer) SubmitOrder(_ context.Context, _ *order.Submit) (order.SubmitResponse, error) { return order.SubmitResponse{}, common.ErrNotYetImplemented } // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (b *Bitflyer) ModifyOrder(action *order.Modify) (order.Modify, error) { +func (b *Bitflyer) ModifyOrder(_ context.Context, _ *order.Modify) (order.Modify, error) { return order.Modify{}, common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number -func (b *Bitflyer) CancelOrder(_ *order.Cancel) error { +func (b *Bitflyer) CancelOrder(_ context.Context, _ *order.Cancel) error { return common.ErrNotYetImplemented } // CancelBatchOrders cancels an orders by their corresponding ID numbers -func (b *Bitflyer) CancelBatchOrders(_ []order.Cancel) (order.CancelBatchResponse, error) { +func (b *Bitflyer) CancelBatchOrders(_ context.Context, _ []order.Cancel) (order.CancelBatchResponse, error) { return order.CancelBatchResponse{}, common.ErrNotYetImplemented } // CancelAllOrders cancels all orders associated with a currency pair -func (b *Bitflyer) CancelAllOrders(_ *order.Cancel) (order.CancelAllResponse, error) { +func (b *Bitflyer) CancelAllOrders(_ context.Context, _ *order.Cancel) (order.CancelAllResponse, error) { // TODO, implement BitFlyer API b.CancelAllExistingOrders() return order.CancelAllResponse{}, common.ErrNotYetImplemented } // GetOrderInfo returns order information based on order ID -func (b *Bitflyer) GetOrderInfo(_ string, _ currency.Pair, _ asset.Item) (order.Detail, error) { +func (b *Bitflyer) GetOrderInfo(_ context.Context, _ string, _ currency.Pair, _ asset.Item) (order.Detail, error) { var orderDetail order.Detail return orderDetail, common.ErrNotYetImplemented } // GetDepositAddress returns a deposit address for a specified currency -func (b *Bitflyer) GetDepositAddress(_ currency.Code, _ string) (string, error) { +func (b *Bitflyer) GetDepositAddress(_ context.Context, _ currency.Code, _ string) (string, error) { return "", common.ErrNotYetImplemented } // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is // submitted -func (b *Bitflyer) WithdrawCryptocurrencyFunds(_ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (b *Bitflyer) WithdrawCryptocurrencyFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrNotYetImplemented } // WithdrawFiatFunds returns a withdrawal ID when a // withdrawal is submitted -func (b *Bitflyer) WithdrawFiatFunds(_ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (b *Bitflyer) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrNotYetImplemented } // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a // withdrawal is submitted -func (b *Bitflyer) WithdrawFiatFundsToInternationalBank(_ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (b *Bitflyer) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrNotYetImplemented } // GetActiveOrders retrieves any orders that are active/open -func (b *Bitflyer) GetActiveOrders(_ *order.GetOrdersRequest) ([]order.Detail, error) { +func (b *Bitflyer) GetActiveOrders(_ context.Context, _ *order.GetOrdersRequest) ([]order.Detail, error) { return nil, common.ErrNotYetImplemented } // GetOrderHistory retrieves account order information // Can Limit response to specific order status -func (b *Bitflyer) GetOrderHistory(_ *order.GetOrdersRequest) ([]order.Detail, error) { +func (b *Bitflyer) GetOrderHistory(_ context.Context, _ *order.GetOrdersRequest) ([]order.Detail, error) { return nil, common.ErrNotYetImplemented } // GetFeeByType returns an estimate of fee based on the type of transaction -func (b *Bitflyer) GetFeeByType(feeBuilder *exchange.FeeBuilder) (float64, error) { +func (b *Bitflyer) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { if !b.AllowAuthenticatedRequest() && // Todo check connection status feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { feeBuilder.FeeType = exchange.OfflineTradeFee @@ -450,17 +451,17 @@ func (b *Bitflyer) GetFeeByType(feeBuilder *exchange.FeeBuilder) (float64, error // ValidateCredentials validates current credentials used for wrapper // functionality -func (b *Bitflyer) ValidateCredentials(assetType asset.Item) error { - _, err := b.UpdateAccountInfo(assetType) +func (b *Bitflyer) ValidateCredentials(ctx context.Context, assetType asset.Item) error { + _, err := b.UpdateAccountInfo(ctx, assetType) return b.CheckTransientError(err) } // GetHistoricCandles returns candles between a time period for a set time interval -func (b *Bitflyer) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (b *Bitflyer) GetHistoricCandles(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time, _ kline.Interval) (kline.Item, error) { return kline.Item{}, common.ErrFunctionNotSupported } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (b *Bitflyer) GetHistoricCandlesExtended(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (b *Bitflyer) GetHistoricCandlesExtended(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time, _ kline.Interval) (kline.Item, error) { return kline.Item{}, common.ErrFunctionNotSupported } diff --git a/exchanges/bithumb/bithumb.go b/exchanges/bithumb/bithumb.go index ba94f725..924c157d 100644 --- a/exchanges/bithumb/bithumb.go +++ b/exchanges/bithumb/bithumb.go @@ -58,8 +58,8 @@ type Bithumb struct { } // GetTradablePairs returns a list of tradable currencies -func (b *Bithumb) GetTradablePairs() ([]string, error) { - result, err := b.GetAllTickers() +func (b *Bithumb) GetTradablePairs(ctx context.Context) ([]string, error) { + result, err := b.GetAllTickers(ctx) if err != nil { return nil, err } @@ -74,9 +74,9 @@ func (b *Bithumb) GetTradablePairs() ([]string, error) { // GetTicker returns ticker information // // symbol e.g. "btc" -func (b *Bithumb) GetTicker(symbol string) (Ticker, error) { +func (b *Bithumb) GetTicker(ctx context.Context, symbol string) (Ticker, error) { var response TickerResponse - err := b.SendHTTPRequest(exchange.RestSpot, publicTicker+strings.ToUpper(symbol), &response) + err := b.SendHTTPRequest(ctx, exchange.RestSpot, publicTicker+strings.ToUpper(symbol), &response) if err != nil { return response.Data, err } @@ -89,9 +89,9 @@ func (b *Bithumb) GetTicker(symbol string) (Ticker, error) { } // GetAllTickers returns all ticker information -func (b *Bithumb) GetAllTickers() (map[string]Ticker, error) { +func (b *Bithumb) GetAllTickers(ctx context.Context) (map[string]Ticker, error) { var response TickersResponse - err := b.SendHTTPRequest(exchange.RestSpot, publicTicker+"all", &response) + err := b.SendHTTPRequest(ctx, exchange.RestSpot, publicTicker+"all", &response) if err != nil { return nil, err } @@ -118,9 +118,9 @@ func (b *Bithumb) GetAllTickers() (map[string]Ticker, error) { // GetOrderBook returns current orderbook // // symbol e.g. "btc" -func (b *Bithumb) GetOrderBook(symbol string) (*Orderbook, error) { +func (b *Bithumb) GetOrderBook(ctx context.Context, symbol string) (*Orderbook, error) { response := Orderbook{} - err := b.SendHTTPRequest(exchange.RestSpot, publicOrderBook+strings.ToUpper(symbol), &response) + err := b.SendHTTPRequest(ctx, exchange.RestSpot, publicOrderBook+strings.ToUpper(symbol), &response) if err != nil { return nil, err } @@ -133,12 +133,12 @@ func (b *Bithumb) GetOrderBook(symbol string) (*Orderbook, error) { } // GetAssetStatus returns the withdrawal and deposit status for the symbol -func (b *Bithumb) GetAssetStatus(symbol string) (*Status, error) { +func (b *Bithumb) GetAssetStatus(ctx context.Context, symbol string) (*Status, error) { if symbol == "" { return nil, errSymbolIsEmpty } var response Status - err := b.SendHTTPRequest(exchange.RestSpot, publicAssetStatus+strings.ToUpper(symbol), &response) + err := b.SendHTTPRequest(ctx, exchange.RestSpot, publicAssetStatus+strings.ToUpper(symbol), &response) if err != nil { return nil, err } @@ -153,12 +153,12 @@ func (b *Bithumb) GetAssetStatus(symbol string) (*Status, error) { // GetTransactionHistory returns recent transactions // // symbol e.g. "btc" -func (b *Bithumb) GetTransactionHistory(symbol string) (TransactionHistory, error) { +func (b *Bithumb) GetTransactionHistory(ctx context.Context, symbol string) (TransactionHistory, error) { response := TransactionHistory{} path := publicTransactionHistory + strings.ToUpper(symbol) - err := b.SendHTTPRequest(exchange.RestSpot, path, &response) + err := b.SendHTTPRequest(ctx, exchange.RestSpot, path, &response) if err != nil { return response, err } @@ -172,7 +172,7 @@ func (b *Bithumb) GetTransactionHistory(symbol string) (TransactionHistory, erro // GetAccountInformation returns account information based on the desired // order/payment currencies -func (b *Bithumb) GetAccountInformation(orderCurrency, paymentCurrency string) (Account, error) { +func (b *Bithumb) GetAccountInformation(ctx context.Context, orderCurrency, paymentCurrency string) (Account, error) { var response Account if orderCurrency == "" { return response, errSymbolIsEmpty @@ -185,11 +185,11 @@ func (b *Bithumb) GetAccountInformation(orderCurrency, paymentCurrency string) ( } return response, - b.SendAuthenticatedHTTPRequest(exchange.RestSpot, privateAccInfo, val, &response) + b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateAccInfo, val, &response) } // GetAccountBalance returns customer wallet information -func (b *Bithumb) GetAccountBalance(c string) (FullBalance, error) { +func (b *Bithumb) GetAccountBalance(ctx context.Context, c string) (FullBalance, error) { var response Balance var fullBalance = FullBalance{ make(map[string]float64), @@ -204,7 +204,7 @@ func (b *Bithumb) GetAccountBalance(c string) (FullBalance, error) { vals.Set("currency", c) } - err := b.SendAuthenticatedHTTPRequest(exchange.RestSpot, privateAccBalance, vals, &response) + err := b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateAccBalance, vals, &response) if err != nil { return fullBalance, err } @@ -252,12 +252,12 @@ func (b *Bithumb) GetAccountBalance(c string) (FullBalance, error) { // GetWalletAddress returns customer wallet address // // currency e.g. btc, ltc or "", will default to btc without currency specified -func (b *Bithumb) GetWalletAddress(currency string) (WalletAddressRes, error) { +func (b *Bithumb) GetWalletAddress(ctx context.Context, currency string) (WalletAddressRes, error) { response := WalletAddressRes{} params := url.Values{} params.Set("currency", strings.ToUpper(currency)) - err := b.SendAuthenticatedHTTPRequest(exchange.RestSpot, privateWalletAdd, params, &response) + err := b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateWalletAdd, params, &response) if err != nil { return response, err } @@ -272,11 +272,11 @@ func (b *Bithumb) GetWalletAddress(currency string) (WalletAddressRes, error) { } // GetLastTransaction returns customer last transaction -func (b *Bithumb) GetLastTransaction() (LastTransactionTicker, error) { +func (b *Bithumb) GetLastTransaction(ctx context.Context) (LastTransactionTicker, error) { response := LastTransactionTicker{} return response, - b.SendAuthenticatedHTTPRequest(exchange.RestSpot, privateTicker, nil, &response) + b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateTicker, nil, &response) } // GetOrders returns order list @@ -286,7 +286,7 @@ func (b *Bithumb) GetLastTransaction() (LastTransactionTicker, error) { // count: Value : 1 ~1000 (default : 100) // after: YYYY-MM-DD hh:mm:ss's UNIX Timestamp // (2014-11-28 16:40:01 = 1417160401000) -func (b *Bithumb) GetOrders(orderID, transactionType, count, after, currency string) (Orders, error) { +func (b *Bithumb) GetOrders(ctx context.Context, orderID, transactionType, count, after, currency string) (Orders, error) { response := Orders{} params := url.Values{} @@ -313,15 +313,15 @@ func (b *Bithumb) GetOrders(orderID, transactionType, count, after, currency str } return response, - b.SendAuthenticatedHTTPRequest(exchange.RestSpot, privateOrders, params, &response) + b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateOrders, params, &response) } // GetUserTransactions returns customer transactions -func (b *Bithumb) GetUserTransactions() (UserTransactions, error) { +func (b *Bithumb) GetUserTransactions(ctx context.Context) (UserTransactions, error) { response := UserTransactions{} return response, - b.SendAuthenticatedHTTPRequest(exchange.RestSpot, privateUserTrans, nil, &response) + b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateUserTrans, nil, &response) } // PlaceTrade executes a trade order @@ -331,7 +331,7 @@ func (b *Bithumb) GetUserTransactions() (UserTransactions, error) { // transactionType: Transaction type(bid : purchase, ask : sales) // units: Order quantity // price: Transaction amount per currency -func (b *Bithumb) PlaceTrade(orderCurrency, transactionType string, units float64, price int64) (OrderPlace, error) { +func (b *Bithumb) PlaceTrade(ctx context.Context, orderCurrency, transactionType string, units float64, price int64) (OrderPlace, error) { response := OrderPlace{} params := url.Values{} @@ -342,11 +342,11 @@ func (b *Bithumb) PlaceTrade(orderCurrency, transactionType string, units float6 params.Set("price", strconv.FormatInt(price, 10)) return response, - b.SendAuthenticatedHTTPRequest(exchange.RestSpot, privatePlaceTrade, params, &response) + b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privatePlaceTrade, params, &response) } // ModifyTrade modifies an order already on the exchange books -func (b *Bithumb) ModifyTrade(orderID, orderCurrency, transactionType string, units float64, price int64) (OrderPlace, error) { +func (b *Bithumb) ModifyTrade(ctx context.Context, orderID, orderCurrency, transactionType string, units float64, price int64) (OrderPlace, error) { response := OrderPlace{} params := url.Values{} @@ -358,7 +358,7 @@ func (b *Bithumb) ModifyTrade(orderID, orderCurrency, transactionType string, un params.Set("order_id", orderID) return response, - b.SendAuthenticatedHTTPRequest(exchange.RestSpot, privatePlaceTrade, params, &response) + b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privatePlaceTrade, params, &response) } // GetOrderDetails returns specific order details @@ -367,7 +367,7 @@ func (b *Bithumb) ModifyTrade(orderID, orderCurrency, transactionType string, un // transactionType: Transaction type(bid : purchase, ask : sales) // currency: BTC, ETH, DASH, LTC, ETC, XRP, BCH, XMR, ZEC, QTUM, BTG, EOS // (default value: BTC) -func (b *Bithumb) GetOrderDetails(orderID, transactionType, currency string) (OrderDetails, error) { +func (b *Bithumb) GetOrderDetails(ctx context.Context, orderID, transactionType, currency string) (OrderDetails, error) { response := OrderDetails{} params := url.Values{} @@ -376,7 +376,7 @@ func (b *Bithumb) GetOrderDetails(orderID, transactionType, currency string) (Or params.Set("currency", strings.ToUpper(currency)) return response, - b.SendAuthenticatedHTTPRequest(exchange.RestSpot, privateOrderDetail, params, &response) + b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateOrderDetail, params, &response) } // CancelTrade cancels a customer purchase/sales transaction @@ -384,7 +384,7 @@ func (b *Bithumb) GetOrderDetails(orderID, transactionType, currency string) (Or // orderID: Order number registered for purchase/sales // currency: BTC, ETH, DASH, LTC, ETC, XRP, BCH, XMR, ZEC, QTUM, BTG, EOS // (default value: BTC) -func (b *Bithumb) CancelTrade(transactionType, orderID, currency string) (ActionStatus, error) { +func (b *Bithumb) CancelTrade(ctx context.Context, transactionType, orderID, currency string) (ActionStatus, error) { response := ActionStatus{} params := url.Values{} @@ -393,7 +393,7 @@ func (b *Bithumb) CancelTrade(transactionType, orderID, currency string) (Action params.Set("currency", strings.ToUpper(currency)) return response, - b.SendAuthenticatedHTTPRequest(exchange.RestSpot, privateCancelTrade, nil, &response) + b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateCancelTrade, nil, &response) } // WithdrawCrypto withdraws a customer currency to an address @@ -404,7 +404,7 @@ func (b *Bithumb) CancelTrade(transactionType, orderID, currency string) (Action // currency: BTC, ETH, DASH, LTC, ETC, XRP, BCH, XMR, ZEC, QTUM // (default value: BTC) // units: Quantity to withdraw currency -func (b *Bithumb) WithdrawCrypto(address, destination, currency string, units float64) (ActionStatus, error) { +func (b *Bithumb) WithdrawCrypto(ctx context.Context, address, destination, currency string, units float64) (ActionStatus, error) { response := ActionStatus{} params := url.Values{} @@ -416,16 +416,16 @@ func (b *Bithumb) WithdrawCrypto(address, destination, currency string, units fl params.Set("units", strconv.FormatFloat(units, 'f', -1, 64)) return response, - b.SendAuthenticatedHTTPRequest(exchange.RestSpot, privateBTCWithdraw, params, &response) + b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateBTCWithdraw, params, &response) } // RequestKRWDepositDetails returns Bithumb banking details for deposit // information -func (b *Bithumb) RequestKRWDepositDetails() (KRWDeposit, error) { +func (b *Bithumb) RequestKRWDepositDetails(ctx context.Context) (KRWDeposit, error) { response := KRWDeposit{} return response, - b.SendAuthenticatedHTTPRequest(exchange.RestSpot, privateKRWDeposit, nil, &response) + b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateKRWDeposit, nil, &response) } // RequestKRWWithdraw allows a customer KRW withdrawal request @@ -433,7 +433,7 @@ func (b *Bithumb) RequestKRWDepositDetails() (KRWDeposit, error) { // bank: Bankcode with bank name e.g. (bankcode)_(bankname) // account: Withdrawing bank account number // price: Withdrawing amount -func (b *Bithumb) RequestKRWWithdraw(bank, account string, price int64) (ActionStatus, error) { +func (b *Bithumb) RequestKRWWithdraw(ctx context.Context, bank, account string, price int64) (ActionStatus, error) { response := ActionStatus{} params := url.Values{} @@ -442,7 +442,7 @@ func (b *Bithumb) RequestKRWWithdraw(bank, account string, price int64) (ActionS params.Set("price", strconv.FormatInt(price, 10)) return response, - b.SendAuthenticatedHTTPRequest(exchange.RestSpot, privateKRWWithdraw, params, &response) + b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateKRWWithdraw, params, &response) } // MarketBuyOrder initiates a buy order through available order books @@ -450,7 +450,7 @@ func (b *Bithumb) RequestKRWWithdraw(bank, account string, price int64) (ActionS // currency: BTC, ETH, DASH, LTC, ETC, XRP, BCH, XMR, ZEC, QTUM, BTG, EOS // (default value: BTC) // units: Order quantity -func (b *Bithumb) MarketBuyOrder(pair currency.Pair, units float64) (MarketBuy, error) { +func (b *Bithumb) MarketBuyOrder(ctx context.Context, pair currency.Pair, units float64) (MarketBuy, error) { response := MarketBuy{} params := url.Values{} @@ -459,7 +459,7 @@ func (b *Bithumb) MarketBuyOrder(pair currency.Pair, units float64) (MarketBuy, params.Set("units", strconv.FormatFloat(units, 'f', -1, 64)) return response, - b.SendAuthenticatedHTTPRequest(exchange.RestSpot, privateMarketBuy, params, &response) + b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateMarketBuy, params, &response) } // MarketSellOrder initiates a sell order through available order books @@ -467,7 +467,7 @@ func (b *Bithumb) MarketBuyOrder(pair currency.Pair, units float64) (MarketBuy, // currency: BTC, ETH, DASH, LTC, ETC, XRP, BCH, XMR, ZEC, QTUM, BTG, EOS // (default value: BTC) // units: Order quantity -func (b *Bithumb) MarketSellOrder(pair currency.Pair, units float64) (MarketSell, error) { +func (b *Bithumb) MarketSellOrder(ctx context.Context, pair currency.Pair, units float64) (MarketSell, error) { response := MarketSell{} params := url.Values{} @@ -476,11 +476,11 @@ func (b *Bithumb) MarketSellOrder(pair currency.Pair, units float64) (MarketSell params.Set("units", strconv.FormatFloat(units, 'f', -1, 64)) return response, - b.SendAuthenticatedHTTPRequest(exchange.RestSpot, privateMarketSell, params, &response) + b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, privateMarketSell, params, &response) } // SendHTTPRequest sends an unauthenticated HTTP request -func (b *Bithumb) SendHTTPRequest(ep exchange.URL, path string, result interface{}) error { +func (b *Bithumb) SendHTTPRequest(ctx context.Context, ep exchange.URL, path string, result interface{}) error { endpoint, err := b.API.Endpoints.GetURL(ep) if err != nil { return err @@ -493,13 +493,13 @@ func (b *Bithumb) SendHTTPRequest(ep exchange.URL, path string, result interface HTTPDebugging: b.HTTPDebugging, HTTPRecording: b.HTTPRecording, } - return b.SendPayload(context.Background(), request.Unset, func() (*request.Item, error) { + return b.SendPayload(ctx, request.Unset, func() (*request.Item, error) { return item, nil }) } // SendAuthenticatedHTTPRequest sends an authenticated HTTP request to bithumb -func (b *Bithumb) SendAuthenticatedHTTPRequest(ep exchange.URL, path string, params url.Values, result interface{}) error { +func (b *Bithumb) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, path string, params url.Values, result interface{}) error { if !b.AllowAuthenticatedRequest() { return fmt.Errorf("%s %w", b.Name, exchange.ErrAuthenticatedRequestWithoutCredentialsSet) } @@ -512,7 +512,7 @@ func (b *Bithumb) SendAuthenticatedHTTPRequest(ep exchange.URL, path string, par } var intermediary json.RawMessage - err = b.SendPayload(context.Background(), request.Auth, func() (*request.Item, error) { + err = b.SendPayload(ctx, request.Auth, func() (*request.Item, error) { // This is time window sensitive tnMS := time.Now().UnixNano() / int64(time.Millisecond) n := strconv.FormatInt(tnMS, 10) @@ -647,15 +647,15 @@ var errCode = map[string]string{ } // GetCandleStick returns candle stick data for requested pair -func (b *Bithumb) GetCandleStick(symbol, interval string) (resp OHLCVResponse, err error) { +func (b *Bithumb) GetCandleStick(ctx context.Context, symbol, interval string) (resp OHLCVResponse, err error) { path := publicCandleStick + symbol + "/" + interval - err = b.SendHTTPRequest(exchange.RestSpot, path, &resp) + err = b.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) return } // FetchExchangeLimits fetches spot order execution limits -func (b *Bithumb) FetchExchangeLimits() ([]order.MinMaxLevel, error) { - ticks, err := b.GetAllTickers() +func (b *Bithumb) FetchExchangeLimits(ctx context.Context) ([]order.MinMaxLevel, error) { + ticks, err := b.GetAllTickers(ctx) if err != nil { return nil, err } diff --git a/exchanges/bithumb/bithumb_test.go b/exchanges/bithumb/bithumb_test.go index a729f744..82200588 100644 --- a/exchanges/bithumb/bithumb_test.go +++ b/exchanges/bithumb/bithumb_test.go @@ -1,6 +1,7 @@ package bithumb import ( + "context" "errors" "log" "os" @@ -54,7 +55,7 @@ func TestMain(m *testing.M) { func TestGetTradablePairs(t *testing.T) { t.Parallel() - _, err := b.GetTradablePairs() + _, err := b.GetTradablePairs(context.Background()) if err != nil { t.Error("Bithumb GetTradablePairs() error", err) } @@ -62,7 +63,7 @@ func TestGetTradablePairs(t *testing.T) { func TestGetTicker(t *testing.T) { t.Parallel() - _, err := b.GetTicker(testCurrency) + _, err := b.GetTicker(context.Background(), testCurrency) if err != nil { t.Error("Bithumb GetTicker() error", err) } @@ -70,7 +71,7 @@ func TestGetTicker(t *testing.T) { func TestGetAllTickers(t *testing.T) { t.Parallel() - _, err := b.GetAllTickers() + _, err := b.GetAllTickers(context.Background()) if err != nil { t.Error("Bithumb GetAllTickers() error", err) } @@ -78,7 +79,7 @@ func TestGetAllTickers(t *testing.T) { func TestGetOrderBook(t *testing.T) { t.Parallel() - _, err := b.GetOrderBook(testCurrency) + _, err := b.GetOrderBook(context.Background(), testCurrency) if err != nil { t.Error("Bithumb GetOrderBook() error", err) } @@ -86,7 +87,7 @@ func TestGetOrderBook(t *testing.T) { func TestGetTransactionHistory(t *testing.T) { t.Parallel() - _, err := b.GetTransactionHistory(testCurrency) + _, err := b.GetTransactionHistory(context.Background(), testCurrency) if err != nil { t.Error("Bithumb GetTransactionHistory() error", err) } @@ -96,7 +97,7 @@ func TestGetAccountInformation(t *testing.T) { t.Parallel() // Offline test - _, err := b.GetAccountInformation("", "") + _, err := b.GetAccountInformation(context.Background(), "", "") if err == nil { t.Error("expected error when no order currency is specified") } @@ -105,7 +106,9 @@ func TestGetAccountInformation(t *testing.T) { t.Skip() } - _, err = b.GetAccountInformation(testCurrency, currency.KRW.String()) + _, err = b.GetAccountInformation(context.Background(), + testCurrency, + currency.KRW.String()) if err != nil { t.Error(err) } @@ -117,7 +120,7 @@ func TestGetAccountBalance(t *testing.T) { t.Skip() } - _, err := b.GetAccountBalance(testCurrency) + _, err := b.GetAccountBalance(context.Background(), testCurrency) if err == nil { t.Error("Bithumb GetAccountBalance() Expected error") } @@ -129,7 +132,7 @@ func TestGetWalletAddress(t *testing.T) { t.Skip() } - _, err := b.GetWalletAddress("") + _, err := b.GetWalletAddress(context.Background(), "") if err == nil { t.Error("Bithumb GetWalletAddress() Expected error") } @@ -137,7 +140,7 @@ func TestGetWalletAddress(t *testing.T) { func TestGetLastTransaction(t *testing.T) { t.Parallel() - _, err := b.GetLastTransaction() + _, err := b.GetLastTransaction(context.Background()) if err == nil { t.Error("Bithumb GetLastTransaction() Expected error") } @@ -145,7 +148,8 @@ func TestGetLastTransaction(t *testing.T) { func TestGetOrders(t *testing.T) { t.Parallel() - _, err := b.GetOrders("1337", order.Bid.Lower(), "100", "", testCurrency) + _, err := b.GetOrders(context.Background(), + "1337", order.Bid.Lower(), "100", "", testCurrency) if err == nil { t.Error("Bithumb GetOrders() Expected error") } @@ -153,7 +157,7 @@ func TestGetOrders(t *testing.T) { func TestGetUserTransactions(t *testing.T) { t.Parallel() - _, err := b.GetUserTransactions() + _, err := b.GetUserTransactions(context.Background()) if err == nil { t.Error("Bithumb GetUserTransactions() Expected error") } @@ -161,7 +165,8 @@ func TestGetUserTransactions(t *testing.T) { func TestPlaceTrade(t *testing.T) { t.Parallel() - _, err := b.PlaceTrade(testCurrency, order.Bid.Lower(), 0, 0) + _, err := b.PlaceTrade(context.Background(), + testCurrency, order.Bid.Lower(), 0, 0) if err == nil { t.Error("Bithumb PlaceTrade() Expected error") } @@ -169,7 +174,8 @@ func TestPlaceTrade(t *testing.T) { func TestGetOrderDetails(t *testing.T) { t.Parallel() - _, err := b.GetOrderDetails("1337", order.Bid.Lower(), testCurrency) + _, err := b.GetOrderDetails(context.Background(), + "1337", order.Bid.Lower(), testCurrency) if err == nil { t.Error("Bithumb GetOrderDetails() Expected error") } @@ -177,7 +183,7 @@ func TestGetOrderDetails(t *testing.T) { func TestCancelTrade(t *testing.T) { t.Parallel() - _, err := b.CancelTrade("", "", "") + _, err := b.CancelTrade(context.Background(), "", "", "") if err == nil { t.Error("Bithumb CancelTrade() Expected error") } @@ -185,7 +191,8 @@ func TestCancelTrade(t *testing.T) { func TestWithdrawCrypto(t *testing.T) { t.Parallel() - _, err := b.WithdrawCrypto("LQxiDhKU7idKiWQhx4ALKYkBx8xKEQVxJR", "", "ltc", 0) + _, err := b.WithdrawCrypto(context.Background(), + "LQxiDhKU7idKiWQhx4ALKYkBx8xKEQVxJR", "", "ltc", 0) if err == nil { t.Error("Bithumb WithdrawCrypto() Expected error") } @@ -196,7 +203,7 @@ func TestRequestKRWDepositDetails(t *testing.T) { if !areTestAPIKeysSet() { t.Skip() } - _, err := b.RequestKRWDepositDetails() + _, err := b.RequestKRWDepositDetails(context.Background()) if err == nil { t.Error("Bithumb RequestKRWDepositDetails() Expected error") } @@ -204,7 +211,8 @@ func TestRequestKRWDepositDetails(t *testing.T) { func TestRequestKRWWithdraw(t *testing.T) { t.Parallel() - _, err := b.RequestKRWWithdraw("102_bank", "1337", 1000) + _, err := b.RequestKRWWithdraw(context.Background(), + "102_bank", "1337", 1000) if err == nil { t.Error("Bithumb RequestKRWWithdraw() Expected error") } @@ -213,7 +221,7 @@ func TestRequestKRWWithdraw(t *testing.T) { func TestMarketBuyOrder(t *testing.T) { t.Parallel() p := currency.NewPair(currency.BTC, currency.KRW) - _, err := b.MarketBuyOrder(p, 0) + _, err := b.MarketBuyOrder(context.Background(), p, 0) if err == nil { t.Error("Bithumb MarketBuyOrder() Expected error") } @@ -222,7 +230,7 @@ func TestMarketBuyOrder(t *testing.T) { func TestMarketSellOrder(t *testing.T) { t.Parallel() p := currency.NewPair(currency.BTC, currency.KRW) - _, err := b.MarketSellOrder(p, 0) + _, err := b.MarketSellOrder(context.Background(), p, 0) if err == nil { t.Error("Bithumb MarketSellOrder() Expected error") } @@ -231,13 +239,13 @@ func TestMarketSellOrder(t *testing.T) { func TestUpdateTicker(t *testing.T) { t.Parallel() cp := currency.NewPair(currency.QTUM, currency.KRW) - _, err := b.UpdateTicker(cp, asset.Spot) + _, err := b.UpdateTicker(context.Background(), cp, asset.Spot) if err != nil { t.Fatal(err) } cp = currency.NewPair(currency.BTC, currency.KRW) - _, err = b.UpdateTicker(cp, asset.Spot) + _, err = b.UpdateTicker(context.Background(), cp, asset.Spot) if err != nil { t.Fatal(err) } @@ -245,7 +253,7 @@ func TestUpdateTicker(t *testing.T) { func TestUpdateTickers(t *testing.T) { t.Parallel() - err := b.UpdateTickers(asset.Spot) + err := b.UpdateTickers(context.Background(), asset.Spot) if err != nil { t.Fatal(err) } @@ -264,7 +272,7 @@ func setFeeBuilder() *exchange.FeeBuilder { func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { t.Parallel() var feeBuilder = setFeeBuilder() - _, err := b.GetFeeByType(feeBuilder) + _, err := b.GetFeeByType(context.Background(), feeBuilder) if err != nil { t.Fatal(err) } @@ -357,7 +365,7 @@ func TestGetActiveOrders(t *testing.T) { AssetType: asset.Spot, } - _, err := b.GetActiveOrders(&getOrdersRequest) + _, err := b.GetActiveOrders(context.Background(), &getOrdersRequest) if areTestAPIKeysSet() && err != nil { t.Errorf("Could not get open orders: %s", err) } else if !areTestAPIKeysSet() && err == nil { @@ -372,7 +380,7 @@ func TestGetOrderHistory(t *testing.T) { AssetType: asset.Spot, } - _, err := b.GetOrderHistory(&getOrdersRequest) + _, err := b.GetOrderHistory(context.Background(), &getOrdersRequest) if areTestAPIKeysSet() && err != nil { t.Errorf("Could not get order history: %s", err) } else if !areTestAPIKeysSet() && err == nil { @@ -404,7 +412,7 @@ func TestSubmitOrder(t *testing.T) { ClientID: "meowOrder", AssetType: asset.Spot, } - response, err := b.SubmitOrder(orderSubmission) + response, err := b.SubmitOrder(context.Background(), orderSubmission) if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) { t.Errorf("Order failed to be placed: %v", err) } else if !areTestAPIKeysSet() && err == nil { @@ -427,7 +435,7 @@ func TestCancelExchangeOrder(t *testing.T) { AssetType: asset.Spot, } - err := b.CancelOrder(orderCancellation) + err := b.CancelOrder(context.Background(), orderCancellation) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") } @@ -451,7 +459,7 @@ func TestCancelAllExchangeOrders(t *testing.T) { AssetType: asset.Spot, } - resp, err := b.CancelAllOrders(orderCancellation) + resp, err := b.CancelAllOrders(context.Background(), orderCancellation) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") @@ -468,12 +476,12 @@ func TestCancelAllExchangeOrders(t *testing.T) { func TestGetAccountInfo(t *testing.T) { t.Parallel() if areTestAPIKeysSet() { - _, err := b.UpdateAccountInfo(asset.Spot) + _, err := b.UpdateAccountInfo(context.Background(), asset.Spot) if err != nil { t.Error("Bithumb GetAccountInfo() error", err) } } else { - _, err := b.UpdateAccountInfo(asset.Spot) + _, err := b.UpdateAccountInfo(context.Background(), asset.Spot) if err == nil { t.Error("Bithumb GetAccountInfo() Expected error") } @@ -486,7 +494,7 @@ func TestModifyOrder(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = b.ModifyOrder(&order.Modify{ + _, err = b.ModifyOrder(context.Background(), &order.Modify{ ID: "1337", Price: 100, Amount: 1000, @@ -514,7 +522,8 @@ func TestWithdraw(t *testing.T) { }, } - _, err := b.WithdrawCryptocurrencyFunds(&withdrawCryptoRequest) + _, err := b.WithdrawCryptocurrencyFunds(context.Background(), + &withdrawCryptoRequest) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") } @@ -540,7 +549,7 @@ func TestWithdrawFiat(t *testing.T) { Description: "WITHDRAW IT ALL", } - _, err := b.WithdrawFiatFunds(&withdrawFiatRequest) + _, err := b.WithdrawFiatFunds(context.Background(), &withdrawFiatRequest) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") } @@ -556,7 +565,8 @@ func TestWithdrawInternationalBank(t *testing.T) { } var withdrawFiatRequest = withdraw.Request{} - _, err := b.WithdrawFiatFundsToInternationalBank(&withdrawFiatRequest) + _, err := b.WithdrawFiatFundsToInternationalBank(context.Background(), + &withdrawFiatRequest) if err != common.ErrFunctionNotSupported { t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err) } @@ -565,12 +575,12 @@ func TestWithdrawInternationalBank(t *testing.T) { func TestGetDepositAddress(t *testing.T) { t.Parallel() if areTestAPIKeysSet() { - _, err := b.GetDepositAddress(currency.BTC, "") + _, err := b.GetDepositAddress(context.Background(), currency.BTC, "") if err != nil { t.Error("GetDepositAddress() error", err) } } else { - _, err := b.GetDepositAddress(currency.BTC, "") + _, err := b.GetDepositAddress(context.Background(), currency.BTC, "") if err == nil { t.Error("GetDepositAddress() error cannot be nil") } @@ -579,7 +589,7 @@ func TestGetDepositAddress(t *testing.T) { func TestGetCandleStick(t *testing.T) { t.Parallel() - _, err := b.GetCandleStick("BTC_KRW", "1m") + _, err := b.GetCandleStick(context.Background(), "BTC_KRW", "1m") if err != nil { t.Fatal(err) } @@ -592,7 +602,8 @@ func TestGetHistoricCandles(t *testing.T) { t.Fatal(err) } startTime := time.Now().Add(-time.Hour * 24) - _, err = b.GetHistoricCandles(currencyPair, asset.Spot, startTime, time.Now(), kline.OneDay) + _, err = b.GetHistoricCandles(context.Background(), + currencyPair, asset.Spot, startTime, time.Now(), kline.OneDay) if err != nil { t.Fatal(err) } @@ -605,7 +616,8 @@ func TestGetHistoricCandlesExtended(t *testing.T) { t.Fatal(err) } startTime := time.Now().Add(-time.Hour * 24) - _, err = b.GetHistoricCandlesExtended(currencyPair, asset.Spot, startTime, time.Now(), kline.OneDay) + _, err = b.GetHistoricCandlesExtended(context.Background(), + currencyPair, asset.Spot, startTime, time.Now(), kline.OneDay) if err != nil { t.Fatal(err) } @@ -617,7 +629,7 @@ func TestGetRecentTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = b.GetRecentTrades(currencyPair, asset.Spot) + _, err = b.GetRecentTrades(context.Background(), currencyPair, asset.Spot) if err != nil { t.Error(err) } @@ -629,7 +641,8 @@ func TestGetHistoricTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = b.GetHistoricTrades(currencyPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) + _, err = b.GetHistoricTrades(context.Background(), + currencyPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) if err != nil && err != common.ErrFunctionNotSupported { t.Error(err) } @@ -637,7 +650,7 @@ func TestGetHistoricTrades(t *testing.T) { func TestUpdateOrderExecutionLimits(t *testing.T) { t.Parallel() - err := b.UpdateOrderExecutionLimits("") + err := b.UpdateOrderExecutionLimits(context.Background(), "") if err != nil { t.Fatal(err) } @@ -718,12 +731,12 @@ func TestGetAmountMinimum(t *testing.T) { func TestGetAssetStatus(t *testing.T) { t.Parallel() - _, err := b.GetAssetStatus("") + _, err := b.GetAssetStatus(context.Background(), "") if !errors.Is(err, errSymbolIsEmpty) { t.Fatalf("received: %v but expected: %v", err, errSymbolIsEmpty) } - _, err = b.GetAssetStatus("sol") + _, err = b.GetAssetStatus(context.Background(), "sol") if !errors.Is(err, nil) { t.Fatalf("received: %v but expected: %v", err, nil) } diff --git a/exchanges/bithumb/bithumb_wrapper.go b/exchanges/bithumb/bithumb_wrapper.go index 873c70c2..492135a3 100644 --- a/exchanges/bithumb/bithumb_wrapper.go +++ b/exchanges/bithumb/bithumb_wrapper.go @@ -1,6 +1,7 @@ package bithumb import ( + "context" "errors" "fmt" "math" @@ -45,7 +46,7 @@ func (b *Bithumb) GetDefaultConfig() (*config.ExchangeConfig, error) { } if b.Features.Supports.RESTCapabilities.AutoPairUpdates { - err = b.UpdateTradablePairs(true) + err = b.UpdateTradablePairs(context.TODO(), true) if err != nil { return nil, err } @@ -203,7 +204,7 @@ func (b *Bithumb) Run() { b.PrintEnabledPairs() } - err := b.UpdateOrderExecutionLimits("") + err := b.UpdateOrderExecutionLimits(context.TODO(), "") if err != nil { log.Errorf(log.ExchangeSys, "%s failed to set exchange order execution limits. Err: %v", @@ -215,15 +216,15 @@ func (b *Bithumb) Run() { return } - err = b.UpdateTradablePairs(false) + err = b.UpdateTradablePairs(context.TODO(), false) if err != nil { log.Errorf(log.ExchangeSys, "%s failed to update tradable pairs. Err: %s", b.Name, err) } } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (b *Bithumb) FetchTradablePairs(asset asset.Item) ([]string, error) { - currencies, err := b.GetTradablePairs() +func (b *Bithumb) FetchTradablePairs(ctx context.Context, asset asset.Item) ([]string, error) { + currencies, err := b.GetTradablePairs(ctx) if err != nil { return nil, err } @@ -237,8 +238,8 @@ func (b *Bithumb) FetchTradablePairs(asset asset.Item) ([]string, error) { // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (b *Bithumb) UpdateTradablePairs(forceUpdate bool) error { - pairs, err := b.FetchTradablePairs(asset.Spot) +func (b *Bithumb) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { + pairs, err := b.FetchTradablePairs(ctx, asset.Spot) if err != nil { return err } @@ -252,8 +253,8 @@ func (b *Bithumb) UpdateTradablePairs(forceUpdate bool) error { } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (b *Bithumb) UpdateTickers(a asset.Item) error { - tickers, err := b.GetAllTickers() +func (b *Bithumb) UpdateTickers(ctx context.Context, a asset.Item) error { + tickers, err := b.GetAllTickers(ctx) if err != nil { return err } @@ -287,8 +288,8 @@ func (b *Bithumb) UpdateTickers(a asset.Item) error { } // UpdateTicker updates and returns the ticker for a currency pair -func (b *Bithumb) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) { - err := b.UpdateTickers(a) +func (b *Bithumb) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { + err := b.UpdateTickers(ctx, a) if err != nil { return nil, err } @@ -296,25 +297,25 @@ func (b *Bithumb) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, er } // FetchTicker returns the ticker for a currency pair -func (b *Bithumb) FetchTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) { +func (b *Bithumb) FetchTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { tickerNew, err := ticker.GetTicker(b.Name, p, a) if err != nil { - return b.UpdateTicker(p, a) + return b.UpdateTicker(ctx, p, a) } return tickerNew, nil } // FetchOrderbook returns orderbook base on the currency pair -func (b *Bithumb) FetchOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (b *Bithumb) FetchOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { ob, err := orderbook.Get(b.Name, p, assetType) if err != nil { - return b.UpdateOrderbook(p, assetType) + return b.UpdateOrderbook(ctx, p, assetType) } return ob, nil } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (b *Bithumb) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (b *Bithumb) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { book := &orderbook.Base{ Exchange: b.Name, Pair: p, @@ -323,7 +324,7 @@ func (b *Bithumb) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*order } curr := p.Base.String() - orderbookNew, err := b.GetOrderBook(curr) + orderbookNew, err := b.GetOrderBook(ctx, curr) if err != nil { return book, err } @@ -353,9 +354,9 @@ func (b *Bithumb) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*order // UpdateAccountInfo retrieves balances for all enabled currencies for the // Bithumb exchange -func (b *Bithumb) UpdateAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (b *Bithumb) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { var info account.Holdings - bal, err := b.GetAccountBalance("ALL") + bal, err := b.GetAccountBalance(ctx, "ALL") if err != nil { return info, err } @@ -390,10 +391,10 @@ func (b *Bithumb) UpdateAccountInfo(assetType asset.Item) (account.Holdings, err } // FetchAccountInfo retrieves balances for all enabled currencies -func (b *Bithumb) FetchAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (b *Bithumb) FetchAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { acc, err := account.GetHoldings(b.Name, assetType) if err != nil { - return b.UpdateAccountInfo(assetType) + return b.UpdateAccountInfo(ctx, assetType) } return acc, nil @@ -401,23 +402,23 @@ func (b *Bithumb) FetchAccountInfo(assetType asset.Item) (account.Holdings, erro // GetFundingHistory returns funding history, deposits and // withdrawals -func (b *Bithumb) GetFundingHistory() ([]exchange.FundHistory, error) { +func (b *Bithumb) GetFundingHistory(ctx context.Context) ([]exchange.FundHistory, error) { return nil, common.ErrFunctionNotSupported } // GetWithdrawalsHistory returns previous withdrawals data -func (b *Bithumb) GetWithdrawalsHistory(c currency.Code) (resp []exchange.WithdrawalHistory, err error) { +func (b *Bithumb) GetWithdrawalsHistory(ctx context.Context, c currency.Code) (resp []exchange.WithdrawalHistory, err error) { return nil, common.ErrNotYetImplemented } // GetRecentTrades returns the most recent trades for a currency and asset -func (b *Bithumb) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade.Data, error) { +func (b *Bithumb) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { var err error p, err = b.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err } - tradeData, err := b.GetTransactionHistory(p.String()) + tradeData, err := b.GetTransactionHistory(ctx, p.String()) if err != nil { return nil, err } @@ -454,13 +455,13 @@ func (b *Bithumb) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trad } // GetHistoricTrades returns historic trade data within the timeframe provided -func (b *Bithumb) GetHistoricTrades(_ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { +func (b *Bithumb) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { return nil, common.ErrFunctionNotSupported } // SubmitOrder submits a new order // TODO: Fill this out to support limit orders -func (b *Bithumb) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { +func (b *Bithumb) SubmitOrder(ctx context.Context, s *order.Submit) (order.SubmitResponse, error) { var submitOrderResponse order.SubmitResponse if err := s.Validate(); err != nil { return submitOrderResponse, err @@ -474,14 +475,14 @@ func (b *Bithumb) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { var orderID string if s.Side == order.Buy { var result MarketBuy - result, err = b.MarketBuyOrder(fPair, s.Amount) + result, err = b.MarketBuyOrder(ctx, fPair, s.Amount) if err != nil { return submitOrderResponse, err } orderID = result.OrderID } else if s.Side == order.Sell { var result MarketSell - result, err = b.MarketSellOrder(fPair, s.Amount) + result, err = b.MarketSellOrder(ctx, fPair, s.Amount) if err != nil { return submitOrderResponse, err } @@ -498,12 +499,13 @@ func (b *Bithumb) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (b *Bithumb) ModifyOrder(action *order.Modify) (order.Modify, error) { +func (b *Bithumb) ModifyOrder(ctx context.Context, action *order.Modify) (order.Modify, error) { if err := action.Validate(); err != nil { return order.Modify{}, err } - o, err := b.ModifyTrade(action.ID, + o, err := b.ModifyTrade(ctx, + action.ID, action.Pair.Base.String(), action.Side.Lower(), action.Amount, @@ -526,24 +528,24 @@ func (b *Bithumb) ModifyOrder(action *order.Modify) (order.Modify, error) { } // CancelOrder cancels an order by its corresponding ID number -func (b *Bithumb) CancelOrder(o *order.Cancel) error { +func (b *Bithumb) CancelOrder(ctx context.Context, o *order.Cancel) error { if err := o.Validate(o.StandardCancel()); err != nil { return err } - _, err := b.CancelTrade(o.Side.String(), + _, err := b.CancelTrade(ctx, o.Side.String(), o.ID, o.Pair.Base.String()) return err } // CancelBatchOrders cancels an orders by their corresponding ID numbers -func (b *Bithumb) CancelBatchOrders(o []order.Cancel) (order.CancelBatchResponse, error) { +func (b *Bithumb) CancelBatchOrders(ctx context.Context, o []order.Cancel) (order.CancelBatchResponse, error) { return order.CancelBatchResponse{}, common.ErrNotYetImplemented } // CancelAllOrders cancels all orders associated with a currency pair -func (b *Bithumb) CancelAllOrders(orderCancellation *order.Cancel) (order.CancelAllResponse, error) { +func (b *Bithumb) CancelAllOrders(ctx context.Context, orderCancellation *order.Cancel) (order.CancelAllResponse, error) { if err := orderCancellation.Validate(); err != nil { return order.CancelAllResponse{}, err } @@ -559,7 +561,8 @@ func (b *Bithumb) CancelAllOrders(orderCancellation *order.Cancel) (order.Cancel } for i := range currs { - orders, err := b.GetOrders("", + orders, err := b.GetOrders(ctx, + "", orderCancellation.Side.String(), "100", "", @@ -571,7 +574,8 @@ func (b *Bithumb) CancelAllOrders(orderCancellation *order.Cancel) (order.Cancel } for i := range allOrders { - _, err := b.CancelTrade(orderCancellation.Side.String(), + _, err := b.CancelTrade(ctx, + orderCancellation.Side.String(), allOrders[i].OrderID, orderCancellation.Pair.Base.String()) if err != nil { @@ -583,14 +587,14 @@ func (b *Bithumb) CancelAllOrders(orderCancellation *order.Cancel) (order.Cancel } // GetOrderInfo returns order information based on order ID -func (b *Bithumb) GetOrderInfo(orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { +func (b *Bithumb) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { var orderDetail order.Detail return orderDetail, common.ErrNotYetImplemented } // GetDepositAddress returns a deposit address for a specified currency -func (b *Bithumb) GetDepositAddress(cryptocurrency currency.Code, _ string) (string, error) { - addr, err := b.GetWalletAddress(cryptocurrency.String()) +func (b *Bithumb) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _ string) (string, error) { + addr, err := b.GetWalletAddress(ctx, cryptocurrency.String()) if err != nil { return "", err } @@ -600,11 +604,12 @@ func (b *Bithumb) GetDepositAddress(cryptocurrency currency.Code, _ string) (str // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is // submitted -func (b *Bithumb) WithdrawCryptocurrencyFunds(withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (b *Bithumb) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } - v, err := b.WithdrawCrypto(withdrawRequest.Crypto.Address, + v, err := b.WithdrawCrypto(ctx, + withdrawRequest.Crypto.Address, withdrawRequest.Crypto.AddressTag, withdrawRequest.Currency.String(), withdrawRequest.Amount) @@ -619,7 +624,7 @@ func (b *Bithumb) WithdrawCryptocurrencyFunds(withdrawRequest *withdraw.Request) // WithdrawFiatFunds returns a withdrawal ID when a // withdrawal is submitted -func (b *Bithumb) WithdrawFiatFunds(withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (b *Bithumb) WithdrawFiatFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } @@ -631,7 +636,10 @@ func (b *Bithumb) WithdrawFiatFunds(withdrawRequest *withdraw.Request) (*withdra } bankDetails := strconv.FormatFloat(withdrawRequest.Fiat.Bank.BankCode, 'f', -1, 64) + "_" + withdrawRequest.Fiat.Bank.BankName - resp, err := b.RequestKRWWithdraw(bankDetails, withdrawRequest.Fiat.Bank.AccountNumber, int64(withdrawRequest.Amount)) + resp, err := b.RequestKRWWithdraw(ctx, + bankDetails, + withdrawRequest.Fiat.Bank.AccountNumber, + int64(withdrawRequest.Amount)) if err != nil { return nil, err } @@ -645,12 +653,12 @@ func (b *Bithumb) WithdrawFiatFunds(withdrawRequest *withdraw.Request) (*withdra } // WithdrawFiatFundsToInternationalBank is not supported as Bithumb only withdraws KRW to South Korean banks -func (b *Bithumb) WithdrawFiatFundsToInternationalBank(_ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (b *Bithumb) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // GetFeeByType returns an estimate of fee based on type of transaction -func (b *Bithumb) GetFeeByType(feeBuilder *exchange.FeeBuilder) (float64, error) { +func (b *Bithumb) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { if !b.AllowAuthenticatedRequest() && // Todo check connection status feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { feeBuilder.FeeType = exchange.OfflineTradeFee @@ -659,7 +667,7 @@ func (b *Bithumb) GetFeeByType(feeBuilder *exchange.FeeBuilder) (float64, error) } // GetActiveOrders retrieves any orders that are active/open -func (b *Bithumb) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, error) { +func (b *Bithumb) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) { if err := req.Validate(); err != nil { return nil, err } @@ -675,7 +683,7 @@ func (b *Bithumb) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, var orders []order.Detail for x := range req.Pairs { - resp, err := b.GetOrders("", "", "1000", "", req.Pairs[x].Base.String()) + resp, err := b.GetOrders(ctx, "", "", "1000", "", req.Pairs[x].Base.String()) if err != nil { return nil, err } @@ -717,7 +725,7 @@ func (b *Bithumb) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, // GetOrderHistory retrieves account order information // Can Limit response to specific order status -func (b *Bithumb) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, error) { +func (b *Bithumb) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) { if err := req.Validate(); err != nil { return nil, err } @@ -733,7 +741,7 @@ func (b *Bithumb) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, var orders []order.Detail for x := range req.Pairs { - resp, err := b.GetOrders("", "", "1000", "", req.Pairs[x].Base.String()) + resp, err := b.GetOrders(ctx, "", "", "1000", "", req.Pairs[x].Base.String()) if err != nil { return nil, err } @@ -774,8 +782,8 @@ func (b *Bithumb) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, // ValidateCredentials validates current credentials used for wrapper // functionality -func (b *Bithumb) ValidateCredentials(assetType asset.Item) error { - _, err := b.UpdateAccountInfo(assetType) +func (b *Bithumb) ValidateCredentials(ctx context.Context, assetType asset.Item) error { + _, err := b.UpdateAccountInfo(ctx, assetType) return b.CheckTransientError(err) } @@ -785,7 +793,7 @@ func (b *Bithumb) FormatExchangeKlineInterval(in kline.Interval) string { } // GetHistoricCandles returns candles between a time period for a set time interval -func (b *Bithumb) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (b *Bithumb) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { if err := b.ValidateKline(pair, a, interval); err != nil { return kline.Item{}, err } @@ -795,7 +803,7 @@ func (b *Bithumb) GetHistoricCandles(pair currency.Pair, a asset.Item, start, en return kline.Item{}, err } - candle, err := b.GetCandleStick(formattedPair.String(), + candle, err := b.GetCandleStick(ctx, formattedPair.String(), b.FormatExchangeKlineInterval(interval)) if err != nil { return kline.Item{}, err @@ -871,13 +879,13 @@ func (b *Bithumb) GetHistoricCandles(pair currency.Pair, a asset.Item, start, en } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (b *Bithumb) GetHistoricCandlesExtended(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { - return b.GetHistoricCandles(pair, a, start, end, interval) +func (b *Bithumb) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { + return b.GetHistoricCandles(ctx, pair, a, start, end, interval) } // UpdateOrderExecutionLimits sets exchange executions for a required asset type -func (b *Bithumb) UpdateOrderExecutionLimits(_ asset.Item) error { - limits, err := b.FetchExchangeLimits() +func (b *Bithumb) UpdateOrderExecutionLimits(ctx context.Context, _ asset.Item) error { + limits, err := b.FetchExchangeLimits(ctx) if err != nil { return fmt.Errorf("cannot update exchange execution limits: %w", err) } diff --git a/exchanges/bithumb/bithumb_ws_orderbook.go b/exchanges/bithumb/bithumb_ws_orderbook.go index cd9a7c54..b00cec7c 100644 --- a/exchanges/bithumb/bithumb_ws_orderbook.go +++ b/exchanges/bithumb/bithumb_ws_orderbook.go @@ -1,6 +1,7 @@ package bithumb import ( + "context" "errors" "fmt" "time" @@ -139,7 +140,7 @@ func (b *Bithumb) SynchroniseWebsocketOrderbook() { // processJob fetches and processes orderbook updates func (b *Bithumb) processJob(p currency.Pair) error { - err := b.SeedLocalCache(p) + err := b.SeedLocalCache(context.TODO(), p) if err != nil { return fmt.Errorf("%s %s seeding local cache for orderbook error: %v", p, asset.Spot, err) @@ -414,8 +415,8 @@ bufferEmpty: } // SeedLocalCache seeds depth data -func (b *Bithumb) SeedLocalCache(p currency.Pair) error { - ob, err := b.GetOrderBook(p.String()) +func (b *Bithumb) SeedLocalCache(ctx context.Context, p currency.Pair) error { + ob, err := b.GetOrderBook(ctx, p.String()) if err != nil { return err } diff --git a/exchanges/bitmex/bitmex.go b/exchanges/bitmex/bitmex.go index adbc6da9..bb081686 100644 --- a/exchanges/bitmex/bitmex.go +++ b/exchanges/bitmex/bitmex.go @@ -104,104 +104,104 @@ const ( ) // GetAnnouncement returns the general announcements from Bitmex -func (b *Bitmex) GetAnnouncement() ([]Announcement, error) { +func (b *Bitmex) GetAnnouncement(ctx context.Context) ([]Announcement, error) { var announcement []Announcement - return announcement, b.SendHTTPRequest(exchange.RestSpot, bitmexEndpointAnnouncement, + return announcement, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointAnnouncement, nil, &announcement) } // GetUrgentAnnouncement returns an urgent announcement for your account -func (b *Bitmex) GetUrgentAnnouncement() ([]Announcement, error) { +func (b *Bitmex) GetUrgentAnnouncement(ctx context.Context) ([]Announcement, error) { var announcement []Announcement - return announcement, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, + return announcement, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, bitmexEndpointAnnouncementUrgent, nil, &announcement) } // GetAPIKeys returns the APIkeys from bitmex -func (b *Bitmex) GetAPIKeys() ([]APIKey, error) { +func (b *Bitmex) GetAPIKeys(ctx context.Context) ([]APIKey, error) { var keys []APIKey - return keys, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, + return keys, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, bitmexEndpointAPIkeys, nil, &keys) } // RemoveAPIKey removes an Apikey from the bitmex trading engine -func (b *Bitmex) RemoveAPIKey(params APIKeyParams) (bool, error) { +func (b *Bitmex) RemoveAPIKey(ctx context.Context, params APIKeyParams) (bool, error) { var keyDeleted bool - return keyDeleted, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodDelete, + return keyDeleted, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodDelete, bitmexEndpointAPIkeys, ¶ms, &keyDeleted) } // DisableAPIKey disables an Apikey from the bitmex trading engine -func (b *Bitmex) DisableAPIKey(params APIKeyParams) (APIKey, error) { +func (b *Bitmex) DisableAPIKey(ctx context.Context, params APIKeyParams) (APIKey, error) { var keyInfo APIKey - return keyInfo, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return keyInfo, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitmexEndpointDisableAPIkey, ¶ms, &keyInfo) } // EnableAPIKey enables an Apikey from the bitmex trading engine -func (b *Bitmex) EnableAPIKey(params APIKeyParams) (APIKey, error) { +func (b *Bitmex) EnableAPIKey(ctx context.Context, params APIKeyParams) (APIKey, error) { var keyInfo APIKey - return keyInfo, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return keyInfo, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitmexEndpointEnableAPIkey, ¶ms, &keyInfo) } // GetTrollboxMessages returns messages from the bitmex trollbox -func (b *Bitmex) GetTrollboxMessages(params ChatGetParams) ([]Chat, error) { +func (b *Bitmex) GetTrollboxMessages(ctx context.Context, params ChatGetParams) ([]Chat, error) { var messages []Chat - return messages, b.SendHTTPRequest(exchange.RestSpot, bitmexEndpointTrollbox, ¶ms, &messages) + return messages, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointTrollbox, ¶ms, &messages) } // SendTrollboxMessage sends a message to the bitmex trollbox -func (b *Bitmex) SendTrollboxMessage(params ChatSendParams) ([]Chat, error) { +func (b *Bitmex) SendTrollboxMessage(ctx context.Context, params ChatSendParams) ([]Chat, error) { var messages []Chat - return messages, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return messages, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitmexEndpointTrollboxSend, ¶ms, &messages) } // GetTrollboxChannels the channels from the the bitmex trollbox -func (b *Bitmex) GetTrollboxChannels() ([]ChatChannel, error) { +func (b *Bitmex) GetTrollboxChannels(ctx context.Context) ([]ChatChannel, error) { var channels []ChatChannel - return channels, b.SendHTTPRequest(exchange.RestSpot, bitmexEndpointTrollboxChannels, + return channels, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointTrollboxChannels, nil, &channels) } // GetTrollboxConnectedUsers the channels from the the bitmex trollbox -func (b *Bitmex) GetTrollboxConnectedUsers() (ConnectedUsers, error) { +func (b *Bitmex) GetTrollboxConnectedUsers(ctx context.Context) (ConnectedUsers, error) { var users ConnectedUsers - return users, b.SendHTTPRequest(exchange.RestSpot, bitmexEndpointTrollboxConnected, nil, &users) + return users, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointTrollboxConnected, nil, &users) } // GetAccountExecutions returns all raw transactions, which includes order // opening and cancelation, and order status changes. It can be quite noisy. // More focused information is available at /execution/tradeHistory. -func (b *Bitmex) GetAccountExecutions(params *GenericRequestParams) ([]Execution, error) { +func (b *Bitmex) GetAccountExecutions(ctx context.Context, params *GenericRequestParams) ([]Execution, error) { var executionList []Execution - return executionList, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, + return executionList, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, bitmexEndpointExecution, params, &executionList) @@ -209,17 +209,17 @@ func (b *Bitmex) GetAccountExecutions(params *GenericRequestParams) ([]Execution // GetAccountExecutionTradeHistory returns all balance-affecting executions. // This includes each trade, insurance charge, and settlement. -func (b *Bitmex) GetAccountExecutionTradeHistory(params *GenericRequestParams) ([]Execution, error) { +func (b *Bitmex) GetAccountExecutionTradeHistory(ctx context.Context, params *GenericRequestParams) ([]Execution, error) { var tradeHistory []Execution - return tradeHistory, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, + return tradeHistory, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, bitmexEndpointExecutionTradeHistory, params, &tradeHistory) } // GetFullFundingHistory returns funding history -func (b *Bitmex) GetFullFundingHistory(symbol, count, filter, columns, start string, reverse bool, startTime, endTime time.Time) ([]Funding, error) { +func (b *Bitmex) GetFullFundingHistory(ctx context.Context, symbol, count, filter, columns, start string, reverse bool, startTime, endTime time.Time) ([]Funding, error) { var fundingHistory []Funding params := url.Values{} params.Set("symbol", symbol) @@ -238,50 +238,50 @@ func (b *Bitmex) GetFullFundingHistory(symbol, count, filter, columns, start str params.Set("startTime", startTime.Format(time.RFC3339)) params.Set("endTime", endTime.Format(time.RFC3339)) } - return fundingHistory, b.SendHTTPRequest(exchange.RestSpot, bitmexEndpointFundingHistory+params.Encode(), + return fundingHistory, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointFundingHistory+params.Encode(), nil, &fundingHistory) } // GetInstruments returns instrument data -func (b *Bitmex) GetInstruments(params *GenericRequestParams) ([]Instrument, error) { +func (b *Bitmex) GetInstruments(ctx context.Context, params *GenericRequestParams) ([]Instrument, error) { var instruments []Instrument - return instruments, b.SendHTTPRequest(exchange.RestSpot, bitmexEndpointInstruments, + return instruments, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointInstruments, params, &instruments) } // GetActiveInstruments returns active instruments -func (b *Bitmex) GetActiveInstruments(params *GenericRequestParams) ([]Instrument, error) { +func (b *Bitmex) GetActiveInstruments(ctx context.Context, params *GenericRequestParams) ([]Instrument, error) { var activeInstruments []Instrument - return activeInstruments, b.SendHTTPRequest(exchange.RestSpot, bitmexEndpointActiveInstruments, + return activeInstruments, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointActiveInstruments, params, &activeInstruments) } // GetActiveAndIndexInstruments returns all active instruments and all indices -func (b *Bitmex) GetActiveAndIndexInstruments() ([]Instrument, error) { +func (b *Bitmex) GetActiveAndIndexInstruments(ctx context.Context) ([]Instrument, error) { var activeAndIndices []Instrument return activeAndIndices, - b.SendHTTPRequest(exchange.RestSpot, bitmexEndpointActiveAndIndexInstruments, + b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointActiveAndIndexInstruments, nil, &activeAndIndices) } // GetActiveIntervals returns funding history -func (b *Bitmex) GetActiveIntervals() (InstrumentInterval, error) { +func (b *Bitmex) GetActiveIntervals(ctx context.Context) (InstrumentInterval, error) { var interval InstrumentInterval - return interval, b.SendHTTPRequest(exchange.RestSpot, bitmexEndpointActiveIntervals, + return interval, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointActiveIntervals, nil, &interval) } // GetCompositeIndex returns composite index -func (b *Bitmex) GetCompositeIndex(symbol, count, filter, columns, start, reverse string, startTime, endTime time.Time) ([]IndexComposite, error) { +func (b *Bitmex) GetCompositeIndex(ctx context.Context, symbol, count, filter, columns, start, reverse string, startTime, endTime time.Time) ([]IndexComposite, error) { var compositeIndices []IndexComposite params := url.Values{} params.Set("symbol", symbol) @@ -307,82 +307,82 @@ func (b *Bitmex) GetCompositeIndex(symbol, count, filter, columns, start, revers params.Set("startTime", startTime.Format(time.RFC3339)) params.Set("endTime", endTime.Format(time.RFC3339)) } - return compositeIndices, b.SendHTTPRequest(exchange.RestSpot, bitmexEndpointCompositeIndex+"?"+params.Encode(), + return compositeIndices, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointCompositeIndex+"?"+params.Encode(), nil, &compositeIndices) } // GetIndices returns all price indices -func (b *Bitmex) GetIndices() ([]Instrument, error) { +func (b *Bitmex) GetIndices(ctx context.Context) ([]Instrument, error) { var indices []Instrument - return indices, b.SendHTTPRequest(exchange.RestSpot, bitmexEndpointIndices, nil, &indices) + return indices, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointIndices, nil, &indices) } // GetInsuranceFundHistory returns insurance fund history -func (b *Bitmex) GetInsuranceFundHistory(params *GenericRequestParams) ([]Insurance, error) { +func (b *Bitmex) GetInsuranceFundHistory(ctx context.Context, params *GenericRequestParams) ([]Insurance, error) { var history []Insurance - return history, b.SendHTTPRequest(exchange.RestSpot, bitmexEndpointIndices, params, &history) + return history, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointIndices, params, &history) } // GetLeaderboard returns leaderboard information -func (b *Bitmex) GetLeaderboard(params LeaderboardGetParams) ([]Leaderboard, error) { +func (b *Bitmex) GetLeaderboard(ctx context.Context, params LeaderboardGetParams) ([]Leaderboard, error) { var leader []Leaderboard - return leader, b.SendHTTPRequest(exchange.RestSpot, bitmexEndpointLeader, params, &leader) + return leader, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointLeader, params, &leader) } // GetAliasOnLeaderboard returns your alias on the leaderboard -func (b *Bitmex) GetAliasOnLeaderboard() (Alias, error) { +func (b *Bitmex) GetAliasOnLeaderboard(ctx context.Context) (Alias, error) { var alias Alias - return alias, b.SendHTTPRequest(exchange.RestSpot, bitmexEndpointAlias, nil, &alias) + return alias, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointAlias, nil, &alias) } // GetLiquidationOrders returns liquidation orders -func (b *Bitmex) GetLiquidationOrders(params *GenericRequestParams) ([]Liquidation, error) { +func (b *Bitmex) GetLiquidationOrders(ctx context.Context, params *GenericRequestParams) ([]Liquidation, error) { var orders []Liquidation - return orders, b.SendHTTPRequest(exchange.RestSpot, bitmexEndpointLiquidation, + return orders, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointLiquidation, params, &orders) } // GetCurrentNotifications returns your current notifications -func (b *Bitmex) GetCurrentNotifications() ([]Notification, error) { +func (b *Bitmex) GetCurrentNotifications(ctx context.Context) ([]Notification, error) { var notifications []Notification - return notifications, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, + return notifications, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, bitmexEndpointNotifications, nil, ¬ifications) } // GetOrders returns all the orders, open and closed -func (b *Bitmex) GetOrders(params *OrdersRequest) ([]Order, error) { +func (b *Bitmex) GetOrders(ctx context.Context, params *OrdersRequest) ([]Order, error) { var orders []Order - return orders, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, + return orders, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, bitmexEndpointOrder, params, &orders) } // AmendOrder amends the quantity or price of an open order -func (b *Bitmex) AmendOrder(params *OrderAmendParams) (Order, error) { +func (b *Bitmex) AmendOrder(ctx context.Context, params *OrderAmendParams) (Order, error) { var order Order - return order, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPut, + return order, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPut, bitmexEndpointOrder, params, &order) } // CreateOrder creates a new order -func (b *Bitmex) CreateOrder(params *OrderNewParams) (Order, error) { +func (b *Bitmex) CreateOrder(ctx context.Context, params *OrderNewParams) (Order, error) { var orderInfo Order - return orderInfo, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return orderInfo, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitmexEndpointOrder, params, &orderInfo) @@ -390,223 +390,223 @@ func (b *Bitmex) CreateOrder(params *OrderNewParams) (Order, error) { // CancelOrders cancels one or a batch of orders on the exchange and returns // a cancelled order list -func (b *Bitmex) CancelOrders(params *OrderCancelParams) ([]Order, error) { +func (b *Bitmex) CancelOrders(ctx context.Context, params *OrderCancelParams) ([]Order, error) { var cancelledOrders []Order - return cancelledOrders, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodDelete, + return cancelledOrders, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodDelete, bitmexEndpointOrder, params, &cancelledOrders) } // CancelAllExistingOrders cancels all open orders on the exchange -func (b *Bitmex) CancelAllExistingOrders(params OrderCancelAllParams) ([]Order, error) { +func (b *Bitmex) CancelAllExistingOrders(ctx context.Context, params OrderCancelAllParams) ([]Order, error) { var cancelledOrders []Order - return cancelledOrders, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodDelete, + return cancelledOrders, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodDelete, bitmexEndpointCancelAllOrders, params, &cancelledOrders) } // AmendBulkOrders amends multiple orders for the same symbol -func (b *Bitmex) AmendBulkOrders(params OrderAmendBulkParams) ([]Order, error) { +func (b *Bitmex) AmendBulkOrders(ctx context.Context, params OrderAmendBulkParams) ([]Order, error) { var amendedOrders []Order - return amendedOrders, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPut, + return amendedOrders, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPut, bitmexEndpointBulk, params, &amendedOrders) } // CreateBulkOrders creates multiple orders for the same symbol -func (b *Bitmex) CreateBulkOrders(params OrderNewBulkParams) ([]Order, error) { +func (b *Bitmex) CreateBulkOrders(ctx context.Context, params OrderNewBulkParams) ([]Order, error) { var orders []Order - return orders, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return orders, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitmexEndpointBulk, params, &orders) } // CancelAllOrdersAfterTime closes all positions after a certain time period -func (b *Bitmex) CancelAllOrdersAfterTime(params OrderCancelAllAfterParams) ([]Order, error) { +func (b *Bitmex) CancelAllOrdersAfterTime(ctx context.Context, params OrderCancelAllAfterParams) ([]Order, error) { var cancelledOrder []Order - return cancelledOrder, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return cancelledOrder, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitmexEndpointCancelOrderAfter, params, &cancelledOrder) } // ClosePosition closes a position WARNING deprecated use /order endpoint -func (b *Bitmex) ClosePosition(params OrderClosePositionParams) ([]Order, error) { +func (b *Bitmex) ClosePosition(ctx context.Context, params OrderClosePositionParams) ([]Order, error) { var closedPositions []Order - return closedPositions, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return closedPositions, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitmexEndpointOrder, params, &closedPositions) } // GetOrderbook returns layer two orderbook data -func (b *Bitmex) GetOrderbook(params OrderBookGetL2Params) ([]OrderBookL2, error) { +func (b *Bitmex) GetOrderbook(ctx context.Context, params OrderBookGetL2Params) ([]OrderBookL2, error) { var orderBooks []OrderBookL2 - return orderBooks, b.SendHTTPRequest(exchange.RestSpot, bitmexEndpointOrderbookL2, + return orderBooks, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointOrderbookL2, params, &orderBooks) } // GetPositions returns positions -func (b *Bitmex) GetPositions(params PositionGetParams) ([]Position, error) { +func (b *Bitmex) GetPositions(ctx context.Context, params PositionGetParams) ([]Position, error) { var positions []Position - return positions, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, + return positions, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, bitmexEndpointPosition, params, &positions) } // IsolatePosition enables isolated margin or cross margin per-position -func (b *Bitmex) IsolatePosition(params PositionIsolateMarginParams) (Position, error) { +func (b *Bitmex) IsolatePosition(ctx context.Context, params PositionIsolateMarginParams) (Position, error) { var position Position - return position, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return position, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitmexEndpointIsolatePosition, params, &position) } // LeveragePosition chooses leverage for a position -func (b *Bitmex) LeveragePosition(params PositionUpdateLeverageParams) (Position, error) { +func (b *Bitmex) LeveragePosition(ctx context.Context, params PositionUpdateLeverageParams) (Position, error) { var position Position - return position, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return position, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitmexEndpointLeveragePosition, params, &position) } // UpdateRiskLimit updates risk limit on a position -func (b *Bitmex) UpdateRiskLimit(params PositionUpdateRiskLimitParams) (Position, error) { +func (b *Bitmex) UpdateRiskLimit(ctx context.Context, params PositionUpdateRiskLimitParams) (Position, error) { var position Position - return position, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return position, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitmexEndpointAdjustRiskLimit, params, &position) } // TransferMargin transfers equity in or out of a position -func (b *Bitmex) TransferMargin(params PositionTransferIsolatedMarginParams) (Position, error) { +func (b *Bitmex) TransferMargin(ctx context.Context, params PositionTransferIsolatedMarginParams) (Position, error) { var position Position - return position, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return position, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitmexEndpointTransferMargin, params, &position) } // GetQuotes returns quotations -func (b *Bitmex) GetQuotes(params *GenericRequestParams) ([]Quote, error) { +func (b *Bitmex) GetQuotes(ctx context.Context, params *GenericRequestParams) ([]Quote, error) { var quotations []Quote - return quotations, b.SendHTTPRequest(exchange.RestSpot, bitmexEndpointQuote, + return quotations, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointQuote, params, "ations) } // GetQuotesByBuckets returns previous quotes in time buckets -func (b *Bitmex) GetQuotesByBuckets(params *QuoteGetBucketedParams) ([]Quote, error) { +func (b *Bitmex) GetQuotesByBuckets(ctx context.Context, params *QuoteGetBucketedParams) ([]Quote, error) { var quotations []Quote - return quotations, b.SendHTTPRequest(exchange.RestSpot, bitmexEndpointQuoteBucketed, + return quotations, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointQuoteBucketed, params, "ations) } // GetSettlementHistory returns settlement history -func (b *Bitmex) GetSettlementHistory(params *GenericRequestParams) ([]Settlement, error) { +func (b *Bitmex) GetSettlementHistory(ctx context.Context, params *GenericRequestParams) ([]Settlement, error) { var history []Settlement - return history, b.SendHTTPRequest(exchange.RestSpot, bitmexEndpointSettlement, + return history, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointSettlement, params, &history) } // GetStats returns exchange wide per series turnover and volume statistics -func (b *Bitmex) GetStats() ([]Stats, error) { +func (b *Bitmex) GetStats(ctx context.Context) ([]Stats, error) { var stats []Stats - return stats, b.SendHTTPRequest(exchange.RestSpot, bitmexEndpointStats, nil, &stats) + return stats, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointStats, nil, &stats) } // GetStatsHistorical historic stats -func (b *Bitmex) GetStatsHistorical() ([]StatsHistory, error) { +func (b *Bitmex) GetStatsHistorical(ctx context.Context) ([]StatsHistory, error) { var history []StatsHistory - return history, b.SendHTTPRequest(exchange.RestSpot, bitmexEndpointStatsHistory, nil, &history) + return history, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointStatsHistory, nil, &history) } // GetStatSummary returns the stats summary in USD terms -func (b *Bitmex) GetStatSummary() ([]StatsUSD, error) { +func (b *Bitmex) GetStatSummary(ctx context.Context) ([]StatsUSD, error) { var summary []StatsUSD - return summary, b.SendHTTPRequest(exchange.RestSpot, bitmexEndpointStatsSummary, nil, &summary) + return summary, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointStatsSummary, nil, &summary) } // GetTrade returns executed trades on the desk -func (b *Bitmex) GetTrade(params *GenericRequestParams) ([]Trade, error) { +func (b *Bitmex) GetTrade(ctx context.Context, params *GenericRequestParams) ([]Trade, error) { var trade []Trade - return trade, b.SendHTTPRequest(exchange.RestSpot, bitmexEndpointTrade, params, &trade) + return trade, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointTrade, params, &trade) } // GetPreviousTrades previous trade history in time buckets -func (b *Bitmex) GetPreviousTrades(params *TradeGetBucketedParams) ([]Trade, error) { +func (b *Bitmex) GetPreviousTrades(ctx context.Context, params *TradeGetBucketedParams) ([]Trade, error) { var trade []Trade - return trade, b.SendHTTPRequest(exchange.RestSpot, bitmexEndpointTradeBucketed, + return trade, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointTradeBucketed, params, &trade) } // GetUserInfo returns your user information -func (b *Bitmex) GetUserInfo() (User, error) { +func (b *Bitmex) GetUserInfo(ctx context.Context) (User, error) { var userInfo User - return userInfo, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, + return userInfo, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, bitmexEndpointUser, nil, &userInfo) } // UpdateUserInfo updates user information -func (b *Bitmex) UpdateUserInfo(params *UserUpdateParams) (User, error) { +func (b *Bitmex) UpdateUserInfo(ctx context.Context, params *UserUpdateParams) (User, error) { var userInfo User - return userInfo, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPut, + return userInfo, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPut, bitmexEndpointUser, params, &userInfo) } // GetAffiliateStatus returns your affiliate status -func (b *Bitmex) GetAffiliateStatus() (AffiliateStatus, error) { +func (b *Bitmex) GetAffiliateStatus(ctx context.Context) (AffiliateStatus, error) { var status AffiliateStatus - return status, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, + return status, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, bitmexEndpointUserAffiliate, nil, &status) } // CancelWithdraw cancels a current withdrawal -func (b *Bitmex) CancelWithdraw(token string) (TransactionInfo, error) { +func (b *Bitmex) CancelWithdraw(ctx context.Context, token string) (TransactionInfo, error) { var info TransactionInfo - return info, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return info, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitmexEndpointUserCancelWithdraw, UserTokenParams{Token: token}, &info) @@ -614,56 +614,56 @@ func (b *Bitmex) CancelWithdraw(token string) (TransactionInfo, error) { // CheckReferalCode checks a code, will return a percentage eg 0.1 for 10% or // if err a 404 -func (b *Bitmex) CheckReferalCode(referralCode string) (float64, error) { +func (b *Bitmex) CheckReferalCode(ctx context.Context, referralCode string) (float64, error) { var percentage float64 - return percentage, b.SendHTTPRequest(exchange.RestSpot, bitmexEndpointUserCheckReferralCode, + return percentage, b.SendHTTPRequest(ctx, exchange.RestSpot, bitmexEndpointUserCheckReferralCode, UserCheckReferralCodeParams{ReferralCode: referralCode}, &percentage) } // GetUserCommision returns your account's commission status. -func (b *Bitmex) GetUserCommision() (UserCommission, error) { +func (b *Bitmex) GetUserCommision(ctx context.Context) (UserCommission, error) { var commissionInfo UserCommission - return commissionInfo, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, + return commissionInfo, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, bitmexEndpointUserCommision, nil, &commissionInfo) } // ConfirmEmail confirms email address with a token -func (b *Bitmex) ConfirmEmail(token string) (ConfirmEmail, error) { +func (b *Bitmex) ConfirmEmail(ctx context.Context, token string) (ConfirmEmail, error) { var confirmation ConfirmEmail - return confirmation, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, + return confirmation, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, bitmexEndpointUserConfirmEmail, UserTokenParams{Token: token}, &confirmation) } // ConfirmTwoFactorAuth confirms 2FA for this account. -func (b *Bitmex) ConfirmTwoFactorAuth(token, typ string) (bool, error) { +func (b *Bitmex) ConfirmTwoFactorAuth(ctx context.Context, token, typ string) (bool, error) { var working bool - return working, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return working, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitmexEndpointUserConfirmTFA, UserConfirmTFAParams{Token: token, Type: typ}, &working) } // ConfirmWithdrawal confirms a withdrawal -func (b *Bitmex) ConfirmWithdrawal(token string) (TransactionInfo, error) { +func (b *Bitmex) ConfirmWithdrawal(ctx context.Context, token string) (TransactionInfo, error) { var info TransactionInfo - return info, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return info, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitmexEndpointUserCancelWithdraw, UserTokenParams{Token: token}, &info) } // GetCryptoDepositAddress returns a deposit address for a cryptocurency -func (b *Bitmex) GetCryptoDepositAddress(cryptoCurrency string) (string, error) { +func (b *Bitmex) GetCryptoDepositAddress(ctx context.Context, cryptoCurrency string) (string, error) { var address string if !strings.EqualFold(cryptoCurrency, currency.XBT.String()) { @@ -672,85 +672,85 @@ func (b *Bitmex) GetCryptoDepositAddress(cryptoCurrency string) (string, error) cryptoCurrency) } - return address, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, + return address, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, bitmexEndpointUserDepositAddress, UserCurrencyParams{Currency: "XBt"}, &address) } // DisableTFA dsiables 2 factor authentication for your account -func (b *Bitmex) DisableTFA(token, typ string) (bool, error) { +func (b *Bitmex) DisableTFA(ctx context.Context, token, typ string) (bool, error) { var disabled bool - return disabled, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return disabled, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitmexEndpointUserDisableTFA, UserConfirmTFAParams{Token: token, Type: typ}, &disabled) } // UserLogOut logs you out of BitMEX -func (b *Bitmex) UserLogOut() error { - return b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, +func (b *Bitmex) UserLogOut(ctx context.Context) error { + return b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitmexEndpointUserLogout, nil, nil) } // UserLogOutAll logs you out of all systems for BitMEX -func (b *Bitmex) UserLogOutAll() (int64, error) { +func (b *Bitmex) UserLogOutAll(ctx context.Context) (int64, error) { var status int64 - return status, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return status, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitmexEndpointUserLogoutAll, nil, &status) } // GetUserMargin returns user margin information -func (b *Bitmex) GetUserMargin(currency string) (UserMargin, error) { +func (b *Bitmex) GetUserMargin(ctx context.Context, currency string) (UserMargin, error) { var info UserMargin - return info, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, + return info, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, bitmexEndpointUserMargin, UserCurrencyParams{Currency: currency}, &info) } // GetAllUserMargin returns user margin information -func (b *Bitmex) GetAllUserMargin() ([]UserMargin, error) { +func (b *Bitmex) GetAllUserMargin(ctx context.Context) ([]UserMargin, error) { var info []UserMargin - return info, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, + return info, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, bitmexEndpointUserMargin, UserCurrencyParams{Currency: "all"}, &info) } // GetMinimumWithdrawalFee returns minimum withdrawal fee information -func (b *Bitmex) GetMinimumWithdrawalFee(currency string) (MinWithdrawalFee, error) { +func (b *Bitmex) GetMinimumWithdrawalFee(ctx context.Context, currency string) (MinWithdrawalFee, error) { var fee MinWithdrawalFee - return fee, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, + return fee, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, bitmexEndpointUserMinWithdrawalFee, UserCurrencyParams{Currency: currency}, &fee) } // GetUserPreferences returns user preferences -func (b *Bitmex) GetUserPreferences(params UserPreferencesParams) (User, error) { +func (b *Bitmex) GetUserPreferences(ctx context.Context, params UserPreferencesParams) (User, error) { var userInfo User - return userInfo, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return userInfo, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitmexEndpointUserPreferences, params, &userInfo) } // EnableTFA enables 2 factor authentication -func (b *Bitmex) EnableTFA(typ string) (bool, error) { +func (b *Bitmex) EnableTFA(ctx context.Context, typ string) (bool, error) { var enabled bool - return enabled, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return enabled, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitmexEndpointUserRequestTFA, UserConfirmTFAParams{Type: typ}, &enabled) @@ -759,47 +759,47 @@ func (b *Bitmex) EnableTFA(typ string) (bool, error) { // UserRequestWithdrawal This will send a confirmation email to the email // address on record, unless requested via an API Key with the withdraw // permission. -func (b *Bitmex) UserRequestWithdrawal(params UserRequestWithdrawalParams) (TransactionInfo, error) { +func (b *Bitmex) UserRequestWithdrawal(ctx context.Context, params UserRequestWithdrawalParams) (TransactionInfo, error) { var info TransactionInfo - return info, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return info, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, bitmexEndpointUserRequestWithdraw, params, &info) } // GetWalletInfo returns user wallet information -func (b *Bitmex) GetWalletInfo(currency string) (WalletInfo, error) { +func (b *Bitmex) GetWalletInfo(ctx context.Context, currency string) (WalletInfo, error) { var info WalletInfo - return info, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, + return info, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, bitmexEndpointUserWallet, UserCurrencyParams{Currency: currency}, &info) } // GetWalletHistory returns user wallet history transaction data -func (b *Bitmex) GetWalletHistory(currency string) ([]TransactionInfo, error) { +func (b *Bitmex) GetWalletHistory(ctx context.Context, currency string) ([]TransactionInfo, error) { var info []TransactionInfo - return info, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, + return info, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, bitmexEndpointUserWalletHistory, UserCurrencyParams{Currency: currency}, &info) } // GetWalletSummary returns user wallet summary -func (b *Bitmex) GetWalletSummary(currency string) ([]TransactionInfo, error) { +func (b *Bitmex) GetWalletSummary(ctx context.Context, currency string) ([]TransactionInfo, error) { var info []TransactionInfo - return info, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, + return info, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, bitmexEndpointUserWalletSummary, UserCurrencyParams{Currency: currency}, &info) } // SendHTTPRequest sends an unauthenticated HTTP request -func (b *Bitmex) SendHTTPRequest(ep exchange.URL, path string, params Parameter, result interface{}) error { +func (b *Bitmex) SendHTTPRequest(ctx context.Context, ep exchange.URL, path string, params Parameter, result interface{}) error { var respCheck interface{} endpoint, err := b.API.Endpoints.GetURL(ep) if err != nil { @@ -822,7 +822,7 @@ func (b *Bitmex) SendHTTPRequest(ep exchange.URL, path string, params Parameter, HTTPRecording: b.HTTPRecording, } - err = b.SendPayload(context.Background(), request.Unset, func() (*request.Item, error) { + err = b.SendPayload(ctx, request.Unset, func() (*request.Item, error) { return item, nil }) if err != nil { @@ -833,7 +833,7 @@ func (b *Bitmex) SendHTTPRequest(ep exchange.URL, path string, params Parameter, } // SendAuthenticatedHTTPRequest sends an authenticated HTTP request to bitmex -func (b *Bitmex) SendAuthenticatedHTTPRequest(ep exchange.URL, verb, path string, params Parameter, result interface{}) error { +func (b *Bitmex) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, verb, path string, params Parameter, result interface{}) error { if !b.AllowAuthenticatedRequest() { return fmt.Errorf("%s %w", b.Name, exchange.ErrAuthenticatedRequestWithoutCredentialsSet) } @@ -890,7 +890,7 @@ func (b *Bitmex) SendAuthenticatedHTTPRequest(ep exchange.URL, verb, path string HTTPRecording: b.HTTPRecording, }, nil } - err = b.SendPayload(context.Background(), request.Auth, newRequest) + err = b.SendPayload(ctx, request.Auth, newRequest) if err != nil { return err } diff --git a/exchanges/bitmex/bitmex_test.go b/exchanges/bitmex/bitmex_test.go index 8331d36f..589be78a 100644 --- a/exchanges/bitmex/bitmex_test.go +++ b/exchanges/bitmex/bitmex_test.go @@ -1,6 +1,7 @@ package bitmex import ( + "context" "log" "net/http" "os" @@ -63,12 +64,14 @@ func TestStart(t *testing.T) { func TestGetFullFundingHistory(t *testing.T) { t.Parallel() - _, err := b.GetFullFundingHistory("", "", "", "", "", true, time.Now().Add(-time.Minute), time.Now()) + _, err := b.GetFullFundingHistory(context.Background(), + "", "", "", "", "", true, time.Now().Add(-time.Minute), time.Now()) if err != nil { t.Error(err) } - _, err = b.GetFullFundingHistory("LTCUSD", "1", "", "", "", true, time.Now().Add(-time.Minute), time.Now()) + _, err = b.GetFullFundingHistory(context.Background(), + "LTCUSD", "1", "", "", "", true, time.Now().Add(-time.Minute), time.Now()) if err != nil { t.Error(err) } @@ -79,7 +82,7 @@ func TestGetUrgentAnnouncement(t *testing.T) { if areTestAPIKeysSet() && !canManipulateRealOrders { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - _, err := b.GetUrgentAnnouncement() + _, err := b.GetUrgentAnnouncement(context.Background()) if err == nil { t.Error("GetUrgentAnnouncement() Expected error") } @@ -90,7 +93,7 @@ func TestGetAPIKeys(t *testing.T) { if areTestAPIKeysSet() && !canManipulateRealOrders { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - _, err := b.GetAPIKeys() + _, err := b.GetAPIKeys(context.Background()) if err == nil { t.Error("GetAPIKeys() Expected error") } @@ -99,7 +102,7 @@ func TestGetAPIKeys(t *testing.T) { func TestRemoveAPIKey(t *testing.T) { t.Parallel() - _, err := b.RemoveAPIKey(APIKeyParams{APIKeyID: "1337"}) + _, err := b.RemoveAPIKey(context.Background(), APIKeyParams{APIKeyID: "1337"}) if err == nil { t.Error("RemoveAPIKey() Expected error") } @@ -110,7 +113,7 @@ func TestDisableAPIKey(t *testing.T) { if areTestAPIKeysSet() && !canManipulateRealOrders { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - _, err := b.DisableAPIKey(APIKeyParams{APIKeyID: "1337"}) + _, err := b.DisableAPIKey(context.Background(), APIKeyParams{APIKeyID: "1337"}) if err == nil { t.Error("DisableAPIKey() Expected error") } @@ -121,7 +124,7 @@ func TestEnableAPIKey(t *testing.T) { if areTestAPIKeysSet() && !canManipulateRealOrders { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - _, err := b.EnableAPIKey(APIKeyParams{APIKeyID: "1337"}) + _, err := b.EnableAPIKey(context.Background(), APIKeyParams{APIKeyID: "1337"}) if err == nil { t.Error("EnableAPIKey() Expected error") } @@ -129,7 +132,7 @@ func TestEnableAPIKey(t *testing.T) { func TestGetTrollboxMessages(t *testing.T) { t.Parallel() - _, err := b.GetTrollboxMessages(ChatGetParams{Count: 1}) + _, err := b.GetTrollboxMessages(context.Background(), ChatGetParams{Count: 1}) if err != nil { t.Error("GetTrollboxMessages() error", err) } @@ -140,9 +143,10 @@ func TestSendTrollboxMessage(t *testing.T) { if areTestAPIKeysSet() && !canManipulateRealOrders { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - _, err := b.SendTrollboxMessage(ChatSendParams{ - ChannelID: 1337, - Message: "Hello,World!"}) + _, err := b.SendTrollboxMessage(context.Background(), + ChatSendParams{ + ChannelID: 1337, + Message: "Hello,World!"}) if err == nil { t.Error("SendTrollboxMessage() Expected error") } @@ -150,7 +154,7 @@ func TestSendTrollboxMessage(t *testing.T) { func TestGetTrollboxChannels(t *testing.T) { t.Parallel() - _, err := b.GetTrollboxChannels() + _, err := b.GetTrollboxChannels(context.Background()) if err != nil { t.Error("GetTrollboxChannels() error", err) } @@ -158,7 +162,7 @@ func TestGetTrollboxChannels(t *testing.T) { func TestGetTrollboxConnectedUsers(t *testing.T) { t.Parallel() - _, err := b.GetTrollboxConnectedUsers() + _, err := b.GetTrollboxConnectedUsers(context.Background()) if err == nil { t.Error("GetTrollboxConnectedUsers() Expected error") } @@ -169,7 +173,8 @@ func TestGetAccountExecutions(t *testing.T) { if areTestAPIKeysSet() && !canManipulateRealOrders { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - _, err := b.GetAccountExecutions(&GenericRequestParams{}) + _, err := b.GetAccountExecutions(context.Background(), + &GenericRequestParams{}) if err == nil { t.Error("GetAccountExecutions() Expected error") } @@ -180,7 +185,8 @@ func TestGetAccountExecutionTradeHistory(t *testing.T) { if areTestAPIKeysSet() && !canManipulateRealOrders { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - _, err := b.GetAccountExecutionTradeHistory(&GenericRequestParams{}) + _, err := b.GetAccountExecutionTradeHistory(context.Background(), + &GenericRequestParams{}) if err == nil { t.Error("GetAccountExecutionTradeHistory() Expected error") } @@ -188,7 +194,7 @@ func TestGetAccountExecutionTradeHistory(t *testing.T) { func TestGetFundingHistory(t *testing.T) { t.Parallel() - _, err := b.GetFundingHistory() + _, err := b.GetFundingHistory(context.Background()) if err == nil { t.Error("GetFundingHistory() Expected error") } @@ -196,9 +202,10 @@ func TestGetFundingHistory(t *testing.T) { func TestGetInstruments(t *testing.T) { t.Parallel() - _, err := b.GetInstruments(&GenericRequestParams{ - Symbol: "XRPUSD", - }) + _, err := b.GetInstruments(context.Background(), + &GenericRequestParams{ + Symbol: "XRPUSD", + }) if err != nil { t.Error("GetInstruments() error", err) } @@ -206,7 +213,8 @@ func TestGetInstruments(t *testing.T) { func TestGetActiveInstruments(t *testing.T) { t.Parallel() - _, err := b.GetActiveInstruments(&GenericRequestParams{}) + _, err := b.GetActiveInstruments(context.Background(), + &GenericRequestParams{}) if err != nil { t.Error("GetActiveInstruments() error", err) } @@ -214,7 +222,7 @@ func TestGetActiveInstruments(t *testing.T) { func TestGetActiveAndIndexInstruments(t *testing.T) { t.Parallel() - _, err := b.GetActiveAndIndexInstruments() + _, err := b.GetActiveAndIndexInstruments(context.Background()) if err != nil { t.Error("GetActiveAndIndexInstruments() error", err) } @@ -222,7 +230,7 @@ func TestGetActiveAndIndexInstruments(t *testing.T) { func TestGetActiveIntervals(t *testing.T) { t.Parallel() - _, err := b.GetActiveIntervals() + _, err := b.GetActiveIntervals(context.Background()) if err == nil { t.Error("GetActiveIntervals() Expected error") } @@ -230,7 +238,8 @@ func TestGetActiveIntervals(t *testing.T) { func TestGetCompositeIndex(t *testing.T) { t.Parallel() - _, err := b.GetCompositeIndex(".XBT", "", "", "", "", "", time.Time{}, time.Time{}) + _, err := b.GetCompositeIndex(context.Background(), + ".XBT", "", "", "", "", "", time.Time{}, time.Time{}) if err != nil { t.Error("GetCompositeIndex() Expected error", err) } @@ -238,7 +247,7 @@ func TestGetCompositeIndex(t *testing.T) { func TestGetIndices(t *testing.T) { t.Parallel() - _, err := b.GetIndices() + _, err := b.GetIndices(context.Background()) if err != nil { t.Error("GetIndices() error", err) } @@ -246,7 +255,8 @@ func TestGetIndices(t *testing.T) { func TestGetInsuranceFundHistory(t *testing.T) { t.Parallel() - _, err := b.GetInsuranceFundHistory(&GenericRequestParams{}) + _, err := b.GetInsuranceFundHistory(context.Background(), + &GenericRequestParams{}) if err != nil { t.Error("GetInsuranceFundHistory() error", err) } @@ -254,7 +264,7 @@ func TestGetInsuranceFundHistory(t *testing.T) { func TestGetLeaderboard(t *testing.T) { t.Parallel() - _, err := b.GetLeaderboard(LeaderboardGetParams{}) + _, err := b.GetLeaderboard(context.Background(), LeaderboardGetParams{}) if err != nil { t.Error("GetLeaderboard() error", err) } @@ -262,7 +272,7 @@ func TestGetLeaderboard(t *testing.T) { func TestGetAliasOnLeaderboard(t *testing.T) { t.Parallel() - _, err := b.GetAliasOnLeaderboard() + _, err := b.GetAliasOnLeaderboard(context.Background()) if err == nil { t.Error("GetAliasOnLeaderboard() Expected error") } @@ -270,7 +280,8 @@ func TestGetAliasOnLeaderboard(t *testing.T) { func TestGetLiquidationOrders(t *testing.T) { t.Parallel() - _, err := b.GetLiquidationOrders(&GenericRequestParams{}) + _, err := b.GetLiquidationOrders(context.Background(), + &GenericRequestParams{}) if err != nil { t.Error("GetLiquidationOrders() error", err) } @@ -281,7 +292,7 @@ func TestGetCurrentNotifications(t *testing.T) { if areTestAPIKeysSet() && !canManipulateRealOrders { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - _, err := b.GetCurrentNotifications() + _, err := b.GetCurrentNotifications(context.Background()) if err == nil { t.Error("GetCurrentNotifications() Expected error") } @@ -292,7 +303,7 @@ func TestAmendOrder(t *testing.T) { if areTestAPIKeysSet() && !canManipulateRealOrders { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - _, err := b.AmendOrder(&OrderAmendParams{}) + _, err := b.AmendOrder(context.Background(), &OrderAmendParams{}) if err == nil { t.Error("AmendOrder() Expected error") } @@ -303,10 +314,11 @@ func TestCreateOrder(t *testing.T) { if areTestAPIKeysSet() && !canManipulateRealOrders { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - _, err := b.CreateOrder(&OrderNewParams{Symbol: "XBTM15", - Price: 219.0, - ClientOrderID: "mm_bitmex_1a/oemUeQ4CAJZgP3fjHsA", - OrderQuantity: 98}) + _, err := b.CreateOrder(context.Background(), + &OrderNewParams{Symbol: "XBTM15", + Price: 219.0, + ClientOrderID: "mm_bitmex_1a/oemUeQ4CAJZgP3fjHsA", + OrderQuantity: 98}) if err == nil { t.Error("CreateOrder() Expected error") } @@ -317,7 +329,7 @@ func TestCancelOrders(t *testing.T) { if areTestAPIKeysSet() && !canManipulateRealOrders { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - _, err := b.CancelOrders(&OrderCancelParams{}) + _, err := b.CancelOrders(context.Background(), &OrderCancelParams{}) if err == nil { t.Error("CancelOrders() Expected error") } @@ -328,9 +340,10 @@ func TestCancelAllOrders(t *testing.T) { if areTestAPIKeysSet() && !canManipulateRealOrders { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - _, err := b.CancelAllExistingOrders(OrderCancelAllParams{}) + _, err := b.CancelAllExistingOrders(context.Background(), + OrderCancelAllParams{}) if err == nil { - t.Error("CancelAllOrders(orderCancellation *order.Cancel) (order.CancelAllResponse, error)", err) + t.Error("CancelAllOrders(ctx context.Context, orderCancellation *order.Cancel) (order.CancelAllResponse, error)", err) } } @@ -339,7 +352,7 @@ func TestAmendBulkOrders(t *testing.T) { if areTestAPIKeysSet() && !canManipulateRealOrders { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - _, err := b.AmendBulkOrders(OrderAmendBulkParams{}) + _, err := b.AmendBulkOrders(context.Background(), OrderAmendBulkParams{}) if err == nil { t.Error("AmendBulkOrders() Expected error") } @@ -350,7 +363,7 @@ func TestCreateBulkOrders(t *testing.T) { if areTestAPIKeysSet() && !canManipulateRealOrders { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - _, err := b.CreateBulkOrders(OrderNewBulkParams{}) + _, err := b.CreateBulkOrders(context.Background(), OrderNewBulkParams{}) if err == nil { t.Error("CreateBulkOrders() Expected error") } @@ -361,7 +374,8 @@ func TestCancelAllOrdersAfterTime(t *testing.T) { if areTestAPIKeysSet() && !canManipulateRealOrders { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - _, err := b.CancelAllOrdersAfterTime(OrderCancelAllAfterParams{}) + _, err := b.CancelAllOrdersAfterTime(context.Background(), + OrderCancelAllAfterParams{}) if err == nil { t.Error("CancelAllOrdersAfterTime() Expected error") } @@ -369,7 +383,7 @@ func TestCancelAllOrdersAfterTime(t *testing.T) { func TestClosePosition(t *testing.T) { t.Parallel() - _, err := b.ClosePosition(OrderClosePositionParams{}) + _, err := b.ClosePosition(context.Background(), OrderClosePositionParams{}) if err == nil { t.Error("ClosePosition() Expected error") } @@ -377,7 +391,8 @@ func TestClosePosition(t *testing.T) { func TestGetOrderbook(t *testing.T) { t.Parallel() - _, err := b.GetOrderbook(OrderBookGetL2Params{Symbol: "XBT"}) + _, err := b.GetOrderbook(context.Background(), + OrderBookGetL2Params{Symbol: "XBT"}) if err != nil { t.Error("GetOrderbook() error", err) } @@ -385,7 +400,7 @@ func TestGetOrderbook(t *testing.T) { func TestGetPositions(t *testing.T) { t.Parallel() - _, err := b.GetPositions(PositionGetParams{}) + _, err := b.GetPositions(context.Background(), PositionGetParams{}) if err == nil { t.Error("GetPositions() Expected error") } @@ -393,7 +408,8 @@ func TestGetPositions(t *testing.T) { func TestIsolatePosition(t *testing.T) { t.Parallel() - _, err := b.IsolatePosition(PositionIsolateMarginParams{Symbol: "XBT"}) + _, err := b.IsolatePosition(context.Background(), + PositionIsolateMarginParams{Symbol: "XBT"}) if err == nil { t.Error("IsolatePosition() Expected error") } @@ -401,7 +417,8 @@ func TestIsolatePosition(t *testing.T) { func TestLeveragePosition(t *testing.T) { t.Parallel() - _, err := b.LeveragePosition(PositionUpdateLeverageParams{}) + _, err := b.LeveragePosition(context.Background(), + PositionUpdateLeverageParams{}) if err == nil { t.Error("LeveragePosition() Expected error") } @@ -409,7 +426,8 @@ func TestLeveragePosition(t *testing.T) { func TestUpdateRiskLimit(t *testing.T) { t.Parallel() - _, err := b.UpdateRiskLimit(PositionUpdateRiskLimitParams{}) + _, err := b.UpdateRiskLimit(context.Background(), + PositionUpdateRiskLimitParams{}) if err == nil { t.Error("UpdateRiskLimit() Expected error") } @@ -417,7 +435,8 @@ func TestUpdateRiskLimit(t *testing.T) { func TestTransferMargin(t *testing.T) { t.Parallel() - _, err := b.TransferMargin(PositionTransferIsolatedMarginParams{}) + _, err := b.TransferMargin(context.Background(), + PositionTransferIsolatedMarginParams{}) if err == nil { t.Error("TransferMargin() Expected error") } @@ -425,7 +444,8 @@ func TestTransferMargin(t *testing.T) { func TestGetQuotesByBuckets(t *testing.T) { t.Parallel() - _, err := b.GetQuotesByBuckets(&QuoteGetBucketedParams{}) + _, err := b.GetQuotesByBuckets(context.Background(), + &QuoteGetBucketedParams{}) if err == nil { t.Error("GetQuotesByBuckets() Expected error") } @@ -433,7 +453,8 @@ func TestGetQuotesByBuckets(t *testing.T) { func TestGetSettlementHistory(t *testing.T) { t.Parallel() - _, err := b.GetSettlementHistory(&GenericRequestParams{}) + _, err := b.GetSettlementHistory(context.Background(), + &GenericRequestParams{}) if err != nil { t.Error("GetSettlementHistory() error", err) } @@ -441,7 +462,7 @@ func TestGetSettlementHistory(t *testing.T) { func TestGetStats(t *testing.T) { t.Parallel() - _, err := b.GetStats() + _, err := b.GetStats(context.Background()) if err != nil { t.Error("GetStats() error", err) } @@ -449,7 +470,7 @@ func TestGetStats(t *testing.T) { func TestGetStatsHistorical(t *testing.T) { t.Parallel() - _, err := b.GetStatsHistorical() + _, err := b.GetStatsHistorical(context.Background()) if err != nil { t.Error("GetStatsHistorical() error", err) } @@ -457,7 +478,7 @@ func TestGetStatsHistorical(t *testing.T) { func TestGetStatSummary(t *testing.T) { t.Parallel() - _, err := b.GetStatSummary() + _, err := b.GetStatSummary(context.Background()) if err != nil { t.Error("GetStatSummary() error", err) } @@ -465,11 +486,12 @@ func TestGetStatSummary(t *testing.T) { func TestGetTrade(t *testing.T) { t.Parallel() - _, err := b.GetTrade(&GenericRequestParams{ - Symbol: "XBT", - Reverse: false, - StartTime: time.Now().Add(-time.Minute).Format(time.RFC3339), - }) + _, err := b.GetTrade(context.Background(), + &GenericRequestParams{ + Symbol: "XBT", + Reverse: false, + StartTime: time.Now().Add(-time.Minute).Format(time.RFC3339), + }) if err != nil { t.Error("GetTrade() error", err) } @@ -477,11 +499,12 @@ func TestGetTrade(t *testing.T) { func TestGetPreviousTrades(t *testing.T) { t.Parallel() - _, err := b.GetPreviousTrades(&TradeGetBucketedParams{ - Symbol: "XBTBTC", - Start: int32(time.Now().Add(-time.Hour).Unix()), - Columns: "open,high,low,close,volume", - }) + _, err := b.GetPreviousTrades(context.Background(), + &TradeGetBucketedParams{ + Symbol: "XBTBTC", + Start: int32(time.Now().Add(-time.Hour).Unix()), + Columns: "open,high,low,close,volume", + }) if err == nil { t.Error("GetPreviousTrades() Expected error") } @@ -500,7 +523,7 @@ func setFeeBuilder() *exchange.FeeBuilder { func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { t.Parallel() var feeBuilder = setFeeBuilder() - _, err := b.GetFeeByType(feeBuilder) + _, err := b.GetFeeByType(context.Background(), feeBuilder) if err != nil { t.Fatal(err) } @@ -593,7 +616,7 @@ func TestGetActiveOrders(t *testing.T) { AssetType: asset.Spot, } - _, err := b.GetActiveOrders(&getOrdersRequest) + _, err := b.GetActiveOrders(context.Background(), &getOrdersRequest) if areTestAPIKeysSet() && err != nil { t.Errorf("Could not get open orders: %s", err) } else if !areTestAPIKeysSet() && err == nil { @@ -610,7 +633,7 @@ func TestGetOrderHistory(t *testing.T) { AssetType: asset.Spot, } - _, err := b.GetOrderHistory(&getOrdersRequest) + _, err := b.GetOrderHistory(context.Background(), &getOrdersRequest) if areTestAPIKeysSet() && err != nil { t.Errorf("Could not get order history: %s", err) } else if !areTestAPIKeysSet() && err == nil { @@ -642,7 +665,7 @@ func TestSubmitOrder(t *testing.T) { ClientID: "meowOrder", AssetType: asset.Futures, } - response, err := b.SubmitOrder(orderSubmission) + response, err := b.SubmitOrder(context.Background(), orderSubmission) if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) { t.Errorf("Order failed to be placed: %v", err) } else if !areTestAPIKeysSet() && err == nil { @@ -665,7 +688,7 @@ func TestCancelExchangeOrder(t *testing.T) { AssetType: asset.Futures, } - err := b.CancelOrder(orderCancellation) + err := b.CancelOrder(context.Background(), orderCancellation) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") } @@ -689,7 +712,7 @@ func TestCancelAllExchangeOrders(t *testing.T) { AssetType: asset.Futures, } - resp, err := b.CancelAllOrders(orderCancellation) + resp, err := b.CancelAllOrders(context.Background(), orderCancellation) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") @@ -706,12 +729,12 @@ func TestCancelAllExchangeOrders(t *testing.T) { func TestGetAccountInfo(t *testing.T) { t.Parallel() if areTestAPIKeysSet() { - _, err := b.UpdateAccountInfo(asset.Spot) + _, err := b.UpdateAccountInfo(context.Background(), asset.Spot) if err != nil { t.Error("GetAccountInfo() error", err) } } else { - _, err := b.UpdateAccountInfo(asset.Spot) + _, err := b.UpdateAccountInfo(context.Background(), asset.Spot) if err == nil { t.Error("GetAccountInfo() error") } @@ -723,7 +746,8 @@ func TestModifyOrder(t *testing.T) { if areTestAPIKeysSet() && !canManipulateRealOrders { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - _, err := b.ModifyOrder(&order.Modify{ID: "1337", AssetType: asset.Futures}) + _, err := b.ModifyOrder(context.Background(), + &order.Modify{ID: "1337", AssetType: asset.Futures}) if err == nil { t.Error("ModifyOrder() error") } @@ -745,7 +769,8 @@ func TestWithdraw(t *testing.T) { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - _, err := b.WithdrawCryptocurrencyFunds(&withdrawCryptoRequest) + _, err := b.WithdrawCryptocurrencyFunds(context.Background(), + &withdrawCryptoRequest) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") } @@ -761,7 +786,7 @@ func TestWithdrawFiat(t *testing.T) { } var withdrawFiatRequest = withdraw.Request{} - _, err := b.WithdrawFiatFunds(&withdrawFiatRequest) + _, err := b.WithdrawFiatFunds(context.Background(), &withdrawFiatRequest) if err != common.ErrFunctionNotSupported { t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err) } @@ -774,7 +799,8 @@ func TestWithdrawInternationalBank(t *testing.T) { } var withdrawFiatRequest = withdraw.Request{} - _, err := b.WithdrawFiatFundsToInternationalBank(&withdrawFiatRequest) + _, err := b.WithdrawFiatFundsToInternationalBank(context.Background(), + &withdrawFiatRequest) if err != common.ErrFunctionNotSupported { t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err) } @@ -783,12 +809,12 @@ func TestWithdrawInternationalBank(t *testing.T) { func TestGetDepositAddress(t *testing.T) { t.Parallel() if areTestAPIKeysSet() { - _, err := b.GetDepositAddress(currency.BTC, "") + _, err := b.GetDepositAddress(context.Background(), currency.BTC, "") if err != nil { t.Error("GetDepositAddress() error", err) } } else { - _, err := b.GetDepositAddress(currency.BTC, "") + _, err := b.GetDepositAddress(context.Background(), currency.BTC, "") if err == nil { t.Error("GetDepositAddress() error cannot be nil") } @@ -826,7 +852,7 @@ func TestWsAuth(t *testing.T) { func TestUpdateTradablePairs(t *testing.T) { t.Parallel() - err := b.UpdateTradablePairs(true) + err := b.UpdateTradablePairs(context.Background(), true) if err != nil { t.Fatal(err) } @@ -1070,12 +1096,12 @@ func TestWsTrades(t *testing.T) { func TestGetRecentTrades(t *testing.T) { t.Parallel() - err := b.UpdateTradablePairs(false) + err := b.UpdateTradablePairs(context.Background(), false) if err != nil { t.Fatal(err) } currencyPair := b.CurrencyPairs.Pairs[asset.Futures].Available[0] - _, err = b.GetRecentTrades(currencyPair, asset.Futures) + _, err = b.GetRecentTrades(context.Background(), currencyPair, asset.Futures) if err != nil { t.Error(err) } @@ -1083,12 +1109,12 @@ func TestGetRecentTrades(t *testing.T) { func TestGetHistoricTrades(t *testing.T) { t.Parallel() - err := b.UpdateTradablePairs(false) + err := b.UpdateTradablePairs(context.Background(), false) if err != nil { t.Fatal(err) } currencyPair := b.CurrencyPairs.Pairs[asset.Futures].Available[0] - _, err = b.GetHistoricTrades(currencyPair, asset.Futures, time.Now().Add(-time.Minute), time.Now()) + _, err = b.GetHistoricTrades(context.Background(), currencyPair, asset.Futures, time.Now().Add(-time.Minute), time.Now()) if err != nil { t.Error(err) } @@ -1096,14 +1122,14 @@ func TestGetHistoricTrades(t *testing.T) { func TestUpdateTicker(t *testing.T) { cp := currency.NewPair(currency.ETH, currency.USD) - _, err := b.UpdateTicker(cp, asset.PerpetualContract) + _, err := b.UpdateTicker(context.Background(), cp, asset.PerpetualContract) if err != nil { t.Fatal(err) } } func TestUpdateTickers(t *testing.T) { - err := b.UpdateTickers(asset.Spot) + err := b.UpdateTickers(context.Background(), asset.Spot) if err != nil { t.Fatal(err) } diff --git a/exchanges/bitmex/bitmex_wrapper.go b/exchanges/bitmex/bitmex_wrapper.go index b2a8dfbb..8429878e 100644 --- a/exchanges/bitmex/bitmex_wrapper.go +++ b/exchanges/bitmex/bitmex_wrapper.go @@ -1,6 +1,7 @@ package bitmex import ( + "context" "errors" "fmt" "math" @@ -41,7 +42,7 @@ func (b *Bitmex) GetDefaultConfig() (*config.ExchangeConfig, error) { } if b.Features.Supports.RESTCapabilities.AutoPairUpdates { - err = b.UpdateTradablePairs(true) + err = b.UpdateTradablePairs(context.TODO(), true) if err != nil { return nil, err } @@ -209,15 +210,15 @@ func (b *Bitmex) Run() { return } - err := b.UpdateTradablePairs(false) + err := b.UpdateTradablePairs(context.TODO(), false) if err != nil { log.Errorf(log.ExchangeSys, "%s failed to update tradable pairs. Err: %s", b.Name, err) } } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (b *Bitmex) FetchTradablePairs(asset asset.Item) ([]string, error) { - marketInfo, err := b.GetActiveAndIndexInstruments() +func (b *Bitmex) FetchTradablePairs(ctx context.Context, asset asset.Item) ([]string, error) { + marketInfo, err := b.GetActiveAndIndexInstruments(ctx) if err != nil { return nil, err } @@ -232,8 +233,8 @@ func (b *Bitmex) FetchTradablePairs(asset asset.Item) ([]string, error) { // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (b *Bitmex) UpdateTradablePairs(forceUpdate bool) error { - pairs, err := b.FetchTradablePairs(asset.Spot) +func (b *Bitmex) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { + pairs, err := b.FetchTradablePairs(ctx, asset.Spot) if err != nil { return err } @@ -280,8 +281,8 @@ func (b *Bitmex) UpdateTradablePairs(forceUpdate bool) error { } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (b *Bitmex) UpdateTickers(a asset.Item) error { - tick, err := b.GetActiveAndIndexInstruments() +func (b *Bitmex) UpdateTickers(ctx context.Context, a asset.Item) error { + tick, err := b.GetActiveAndIndexInstruments(ctx) if err != nil { return err } @@ -316,8 +317,8 @@ func (b *Bitmex) UpdateTickers(a asset.Item) error { } // UpdateTicker updates and returns the ticker for a currency pair -func (b *Bitmex) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) { - err := b.UpdateTickers(a) +func (b *Bitmex) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { + err := b.UpdateTickers(ctx, a) if err != nil { return nil, err } @@ -331,7 +332,7 @@ func (b *Bitmex) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, err } // FetchTicker returns the ticker for a currency pair -func (b *Bitmex) FetchTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) { +func (b *Bitmex) FetchTicker(ctx context.Context, p currency.Pair, assetType asset.Item) (*ticker.Price, error) { fPair, err := b.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err @@ -339,13 +340,13 @@ func (b *Bitmex) FetchTicker(p currency.Pair, assetType asset.Item) (*ticker.Pri tickerNew, err := ticker.GetTicker(b.Name, fPair, assetType) if err != nil { - return b.UpdateTicker(fPair, assetType) + return b.UpdateTicker(ctx, fPair, assetType) } return tickerNew, nil } // FetchOrderbook returns orderbook base on the currency pair -func (b *Bitmex) FetchOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (b *Bitmex) FetchOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { fPair, err := b.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err @@ -353,13 +354,13 @@ func (b *Bitmex) FetchOrderbook(p currency.Pair, assetType asset.Item) (*orderbo ob, err := orderbook.Get(b.Name, fPair, assetType) if err != nil { - return b.UpdateOrderbook(fPair, assetType) + return b.UpdateOrderbook(ctx, fPair, assetType) } return ob, nil } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (b *Bitmex) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (b *Bitmex) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { book := &orderbook.Base{ Exchange: b.Name, Pair: p, @@ -376,9 +377,10 @@ func (b *Bitmex) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderb return book, err } - orderbookNew, err := b.GetOrderbook(OrderBookGetL2Params{ - Symbol: fpair.String(), - Depth: 500}) + orderbookNew, err := b.GetOrderbook(ctx, + OrderBookGetL2Params{ + Symbol: fpair.String(), + Depth: 500}) if err != nil { return book, err } @@ -410,10 +412,10 @@ func (b *Bitmex) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderb // UpdateAccountInfo retrieves balances for all enabled currencies for the // Bitmex exchange -func (b *Bitmex) UpdateAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (b *Bitmex) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { var info account.Holdings - bal, err := b.GetAllUserMargin() + bal, err := b.GetAllUserMargin(ctx) if err != nil { return info, err } @@ -441,10 +443,10 @@ func (b *Bitmex) UpdateAccountInfo(assetType asset.Item) (account.Holdings, erro } // FetchAccountInfo retrieves balances for all enabled currencies -func (b *Bitmex) FetchAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (b *Bitmex) FetchAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { acc, err := account.GetHoldings(b.Name, assetType) if err != nil { - return b.UpdateAccountInfo(assetType) + return b.UpdateAccountInfo(ctx, assetType) } return acc, nil @@ -452,22 +454,22 @@ func (b *Bitmex) FetchAccountInfo(assetType asset.Item) (account.Holdings, error // GetFundingHistory returns funding history, deposits and // withdrawals -func (b *Bitmex) GetFundingHistory() ([]exchange.FundHistory, error) { +func (b *Bitmex) GetFundingHistory(ctx context.Context) ([]exchange.FundHistory, error) { return nil, common.ErrNotYetImplemented } // GetWithdrawalsHistory returns previous withdrawals data -func (b *Bitmex) GetWithdrawalsHistory(c currency.Code) (resp []exchange.WithdrawalHistory, err error) { +func (b *Bitmex) GetWithdrawalsHistory(ctx context.Context, c currency.Code) (resp []exchange.WithdrawalHistory, err error) { return nil, common.ErrNotYetImplemented } // GetRecentTrades returns the most recent trades for a currency and asset -func (b *Bitmex) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade.Data, error) { - return b.GetHistoricTrades(p, assetType, time.Now().Add(-time.Minute*15), time.Now()) +func (b *Bitmex) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { + return b.GetHistoricTrades(ctx, p, assetType, time.Now().Add(-time.Minute*15), time.Now()) } // GetHistoricTrades returns historic trade data within the timeframe provided -func (b *Bitmex) GetHistoricTrades(p currency.Pair, assetType asset.Item, timestampStart, timestampEnd time.Time) ([]trade.Data, error) { +func (b *Bitmex) GetHistoricTrades(ctx context.Context, p currency.Pair, assetType asset.Item, timestampStart, timestampEnd time.Time) ([]trade.Data, error) { if assetType == asset.Index { return nil, fmt.Errorf("asset type '%v' not supported", assetType) } @@ -491,7 +493,7 @@ allTrades: for { req.StartTime = ts.UTC().Format("2006-01-02T15:04:05.000Z") var tradeData []Trade - tradeData, err = b.GetTrade(req) + tradeData, err = b.GetTrade(ctx, req) if err != nil { return nil, err } @@ -541,7 +543,7 @@ allTrades: } // SubmitOrder submits a new order -func (b *Bitmex) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { +func (b *Bitmex) SubmitOrder(ctx context.Context, s *order.Submit) (order.SubmitResponse, error) { var submitOrderResponse order.SubmitResponse if err := s.Validate(); err != nil { return submitOrderResponse, err @@ -568,7 +570,7 @@ func (b *Bitmex) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { orderNewParams.Price = s.Price } - response, err := b.CreateOrder(&orderNewParams) + response, err := b.CreateOrder(ctx, &orderNewParams) if err != nil { return submitOrderResponse, err } @@ -585,7 +587,7 @@ func (b *Bitmex) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (b *Bitmex) ModifyOrder(action *order.Modify) (order.Modify, error) { +func (b *Bitmex) ModifyOrder(ctx context.Context, action *order.Modify) (order.Modify, error) { if err := action.Validate(); err != nil { return order.Modify{}, err } @@ -600,7 +602,7 @@ func (b *Bitmex) ModifyOrder(action *order.Modify) (order.Modify, error) { params.OrderQty = int32(action.Amount) params.Price = action.Price - o, err := b.AmendOrder(¶ms) + o, err := b.AmendOrder(ctx, ¶ms) if err != nil { return order.Modify{}, err } @@ -617,29 +619,29 @@ func (b *Bitmex) ModifyOrder(action *order.Modify) (order.Modify, error) { } // CancelOrder cancels an order by its corresponding ID number -func (b *Bitmex) CancelOrder(o *order.Cancel) error { +func (b *Bitmex) CancelOrder(ctx context.Context, o *order.Cancel) error { if err := o.Validate(o.StandardCancel()); err != nil { return err } var params = OrderCancelParams{ OrderID: o.ID, } - _, err := b.CancelOrders(¶ms) + _, err := b.CancelOrders(ctx, ¶ms) return err } // CancelBatchOrders cancels an orders by their corresponding ID numbers -func (b *Bitmex) CancelBatchOrders(o []order.Cancel) (order.CancelBatchResponse, error) { +func (b *Bitmex) CancelBatchOrders(ctx context.Context, o []order.Cancel) (order.CancelBatchResponse, error) { return order.CancelBatchResponse{}, common.ErrNotYetImplemented } // CancelAllOrders cancels all orders associated with a currency pair -func (b *Bitmex) CancelAllOrders(_ *order.Cancel) (order.CancelAllResponse, error) { +func (b *Bitmex) CancelAllOrders(ctx context.Context, _ *order.Cancel) (order.CancelAllResponse, error) { cancelAllOrdersResponse := order.CancelAllResponse{ Status: make(map[string]string), } var emptyParams OrderCancelAllParams - orders, err := b.CancelAllExistingOrders(emptyParams) + orders, err := b.CancelAllExistingOrders(ctx, emptyParams) if err != nil { return cancelAllOrdersResponse, err } @@ -654,19 +656,19 @@ func (b *Bitmex) CancelAllOrders(_ *order.Cancel) (order.CancelAllResponse, erro } // GetOrderInfo returns order information based on order ID -func (b *Bitmex) GetOrderInfo(orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { +func (b *Bitmex) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { var orderDetail order.Detail return orderDetail, common.ErrNotYetImplemented } // GetDepositAddress returns a deposit address for a specified currency -func (b *Bitmex) GetDepositAddress(cryptocurrency currency.Code, _ string) (string, error) { - return b.GetCryptoDepositAddress(cryptocurrency.String()) +func (b *Bitmex) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _ string) (string, error) { + return b.GetCryptoDepositAddress(ctx, cryptocurrency.String()) } // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is // submitted -func (b *Bitmex) WithdrawCryptocurrencyFunds(withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (b *Bitmex) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } @@ -680,7 +682,7 @@ func (b *Bitmex) WithdrawCryptocurrencyFunds(withdrawRequest *withdraw.Request) r.Fee = withdrawRequest.Crypto.FeeAmount } - resp, err := b.UserRequestWithdrawal(r) + resp, err := b.UserRequestWithdrawal(ctx, r) if err != nil { return nil, err } @@ -693,18 +695,18 @@ func (b *Bitmex) WithdrawCryptocurrencyFunds(withdrawRequest *withdraw.Request) // WithdrawFiatFunds returns a withdrawal ID when a withdrawal is // submitted -func (b *Bitmex) WithdrawFiatFunds(_ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (b *Bitmex) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a withdrawal is // submitted -func (b *Bitmex) WithdrawFiatFundsToInternationalBank(_ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (b *Bitmex) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // GetFeeByType returns an estimate of fee based on type of transaction -func (b *Bitmex) GetFeeByType(feeBuilder *exchange.FeeBuilder) (float64, error) { +func (b *Bitmex) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { if !b.AllowAuthenticatedRequest() && // Todo check connection status feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { feeBuilder.FeeType = exchange.OfflineTradeFee @@ -714,7 +716,7 @@ func (b *Bitmex) GetFeeByType(feeBuilder *exchange.FeeBuilder) (float64, error) // GetActiveOrders retrieves any orders that are active/open // This function is not concurrency safe due to orderSide/orderType maps -func (b *Bitmex) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, error) { +func (b *Bitmex) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) { if err := req.Validate(); err != nil { return nil, err } @@ -723,7 +725,7 @@ func (b *Bitmex) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, e params := OrdersRequest{} params.Filter = "{\"open\":true}" - resp, err := b.GetOrders(¶ms) + resp, err := b.GetOrders(ctx, ¶ms) if err != nil { return nil, err } @@ -767,14 +769,14 @@ func (b *Bitmex) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, e // GetOrderHistory retrieves account order information // Can Limit response to specific order status // This function is not concurrency safe due to orderSide/orderType maps -func (b *Bitmex) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, error) { +func (b *Bitmex) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) { if err := req.Validate(); err != nil { return nil, err } var orders []order.Detail params := OrdersRequest{} - resp, err := b.GetOrders(¶ms) + resp, err := b.GetOrders(ctx, ¶ms) if err != nil { return nil, err } @@ -815,23 +817,23 @@ func (b *Bitmex) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, e } // AuthenticateWebsocket sends an authentication message to the websocket -func (b *Bitmex) AuthenticateWebsocket() error { +func (b *Bitmex) AuthenticateWebsocket(_ context.Context) error { return b.websocketSendAuth() } // ValidateCredentials validates current credentials used for wrapper // functionality -func (b *Bitmex) ValidateCredentials(assetType asset.Item) error { - _, err := b.UpdateAccountInfo(assetType) +func (b *Bitmex) ValidateCredentials(ctx context.Context, assetType asset.Item) error { + _, err := b.UpdateAccountInfo(ctx, assetType) return b.CheckTransientError(err) } // GetHistoricCandles returns candles between a time period for a set time interval -func (b *Bitmex) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (b *Bitmex) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { return kline.Item{}, common.ErrFunctionNotSupported } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (b *Bitmex) GetHistoricCandlesExtended(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (b *Bitmex) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { return kline.Item{}, common.ErrFunctionNotSupported } diff --git a/exchanges/bitstamp/bitstamp.go b/exchanges/bitstamp/bitstamp.go index 233ffe6b..e34f0eb9 100644 --- a/exchanges/bitstamp/bitstamp.go +++ b/exchanges/bitstamp/bitstamp.go @@ -66,12 +66,12 @@ type Bitstamp struct { } // GetFee returns an estimate of fee based on type of transaction -func (b *Bitstamp) GetFee(feeBuilder *exchange.FeeBuilder) (float64, error) { +func (b *Bitstamp) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { var fee float64 switch feeBuilder.FeeType { case exchange.CryptocurrencyTradeFee: - balance, err := b.GetBalance() + balance, err := b.GetBalance(ctx) if err != nil { return 0, err } @@ -140,7 +140,7 @@ func (b *Bitstamp) CalculateTradingFee(base, quote currency.Code, purchasePrice, } // GetTicker returns ticker information -func (b *Bitstamp) GetTicker(currency string, hourly bool) (*Ticker, error) { +func (b *Bitstamp) GetTicker(ctx context.Context, currency string, hourly bool) (*Ticker, error) { response := Ticker{} tickerEndpoint := bitstampAPITicker @@ -148,13 +148,13 @@ func (b *Bitstamp) GetTicker(currency string, hourly bool) (*Ticker, error) { tickerEndpoint = bitstampAPITickerHourly } path := "/v" + bitstampAPIVersion + "/" + tickerEndpoint + "/" + strings.ToLower(currency) + "/" - return &response, b.SendHTTPRequest(exchange.RestSpot, path, &response) + return &response, b.SendHTTPRequest(ctx, exchange.RestSpot, path, &response) } // GetOrderbook Returns a JSON dictionary with "bids" and "asks". Each is a list // of open orders and each order is represented as a list holding the price and // the amount. -func (b *Bitstamp) GetOrderbook(currency string) (Orderbook, error) { +func (b *Bitstamp) GetOrderbook(ctx context.Context, currency string) (Orderbook, error) { type response struct { Timestamp int64 `json:"timestamp,string"` Bids [][]string `json:"bids"` @@ -162,7 +162,7 @@ func (b *Bitstamp) GetOrderbook(currency string) (Orderbook, error) { } resp := response{} path := "/v" + bitstampAPIVersion + "/" + bitstampAPIOrderbook + "/" + strings.ToLower(currency) + "/" - err := b.SendHTTPRequest(exchange.RestSpot, path, &resp) + err := b.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) if err != nil { return Orderbook{}, err } @@ -203,35 +203,35 @@ func (b *Bitstamp) GetOrderbook(currency string) (Orderbook, error) { // GetTradingPairs returns a list of trading pairs which Bitstamp // currently supports -func (b *Bitstamp) GetTradingPairs() ([]TradingPair, error) { +func (b *Bitstamp) GetTradingPairs(ctx context.Context) ([]TradingPair, error) { var result []TradingPair path := "/v" + bitstampAPIVersion + "/" + bitstampAPITradingPairsInfo - return result, b.SendHTTPRequest(exchange.RestSpot, path, &result) + return result, b.SendHTTPRequest(ctx, exchange.RestSpot, path, &result) } // GetTransactions returns transaction information // value paramater ["time"] = "minute", "hour", "day" will collate your // response into time intervals. -func (b *Bitstamp) GetTransactions(currencyPair, timePeriod string) ([]Transactions, error) { +func (b *Bitstamp) GetTransactions(ctx context.Context, currencyPair, timePeriod string) ([]Transactions, error) { var transactions []Transactions requestURL := "/v" + bitstampAPIVersion + "/" + bitstampAPITransactions + "/" + strings.ToLower(currencyPair) + "/" if timePeriod != "" { requestURL += "?time=" + url.QueryEscape(timePeriod) } - return transactions, b.SendHTTPRequest(exchange.RestSpot, requestURL, &transactions) + return transactions, b.SendHTTPRequest(ctx, exchange.RestSpot, requestURL, &transactions) } // GetEURUSDConversionRate returns the conversion rate between Euro and USD -func (b *Bitstamp) GetEURUSDConversionRate() (EURUSDConversionRate, error) { +func (b *Bitstamp) GetEURUSDConversionRate(ctx context.Context) (EURUSDConversionRate, error) { rate := EURUSDConversionRate{} path := "/" + bitstampAPIEURUSD - return rate, b.SendHTTPRequest(exchange.RestSpot, path, &rate) + return rate, b.SendHTTPRequest(ctx, exchange.RestSpot, path, &rate) } // GetBalance returns full balance of currency held on the exchange -func (b *Bitstamp) GetBalance() (Balances, error) { +func (b *Bitstamp) GetBalance(ctx context.Context) (Balances, error) { var balance map[string]string - err := b.SendAuthenticatedHTTPRequest(exchange.RestSpot, bitstampAPIBalance, true, nil, &balance) + err := b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, bitstampAPIBalance, true, nil, &balance) if err != nil { return nil, err } @@ -272,7 +272,7 @@ func (b *Bitstamp) GetBalance() (Balances, error) { } // GetUserTransactions returns an array of transactions -func (b *Bitstamp) GetUserTransactions(currencyPair string) ([]UserTransactions, error) { +func (b *Bitstamp) GetUserTransactions(ctx context.Context, currencyPair string) ([]UserTransactions, error) { type Response struct { Date string `json:"datetime"` TransactionID int64 `json:"id"` @@ -288,14 +288,14 @@ func (b *Bitstamp) GetUserTransactions(currencyPair string) ([]UserTransactions, var response []Response if currencyPair == "" { - if err := b.SendAuthenticatedHTTPRequest(exchange.RestSpot, bitstampAPIUserTransactions, + if err := b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, bitstampAPIUserTransactions, true, url.Values{}, &response); err != nil { return nil, err } } else { - if err := b.SendAuthenticatedHTTPRequest(exchange.RestSpot, bitstampAPIUserTransactions+"/"+currencyPair, + if err := b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, bitstampAPIUserTransactions+"/"+currencyPair, true, url.Values{}, &response); err != nil { @@ -335,29 +335,29 @@ func (b *Bitstamp) GetUserTransactions(currencyPair string) ([]UserTransactions, } // GetOpenOrders returns all open orders on the exchange -func (b *Bitstamp) GetOpenOrders(currencyPair string) ([]Order, error) { +func (b *Bitstamp) GetOpenOrders(ctx context.Context, currencyPair string) ([]Order, error) { var resp []Order path := bitstampAPIOpenOrders + "/" + strings.ToLower(currencyPair) - return resp, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, path, true, nil, &resp) + return resp, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, path, true, nil, &resp) } // GetOrderStatus returns an the status of an order by its ID -func (b *Bitstamp) GetOrderStatus(orderID int64) (OrderStatus, error) { +func (b *Bitstamp) GetOrderStatus(ctx context.Context, orderID int64) (OrderStatus, error) { resp := OrderStatus{} req := url.Values{} req.Add("id", strconv.FormatInt(orderID, 10)) return resp, - b.SendAuthenticatedHTTPRequest(exchange.RestSpot, bitstampAPIOrderStatus, false, req, &resp) + b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, bitstampAPIOrderStatus, false, req, &resp) } // CancelExistingOrder cancels order by ID -func (b *Bitstamp) CancelExistingOrder(orderID int64) (CancelOrder, error) { +func (b *Bitstamp) CancelExistingOrder(ctx context.Context, orderID int64) (CancelOrder, error) { var req = url.Values{} req.Add("id", strconv.FormatInt(orderID, 10)) var result CancelOrder - err := b.SendAuthenticatedHTTPRequest(exchange.RestSpot, bitstampAPICancelOrder, true, req, &result) + err := b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, bitstampAPICancelOrder, true, req, &result) if err != nil { return result, err } @@ -366,15 +366,15 @@ func (b *Bitstamp) CancelExistingOrder(orderID int64) (CancelOrder, error) { } // CancelAllExistingOrders cancels all open orders on the exchange -func (b *Bitstamp) CancelAllExistingOrders() (bool, error) { +func (b *Bitstamp) CancelAllExistingOrders(ctx context.Context) (bool, error) { result := false return result, - b.SendAuthenticatedHTTPRequest(exchange.RestSpot, bitstampAPICancelAllOrders, false, nil, &result) + b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, bitstampAPICancelAllOrders, false, nil, &result) } // PlaceOrder places an order on the exchange. -func (b *Bitstamp) PlaceOrder(currencyPair string, price, amount float64, buy, market bool) (Order, error) { +func (b *Bitstamp) PlaceOrder(ctx context.Context, currencyPair string, price, amount float64, buy, market bool) (Order, error) { var req = url.Values{} req.Add("amount", strconv.FormatFloat(amount, 'f', -1, 64)) req.Add("price", strconv.FormatFloat(price, 'f', -1, 64)) @@ -393,13 +393,13 @@ func (b *Bitstamp) PlaceOrder(currencyPair string, price, amount float64, buy, m } return response, - b.SendAuthenticatedHTTPRequest(exchange.RestSpot, path, true, req, &response) + b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, path, true, req, &response) } // GetWithdrawalRequests returns withdrawal requests for the account // timedelta - positive integer with max value 50000000 which returns requests // from number of seconds ago to now. -func (b *Bitstamp) GetWithdrawalRequests(timedelta int64) ([]WithdrawalRequests, error) { +func (b *Bitstamp) GetWithdrawalRequests(ctx context.Context, timedelta int64) ([]WithdrawalRequests, error) { var resp []WithdrawalRequests if timedelta > 50000000 || timedelta < 0 { return resp, errors.New("time delta exceeded, max: 50000000 min: 0") @@ -413,7 +413,7 @@ func (b *Bitstamp) GetWithdrawalRequests(timedelta int64) ([]WithdrawalRequests, } return resp, - b.SendAuthenticatedHTTPRequest(exchange.RestSpot, bitstampAPIWithdrawalRequests, false, value, &resp) + b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, bitstampAPIWithdrawalRequests, false, value, &resp) } // CryptoWithdrawal withdraws a cryptocurrency into a supplied wallet, returns ID @@ -422,7 +422,7 @@ func (b *Bitstamp) GetWithdrawalRequests(timedelta int64) ([]WithdrawalRequests, // symbol - the type of crypto ie "ltc", "btc", "eth" // destTag - only for XRP default to "" // instant - only for bitcoins -func (b *Bitstamp) CryptoWithdrawal(amount float64, address, symbol, destTag string, instant bool) (CryptoWithdrawalResponse, error) { +func (b *Bitstamp) CryptoWithdrawal(ctx context.Context, amount float64, address, symbol, destTag string, instant bool) (CryptoWithdrawalResponse, error) { var req = url.Values{} req.Add("amount", strconv.FormatFloat(amount, 'f', -1, 64)) req.Add("address", address) @@ -452,11 +452,11 @@ func (b *Bitstamp) CryptoWithdrawal(amount float64, address, symbol, destTag str return resp, errors.New("incorrect symbol") } - return resp, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, endpoint, false, req, &resp) + return resp, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, endpoint, false, req, &resp) } // OpenBankWithdrawal Opens a bank withdrawal request (SEPA or international) -func (b *Bitstamp) OpenBankWithdrawal(amount float64, currency, +func (b *Bitstamp) OpenBankWithdrawal(ctx context.Context, amount float64, currency, name, iban, bic, address, postalCode, city, country, comment, withdrawalType string) (FIATWithdrawalResponse, error) { var req = url.Values{} @@ -473,11 +473,11 @@ func (b *Bitstamp) OpenBankWithdrawal(amount float64, currency, req.Add("comment", comment) resp := FIATWithdrawalResponse{} - return resp, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, bitstampAPIOpenWithdrawal, true, req, &resp) + return resp, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, bitstampAPIOpenWithdrawal, true, req, &resp) } // OpenInternationalBankWithdrawal Opens a bank withdrawal request (international) -func (b *Bitstamp) OpenInternationalBankWithdrawal(amount float64, currency, +func (b *Bitstamp) OpenInternationalBankWithdrawal(ctx context.Context, amount float64, currency, name, iban, bic, address, postalCode, city, country, bankName, bankAddress, bankPostCode, bankCity, bankCountry, internationalCurrency, comment, withdrawalType string) (FIATWithdrawalResponse, error) { @@ -501,12 +501,12 @@ func (b *Bitstamp) OpenInternationalBankWithdrawal(amount float64, currency, req.Add("bank_country", bankCountry) resp := FIATWithdrawalResponse{} - return resp, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, bitstampAPIOpenWithdrawal, true, req, &resp) + return resp, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, bitstampAPIOpenWithdrawal, true, req, &resp) } // GetCryptoDepositAddress returns a depositing address by crypto // crypto - example "btc", "ltc", "eth", "xrp" or "bch" -func (b *Bitstamp) GetCryptoDepositAddress(crypto currency.Code) (string, error) { +func (b *Bitstamp) GetCryptoDepositAddress(ctx context.Context, crypto currency.Code) (string, error) { var resp string v2Resp := struct { Address string `json:"address"` @@ -515,23 +515,23 @@ func (b *Bitstamp) GetCryptoDepositAddress(crypto currency.Code) (string, error) switch crypto { case currency.BTC: return resp, - b.SendAuthenticatedHTTPRequest(exchange.RestSpot, bitstampAPIBitcoinDeposit, false, nil, &resp) + b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, bitstampAPIBitcoinDeposit, false, nil, &resp) case currency.LTC: return v2Resp.Address, - b.SendAuthenticatedHTTPRequest(exchange.RestSpot, bitstampAPILitecoinDeposit, true, nil, &v2Resp) + b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, bitstampAPILitecoinDeposit, true, nil, &v2Resp) case currency.ETH: return v2Resp.Address, - b.SendAuthenticatedHTTPRequest(exchange.RestSpot, bitstampAPIEthereumDeposit, true, nil, &v2Resp) + b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, bitstampAPIEthereumDeposit, true, nil, &v2Resp) case currency.XRP: return v2Resp.Address, - b.SendAuthenticatedHTTPRequest(exchange.RestSpot, bitstampAPIXrpDeposit, true, nil, &v2Resp) + b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, bitstampAPIXrpDeposit, true, nil, &v2Resp) case currency.BCH: return v2Resp.Address, - b.SendAuthenticatedHTTPRequest(exchange.RestSpot, bitstampAPIBitcoinCashDeposit, true, nil, &v2Resp) + b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, bitstampAPIBitcoinCashDeposit, true, nil, &v2Resp) default: return resp, fmt.Errorf("unsupported cryptocurrency string %s", crypto) @@ -539,15 +539,15 @@ func (b *Bitstamp) GetCryptoDepositAddress(crypto currency.Code) (string, error) } // GetUnconfirmedBitcoinDeposits returns unconfirmed transactions -func (b *Bitstamp) GetUnconfirmedBitcoinDeposits() ([]UnconfirmedBTCTransactions, error) { +func (b *Bitstamp) GetUnconfirmedBitcoinDeposits(ctx context.Context) ([]UnconfirmedBTCTransactions, error) { var response []UnconfirmedBTCTransactions return response, - b.SendAuthenticatedHTTPRequest(exchange.RestSpot, bitstampAPIUnconfirmedBitcoin, false, nil, &response) + b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, bitstampAPIUnconfirmedBitcoin, false, nil, &response) } // OHLC returns OHLCV data for step (interval) -func (b *Bitstamp) OHLC(currency string, start, end time.Time, step, limit string) (resp OHLCResponse, err error) { +func (b *Bitstamp) OHLC(ctx context.Context, currency string, start, end time.Time, step, limit string) (resp OHLCResponse, err error) { var v = url.Values{} v.Add("limit", limit) v.Add("step", step) @@ -561,7 +561,7 @@ func (b *Bitstamp) OHLC(currency string, start, end time.Time, step, limit strin if !end.IsZero() { v.Add("end", strconv.FormatInt(end.Unix(), 10)) } - return resp, b.SendHTTPRequest(exchange.RestSpot, common.EncodeURLValues("/v"+bitstampAPIVersion+"/"+bitstampOHLC+"/"+currency, v), &resp) + return resp, b.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues("/v"+bitstampAPIVersion+"/"+bitstampOHLC+"/"+currency, v), &resp) } // TransferAccountBalance transfers funds from either a main or sub account @@ -569,7 +569,7 @@ func (b *Bitstamp) OHLC(currency string, start, end time.Time, step, limit strin // currency - which currency to transfer // subaccount - name of account // toMain - bool either to or from account -func (b *Bitstamp) TransferAccountBalance(amount float64, currency, subAccount string, toMain bool) error { +func (b *Bitstamp) TransferAccountBalance(ctx context.Context, amount float64, currency, subAccount string, toMain bool) error { var req = url.Values{} req.Add("amount", strconv.FormatFloat(amount, 'f', -1, 64)) req.Add("currency", currency) @@ -589,11 +589,11 @@ func (b *Bitstamp) TransferAccountBalance(amount float64, currency, subAccount s var resp interface{} - return b.SendAuthenticatedHTTPRequest(exchange.RestSpot, path, true, req, &resp) + return b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, path, true, req, &resp) } // SendHTTPRequest sends an unauthenticated HTTP request -func (b *Bitstamp) SendHTTPRequest(ep exchange.URL, path string, result interface{}) error { +func (b *Bitstamp) SendHTTPRequest(ctx context.Context, ep exchange.URL, path string, result interface{}) error { endpoint, err := b.API.Endpoints.GetURL(ep) if err != nil { return err @@ -606,13 +606,13 @@ func (b *Bitstamp) SendHTTPRequest(ep exchange.URL, path string, result interfac HTTPDebugging: b.HTTPDebugging, HTTPRecording: b.HTTPRecording, } - return b.SendPayload(context.Background(), request.Unset, func() (*request.Item, error) { + return b.SendPayload(ctx, request.Unset, func() (*request.Item, error) { return item, nil }) } // SendAuthenticatedHTTPRequest sends an authenticated request -func (b *Bitstamp) SendAuthenticatedHTTPRequest(ep exchange.URL, path string, v2 bool, values url.Values, result interface{}) error { +func (b *Bitstamp) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, path string, v2 bool, values url.Values, result interface{}) error { if !b.AllowAuthenticatedRequest() { return fmt.Errorf("%s %w", b.Name, exchange.ErrAuthenticatedRequestWithoutCredentialsSet) } @@ -626,7 +626,7 @@ func (b *Bitstamp) SendAuthenticatedHTTPRequest(ep exchange.URL, path string, v2 } interim := json.RawMessage{} - err = b.SendPayload(context.Background(), request.Unset, func() (*request.Item, error) { + err = b.SendPayload(ctx, request.Unset, func() (*request.Item, error) { n := b.Requester.GetNonce(true).String() values.Set("key", b.API.Credentials.Key) diff --git a/exchanges/bitstamp/bitstamp_test.go b/exchanges/bitstamp/bitstamp_test.go index aebed087..2c625328 100644 --- a/exchanges/bitstamp/bitstamp_test.go +++ b/exchanges/bitstamp/bitstamp_test.go @@ -1,6 +1,7 @@ package bitstamp import ( + "context" "errors" "testing" "time" @@ -44,7 +45,7 @@ func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { t.Parallel() var feeBuilder = setFeeBuilder() - _, err := b.GetFeeByType(feeBuilder) + _, err := b.GetFeeByType(context.Background(), feeBuilder) if err != nil { t.Fatal(err) } @@ -69,7 +70,7 @@ func TestGetFee(t *testing.T) { var feeBuilder = setFeeBuilder() // CryptocurrencyTradeFee Basic - if _, err := b.GetFee(feeBuilder); err != nil { + if _, err := b.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } @@ -77,35 +78,35 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.Amount = 1000 feeBuilder.PurchasePrice = 1000 - if _, err := b.GetFee(feeBuilder); err != nil { + if _, err := b.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyTradeFee IsMaker feeBuilder = setFeeBuilder() feeBuilder.IsMaker = true - if _, err := b.GetFee(feeBuilder); err != nil { + if _, err := b.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyTradeFee Negative purchase price feeBuilder = setFeeBuilder() feeBuilder.PurchasePrice = -1000 - if _, err := b.GetFee(feeBuilder); err != nil { + if _, err := b.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyWithdrawalFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee - if _, err := b.GetFee(feeBuilder); err != nil { + if _, err := b.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyDepositFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.CryptocurrencyDepositFee - if _, err := b.GetFee(feeBuilder); err != nil { + if _, err := b.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } @@ -113,7 +114,7 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankDepositFee feeBuilder.FiatCurrency = currency.HKD - if _, err := b.GetFee(feeBuilder); err != nil { + if _, err := b.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } @@ -121,7 +122,7 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee feeBuilder.FiatCurrency = currency.HKD - if _, err := b.GetFee(feeBuilder); err != nil { + if _, err := b.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } } @@ -154,7 +155,8 @@ func TestCalculateTradingFee(t *testing.T) { func TestGetTicker(t *testing.T) { t.Parallel() - _, err := b.GetTicker(currency.BTC.String()+currency.USD.String(), false) + _, err := b.GetTicker(context.Background(), + currency.BTC.String()+currency.USD.String(), false) if err != nil { t.Error("GetTicker() error", err) } @@ -162,7 +164,8 @@ func TestGetTicker(t *testing.T) { func TestGetOrderbook(t *testing.T) { t.Parallel() - _, err := b.GetOrderbook(currency.BTC.String() + currency.USD.String()) + _, err := b.GetOrderbook(context.Background(), + currency.BTC.String()+currency.USD.String()) if err != nil { t.Error("GetOrderbook() error", err) } @@ -171,7 +174,7 @@ func TestGetOrderbook(t *testing.T) { func TestGetTradingPairs(t *testing.T) { t.Parallel() - _, err := b.GetTradingPairs() + _, err := b.GetTradingPairs(context.Background()) if err != nil { t.Error("GetTradingPairs() error", err) } @@ -179,7 +182,7 @@ func TestGetTradingPairs(t *testing.T) { func TestFetchTradablePairs(t *testing.T) { t.Parallel() - r, err := b.FetchTradablePairs(asset.Spot) + r, err := b.FetchTradablePairs(context.Background(), asset.Spot) if err != nil { t.Fatal(err) } @@ -200,7 +203,8 @@ func TestFetchTradablePairs(t *testing.T) { func TestGetTransactions(t *testing.T) { t.Parallel() - _, err := b.GetTransactions(currency.BTC.String()+currency.USD.String(), "hour") + _, err := b.GetTransactions(context.Background(), + currency.BTC.String()+currency.USD.String(), "hour") if err != nil { t.Error("GetTransactions() error", err) } @@ -209,7 +213,7 @@ func TestGetTransactions(t *testing.T) { func TestGetEURUSDConversionRate(t *testing.T) { t.Parallel() - _, err := b.GetEURUSDConversionRate() + _, err := b.GetEURUSDConversionRate(context.Background()) if err != nil { t.Error("GetEURUSDConversionRate() error", err) } @@ -217,7 +221,7 @@ func TestGetEURUSDConversionRate(t *testing.T) { func TestGetBalance(t *testing.T) { t.Parallel() - _, err := b.GetBalance() + _, err := b.GetBalance(context.Background()) switch { case areTestAPIKeysSet() && err != nil && !mockTests: t.Error("GetBalance() error", err) @@ -231,7 +235,7 @@ func TestGetBalance(t *testing.T) { func TestGetUserTransactions(t *testing.T) { t.Parallel() - _, err := b.GetUserTransactions("btcusd") + _, err := b.GetUserTransactions(context.Background(), "btcusd") switch { case areTestAPIKeysSet() && err != nil && !mockTests: t.Error("GetUserTransactions() error", err) @@ -245,7 +249,7 @@ func TestGetUserTransactions(t *testing.T) { func TestGetOpenOrders(t *testing.T) { t.Parallel() - _, err := b.GetOpenOrders("btcusd") + _, err := b.GetOpenOrders(context.Background(), "btcusd") switch { case areTestAPIKeysSet() && err != nil && !mockTests: t.Error("GetOpenOrders() error", err) @@ -259,7 +263,7 @@ func TestGetOpenOrders(t *testing.T) { func TestGetOrderStatus(t *testing.T) { t.Parallel() - _, err := b.GetOrderStatus(1337) + _, err := b.GetOrderStatus(context.Background(), 1337) switch { case areTestAPIKeysSet() && err != nil && !mockTests: t.Error("GetOrderStatus() error", err) @@ -273,7 +277,7 @@ func TestGetOrderStatus(t *testing.T) { func TestGetWithdrawalRequests(t *testing.T) { t.Parallel() - _, err := b.GetWithdrawalRequests(0) + _, err := b.GetWithdrawalRequests(context.Background(), 0) switch { case areTestAPIKeysSet() && err != nil && !mockTests: t.Error("GetWithdrawalRequests() error", err) @@ -287,7 +291,7 @@ func TestGetWithdrawalRequests(t *testing.T) { func TestGetUnconfirmedBitcoinDeposits(t *testing.T) { t.Parallel() - _, err := b.GetUnconfirmedBitcoinDeposits() + _, err := b.GetUnconfirmedBitcoinDeposits(context.Background()) switch { case areTestAPIKeysSet() && err != nil && !mockTests: t.Error("GetUnconfirmedBitcoinDeposits() error", err) @@ -305,7 +309,8 @@ func TestTransferAccountBalance(t *testing.T) { t.Skip() } - err := b.TransferAccountBalance(0.01, "btc", "testAccount", true) + err := b.TransferAccountBalance(context.Background(), + 0.01, "btc", "testAccount", true) if !mockTests && err != nil { t.Error("TransferAccountBalance() error", err) } @@ -336,7 +341,7 @@ func TestGetActiveOrders(t *testing.T) { AssetType: asset.Spot, } - _, err := b.GetActiveOrders(&getOrdersRequest) + _, err := b.GetActiveOrders(context.Background(), &getOrdersRequest) switch { case areTestAPIKeysSet() && err != nil && !mockTests: t.Errorf("Could not get open orders: %s", err) @@ -355,7 +360,7 @@ func TestGetOrderHistory(t *testing.T) { AssetType: asset.Spot, } - _, err := b.GetOrderHistory(&getOrdersRequest) + _, err := b.GetOrderHistory(context.Background(), &getOrdersRequest) switch { case areTestAPIKeysSet() && err != nil && !mockTests: t.Errorf("Could not get order history: %s", err) @@ -388,7 +393,7 @@ func TestSubmitOrder(t *testing.T) { ClientID: "meowOrder", AssetType: asset.Spot, } - response, err := b.SubmitOrder(orderSubmission) + response, err := b.SubmitOrder(context.Background(), orderSubmission) switch { case areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) && !mockTests: t.Errorf("Order failed to be placed: %v", err) @@ -410,7 +415,7 @@ func TestCancelExchangeOrder(t *testing.T) { ID: "1234", AssetType: asset.Spot, } - err := b.CancelOrder(orderCancellation) + err := b.CancelOrder(context.Background(), orderCancellation) switch { case !areTestAPIKeysSet() && err == nil && !mockTests: t.Error("Expecting an error when no keys are set") @@ -428,7 +433,8 @@ func TestCancelAllExchangeOrders(t *testing.T) { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - resp, err := b.CancelAllOrders(&order.Cancel{AssetType: asset.Spot}) + resp, err := b.CancelAllOrders(context.Background(), + &order.Cancel{AssetType: asset.Spot}) switch { case !areTestAPIKeysSet() && err == nil && !mockTests: t.Error("Expecting an error when no keys are set") @@ -446,7 +452,7 @@ func TestCancelAllExchangeOrders(t *testing.T) { func TestModifyOrder(t *testing.T) { t.Parallel() - _, err := b.ModifyOrder(&order.Modify{AssetType: asset.Spot}) + _, err := b.ModifyOrder(context.Background(), &order.Modify{AssetType: asset.Spot}) if err == nil { t.Error("ModifyOrder() Expected error") } @@ -468,7 +474,7 @@ func TestWithdraw(t *testing.T) { }, } - _, err := b.WithdrawCryptocurrencyFunds(&withdrawCryptoRequest) + _, err := b.WithdrawCryptocurrencyFunds(context.Background(), &withdrawCryptoRequest) switch { case !areTestAPIKeysSet() && err == nil && !mockTests: t.Error("Expecting an error when no keys are set") @@ -508,7 +514,7 @@ func TestWithdrawFiat(t *testing.T) { Description: "WITHDRAW IT ALL", } - _, err := b.WithdrawFiatFunds(&withdrawFiatRequest) + _, err := b.WithdrawFiatFunds(context.Background(), &withdrawFiatRequest) switch { case !areTestAPIKeysSet() && err == nil && !mockTests: t.Error("Expecting an error when no keys are set") @@ -554,7 +560,8 @@ func TestWithdrawInternationalBank(t *testing.T) { Description: "WITHDRAW IT ALL", } - _, err := b.WithdrawFiatFundsToInternationalBank(&withdrawFiatRequest) + _, err := b.WithdrawFiatFundsToInternationalBank(context.Background(), + &withdrawFiatRequest) switch { case !areTestAPIKeysSet() && err == nil && !mockTests: t.Error("Expecting an error when no keys are set") @@ -568,7 +575,7 @@ func TestWithdrawInternationalBank(t *testing.T) { func TestGetDepositAddress(t *testing.T) { t.Parallel() - _, err := b.GetDepositAddress(currency.BTC, "") + _, err := b.GetDepositAddress(context.Background(), currency.BTC, "") switch { case areTestAPIKeysSet() && customerID != "" && err != nil && !mockTests: t.Error("GetDepositAddress error", err) @@ -674,7 +681,7 @@ func TestWsRequestReconnect(t *testing.T) { func TestBitstamp_OHLC(t *testing.T) { start := time.Unix(1546300800, 0) end := time.Unix(1577836799, 0) - _, err := b.OHLC("btcusd", start, end, "60", "10") + _, err := b.OHLC(context.Background(), "btcusd", start, end, "60", "10") if err != nil { t.Fatal(err) } @@ -688,7 +695,8 @@ func TestBitstamp_GetHistoricCandles(t *testing.T) { start := time.Unix(1546300800, 0) end := time.Unix(1577836799, 0) - _, err = b.GetHistoricCandles(currencyPair, asset.Spot, start, end, kline.OneDay) + _, err = b.GetHistoricCandles(context.Background(), + currencyPair, asset.Spot, start, end, kline.OneDay) if err != nil { t.Fatal(err) } @@ -701,7 +709,8 @@ func TestBitstamp_GetHistoricCandlesExtended(t *testing.T) { } start := time.Unix(1546300800, 0) end := time.Unix(1577836799, 0) - _, err = b.GetHistoricCandlesExtended(currencyPair, asset.Spot, start, end, kline.OneDay) + _, err = b.GetHistoricCandlesExtended(context.Background(), + currencyPair, asset.Spot, start, end, kline.OneDay) if err != nil { t.Fatal(err) } @@ -713,7 +722,7 @@ func TestGetRecentTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = b.GetRecentTrades(currencyPair, asset.Spot) + _, err = b.GetRecentTrades(context.Background(), currencyPair, asset.Spot) if err != nil { t.Error(err) } @@ -725,7 +734,8 @@ func TestGetHistoricTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = b.GetHistoricTrades(currencyPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) + _, err = b.GetHistoricTrades(context.Background(), + currencyPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) if err != nil && err != common.ErrFunctionNotSupported { t.Error(err) } diff --git a/exchanges/bitstamp/bitstamp_websocket.go b/exchanges/bitstamp/bitstamp_websocket.go index ed3b7ca8..14daad25 100644 --- a/exchanges/bitstamp/bitstamp_websocket.go +++ b/exchanges/bitstamp/bitstamp_websocket.go @@ -1,6 +1,7 @@ package bitstamp import ( + "context" "encoding/json" "errors" "net/http" @@ -36,7 +37,7 @@ func (b *Bitstamp) WsConnect() error { if b.Verbose { log.Debugf(log.ExchangeSys, "%s Connected to Websocket.\n", b.Name) } - err = b.seedOrderBook() + err = b.seedOrderBook(context.TODO()) if err != nil { b.Websocket.DataHandler <- err } @@ -293,7 +294,7 @@ func (b *Bitstamp) wsUpdateOrderbook(update websocketOrderBook, p currency.Pair, }) } -func (b *Bitstamp) seedOrderBook() error { +func (b *Bitstamp) seedOrderBook(ctx context.Context) error { p, err := b.GetEnabledPairs(asset.Spot) if err != nil { return err @@ -304,7 +305,7 @@ func (b *Bitstamp) seedOrderBook() error { if err != nil { return err } - orderbookSeed, err := b.GetOrderbook(pairFmt.String()) + orderbookSeed, err := b.GetOrderbook(ctx, pairFmt.String()) if err != nil { return err } diff --git a/exchanges/bitstamp/bitstamp_wrapper.go b/exchanges/bitstamp/bitstamp_wrapper.go index 364c9687..647854ba 100644 --- a/exchanges/bitstamp/bitstamp_wrapper.go +++ b/exchanges/bitstamp/bitstamp_wrapper.go @@ -1,6 +1,7 @@ package bitstamp import ( + "context" "errors" "sort" "strconv" @@ -39,7 +40,7 @@ func (b *Bitstamp) GetDefaultConfig() (*config.ExchangeConfig, error) { } if b.Features.Supports.RESTCapabilities.AutoPairUpdates { - err = b.UpdateTradablePairs(true) + err = b.UpdateTradablePairs(context.TODO(), true) if err != nil { return nil, err } @@ -261,7 +262,7 @@ func (b *Bitstamp) Run() { return } - err = b.UpdateTradablePairs(forceUpdate) + err = b.UpdateTradablePairs(context.TODO(), forceUpdate) if err != nil { log.Errorf(log.ExchangeSys, "%s failed to update tradable pairs. Err: %s", @@ -271,8 +272,8 @@ func (b *Bitstamp) Run() { } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (b *Bitstamp) FetchTradablePairs(asset asset.Item) ([]string, error) { - pairs, err := b.GetTradingPairs() +func (b *Bitstamp) FetchTradablePairs(ctx context.Context, asset asset.Item) ([]string, error) { + pairs, err := b.GetTradingPairs(ctx) if err != nil { return nil, err } @@ -290,8 +291,8 @@ func (b *Bitstamp) FetchTradablePairs(asset asset.Item) ([]string, error) { // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (b *Bitstamp) UpdateTradablePairs(forceUpdate bool) error { - pairs, err := b.FetchTradablePairs(asset.Spot) +func (b *Bitstamp) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { + pairs, err := b.FetchTradablePairs(ctx, asset.Spot) if err != nil { return err } @@ -305,18 +306,18 @@ func (b *Bitstamp) UpdateTradablePairs(forceUpdate bool) error { } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (b *Bitstamp) UpdateTickers(a asset.Item) error { +func (b *Bitstamp) UpdateTickers(ctx context.Context, a asset.Item) error { return common.ErrFunctionNotSupported } // UpdateTicker updates and returns the ticker for a currency pair -func (b *Bitstamp) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) { +func (b *Bitstamp) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { fPair, err := b.FormatExchangeCurrency(p, a) if err != nil { return nil, err } - tick, err := b.GetTicker(fPair.String(), false) + tick, err := b.GetTicker(ctx, fPair.String(), false) if err != nil { return nil, err } @@ -341,7 +342,7 @@ func (b *Bitstamp) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, e } // FetchTicker returns the ticker for a currency pair -func (b *Bitstamp) FetchTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) { +func (b *Bitstamp) FetchTicker(ctx context.Context, p currency.Pair, assetType asset.Item) (*ticker.Price, error) { fPair, err := b.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err @@ -349,22 +350,22 @@ func (b *Bitstamp) FetchTicker(p currency.Pair, assetType asset.Item) (*ticker.P tick, err := ticker.GetTicker(b.Name, fPair, assetType) if err != nil { - return b.UpdateTicker(fPair, assetType) + return b.UpdateTicker(ctx, fPair, assetType) } return tick, nil } // GetFeeByType returns an estimate of fee based on type of transaction -func (b *Bitstamp) GetFeeByType(feeBuilder *exchange.FeeBuilder) (float64, error) { +func (b *Bitstamp) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { if (!b.AllowAuthenticatedRequest() || b.SkipAuthCheck) && // Todo check connection status feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { feeBuilder.FeeType = exchange.OfflineTradeFee } - return b.GetFee(feeBuilder) + return b.GetFee(ctx, feeBuilder) } // FetchOrderbook returns the orderbook for a currency pair -func (b *Bitstamp) FetchOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (b *Bitstamp) FetchOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { fPair, err := b.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err @@ -372,13 +373,13 @@ func (b *Bitstamp) FetchOrderbook(p currency.Pair, assetType asset.Item) (*order ob, err := orderbook.Get(b.Name, fPair, assetType) if err != nil { - return b.UpdateOrderbook(fPair, assetType) + return b.UpdateOrderbook(ctx, fPair, assetType) } return ob, nil } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (b *Bitstamp) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (b *Bitstamp) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { book := &orderbook.Base{ Exchange: b.Name, Pair: p, @@ -390,7 +391,7 @@ func (b *Bitstamp) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orde return book, err } - orderbookNew, err := b.GetOrderbook(fPair.String()) + orderbookNew, err := b.GetOrderbook(ctx, fPair.String()) if err != nil { return book, err } @@ -417,10 +418,10 @@ func (b *Bitstamp) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orde // UpdateAccountInfo retrieves balances for all enabled currencies for the // Bitstamp exchange -func (b *Bitstamp) UpdateAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (b *Bitstamp) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { var response account.Holdings response.Exchange = b.Name - accountBalance, err := b.GetBalance() + accountBalance, err := b.GetBalance(ctx) if err != nil { return response, err } @@ -446,10 +447,10 @@ func (b *Bitstamp) UpdateAccountInfo(assetType asset.Item) (account.Holdings, er } // FetchAccountInfo retrieves balances for all enabled currencies -func (b *Bitstamp) FetchAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (b *Bitstamp) FetchAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { acc, err := account.GetHoldings(b.Name, assetType) if err != nil { - return b.UpdateAccountInfo(assetType) + return b.UpdateAccountInfo(ctx, assetType) } return acc, nil @@ -457,24 +458,24 @@ func (b *Bitstamp) FetchAccountInfo(assetType asset.Item) (account.Holdings, err // GetFundingHistory returns funding history, deposits and // withdrawals -func (b *Bitstamp) GetFundingHistory() ([]exchange.FundHistory, error) { +func (b *Bitstamp) GetFundingHistory(ctx context.Context) ([]exchange.FundHistory, error) { return nil, common.ErrFunctionNotSupported } // GetWithdrawalsHistory returns previous withdrawals data -func (b *Bitstamp) GetWithdrawalsHistory(c currency.Code) (resp []exchange.WithdrawalHistory, err error) { +func (b *Bitstamp) GetWithdrawalsHistory(ctx context.Context, c currency.Code) (resp []exchange.WithdrawalHistory, err error) { return nil, common.ErrNotYetImplemented } // GetRecentTrades returns the most recent trades for a currency and asset -func (b *Bitstamp) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade.Data, error) { +func (b *Bitstamp) GetRecentTrades(ctx context.Context, 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 tradeData []Transactions - tradeData, err = b.GetTransactions(p.String(), "") + tradeData, err = b.GetTransactions(ctx, p.String(), "") if err != nil { return nil, err } @@ -506,12 +507,12 @@ func (b *Bitstamp) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]tra } // GetHistoricTrades returns historic trade data within the timeframe provided -func (b *Bitstamp) GetHistoricTrades(_ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { +func (b *Bitstamp) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { return nil, common.ErrFunctionNotSupported } // SubmitOrder submits a new order -func (b *Bitstamp) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { +func (b *Bitstamp) SubmitOrder(ctx context.Context, s *order.Submit) (order.SubmitResponse, error) { var submitOrderResponse order.SubmitResponse if err := s.Validate(); err != nil { return submitOrderResponse, err @@ -524,7 +525,8 @@ func (b *Bitstamp) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { buy := s.Side == order.Buy market := s.Type == order.Market - response, err := b.PlaceOrder(fPair.String(), + response, err := b.PlaceOrder(ctx, + fPair.String(), s.Price, s.Amount, buy, @@ -545,12 +547,12 @@ func (b *Bitstamp) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (b *Bitstamp) ModifyOrder(action *order.Modify) (order.Modify, error) { +func (b *Bitstamp) ModifyOrder(ctx context.Context, action *order.Modify) (order.Modify, error) { return order.Modify{}, common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number -func (b *Bitstamp) CancelOrder(o *order.Cancel) error { +func (b *Bitstamp) CancelOrder(ctx context.Context, o *order.Cancel) error { if err := o.Validate(o.StandardCancel()); err != nil { return err } @@ -559,18 +561,18 @@ func (b *Bitstamp) CancelOrder(o *order.Cancel) error { if err != nil { return err } - _, err = b.CancelExistingOrder(orderIDInt) + _, err = b.CancelExistingOrder(ctx, orderIDInt) return err } // CancelBatchOrders cancels an orders by their corresponding ID numbers -func (b *Bitstamp) CancelBatchOrders(o []order.Cancel) (order.CancelBatchResponse, error) { +func (b *Bitstamp) CancelBatchOrders(ctx context.Context, o []order.Cancel) (order.CancelBatchResponse, error) { return order.CancelBatchResponse{}, common.ErrNotYetImplemented } // CancelAllOrders cancels all orders associated with a currency pair -func (b *Bitstamp) CancelAllOrders(_ *order.Cancel) (order.CancelAllResponse, error) { - success, err := b.CancelAllExistingOrders() +func (b *Bitstamp) CancelAllOrders(ctx context.Context, _ *order.Cancel) (order.CancelAllResponse, error) { + success, err := b.CancelAllExistingOrders(ctx) if err != nil { return order.CancelAllResponse{}, err } @@ -582,23 +584,24 @@ func (b *Bitstamp) CancelAllOrders(_ *order.Cancel) (order.CancelAllResponse, er } // GetOrderInfo returns order information based on order ID -func (b *Bitstamp) GetOrderInfo(orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { +func (b *Bitstamp) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { var orderDetail order.Detail return orderDetail, common.ErrNotYetImplemented } // GetDepositAddress returns a deposit address for a specified currency -func (b *Bitstamp) GetDepositAddress(cryptocurrency currency.Code, _ string) (string, error) { - return b.GetCryptoDepositAddress(cryptocurrency) +func (b *Bitstamp) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _ string) (string, error) { + return b.GetCryptoDepositAddress(ctx, cryptocurrency) } // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is // submitted -func (b *Bitstamp) WithdrawCryptocurrencyFunds(withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (b *Bitstamp) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } - resp, err := b.CryptoWithdrawal(withdrawRequest.Amount, + resp, err := b.CryptoWithdrawal(ctx, + withdrawRequest.Amount, withdrawRequest.Crypto.Address, withdrawRequest.Currency.String(), withdrawRequest.Crypto.AddressTag, @@ -621,11 +624,12 @@ func (b *Bitstamp) WithdrawCryptocurrencyFunds(withdrawRequest *withdraw.Request // WithdrawFiatFunds returns a withdrawal ID when a // withdrawal is submitted -func (b *Bitstamp) WithdrawFiatFunds(withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (b *Bitstamp) WithdrawFiatFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } - resp, err := b.OpenBankWithdrawal(withdrawRequest.Amount, + resp, err := b.OpenBankWithdrawal(ctx, + withdrawRequest.Amount, withdrawRequest.Currency.String(), withdrawRequest.Fiat.Bank.AccountName, withdrawRequest.Fiat.Bank.IBAN, @@ -655,11 +659,12 @@ func (b *Bitstamp) WithdrawFiatFunds(withdrawRequest *withdraw.Request) (*withdr // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a // withdrawal is submitted -func (b *Bitstamp) WithdrawFiatFundsToInternationalBank(withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (b *Bitstamp) WithdrawFiatFundsToInternationalBank(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } - resp, err := b.OpenInternationalBankWithdrawal(withdrawRequest.Amount, + resp, err := b.OpenInternationalBankWithdrawal(ctx, + withdrawRequest.Amount, withdrawRequest.Currency.String(), withdrawRequest.Fiat.Bank.AccountName, withdrawRequest.Fiat.Bank.IBAN, @@ -694,7 +699,7 @@ func (b *Bitstamp) WithdrawFiatFundsToInternationalBank(withdrawRequest *withdra } // GetActiveOrders retrieves any orders that are active/open -func (b *Bitstamp) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, error) { +func (b *Bitstamp) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) { if err := req.Validate(); err != nil { return nil, err } @@ -710,7 +715,7 @@ func (b *Bitstamp) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, currPair = fPair.String() } - resp, err := b.GetOpenOrders(currPair) + resp, err := b.GetOpenOrders(ctx, currPair) if err != nil { return nil, err } @@ -759,7 +764,7 @@ func (b *Bitstamp) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, // GetOrderHistory retrieves account order information // Can Limit response to specific order status -func (b *Bitstamp) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, error) { +func (b *Bitstamp) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) { if err := req.Validate(); err != nil { return nil, err } @@ -778,7 +783,7 @@ func (b *Bitstamp) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, return nil, err } - resp, err := b.GetUserTransactions(currPair) + resp, err := b.GetUserTransactions(ctx, currPair) if err != nil { return nil, err } @@ -842,13 +847,13 @@ func (b *Bitstamp) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, // ValidateCredentials validates current credentials used for wrapper // functionality -func (b *Bitstamp) ValidateCredentials(assetType asset.Item) error { - _, err := b.UpdateAccountInfo(assetType) +func (b *Bitstamp) ValidateCredentials(ctx context.Context, assetType asset.Item) error { + _, err := b.UpdateAccountInfo(ctx, assetType) return b.CheckTransientError(err) } // GetHistoricCandles returns candles between a time period for a set time interval -func (b *Bitstamp) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (b *Bitstamp) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { if err := b.ValidateKline(pair, a, interval); err != nil { return kline.Item{}, err } @@ -865,7 +870,7 @@ func (b *Bitstamp) GetHistoricCandles(pair currency.Pair, a asset.Item, start, e return kline.Item{}, err } - candles, err := b.OHLC( + candles, err := b.OHLC(ctx, formattedPair.Lower().String(), start, end, @@ -897,7 +902,7 @@ func (b *Bitstamp) GetHistoricCandles(pair currency.Pair, a asset.Item, start, e } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (b *Bitstamp) GetHistoricCandlesExtended(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (b *Bitstamp) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { if err := b.ValidateKline(pair, a, interval); err != nil { return kline.Item{}, err } @@ -920,7 +925,7 @@ func (b *Bitstamp) GetHistoricCandlesExtended(pair currency.Pair, a asset.Item, for x := range dates.Ranges { var candles OHLCResponse - candles, err = b.OHLC( + candles, err = b.OHLC(ctx, formattedPair.Lower().String(), dates.Ranges[x].Start.Time, dates.Ranges[x].End.Time, diff --git a/exchanges/bittrex/bittrex.go b/exchanges/bittrex/bittrex.go index 1e329ed6..17847111 100644 --- a/exchanges/bittrex/bittrex.go +++ b/exchanges/bittrex/bittrex.go @@ -67,48 +67,48 @@ const ( // GetMarkets is used to get the open and available trading markets at Bittrex // along with other meta data. -func (b *Bittrex) GetMarkets() ([]MarketData, error) { +func (b *Bittrex) GetMarkets(ctx context.Context) ([]MarketData, error) { var resp []MarketData - return resp, b.SendHTTPRequest(exchange.RestSpot, getMarkets, &resp, nil) + return resp, b.SendHTTPRequest(ctx, exchange.RestSpot, getMarkets, &resp, nil) } // GetCurrencies is used to get all supported currencies at Bittrex -func (b *Bittrex) GetCurrencies() ([]CurrencyData, error) { +func (b *Bittrex) GetCurrencies(ctx context.Context) ([]CurrencyData, error) { var resp []CurrencyData - return resp, b.SendHTTPRequest(exchange.RestSpot, getCurrencies, &resp, nil) + return resp, b.SendHTTPRequest(ctx, exchange.RestSpot, getCurrencies, &resp, nil) } // GetTicker sends a public get request and returns current ticker information // on the supplied currency. Example currency input param "ltc-btc". -func (b *Bittrex) GetTicker(marketName string) (TickerData, error) { +func (b *Bittrex) GetTicker(ctx context.Context, marketName string) (TickerData, error) { var resp TickerData - return resp, b.SendHTTPRequest(exchange.RestSpot, fmt.Sprintf(getTicker, marketName), &resp, nil) + return resp, b.SendHTTPRequest(ctx, exchange.RestSpot, fmt.Sprintf(getTicker, marketName), &resp, nil) } // GetMarketSummaries is used to get the last 24 hour summary of all active // exchanges -func (b *Bittrex) GetMarketSummaries() ([]MarketSummaryData, error) { +func (b *Bittrex) GetMarketSummaries(ctx context.Context) ([]MarketSummaryData, error) { var resp []MarketSummaryData - return resp, b.SendHTTPRequest(exchange.RestSpot, getMarketSummaries, &resp, nil) + return resp, b.SendHTTPRequest(ctx, exchange.RestSpot, getMarketSummaries, &resp, nil) } // GetMarketSummary is used to get the last 24 hour summary of all active // exchanges by currency pair (ltc-btc). -func (b *Bittrex) GetMarketSummary(marketName string) (MarketSummaryData, error) { +func (b *Bittrex) GetMarketSummary(ctx context.Context, marketName string) (MarketSummaryData, error) { var resp MarketSummaryData - return resp, b.SendHTTPRequest(exchange.RestSpot, fmt.Sprintf(getMarketSummary, marketName), &resp, nil) + return resp, b.SendHTTPRequest(ctx, exchange.RestSpot, fmt.Sprintf(getMarketSummary, marketName), &resp, nil) } // GetOrderbook method returns current order book information by currency and depth. // "marketSymbol" ie ltc-btc // "depth" is either 1, 25 or 500. Server side, the depth defaults to 25. -func (b *Bittrex) GetOrderbook(marketName string, depth int64) (OrderbookData, int64, error) { +func (b *Bittrex) GetOrderbook(ctx context.Context, marketName string, depth int64) (OrderbookData, int64, error) { strDepth := strconv.FormatInt(depth, 10) var resp OrderbookData var sequence int64 resultHeader := http.Header{} - err := b.SendHTTPRequest(exchange.RestSpot, fmt.Sprintf(getOrderbook, marketName, strDepth), &resp, &resultHeader) + err := b.SendHTTPRequest(ctx, exchange.RestSpot, fmt.Sprintf(getOrderbook, marketName, strDepth), &resp, &resultHeader) if err != nil { return OrderbookData{}, 0, err } @@ -121,13 +121,13 @@ func (b *Bittrex) GetOrderbook(marketName string, depth int64) (OrderbookData, i } // GetMarketHistory retrieves the latest trades that have occurred for a specific market -func (b *Bittrex) GetMarketHistory(currency string) ([]TradeData, error) { +func (b *Bittrex) GetMarketHistory(ctx context.Context, currency string) ([]TradeData, error) { var resp []TradeData - return resp, b.SendHTTPRequest(exchange.RestSpot, fmt.Sprintf(getMarketTrades, currency), &resp, nil) + return resp, b.SendHTTPRequest(ctx, exchange.RestSpot, fmt.Sprintf(getMarketTrades, currency), &resp, nil) } // Order places an order -func (b *Bittrex) Order(marketName, side, orderType string, timeInForce TimeInForce, price, amount, ceiling float64) (OrderData, error) { +func (b *Bittrex) Order(ctx context.Context, marketName, side, orderType string, timeInForce TimeInForce, price, amount, ceiling float64) (OrderData, error) { req := make(map[string]interface{}) req["marketSymbol"] = marketName req["direction"] = side @@ -145,12 +145,12 @@ func (b *Bittrex) Order(marketName, side, orderType string, timeInForce TimeInFo req["timeInForce"] = GoodTilCancelled } var resp OrderData - return resp, b.SendAuthHTTPRequest(exchange.RestSpot, http.MethodPost, submitOrder, nil, req, &resp, nil) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, submitOrder, nil, req, &resp, nil) } // GetOpenOrders returns all orders that you currently have opened. // A specific market can be requested for example "ltc-btc" -func (b *Bittrex) GetOpenOrders(marketName string) ([]OrderData, int64, error) { +func (b *Bittrex) GetOpenOrders(ctx context.Context, marketName string) ([]OrderData, int64, error) { var path string if marketName == "" || marketName == " " { path = getAllOpenOrders @@ -160,7 +160,7 @@ func (b *Bittrex) GetOpenOrders(marketName string) ([]OrderData, int64, error) { var resp []OrderData var sequence int64 resultHeader := http.Header{} - err := b.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, path, nil, nil, &resp, &resultHeader) + err := b.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, path, nil, nil, &resp, &resultHeader) if err != nil { return nil, 0, err } @@ -172,14 +172,14 @@ func (b *Bittrex) GetOpenOrders(marketName string) ([]OrderData, int64, error) { } // CancelExistingOrder is used to cancel a buy or sell order. -func (b *Bittrex) CancelExistingOrder(uuid string) (OrderData, error) { +func (b *Bittrex) CancelExistingOrder(ctx context.Context, uuid string) (OrderData, error) { var resp OrderData - return resp, b.SendAuthHTTPRequest(exchange.RestSpot, http.MethodDelete, fmt.Sprintf(cancelOrder, uuid), nil, nil, &resp, nil) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodDelete, fmt.Sprintf(cancelOrder, uuid), nil, nil, &resp, nil) } // CancelOpenOrders is used to cancel all open orders for a specific market // Or cancel all orders for all markets if the parameter `markets` is set to "" -func (b *Bittrex) CancelOpenOrders(market string) ([]BulkCancelResultData, error) { +func (b *Bittrex) CancelOpenOrders(ctx context.Context, market string) ([]BulkCancelResultData, error) { var resp []BulkCancelResultData params := url.Values{} @@ -187,21 +187,21 @@ func (b *Bittrex) CancelOpenOrders(market string) ([]BulkCancelResultData, error params.Set("marketSymbol", market) } - return resp, b.SendAuthHTTPRequest(exchange.RestSpot, http.MethodDelete, cancelOpenOrders, params, nil, &resp, nil) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodDelete, cancelOpenOrders, params, nil, &resp, nil) } // GetRecentCandles retrieves recent candles; // Interval: MINUTE_1, MINUTE_5, HOUR_1, or DAY_1 // Type: TRADE or MIDPOINT -func (b *Bittrex) GetRecentCandles(marketName, candleInterval, candleType string) ([]CandleData, error) { +func (b *Bittrex) GetRecentCandles(ctx context.Context, marketName, candleInterval, candleType string) ([]CandleData, error) { var resp []CandleData - return resp, b.SendHTTPRequest(exchange.RestSpot, fmt.Sprintf(getRecentCandles, marketName, candleType, candleInterval), &resp, nil) + return resp, b.SendHTTPRequest(ctx, exchange.RestSpot, fmt.Sprintf(getRecentCandles, marketName, candleType, candleInterval), &resp, nil) } // GetHistoricalCandles retrieves recent candles // Type: TRADE or MIDPOINT -func (b *Bittrex) GetHistoricalCandles(marketName, candleInterval, candleType string, year, month, day int) ([]CandleData, error) { +func (b *Bittrex) GetHistoricalCandles(ctx context.Context, marketName, candleInterval, candleType string, year, month, day int) ([]CandleData, error) { var resp []CandleData var start string @@ -219,30 +219,30 @@ func (b *Bittrex) GetHistoricalCandles(marketName, candleInterval, candleType st return resp, fmt.Errorf("invalid interval %v, not supported", candleInterval) } - return resp, b.SendHTTPRequest(exchange.RestSpot, fmt.Sprintf(getHistoricalCandles, marketName, candleType, candleInterval, start), &resp, nil) + return resp, b.SendHTTPRequest(ctx, exchange.RestSpot, fmt.Sprintf(getHistoricalCandles, marketName, candleType, candleInterval, start), &resp, nil) } // GetBalances is used to retrieve all balances from your account -func (b *Bittrex) GetBalances() ([]BalanceData, error) { +func (b *Bittrex) GetBalances(ctx context.Context) ([]BalanceData, error) { var resp []BalanceData - return resp, b.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getBalances, nil, nil, &resp, nil) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, getBalances, nil, nil, &resp, nil) } // GetAccountBalanceByCurrency is used to retrieve the balance from your account // for a specific currency. ie. "btc" or "ltc" -func (b *Bittrex) GetAccountBalanceByCurrency(currency string) (BalanceData, error) { +func (b *Bittrex) GetAccountBalanceByCurrency(ctx context.Context, currency string) (BalanceData, error) { var resp BalanceData - return resp, b.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, fmt.Sprintf(getBalance, currency), nil, nil, &resp, nil) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, fmt.Sprintf(getBalance, currency), nil, nil, &resp, nil) } // GetCryptoDepositAddress is used to retrieve an address for a specific currency -func (b *Bittrex) GetCryptoDepositAddress(currency string) (AddressData, error) { +func (b *Bittrex) GetCryptoDepositAddress(ctx context.Context, currency string) (AddressData, error) { var resp AddressData - return resp, b.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, fmt.Sprintf(getDepositAddress, currency), nil, nil, &resp, nil) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, fmt.Sprintf(getDepositAddress, currency), nil, nil, &resp, nil) } // Withdraw is used to withdraw funds from your account. -func (b *Bittrex) Withdraw(currency, paymentID, address string, quantity float64) (WithdrawalData, error) { +func (b *Bittrex) Withdraw(ctx context.Context, currency, paymentID, address string, quantity float64) (WithdrawalData, error) { req := make(map[string]interface{}) req["currencySymbol"] = currency req["quantity"] = strconv.FormatFloat(quantity, 'f', -1, 64) @@ -251,60 +251,60 @@ func (b *Bittrex) Withdraw(currency, paymentID, address string, quantity float64 req["cryptoAddressTag"] = paymentID } var resp WithdrawalData - return resp, b.SendAuthHTTPRequest(exchange.RestSpot, http.MethodPost, submitWithdrawal, nil, req, &resp, nil) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, submitWithdrawal, nil, req, &resp, nil) } // GetOrder is used to retrieve a single order by UUID. -func (b *Bittrex) GetOrder(uuid string) (OrderData, error) { +func (b *Bittrex) GetOrder(ctx context.Context, uuid string) (OrderData, error) { var resp OrderData - return resp, b.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, fmt.Sprintf(getOrder, uuid), nil, nil, &resp, nil) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, fmt.Sprintf(getOrder, uuid), nil, nil, &resp, nil) } // GetOrderHistoryForCurrency is used to retrieve your order history. If marketName // is omitted it will return the entire order History. -func (b *Bittrex) GetOrderHistoryForCurrency(currency string) ([]OrderData, error) { +func (b *Bittrex) GetOrderHistoryForCurrency(ctx context.Context, currency string) ([]OrderData, error) { var resp []OrderData - return resp, b.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, fmt.Sprintf(getClosedOrders, currency), nil, nil, &resp, nil) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, fmt.Sprintf(getClosedOrders, currency), nil, nil, &resp, nil) } // GetClosedWithdrawals is used to retrieve your withdrawal history. -func (b *Bittrex) GetClosedWithdrawals() ([]WithdrawalData, error) { +func (b *Bittrex) GetClosedWithdrawals(ctx context.Context) ([]WithdrawalData, error) { var resp []WithdrawalData - return resp, b.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getClosedWithdrawals, nil, nil, &resp, nil) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, getClosedWithdrawals, nil, nil, &resp, nil) } // GetClosedWithdrawalsForCurrency is used to retrieve your withdrawal history for the specified currency. -func (b *Bittrex) GetClosedWithdrawalsForCurrency(currency string) ([]WithdrawalData, error) { +func (b *Bittrex) GetClosedWithdrawalsForCurrency(ctx context.Context, currency string) ([]WithdrawalData, error) { var resp []WithdrawalData params := url.Values{} params.Set("currencySymbol", currency) - return resp, b.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getClosedWithdrawals, params, nil, &resp, nil) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, getClosedWithdrawals, params, nil, &resp, nil) } // GetOpenWithdrawals is used to retrieve your withdrawal history. If currency // omitted it will return the entire history -func (b *Bittrex) GetOpenWithdrawals() ([]WithdrawalData, error) { +func (b *Bittrex) GetOpenWithdrawals(ctx context.Context) ([]WithdrawalData, error) { var resp []WithdrawalData - return resp, b.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getOpenWithdrawals, nil, nil, &resp, nil) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, getOpenWithdrawals, nil, nil, &resp, nil) } // GetClosedDeposits is used to retrieve your deposit history. -func (b *Bittrex) GetClosedDeposits() ([]DepositData, error) { +func (b *Bittrex) GetClosedDeposits(ctx context.Context) ([]DepositData, error) { var resp []DepositData - return resp, b.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getClosedDeposits, nil, nil, &resp, nil) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, getClosedDeposits, nil, nil, &resp, nil) } // GetClosedDepositsForCurrency is used to retrieve your deposit history for the specified currency -func (b *Bittrex) GetClosedDepositsForCurrency(currency string) ([]DepositData, error) { +func (b *Bittrex) GetClosedDepositsForCurrency(ctx context.Context, currency string) ([]DepositData, error) { var resp []DepositData params := url.Values{} params.Set("currencySymbol", currency) - return resp, b.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getClosedDeposits, params, nil, &resp, nil) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, getClosedDeposits, params, nil, &resp, nil) } // GetClosedDepositsPaginated is used to retrieve your deposit history. @@ -312,7 +312,7 @@ func (b *Bittrex) GetClosedDepositsForCurrency(currency string) ([]DepositData, // PreviousPageToken is the unique identifier of the item that the resulting // query result should end before, in the sort order of the given endpoint. Used // for traversing a paginated set in the reverse direction. -func (b *Bittrex) GetClosedDepositsPaginated(pageSize int, previousPageTokenOptional ...string) ([]DepositData, error) { +func (b *Bittrex) GetClosedDepositsPaginated(ctx context.Context, pageSize int, previousPageTokenOptional ...string) ([]DepositData, error) { var resp []DepositData params := url.Values{} @@ -322,27 +322,27 @@ func (b *Bittrex) GetClosedDepositsPaginated(pageSize int, previousPageTokenOpti params.Set("previousPageToken", previousPageTokenOptional[0]) } - return resp, b.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getClosedDeposits, params, nil, &resp, nil) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, getClosedDeposits, params, nil, &resp, nil) } // GetOpenDeposits is used to retrieve your open deposits. -func (b *Bittrex) GetOpenDeposits() ([]DepositData, error) { +func (b *Bittrex) GetOpenDeposits(ctx context.Context) ([]DepositData, error) { var resp []DepositData - return resp, b.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getOpenDeposits, nil, nil, &resp, nil) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, getOpenDeposits, nil, nil, &resp, nil) } // GetOpenDepositsForCurrency is used to retrieve your open deposits for the specified currency -func (b *Bittrex) GetOpenDepositsForCurrency(currency string) ([]DepositData, error) { +func (b *Bittrex) GetOpenDepositsForCurrency(ctx context.Context, currency string) ([]DepositData, error) { var resp []DepositData params := url.Values{} params.Set("currencySymbol", currency) - return resp, b.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getOpenDeposits, params, nil, &resp, nil) + return resp, b.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, getOpenDeposits, params, nil, &resp, nil) } // SendHTTPRequest sends an unauthenticated HTTP request -func (b *Bittrex) SendHTTPRequest(ep exchange.URL, path string, result interface{}, resultHeader *http.Header) error { +func (b *Bittrex) SendHTTPRequest(ctx context.Context, ep exchange.URL, path string, result interface{}, resultHeader *http.Header) error { endpoint, err := b.API.Endpoints.GetURL(ep) if err != nil { return err @@ -356,11 +356,11 @@ func (b *Bittrex) SendHTTPRequest(ep exchange.URL, path string, result interface HTTPRecording: b.HTTPRecording, HeaderResponse: resultHeader, } - return b.SendPayload(context.Background(), request.Unset, func() (*request.Item, error) { return item, nil }) + return b.SendPayload(ctx, request.Unset, func() (*request.Item, error) { return item, nil }) } // SendAuthHTTPRequest sends an authenticated request -func (b *Bittrex) SendAuthHTTPRequest(ep exchange.URL, method, action string, params url.Values, data, result interface{}, resultHeader *http.Header) error { +func (b *Bittrex) SendAuthHTTPRequest(ctx context.Context, ep exchange.URL, method, action string, params url.Values, data, result interface{}, resultHeader *http.Header) error { if !b.AllowAuthenticatedRequest() { return fmt.Errorf("%s %w", b.Name, exchange.ErrAuthenticatedRequestWithoutCredentialsSet) } @@ -421,11 +421,11 @@ func (b *Bittrex) SendAuthHTTPRequest(ep exchange.URL, method, action string, pa }, nil } - return b.SendPayload(context.Background(), request.Unset, newRequest) + return b.SendPayload(ctx, request.Unset, newRequest) } // GetFee returns an estimate of fee based on type of transaction -func (b *Bittrex) GetFee(feeBuilder *exchange.FeeBuilder) (float64, error) { +func (b *Bittrex) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { var fee float64 var err error @@ -433,7 +433,7 @@ func (b *Bittrex) GetFee(feeBuilder *exchange.FeeBuilder) (float64, error) { case exchange.CryptocurrencyTradeFee: fee = calculateTradingFee(feeBuilder.PurchasePrice, feeBuilder.Amount) case exchange.CryptocurrencyWithdrawalFee: - fee, err = b.GetWithdrawalFee(feeBuilder.Pair.Base) + fee, err = b.GetWithdrawalFee(ctx, feeBuilder.Pair.Base) case exchange.OfflineTradeFee: fee = calculateTradingFee(feeBuilder.PurchasePrice, feeBuilder.Amount) } @@ -444,10 +444,10 @@ func (b *Bittrex) GetFee(feeBuilder *exchange.FeeBuilder) (float64, error) { } // GetWithdrawalFee returns the fee for withdrawing from the exchange -func (b *Bittrex) GetWithdrawalFee(c currency.Code) (float64, error) { +func (b *Bittrex) GetWithdrawalFee(ctx context.Context, c currency.Code) (float64, error) { var fee float64 - currencies, err := b.GetCurrencies() + currencies, err := b.GetCurrencies(ctx) if err != nil { return 0, err } diff --git a/exchanges/bittrex/bittrex_test.go b/exchanges/bittrex/bittrex_test.go index 019555ca..22595efa 100644 --- a/exchanges/bittrex/bittrex_test.go +++ b/exchanges/bittrex/bittrex_test.go @@ -1,6 +1,7 @@ package bittrex import ( + "context" "log" "os" "testing" @@ -57,7 +58,7 @@ func TestMain(m *testing.M) { func TestGetMarkets(t *testing.T) { t.Parallel() - _, err := b.GetMarkets() + _, err := b.GetMarkets(context.Background()) if err != nil { t.Error(err) } @@ -65,7 +66,7 @@ func TestGetMarkets(t *testing.T) { func TestGetCurrencies(t *testing.T) { t.Parallel() - _, err := b.GetCurrencies() + _, err := b.GetCurrencies(context.Background()) if err != nil { t.Error(err) } @@ -73,7 +74,7 @@ func TestGetCurrencies(t *testing.T) { func TestGetTicker(t *testing.T) { t.Parallel() - _, err := b.GetTicker(currPair) + _, err := b.GetTicker(context.Background(), currPair) if err != nil { t.Error(err) } @@ -81,7 +82,7 @@ func TestGetTicker(t *testing.T) { func TestGetMarketSummaries(t *testing.T) { t.Parallel() - _, err := b.GetMarketSummaries() + _, err := b.GetMarketSummaries(context.Background()) if err != nil { t.Error(err) } @@ -89,7 +90,7 @@ func TestGetMarketSummaries(t *testing.T) { func TestGetMarketSummary(t *testing.T) { t.Parallel() - _, err := b.GetMarketSummary(currPair) + _, err := b.GetMarketSummary(context.Background(), currPair) if err != nil { t.Error(err) } @@ -98,7 +99,7 @@ func TestGetMarketSummary(t *testing.T) { func TestGetOrderbook(t *testing.T) { t.Parallel() - _, _, err := b.GetOrderbook(currPair, 500) + _, _, err := b.GetOrderbook(context.Background(), currPair, 500) if err != nil { t.Error(err) } @@ -107,7 +108,7 @@ func TestGetOrderbook(t *testing.T) { func TestGetMarketHistory(t *testing.T) { t.Parallel() - _, err := b.GetMarketHistory(currPair) + _, err := b.GetMarketHistory(context.Background(), currPair) if err != nil { t.Error(err) } @@ -116,7 +117,8 @@ func TestGetMarketHistory(t *testing.T) { func TestGetRecentCandles(t *testing.T) { t.Parallel() - _, err := b.GetRecentCandles(currPair, "HOUR_1", "MIDPOINT") + _, err := b.GetRecentCandles(context.Background(), + currPair, "HOUR_1", "MIDPOINT") if err != nil { t.Error(err) } @@ -125,11 +127,13 @@ func TestGetRecentCandles(t *testing.T) { func TestGetHistoricalCandles(t *testing.T) { t.Parallel() - _, err := b.GetHistoricalCandles(currPair, "MINUTE_5", "MIDPOINT", 2020, 12, 31) + _, err := b.GetHistoricalCandles(context.Background(), + currPair, "MINUTE_5", "MIDPOINT", 2020, 12, 31) if err != nil { t.Error(err) } - _, err = b.GetHistoricalCandles(currPair, "MINUTE_5", "MIDPOINT", 2020, 12, 32) + _, err = b.GetHistoricalCandles(context.Background(), + currPair, "MINUTE_5", "MIDPOINT", 2020, 12, 32) if err == nil { t.Error("invalid date should give an error") } @@ -138,7 +142,8 @@ func TestGetHistoricalCandles(t *testing.T) { func TestOrder(t *testing.T) { t.Parallel() - _, err := b.Order(currPair, order.Buy.String(), order.Limit.String(), "", 1, 1, 0.0) + _, err := b.Order(context.Background(), + currPair, order.Buy.String(), order.Limit.String(), "", 1, 1, 0.0) if areTestAPIKeysSet() && err != nil { t.Error(err) } else if !areTestAPIKeysSet() && err == nil { @@ -149,13 +154,13 @@ func TestOrder(t *testing.T) { func TestGetOpenOrders(t *testing.T) { t.Parallel() - _, _, err := b.GetOpenOrders("") + _, _, err := b.GetOpenOrders(context.Background(), "") if areTestAPIKeysSet() && err != nil { t.Error(err) } else if !areTestAPIKeysSet() && err == nil { t.Error("Expected error") } - _, _, err = b.GetOpenOrders(currPair) + _, _, err = b.GetOpenOrders(context.Background(), currPair) if areTestAPIKeysSet() && err != nil { t.Error(err) } else if !areTestAPIKeysSet() && err == nil { @@ -166,7 +171,7 @@ func TestGetOpenOrders(t *testing.T) { func TestCancelExistingOrder(t *testing.T) { t.Parallel() - _, err := b.CancelExistingOrder("invalid-order") + _, err := b.CancelExistingOrder(context.Background(), "invalid-order") if err == nil { t.Error("Expected error") } @@ -175,7 +180,7 @@ func TestCancelExistingOrder(t *testing.T) { func TestGetAccountBalances(t *testing.T) { t.Parallel() - _, err := b.GetBalances() + _, err := b.GetBalances(context.Background()) if areTestAPIKeysSet() && err != nil { t.Error(err) } else if !areTestAPIKeysSet() && err == nil { @@ -186,7 +191,7 @@ func TestGetAccountBalances(t *testing.T) { func TestGetAccountBalanceByCurrency(t *testing.T) { t.Parallel() - _, err := b.GetAccountBalanceByCurrency(curr) + _, err := b.GetAccountBalanceByCurrency(context.Background(), curr) if areTestAPIKeysSet() && err != nil { t.Error(err) } else if !areTestAPIKeysSet() && err == nil { @@ -197,13 +202,13 @@ func TestGetAccountBalanceByCurrency(t *testing.T) { func TestGetOrder(t *testing.T) { t.Parallel() - _, err := b.GetOrder("0cb4c4e4-bdc7-4e13-8c13-430e587d2cc1") + _, err := b.GetOrder(context.Background(), "0cb4c4e4-bdc7-4e13-8c13-430e587d2cc1") if areTestAPIKeysSet() && err != nil { t.Error(err) } else if !areTestAPIKeysSet() && err == nil { t.Error("Expected error") } - _, err = b.GetOrder("") + _, err = b.GetOrder(context.Background(), "") if areTestAPIKeysSet() && err == nil { t.Error("Expected error") } else if !areTestAPIKeysSet() && err == nil { @@ -214,13 +219,13 @@ func TestGetOrder(t *testing.T) { func TestGetOrderHistoryForCurrency(t *testing.T) { t.Parallel() - _, err := b.GetOrderHistoryForCurrency("") + _, err := b.GetOrderHistoryForCurrency(context.Background(), "") if areTestAPIKeysSet() && err != nil { t.Error(err) } else if !areTestAPIKeysSet() && err == nil { t.Error("Expected error") } - _, err = b.GetOrderHistoryForCurrency(currPair) + _, err = b.GetOrderHistoryForCurrency(context.Background(), currPair) if areTestAPIKeysSet() && err != nil { t.Error(err) } else if !areTestAPIKeysSet() && err == nil { @@ -231,7 +236,7 @@ func TestGetOrderHistoryForCurrency(t *testing.T) { func TestGetClosedWithdrawals(t *testing.T) { t.Parallel() - _, err := b.GetClosedWithdrawals() + _, err := b.GetClosedWithdrawals(context.Background()) if areTestAPIKeysSet() && err != nil { t.Error(err) } else if !areTestAPIKeysSet() && err == nil { @@ -242,7 +247,7 @@ func TestGetClosedWithdrawals(t *testing.T) { func TestGetClosedWithdrawalsForCurrency(t *testing.T) { t.Parallel() - _, err := b.GetClosedWithdrawalsForCurrency(curr) + _, err := b.GetClosedWithdrawalsForCurrency(context.Background(), curr) if areTestAPIKeysSet() && err != nil { t.Error(err) } else if !areTestAPIKeysSet() && err == nil { @@ -253,7 +258,7 @@ func TestGetClosedWithdrawalsForCurrency(t *testing.T) { func TestGetOpenWithdrawals(t *testing.T) { t.Parallel() - _, err := b.GetOpenWithdrawals() + _, err := b.GetOpenWithdrawals(context.Background()) if areTestAPIKeysSet() && err != nil { t.Error(err) } else if !areTestAPIKeysSet() && err == nil { @@ -264,7 +269,7 @@ func TestGetOpenWithdrawals(t *testing.T) { func TestGetClosedDeposits(t *testing.T) { t.Parallel() - _, err := b.GetClosedDeposits() + _, err := b.GetClosedDeposits(context.Background()) if areTestAPIKeysSet() && err != nil { t.Error(err) } else if !areTestAPIKeysSet() && err == nil { @@ -275,7 +280,7 @@ func TestGetClosedDeposits(t *testing.T) { func TestGetClosedDepositsForCurrency(t *testing.T) { t.Parallel() - _, err := b.GetClosedDepositsForCurrency(curr) + _, err := b.GetClosedDepositsForCurrency(context.Background(), curr) if areTestAPIKeysSet() && err != nil { t.Error(err) } else if !areTestAPIKeysSet() && err == nil { @@ -286,7 +291,7 @@ func TestGetClosedDepositsForCurrency(t *testing.T) { func TestGetClosedDepositsPaginated(t *testing.T) { t.Parallel() - _, err := b.GetClosedDepositsPaginated(100) + _, err := b.GetClosedDepositsPaginated(context.Background(), 100) if areTestAPIKeysSet() && err != nil { t.Error(err) } else if !areTestAPIKeysSet() && err == nil { @@ -297,7 +302,7 @@ func TestGetClosedDepositsPaginated(t *testing.T) { func TestGetOpenDeposits(t *testing.T) { t.Parallel() - _, err := b.GetOpenDeposits() + _, err := b.GetOpenDeposits(context.Background()) if areTestAPIKeysSet() && err != nil { t.Error(err) } else if !areTestAPIKeysSet() && err == nil { @@ -308,7 +313,7 @@ func TestGetOpenDeposits(t *testing.T) { func TestGetOpenDepositsForCurrency(t *testing.T) { t.Parallel() - _, err := b.GetOpenDepositsForCurrency(curr) + _, err := b.GetOpenDepositsForCurrency(context.Background(), curr) if areTestAPIKeysSet() && err != nil { t.Error(err) } else if !areTestAPIKeysSet() && err == nil { @@ -321,7 +326,8 @@ func TestWithdraw(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test, either api keys or canManipulateRealOrders isnt set correctly") } - _, err := b.Withdraw(curr, "", core.BitcoinDonationAddress, 0.0009) + _, err := b.Withdraw(context.Background(), + curr, "", core.BitcoinDonationAddress, 0.0009) if err != nil { t.Error(err) } @@ -339,7 +345,7 @@ func setFeeBuilder() *exchange.FeeBuilder { // TestGetFeeByTypeOfflineTradeFee logic test func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { var feeBuilder = setFeeBuilder() - _, err := b.GetFeeByType(feeBuilder) + _, err := b.GetFeeByType(context.Background(), feeBuilder) if err != nil { t.Fatal(err) } @@ -357,7 +363,7 @@ func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { func TestGetFee(t *testing.T) { var feeBuilder = setFeeBuilder() // CryptocurrencyTradeFee Basic - if _, err := b.GetFee(feeBuilder); err != nil { + if _, err := b.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } @@ -365,35 +371,35 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.Amount = 1000 feeBuilder.PurchasePrice = 1000 - if _, err := b.GetFee(feeBuilder); err != nil { + if _, err := b.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyTradeFee IsMaker feeBuilder = setFeeBuilder() feeBuilder.IsMaker = true - if _, err := b.GetFee(feeBuilder); err != nil { + if _, err := b.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyTradeFee Negative purchase price feeBuilder = setFeeBuilder() feeBuilder.PurchasePrice = -1000 - if _, err := b.GetFee(feeBuilder); err != nil { + if _, err := b.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyWithdrawalFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee - if _, err := b.GetFee(feeBuilder); err != nil { + if _, err := b.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyDepositFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.CryptocurrencyDepositFee - if _, err := b.GetFee(feeBuilder); err != nil { + if _, err := b.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } @@ -401,7 +407,7 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankDepositFee feeBuilder.FiatCurrency = currency.HKD - if _, err := b.GetFee(feeBuilder); err != nil { + if _, err := b.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } @@ -409,7 +415,7 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee feeBuilder.FiatCurrency = currency.HKD - if _, err := b.GetFee(feeBuilder); err != nil { + if _, err := b.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } } @@ -436,7 +442,7 @@ func TestGetActiveOrders(t *testing.T) { getOrdersRequest.Pairs[0].Delimiter = currency.DashDelimiter - _, err = b.GetActiveOrders(&getOrdersRequest) + _, err = b.GetActiveOrders(context.Background(), &getOrdersRequest) if areTestAPIKeysSet() && err != nil { t.Errorf("Could not get open orders: %s", err) } else if !areTestAPIKeysSet() && err == nil { @@ -450,7 +456,7 @@ func TestGetOrderHistory(t *testing.T) { AssetType: asset.Spot, } - _, err := b.GetOrderHistory(&getOrdersRequest) + _, err := b.GetOrderHistory(context.Background(), &getOrdersRequest) if err == nil { t.Error("Expected: 'At least one currency is required to fetch order history'. received nil") } @@ -459,7 +465,7 @@ func TestGetOrderHistory(t *testing.T) { currency.NewPair(currency.BTC, currency.USDT), } - _, err = b.GetOrderHistory(&getOrdersRequest) + _, err = b.GetOrderHistory(context.Background(), &getOrdersRequest) if areTestAPIKeysSet() && err != nil { t.Errorf("Could not get order history: %s", err) } else if !areTestAPIKeysSet() && err == nil { @@ -491,7 +497,7 @@ func TestSubmitOrder(t *testing.T) { ClientID: "meowOrder", AssetType: asset.Spot, } - response, err := b.SubmitOrder(orderSubmission) + response, err := b.SubmitOrder(context.Background(), orderSubmission) if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) { t.Errorf("Order failed to be placed: %v", err) } else if !areTestAPIKeysSet() && err == nil { @@ -513,7 +519,7 @@ func TestCancelExchangeOrder(t *testing.T) { AssetType: asset.Spot, } - err := b.CancelOrder(orderCancellation) + err := b.CancelOrder(context.Background(), orderCancellation) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") } @@ -536,7 +542,7 @@ func TestCancelAllExchangeOrders(t *testing.T) { AssetType: asset.Spot, } - resp, err := b.CancelAllOrders(orderCancellation) + resp, err := b.CancelAllOrders(context.Background(), orderCancellation) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") @@ -554,7 +560,8 @@ func TestModifyOrder(t *testing.T) { if areTestAPIKeysSet() && !canManipulateRealOrders { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - _, err := b.ModifyOrder(&order.Modify{AssetType: asset.Spot}) + _, err := b.ModifyOrder(context.Background(), + &order.Modify{AssetType: asset.Spot}) if err == nil { t.Error("Expected error") } @@ -574,7 +581,8 @@ func WithdrawCryptocurrencyFunds(t *testing.T) { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - _, err := b.WithdrawCryptocurrencyFunds(&withdrawCryptoRequest) + _, err := b.WithdrawCryptocurrencyFunds(context.Background(), + &withdrawCryptoRequest) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") } @@ -590,7 +598,7 @@ func TestWithdrawFiat(t *testing.T) { var withdrawFiatRequest = withdraw.Request{} - _, err := b.WithdrawFiatFunds(&withdrawFiatRequest) + _, err := b.WithdrawFiatFunds(context.Background(), &withdrawFiatRequest) if err != common.ErrFunctionNotSupported { t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err) } @@ -603,7 +611,8 @@ func TestWithdrawInternationalBank(t *testing.T) { var withdrawFiatRequest = withdraw.Request{} - _, err := b.WithdrawFiatFundsToInternationalBank(&withdrawFiatRequest) + _, err := b.WithdrawFiatFundsToInternationalBank(context.Background(), + &withdrawFiatRequest) if err != common.ErrFunctionNotSupported { t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err) } @@ -611,12 +620,12 @@ func TestWithdrawInternationalBank(t *testing.T) { func TestGetDepositAddress(t *testing.T) { if areTestAPIKeysSet() { - _, err := b.GetDepositAddress(currency.BTC, "") + _, err := b.GetDepositAddress(context.Background(), currency.BTC, "") if err != nil { t.Error(err) } } else { - _, err := b.GetDepositAddress(currency.BTC, "") + _, err := b.GetDepositAddress(context.Background(), currency.BTC, "") if err == nil { t.Error("error cannot be nil") } @@ -629,7 +638,7 @@ func TestGetRecentTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = b.GetRecentTrades(currencyPair, asset.Spot) + _, err = b.GetRecentTrades(context.Background(), currencyPair, asset.Spot) if err != nil { t.Error(err) } @@ -641,7 +650,8 @@ func TestGetHistoricTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = b.GetHistoricTrades(currencyPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) + _, err = b.GetHistoricTrades(context.Background(), + currencyPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) if err != nil && err != common.ErrFunctionNotSupported { t.Fatal(err) } diff --git a/exchanges/bittrex/bittrex_websocket.go b/exchanges/bittrex/bittrex_websocket.go index 55d4520f..479fbac6 100644 --- a/exchanges/bittrex/bittrex_websocket.go +++ b/exchanges/bittrex/bittrex_websocket.go @@ -71,7 +71,7 @@ func (b *Bittrex) WsConnect() error { } var wsHandshakeData WsSignalRHandshakeData - err := b.WsSignalRHandshake(&wsHandshakeData) + err := b.WsSignalRHandshake(context.TODO(), &wsHandshakeData) if err != nil { return err } @@ -128,7 +128,7 @@ func (b *Bittrex) WsConnect() error { } // WsSignalRHandshake requests the SignalR connection token over https -func (b *Bittrex) WsSignalRHandshake(result interface{}) error { +func (b *Bittrex) WsSignalRHandshake(ctx context.Context, result interface{}) error { endpoint, err := b.API.Endpoints.GetURL(exchange.WebsocketSpotSupplementary) if err != nil { return err @@ -142,7 +142,7 @@ func (b *Bittrex) WsSignalRHandshake(result interface{}) error { HTTPDebugging: b.HTTPDebugging, HTTPRecording: b.HTTPRecording, } - return b.SendPayload(context.Background(), request.Unset, func() (*request.Item, error) { + return b.SendPayload(ctx, request.Unset, func() (*request.Item, error) { return item, nil }) } diff --git a/exchanges/bittrex/bittrex_wrapper.go b/exchanges/bittrex/bittrex_wrapper.go index 6555842b..9ebee762 100644 --- a/exchanges/bittrex/bittrex_wrapper.go +++ b/exchanges/bittrex/bittrex_wrapper.go @@ -1,6 +1,7 @@ package bittrex import ( + "context" "errors" "fmt" "sort" @@ -40,7 +41,7 @@ func (b *Bittrex) GetDefaultConfig() (*config.ExchangeConfig, error) { } if b.Features.Supports.RESTCapabilities.AutoPairUpdates { - err = b.UpdateTradablePairs(true) + err = b.UpdateTradablePairs(context.TODO(), true) if err != nil { return nil, err } @@ -212,7 +213,7 @@ func (b *Bittrex) Run() { return } - err := b.UpdateTradablePairs(false) + err := b.UpdateTradablePairs(context.TODO(), false) if err != nil { log.Errorf(log.ExchangeSys, "%s failed to update tradable pairs. Err: %s", @@ -241,12 +242,12 @@ func (b *Bittrex) Run() { } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (b *Bittrex) FetchTradablePairs(asset asset.Item) ([]string, error) { +func (b *Bittrex) FetchTradablePairs(ctx context.Context, asset asset.Item) ([]string, error) { // Bittrex only supports spot trading if !b.SupportsAsset(asset) { return nil, fmt.Errorf("asset type of %s is not supported by %s", asset, b.Name) } - markets, err := b.GetMarkets() + markets, err := b.GetMarkets(ctx) if err != nil { return nil, err } @@ -264,8 +265,8 @@ func (b *Bittrex) FetchTradablePairs(asset asset.Item) ([]string, error) { // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (b *Bittrex) UpdateTradablePairs(forceUpdate bool) error { - pairs, err := b.FetchTradablePairs(asset.Spot) +func (b *Bittrex) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { + pairs, err := b.FetchTradablePairs(ctx, asset.Spot) if err != nil { return err } @@ -279,23 +280,23 @@ func (b *Bittrex) UpdateTradablePairs(forceUpdate bool) error { } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (b *Bittrex) UpdateTickers(a asset.Item) error { +func (b *Bittrex) UpdateTickers(ctx context.Context, a asset.Item) error { return common.ErrFunctionNotSupported } // UpdateTicker updates and returns the ticker for a currency pair -func (b *Bittrex) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) { +func (b *Bittrex) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { formattedPair, err := b.FormatExchangeCurrency(p, a) if err != nil { return nil, err } - t, err := b.GetTicker(formattedPair.String()) + t, err := b.GetTicker(ctx, formattedPair.String()) if err != nil { return nil, err } - s, err := b.GetMarketSummary(formattedPair.String()) + s, err := b.GetMarketSummary(ctx, formattedPair.String()) if err != nil { return nil, err } @@ -333,32 +334,33 @@ func (b *Bittrex) constructTicker(t TickerData, s *MarketSummaryData, pair curre } // FetchTicker returns the ticker for a currency pair -func (b *Bittrex) FetchTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) { +func (b *Bittrex) FetchTicker(ctx context.Context, p currency.Pair, assetType asset.Item) (*ticker.Price, error) { resp, err := ticker.GetTicker(b.Name, p, assetType) if err != nil { - return b.UpdateTicker(p, assetType) + return b.UpdateTicker(ctx, p, assetType) } return resp, nil } // FetchOrderbook returns orderbook base on the currency pair -func (b *Bittrex) FetchOrderbook(currency currency.Pair, assetType asset.Item) (*orderbook.Base, error) { - resp, err := orderbook.Get(b.Name, currency, assetType) +func (b *Bittrex) FetchOrderbook(ctx context.Context, c currency.Pair, assetType asset.Item) (*orderbook.Base, error) { + resp, err := orderbook.Get(b.Name, c, assetType) if err != nil { - return b.UpdateOrderbook(currency, assetType) + return b.UpdateOrderbook(ctx, c, assetType) } return resp, nil } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (b *Bittrex) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (b *Bittrex) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { formattedPair, err := b.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err } // Valid order book depths are 1, 25 and 500 - orderbookData, sequence, err := b.GetOrderbook(formattedPair.String(), orderbookDepth) + orderbookData, sequence, err := b.GetOrderbook(ctx, + formattedPair.String(), orderbookDepth) if err != nil { return nil, err } @@ -397,9 +399,9 @@ func (b *Bittrex) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*order } // UpdateAccountInfo retrieves balances for all enabled currencies -func (b *Bittrex) UpdateAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (b *Bittrex) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { var resp account.Holdings - balanceData, err := b.GetBalances() + balanceData, err := b.GetBalances(ctx) if err != nil { return resp, err } @@ -422,24 +424,23 @@ func (b *Bittrex) UpdateAccountInfo(assetType asset.Item) (account.Holdings, err } // FetchAccountInfo retrieves balances for all enabled currencies -func (b *Bittrex) FetchAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (b *Bittrex) FetchAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { resp, err := account.GetHoldings(b.Name, assetType) if err != nil { - return b.UpdateAccountInfo(assetType) + return b.UpdateAccountInfo(ctx, assetType) } - return resp, nil } // GetFundingHistory returns funding history, deposits and // withdrawals -func (b *Bittrex) GetFundingHistory() ([]exchange.FundHistory, error) { +func (b *Bittrex) GetFundingHistory(ctx context.Context) ([]exchange.FundHistory, error) { var resp []exchange.FundHistory - closedDepositData, err := b.GetClosedDeposits() + closedDepositData, err := b.GetClosedDeposits(ctx) if err != nil { return resp, err } - openDepositData, err := b.GetOpenDeposits() + openDepositData, err := b.GetOpenDeposits(ctx) if err != nil { return resp, err } @@ -458,11 +459,11 @@ func (b *Bittrex) GetFundingHistory() ([]exchange.FundHistory, error) { CryptoTxID: depositData[x].TxID, }) } - closedWithdrawalData, err := b.GetClosedWithdrawals() + closedWithdrawalData, err := b.GetClosedWithdrawals(ctx) if err != nil { return resp, err } - openWithdrawalData, err := b.GetOpenWithdrawals() + openWithdrawalData, err := b.GetOpenWithdrawals(ctx) if err != nil { return resp, err } @@ -487,18 +488,18 @@ func (b *Bittrex) GetFundingHistory() ([]exchange.FundHistory, error) { } // GetWithdrawalsHistory returns previous withdrawals data -func (b *Bittrex) GetWithdrawalsHistory(c currency.Code) (resp []exchange.WithdrawalHistory, err error) { +func (b *Bittrex) GetWithdrawalsHistory(ctx context.Context, c currency.Code) (resp []exchange.WithdrawalHistory, err error) { return nil, common.ErrNotYetImplemented } // GetRecentTrades returns the most recent trades for a currency and asset -func (b *Bittrex) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade.Data, error) { +func (b *Bittrex) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { var err error formattedPair, err := b.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err } - tradeData, err := b.GetMarketHistory(formattedPair.String()) + tradeData, err := b.GetMarketHistory(ctx, formattedPair.String()) if err != nil { return nil, err } @@ -532,12 +533,12 @@ func (b *Bittrex) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trad // GetHistoricTrades returns historic trade data within the timeframe provided // Bittrex only reports recent trades -func (b *Bittrex) GetHistoricTrades(_ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { +func (b *Bittrex) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { return nil, common.ErrFunctionNotSupported } // SubmitOrder submits a new order -func (b *Bittrex) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { +func (b *Bittrex) SubmitOrder(ctx context.Context, s *order.Submit) (order.SubmitResponse, error) { if err := s.Validate(); err != nil { return order.SubmitResponse{}, err } @@ -555,7 +556,8 @@ func (b *Bittrex) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { return order.SubmitResponse{}, err } - orderData, err := b.Order(formattedPair.String(), + orderData, err := b.Order(ctx, + formattedPair.String(), s.Side.String(), s.Type.String(), GoodTilCancelled, @@ -574,27 +576,27 @@ func (b *Bittrex) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (b *Bittrex) ModifyOrder(action *order.Modify) (order.Modify, error) { +func (b *Bittrex) ModifyOrder(_ context.Context, _ *order.Modify) (order.Modify, error) { return order.Modify{}, common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number -func (b *Bittrex) CancelOrder(ord *order.Cancel) error { +func (b *Bittrex) CancelOrder(ctx context.Context, ord *order.Cancel) error { if err := ord.Validate(ord.StandardCancel()); err != nil { return err } - _, err := b.CancelExistingOrder(ord.ID) + _, err := b.CancelExistingOrder(ctx, ord.ID) return err } // CancelBatchOrders cancels an orders by their corresponding ID numbers -func (b *Bittrex) CancelBatchOrders(orders []order.Cancel) (order.CancelBatchResponse, error) { +func (b *Bittrex) CancelBatchOrders(_ context.Context, _ []order.Cancel) (order.CancelBatchResponse, error) { return order.CancelBatchResponse{}, common.ErrNotYetImplemented } // CancelAllOrders cancels all orders associated with a currency pair, or cancels all orders for all // pairs if no pair was specified -func (b *Bittrex) CancelAllOrders(orderCancellation *order.Cancel) (order.CancelAllResponse, error) { +func (b *Bittrex) CancelAllOrders(ctx context.Context, orderCancellation *order.Cancel) (order.CancelAllResponse, error) { var pair string if orderCancellation != nil { formattedPair, err := b.FormatExchangeCurrency(orderCancellation.Pair, orderCancellation.AssetType) @@ -603,7 +605,7 @@ func (b *Bittrex) CancelAllOrders(orderCancellation *order.Cancel) (order.Cancel } pair = formattedPair.String() } - orderData, err := b.CancelOpenOrders(pair) + orderData, err := b.CancelOpenOrders(ctx, pair) if err != nil { return order.CancelAllResponse{}, err } @@ -622,8 +624,8 @@ func (b *Bittrex) CancelAllOrders(orderCancellation *order.Cancel) (order.Cancel } // GetOrderInfo returns information on a current open order -func (b *Bittrex) GetOrderInfo(orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { - orderData, err := b.GetOrder(orderID) +func (b *Bittrex) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { + orderData, err := b.GetOrder(ctx, orderID) if err != nil { return order.Detail{}, err } @@ -692,8 +694,8 @@ func (b *Bittrex) ConstructOrderDetail(orderData *OrderData) (order.Detail, erro } // GetDepositAddress returns a deposit address for a specified currency -func (b *Bittrex) GetDepositAddress(cryptocurrency currency.Code, _ string) (string, error) { - depositAddr, err := b.GetCryptoDepositAddress(cryptocurrency.String()) +func (b *Bittrex) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _ string) (string, error) { + depositAddr, err := b.GetCryptoDepositAddress(ctx, cryptocurrency.String()) if err != nil { return "", err } @@ -706,11 +708,12 @@ func (b *Bittrex) GetDepositAddress(cryptocurrency currency.Code, _ string) (str // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is // submitted -func (b *Bittrex) WithdrawCryptocurrencyFunds(withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (b *Bittrex) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } - result, err := b.Withdraw(withdrawRequest.Currency.String(), + result, err := b.Withdraw(ctx, + withdrawRequest.Currency.String(), withdrawRequest.Crypto.AddressTag, withdrawRequest.Crypto.Address, withdrawRequest.Amount) @@ -726,18 +729,18 @@ func (b *Bittrex) WithdrawCryptocurrencyFunds(withdrawRequest *withdraw.Request) // WithdrawFiatFunds returns a withdrawal ID when a // withdrawal is submitted -func (b *Bittrex) WithdrawFiatFunds(_ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (b *Bittrex) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a // withdrawal is submitted -func (b *Bittrex) WithdrawFiatFundsToInternationalBank(_ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (b *Bittrex) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // GetActiveOrders retrieves any orders that are active/open -func (b *Bittrex) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, error) { +func (b *Bittrex) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) { if err := req.Validate(); err != nil { return nil, err } @@ -756,7 +759,7 @@ func (b *Bittrex) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, return nil, err } - orderData, sequence, err := b.GetOpenOrders(currPair) + orderData, sequence, err := b.GetOpenOrders(ctx, currPair) if err != nil { return nil, err } @@ -806,7 +809,7 @@ func (b *Bittrex) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, // GetOrderHistory retrieves account order information // Can Limit response to specific order status -func (b *Bittrex) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, error) { +func (b *Bittrex) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) { if err := req.Validate(); err != nil { return nil, err } @@ -826,7 +829,7 @@ func (b *Bittrex) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, return nil, err } - orderData, err := b.GetOrderHistoryForCurrency(formattedPair.String()) + orderData, err := b.GetOrderHistoryForCurrency(ctx, formattedPair.String()) if err != nil { return nil, err } @@ -880,18 +883,18 @@ func (b *Bittrex) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, } // GetFeeByType returns an estimate of fee based on type of transaction -func (b *Bittrex) GetFeeByType(feeBuilder *exchange.FeeBuilder) (float64, error) { +func (b *Bittrex) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { if !b.AllowAuthenticatedRequest() && // Todo check connection status feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { feeBuilder.FeeType = exchange.OfflineTradeFee } - return b.GetFee(feeBuilder) + return b.GetFee(ctx, feeBuilder) } // ValidateCredentials validates current credentials used for wrapper // functionality -func (b *Bittrex) ValidateCredentials(assetType asset.Item) error { - _, err := b.UpdateAccountInfo(assetType) +func (b *Bittrex) ValidateCredentials(ctx context.Context, assetType asset.Item) error { + _, err := b.UpdateAccountInfo(ctx, assetType) return b.CheckTransientError(err) } @@ -920,7 +923,7 @@ func (b *Bittrex) FormatExchangeKlineInterval(in kline.Interval) string { // - 1 day interval: candles for 366 days // This implementation rounds returns candles up to the next interval or to the end // time (whichever comes first) -func (b *Bittrex) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (b *Bittrex) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { if err := b.ValidateKline(pair, a, interval); err != nil { return kline.Item{}, err } @@ -974,8 +977,13 @@ func (b *Bittrex) GetHistoricCandles(pair currency.Pair, a asset.Item, start, en var ohlcData []CandleData if getHistoric { var historicData []CandleData - historicData, err = b.GetHistoricalCandles(formattedPair.String(), - b.FormatExchangeKlineInterval(interval), "TRADE", year, int(month), day) + historicData, err = b.GetHistoricalCandles(ctx, + formattedPair.String(), + b.FormatExchangeKlineInterval(interval), + "TRADE", + year, + int(month), + day) if err != nil { return kline.Item{}, err } @@ -983,8 +991,10 @@ func (b *Bittrex) GetHistoricCandles(pair currency.Pair, a asset.Item, start, en } if getRecent { var recentData []CandleData - recentData, err = b.GetRecentCandles(formattedPair.String(), - b.FormatExchangeKlineInterval(interval), "TRADE") + recentData, err = b.GetRecentCandles(ctx, + formattedPair.String(), + b.FormatExchangeKlineInterval(interval), + "TRADE") if err != nil { return kline.Item{}, err } @@ -1011,6 +1021,6 @@ func (b *Bittrex) GetHistoricCandles(pair currency.Pair, a asset.Item, start, en } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (b *Bittrex) GetHistoricCandlesExtended(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (b *Bittrex) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { return kline.Item{}, common.ErrNotYetImplemented } diff --git a/exchanges/bittrex/bittrex_ws_orderbook.go b/exchanges/bittrex/bittrex_ws_orderbook.go index 35f90245..73b5888d 100644 --- a/exchanges/bittrex/bittrex_ws_orderbook.go +++ b/exchanges/bittrex/bittrex_ws_orderbook.go @@ -1,6 +1,7 @@ package bittrex import ( + "context" "fmt" "github.com/thrasher-corp/gocryptotrader/currency" @@ -110,8 +111,8 @@ func (b *Bittrex) UpdateLocalOBBuffer(update *OrderbookUpdateMessage) (bool, err } // SeedLocalOBCache seeds depth data -func (b *Bittrex) SeedLocalOBCache(p currency.Pair) error { - ob, sequence, err := b.GetOrderbook(p.String(), orderbookDepth) +func (b *Bittrex) SeedLocalOBCache(ctx context.Context, p currency.Pair) error { + ob, sequence, err := b.GetOrderbook(ctx, p.String(), orderbookDepth) if err != nil { return err } @@ -215,7 +216,7 @@ func (b *Bittrex) SynchroniseWebsocketOrderbook() { // processJob fetches and processes orderbook updates func (b *Bittrex) processJob(p currency.Pair) error { - err := b.SeedLocalOBCache(p) + err := b.SeedLocalOBCache(context.TODO(), p) if err != nil { return fmt.Errorf("%s %s seeding local cache for orderbook error: %v", p, asset.Spot, err) diff --git a/exchanges/btcmarkets/btcmarkets.go b/exchanges/btcmarkets/btcmarkets.go index 73688171..e9802fc8 100644 --- a/exchanges/btcmarkets/btcmarkets.go +++ b/exchanges/btcmarkets/btcmarkets.go @@ -80,20 +80,20 @@ type BTCMarkets struct { } // GetMarkets returns the BTCMarkets instruments -func (b *BTCMarkets) GetMarkets() ([]Market, error) { +func (b *BTCMarkets) GetMarkets(ctx context.Context) ([]Market, error) { var resp []Market - return resp, b.SendHTTPRequest(btcMarketsUnauthPath, &resp) + return resp, b.SendHTTPRequest(ctx, btcMarketsUnauthPath, &resp) } // GetTicker returns a ticker // symbol - example "btc" or "ltc" -func (b *BTCMarkets) GetTicker(marketID string) (Ticker, error) { +func (b *BTCMarkets) GetTicker(ctx context.Context, marketID string) (Ticker, error) { var tick Ticker - return tick, b.SendHTTPRequest(btcMarketsUnauthPath+marketID+btcMarketsGetTicker, &tick) + return tick, b.SendHTTPRequest(ctx, btcMarketsUnauthPath+marketID+btcMarketsGetTicker, &tick) } // GetTrades returns executed trades on the exchange -func (b *BTCMarkets) GetTrades(marketID string, before, after, limit int64) ([]Trade, error) { +func (b *BTCMarkets) GetTrades(ctx context.Context, marketID string, before, after, limit int64) ([]Trade, error) { if (before > 0) && (after >= 0) { return nil, errors.New("BTCMarkets only supports either before or after, not both") } @@ -108,19 +108,19 @@ func (b *BTCMarkets) GetTrades(marketID string, before, after, limit int64) ([]T if limit > 0 { params.Set("limit", strconv.FormatInt(limit, 10)) } - return trades, b.SendHTTPRequest(btcMarketsUnauthPath+marketID+btcMarketsGetTrades+params.Encode(), + return trades, b.SendHTTPRequest(ctx, btcMarketsUnauthPath+marketID+btcMarketsGetTrades+params.Encode(), &trades) } // GetOrderbook returns current orderbook -func (b *BTCMarkets) GetOrderbook(marketID string, level int64) (Orderbook, error) { +func (b *BTCMarkets) GetOrderbook(ctx context.Context, marketID string, level int64) (Orderbook, error) { var orderbook Orderbook var temp tempOrderbook params := url.Values{} if level != 0 { params.Set("level", strconv.FormatInt(level, 10)) } - err := b.SendHTTPRequest(btcMarketsUnauthPath+marketID+btcMarketOrderBooks+params.Encode(), + err := b.SendHTTPRequest(ctx, btcMarketsUnauthPath+marketID+btcMarketOrderBooks+params.Encode(), &temp) if err != nil { return orderbook, err @@ -160,7 +160,7 @@ func (b *BTCMarkets) GetOrderbook(marketID string, level int64) (Orderbook, erro } // GetMarketCandles gets candles for specified currency pair -func (b *BTCMarkets) GetMarketCandles(marketID, timeWindow string, from, to time.Time, before, after, limit int64) (out CandleResponse, err error) { +func (b *BTCMarkets) GetMarketCandles(ctx context.Context, marketID, timeWindow string, from, to time.Time, before, after, limit int64) (out CandleResponse, err error) { if (before > 0) && (after >= 0) { return out, errors.New("BTCMarkets only supports either before or after, not both") } @@ -185,22 +185,22 @@ func (b *BTCMarkets) GetMarketCandles(marketID, timeWindow string, from, to time if limit > 0 { params.Set("limit", strconv.FormatInt(limit, 10)) } - return out, b.SendHTTPRequest(btcMarketsUnauthPath+marketID+btcMarketsCandles+params.Encode(), &out) + return out, b.SendHTTPRequest(ctx, btcMarketsUnauthPath+marketID+btcMarketsCandles+params.Encode(), &out) } // GetTickers gets multiple tickers -func (b *BTCMarkets) GetTickers(marketIDs currency.Pairs) ([]Ticker, error) { +func (b *BTCMarkets) GetTickers(ctx context.Context, marketIDs currency.Pairs) ([]Ticker, error) { var tickers []Ticker params := url.Values{} for x := range marketIDs { params.Add("marketId", marketIDs[x].String()) } - return tickers, b.SendHTTPRequest(btcMarketsUnauthPath+btcMarketsTickers+params.Encode(), + return tickers, b.SendHTTPRequest(ctx, btcMarketsUnauthPath+btcMarketsTickers+params.Encode(), &tickers) } // GetMultipleOrderbooks gets orderbooks -func (b *BTCMarkets) GetMultipleOrderbooks(marketIDs []string) ([]Orderbook, error) { +func (b *BTCMarkets) GetMultipleOrderbooks(ctx context.Context, marketIDs []string) ([]Orderbook, error) { var orderbooks []Orderbook var temp []tempOrderbook var tempOB Orderbook @@ -208,7 +208,7 @@ func (b *BTCMarkets) GetMultipleOrderbooks(marketIDs []string) ([]Orderbook, err for x := range marketIDs { params.Add("marketId", marketIDs[x]) } - err := b.SendHTTPRequest(btcMarketsUnauthPath+btcMarketsMultipleOrderbooks+params.Encode(), + err := b.SendHTTPRequest(ctx, btcMarketsUnauthPath+btcMarketsMultipleOrderbooks+params.Encode(), &temp) if err != nil { return orderbooks, err @@ -245,17 +245,17 @@ func (b *BTCMarkets) GetMultipleOrderbooks(marketIDs []string) ([]Orderbook, err } // GetServerTime gets time from btcmarkets -func (b *BTCMarkets) GetServerTime() (time.Time, error) { +func (b *BTCMarkets) GetServerTime(ctx context.Context) (time.Time, error) { var resp TimeResp - return resp.Time, b.SendHTTPRequest(btcMarketsAPIURL+btcMarketsAPIVersion+btcMarketsGetTime, + return resp.Time, b.SendHTTPRequest(ctx, btcMarketsAPIURL+btcMarketsAPIVersion+btcMarketsGetTime, &resp) } // GetAccountBalance returns the full account balance -func (b *BTCMarkets) GetAccountBalance() ([]AccountData, error) { +func (b *BTCMarkets) GetAccountBalance(ctx context.Context) ([]AccountData, error) { var resp []AccountData return resp, - b.SendAuthenticatedRequest(http.MethodGet, + b.SendAuthenticatedRequest(ctx, http.MethodGet, btcMarketsAccountBalance, nil, &resp, @@ -263,9 +263,9 @@ func (b *BTCMarkets) GetAccountBalance() ([]AccountData, error) { } // GetTradingFees returns trading fees for all pairs based on trading activity -func (b *BTCMarkets) GetTradingFees() (TradingFeeResponse, error) { +func (b *BTCMarkets) GetTradingFees(ctx context.Context) (TradingFeeResponse, error) { var resp TradingFeeResponse - return resp, b.SendAuthenticatedRequest(http.MethodGet, + return resp, b.SendAuthenticatedRequest(ctx, http.MethodGet, btcMarketsTradingFees, nil, &resp, @@ -273,7 +273,7 @@ func (b *BTCMarkets) GetTradingFees() (TradingFeeResponse, error) { } // GetTradeHistory returns trade history -func (b *BTCMarkets) GetTradeHistory(marketID, orderID string, before, after, limit int64) ([]TradeHistoryData, error) { +func (b *BTCMarkets) GetTradeHistory(ctx context.Context, marketID, orderID string, before, after, limit int64) ([]TradeHistoryData, error) { if (before > 0) && (after >= 0) { return nil, errors.New("BTCMarkets only supports either before or after, not both") } @@ -294,7 +294,7 @@ func (b *BTCMarkets) GetTradeHistory(marketID, orderID string, before, after, li if limit > 0 { params.Set("limit", strconv.FormatInt(limit, 10)) } - return resp, b.SendAuthenticatedRequest(http.MethodGet, + return resp, b.SendAuthenticatedRequest(ctx, http.MethodGet, common.EncodeURLValues(btcMarketsTradeHistory, params), nil, &resp, @@ -302,9 +302,9 @@ func (b *BTCMarkets) GetTradeHistory(marketID, orderID string, before, after, li } // GetTradeByID returns the singular trade of the ID given -func (b *BTCMarkets) GetTradeByID(id string) (TradeHistoryData, error) { +func (b *BTCMarkets) GetTradeByID(ctx context.Context, id string) (TradeHistoryData, error) { var resp TradeHistoryData - return resp, b.SendAuthenticatedRequest(http.MethodGet, + return resp, b.SendAuthenticatedRequest(ctx, http.MethodGet, btcMarketsTradeHistory+"/"+id, nil, &resp, @@ -312,7 +312,7 @@ func (b *BTCMarkets) GetTradeByID(id string) (TradeHistoryData, error) { } // NewOrder requests a new order and returns an ID -func (b *BTCMarkets) NewOrder(marketID string, price, amount float64, orderType, side string, triggerPrice, +func (b *BTCMarkets) NewOrder(ctx context.Context, marketID string, price, amount float64, orderType, side string, triggerPrice, targetAmount float64, timeInForce string, postOnly bool, selfTrade, clientOrderID string) (OrderData, error) { var resp OrderData req := make(map[string]interface{}) @@ -337,7 +337,7 @@ func (b *BTCMarkets) NewOrder(marketID string, price, amount float64, orderType, if clientOrderID != "" { req["clientOrderID"] = clientOrderID } - return resp, b.SendAuthenticatedRequest(http.MethodPost, + return resp, b.SendAuthenticatedRequest(ctx, http.MethodPost, btcMarketsOrders, req, &resp, @@ -345,7 +345,7 @@ func (b *BTCMarkets) NewOrder(marketID string, price, amount float64, orderType, } // GetOrders returns current order information on the exchange -func (b *BTCMarkets) GetOrders(marketID string, before, after, limit int64, openOnly bool) ([]OrderData, error) { +func (b *BTCMarkets) GetOrders(ctx context.Context, marketID string, before, after, limit int64, openOnly bool) ([]OrderData, error) { if (before > 0) && (after >= 0) { return nil, errors.New("BTCMarkets only supports either before or after, not both") } @@ -366,7 +366,7 @@ func (b *BTCMarkets) GetOrders(marketID string, before, after, limit int64, open if openOnly { params.Set("status", "open") } - return resp, b.SendAuthenticatedRequest(http.MethodGet, + return resp, b.SendAuthenticatedRequest(ctx, http.MethodGet, common.EncodeURLValues(btcMarketsOrders, params), nil, &resp, @@ -374,7 +374,7 @@ func (b *BTCMarkets) GetOrders(marketID string, before, after, limit int64, open } // CancelAllOpenOrdersByPairs cancels all open orders unless pairs are specified -func (b *BTCMarkets) CancelAllOpenOrdersByPairs(marketIDs []string) ([]CancelOrderResp, error) { +func (b *BTCMarkets) CancelAllOpenOrdersByPairs(ctx context.Context, marketIDs []string) ([]CancelOrderResp, error) { var resp []CancelOrderResp req := make(map[string]interface{}) if len(marketIDs) > 0 { @@ -384,7 +384,7 @@ func (b *BTCMarkets) CancelAllOpenOrdersByPairs(marketIDs []string) ([]CancelOrd } req["marketId"] = strTemp.String()[:strTemp.Len()-1] } - return resp, b.SendAuthenticatedRequest(http.MethodDelete, + return resp, b.SendAuthenticatedRequest(ctx, http.MethodDelete, btcMarketsOrders, req, &resp, @@ -392,9 +392,9 @@ func (b *BTCMarkets) CancelAllOpenOrdersByPairs(marketIDs []string) ([]CancelOrd } // FetchOrder finds order based on the provided id -func (b *BTCMarkets) FetchOrder(id string) (OrderData, error) { +func (b *BTCMarkets) FetchOrder(ctx context.Context, id string) (OrderData, error) { var resp OrderData - return resp, b.SendAuthenticatedRequest(http.MethodGet, + return resp, b.SendAuthenticatedRequest(ctx, http.MethodGet, btcMarketsOrders+"/"+id, nil, &resp, @@ -402,9 +402,9 @@ func (b *BTCMarkets) FetchOrder(id string) (OrderData, error) { } // RemoveOrder removes a given order -func (b *BTCMarkets) RemoveOrder(id string) (CancelOrderResp, error) { +func (b *BTCMarkets) RemoveOrder(ctx context.Context, id string) (CancelOrderResp, error) { var resp CancelOrderResp - return resp, b.SendAuthenticatedRequest(http.MethodDelete, + return resp, b.SendAuthenticatedRequest(ctx, http.MethodDelete, btcMarketsOrders+"/"+id, nil, &resp, @@ -412,7 +412,7 @@ func (b *BTCMarkets) RemoveOrder(id string) (CancelOrderResp, error) { } // ListWithdrawals lists the withdrawal history -func (b *BTCMarkets) ListWithdrawals(before, after, limit int64) ([]TransferData, error) { +func (b *BTCMarkets) ListWithdrawals(ctx context.Context, before, after, limit int64) ([]TransferData, error) { if (before > 0) && (after >= 0) { return nil, errors.New("BTCMarkets only supports either before or after, not both") } @@ -427,7 +427,7 @@ func (b *BTCMarkets) ListWithdrawals(before, after, limit int64) ([]TransferData if limit > 0 { params.Set("limit", strconv.FormatInt(limit, 10)) } - return resp, b.SendAuthenticatedRequest(http.MethodGet, + return resp, b.SendAuthenticatedRequest(ctx, http.MethodGet, common.EncodeURLValues(btcMarketsWithdrawals, params), nil, &resp, @@ -435,12 +435,12 @@ func (b *BTCMarkets) ListWithdrawals(before, after, limit int64) ([]TransferData } // GetWithdrawal gets withdrawawl info for a given id -func (b *BTCMarkets) GetWithdrawal(id string) (TransferData, error) { +func (b *BTCMarkets) GetWithdrawal(ctx context.Context, id string) (TransferData, error) { var resp TransferData if id == "" { return resp, errors.New("id cannot be an empty string") } - return resp, b.SendAuthenticatedRequest(http.MethodGet, + return resp, b.SendAuthenticatedRequest(ctx, http.MethodGet, btcMarketsWithdrawals+"/"+id, nil, &resp, @@ -448,7 +448,7 @@ func (b *BTCMarkets) GetWithdrawal(id string) (TransferData, error) { } // ListDeposits lists the deposit history -func (b *BTCMarkets) ListDeposits(before, after, limit int64) ([]TransferData, error) { +func (b *BTCMarkets) ListDeposits(ctx context.Context, before, after, limit int64) ([]TransferData, error) { if (before > 0) && (after >= 0) { return nil, errors.New("BTCMarkets only supports either before or after, not both") } @@ -463,7 +463,7 @@ func (b *BTCMarkets) ListDeposits(before, after, limit int64) ([]TransferData, e if limit > 0 { params.Set("limit", strconv.FormatInt(limit, 10)) } - return resp, b.SendAuthenticatedRequest(http.MethodGet, + return resp, b.SendAuthenticatedRequest(ctx, http.MethodGet, common.EncodeURLValues(btcMarketsDeposits, params), nil, &resp, @@ -471,9 +471,9 @@ func (b *BTCMarkets) ListDeposits(before, after, limit int64) ([]TransferData, e } // GetDeposit gets deposit info for a given ID -func (b *BTCMarkets) GetDeposit(id string) (TransferData, error) { +func (b *BTCMarkets) GetDeposit(ctx context.Context, id string) (TransferData, error) { var resp TransferData - return resp, b.SendAuthenticatedRequest(http.MethodGet, + return resp, b.SendAuthenticatedRequest(ctx, http.MethodGet, btcMarketsDeposits+"/"+id, nil, &resp, @@ -481,7 +481,7 @@ func (b *BTCMarkets) GetDeposit(id string) (TransferData, error) { } // ListTransfers lists the past asset transfers -func (b *BTCMarkets) ListTransfers(before, after, limit int64) ([]TransferData, error) { +func (b *BTCMarkets) ListTransfers(ctx context.Context, before, after, limit int64) ([]TransferData, error) { if (before > 0) && (after >= 0) { return nil, errors.New("BTCMarkets only supports either before or after, not both") } @@ -496,7 +496,7 @@ func (b *BTCMarkets) ListTransfers(before, after, limit int64) ([]TransferData, if limit > 0 { params.Set("limit", strconv.FormatInt(limit, 10)) } - return resp, b.SendAuthenticatedRequest(http.MethodGet, + return resp, b.SendAuthenticatedRequest(ctx, http.MethodGet, common.EncodeURLValues(btcMarketsTransfers, params), nil, &resp, @@ -504,9 +504,9 @@ func (b *BTCMarkets) ListTransfers(before, after, limit int64) ([]TransferData, } // GetTransfer gets asset transfer info for a given ID -func (b *BTCMarkets) GetTransfer(id string) (TransferData, error) { +func (b *BTCMarkets) GetTransfer(ctx context.Context, id string) (TransferData, error) { var resp TransferData - return resp, b.SendAuthenticatedRequest(http.MethodGet, + return resp, b.SendAuthenticatedRequest(ctx, http.MethodGet, btcMarketsTransfers+"/"+id, nil, &resp, @@ -514,7 +514,7 @@ func (b *BTCMarkets) GetTransfer(id string) (TransferData, error) { } // FetchDepositAddress gets deposit address for the given asset -func (b *BTCMarkets) FetchDepositAddress(assetName string, before, after, limit int64) (DepositAddress, error) { +func (b *BTCMarkets) FetchDepositAddress(ctx context.Context, assetName string, before, after, limit int64) (DepositAddress, error) { var resp DepositAddress if (before > 0) && (after >= 0) { return resp, errors.New("BTCMarkets only supports either before or after, not both") @@ -530,7 +530,7 @@ func (b *BTCMarkets) FetchDepositAddress(assetName string, before, after, limit if limit > 0 { params.Set("limit", strconv.FormatInt(limit, 10)) } - return resp, b.SendAuthenticatedRequest(http.MethodGet, + return resp, b.SendAuthenticatedRequest(ctx, http.MethodGet, common.EncodeURLValues(btcMarketsAddresses, params), nil, &resp, @@ -538,16 +538,16 @@ func (b *BTCMarkets) FetchDepositAddress(assetName string, before, after, limit } // GetWithdrawalFees gets withdrawal fees for all assets -func (b *BTCMarkets) GetWithdrawalFees() ([]WithdrawalFeeData, error) { +func (b *BTCMarkets) GetWithdrawalFees(ctx context.Context) ([]WithdrawalFeeData, error) { var resp []WithdrawalFeeData - return resp, b.SendHTTPRequest(btcMarketsAPIURL+btcMarketsAPIVersion+btcMarketsWithdrawalFees, + return resp, b.SendHTTPRequest(ctx, btcMarketsAPIURL+btcMarketsAPIVersion+btcMarketsWithdrawalFees, &resp) } // ListAssets lists all available assets -func (b *BTCMarkets) ListAssets() ([]AssetData, error) { +func (b *BTCMarkets) ListAssets(ctx context.Context) ([]AssetData, error) { var resp []AssetData - return resp, b.SendAuthenticatedRequest(http.MethodGet, + return resp, b.SendAuthenticatedRequest(ctx, http.MethodGet, btcMarketsAssets, nil, &resp, @@ -555,7 +555,7 @@ func (b *BTCMarkets) ListAssets() ([]AssetData, error) { } // GetTransactions gets trading fees -func (b *BTCMarkets) GetTransactions(assetName string, before, after, limit int64) ([]TransactionData, error) { +func (b *BTCMarkets) GetTransactions(ctx context.Context, assetName string, before, after, limit int64) ([]TransactionData, error) { if (before > 0) && (after >= 0) { return nil, errors.New("BTCMarkets only supports either before or after, not both") } @@ -573,7 +573,7 @@ func (b *BTCMarkets) GetTransactions(assetName string, before, after, limit int6 if limit > 0 { params.Set("limit", strconv.FormatInt(limit, 10)) } - return resp, b.SendAuthenticatedRequest(http.MethodGet, + return resp, b.SendAuthenticatedRequest(ctx, http.MethodGet, common.EncodeURLValues(btcMarketsTransactions, params), nil, &resp, @@ -581,12 +581,12 @@ func (b *BTCMarkets) GetTransactions(assetName string, before, after, limit int6 } // CreateNewReport creates a new report -func (b *BTCMarkets) CreateNewReport(reportType, format string) (CreateReportResp, error) { +func (b *BTCMarkets) CreateNewReport(ctx context.Context, reportType, format string) (CreateReportResp, error) { var resp CreateReportResp req := make(map[string]interface{}) req["type"] = reportType req["format"] = format - return resp, b.SendAuthenticatedRequest(http.MethodPost, + return resp, b.SendAuthenticatedRequest(ctx, http.MethodPost, btcMarketsReports, req, &resp, @@ -594,9 +594,9 @@ func (b *BTCMarkets) CreateNewReport(reportType, format string) (CreateReportRes } // GetReport finds details bout a past report -func (b *BTCMarkets) GetReport(reportID string) (ReportData, error) { +func (b *BTCMarkets) GetReport(ctx context.Context, reportID string) (ReportData, error) { var resp ReportData - return resp, b.SendAuthenticatedRequest(http.MethodGet, + return resp, b.SendAuthenticatedRequest(ctx, http.MethodGet, btcMarketsReports+"/"+reportID, nil, &resp, @@ -604,7 +604,7 @@ func (b *BTCMarkets) GetReport(reportID string) (ReportData, error) { } // RequestWithdraw requests withdrawals -func (b *BTCMarkets) RequestWithdraw(assetName string, amount float64, +func (b *BTCMarkets) RequestWithdraw(ctx context.Context, assetName string, amount float64, toAddress, accountName, accountNumber, bsbNumber, bankName string) (TransferData, error) { var resp TransferData req := make(map[string]interface{}) @@ -626,7 +626,7 @@ func (b *BTCMarkets) RequestWithdraw(assetName string, amount float64, req["bankName"] = bankName } } - return resp, b.SendAuthenticatedRequest(http.MethodPost, + return resp, b.SendAuthenticatedRequest(ctx, http.MethodPost, btcMarketsWithdrawals, req, &resp, @@ -634,7 +634,7 @@ func (b *BTCMarkets) RequestWithdraw(assetName string, amount float64, } // BatchPlaceCancelOrders places and cancels batch orders -func (b *BTCMarkets) BatchPlaceCancelOrders(cancelOrders []CancelBatch, placeOrders []PlaceBatch) (BatchPlaceCancelResponse, error) { +func (b *BTCMarkets) BatchPlaceCancelOrders(ctx context.Context, cancelOrders []CancelBatch, placeOrders []PlaceBatch) (BatchPlaceCancelResponse, error) { var resp BatchPlaceCancelResponse var orderRequests []interface{} if len(cancelOrders)+len(placeOrders) > 4 { @@ -649,7 +649,7 @@ func (b *BTCMarkets) BatchPlaceCancelOrders(cancelOrders []CancelBatch, placeOrd } orderRequests = append(orderRequests, PlaceOrderMethod{PlaceOrder: placeOrders[y]}) } - return resp, b.SendAuthenticatedRequest(http.MethodPost, + return resp, b.SendAuthenticatedRequest(ctx, http.MethodPost, btcMarketsBatchOrders, orderRequests, &resp, @@ -657,13 +657,13 @@ func (b *BTCMarkets) BatchPlaceCancelOrders(cancelOrders []CancelBatch, placeOrd } // GetBatchTrades gets batch trades -func (b *BTCMarkets) GetBatchTrades(ids []string) (BatchTradeResponse, error) { +func (b *BTCMarkets) GetBatchTrades(ctx context.Context, ids []string) (BatchTradeResponse, error) { var resp BatchTradeResponse if len(ids) > 50 { return resp, errors.New("batchtrades can only handle 50 ids at a time") } marketIDs := strings.Join(ids, ",") - return resp, b.SendAuthenticatedRequest(http.MethodGet, + return resp, b.SendAuthenticatedRequest(ctx, http.MethodGet, btcMarketsBatchOrders+"/"+marketIDs, nil, &resp, @@ -671,10 +671,10 @@ func (b *BTCMarkets) GetBatchTrades(ids []string) (BatchTradeResponse, error) { } // CancelBatch cancels given ids -func (b *BTCMarkets) CancelBatch(ids []string) (BatchCancelResponse, error) { +func (b *BTCMarkets) CancelBatch(ctx context.Context, ids []string) (BatchCancelResponse, error) { var resp BatchCancelResponse marketIDs := strings.Join(ids, ",") - return resp, b.SendAuthenticatedRequest(http.MethodDelete, + return resp, b.SendAuthenticatedRequest(ctx, http.MethodDelete, btcMarketsBatchOrders+"/"+marketIDs, nil, &resp, @@ -682,7 +682,7 @@ func (b *BTCMarkets) CancelBatch(ids []string) (BatchCancelResponse, error) { } // SendHTTPRequest sends an unauthenticated HTTP request -func (b *BTCMarkets) SendHTTPRequest(path string, result interface{}) error { +func (b *BTCMarkets) SendHTTPRequest(ctx context.Context, path string, result interface{}) error { item := &request.Item{ Method: http.MethodGet, Path: path, @@ -691,13 +691,13 @@ func (b *BTCMarkets) SendHTTPRequest(path string, result interface{}) error { HTTPDebugging: b.HTTPDebugging, HTTPRecording: b.HTTPRecording, } - return b.SendPayload(context.Background(), request.Unset, func() (*request.Item, error) { + return b.SendPayload(ctx, request.Unset, func() (*request.Item, error) { return item, nil }) } // SendAuthenticatedRequest sends an authenticated HTTP request -func (b *BTCMarkets) SendAuthenticatedRequest(method, path string, data, result interface{}, f request.EndpointLimit) (err error) { +func (b *BTCMarkets) SendAuthenticatedRequest(ctx context.Context, method, path string, data, result interface{}, f request.EndpointLimit) (err error) { if !b.AllowAuthenticatedRequest() { return fmt.Errorf("%s %w", b.Name, exchange.ErrAuthenticatedRequestWithoutCredentialsSet) } @@ -753,16 +753,16 @@ func (b *BTCMarkets) SendAuthenticatedRequest(method, path string, data, result }, nil } - return b.SendPayload(context.Background(), f, newRequest) + return b.SendPayload(ctx, f, newRequest) } // GetFee returns an estimate of fee based on type of transaction -func (b *BTCMarkets) GetFee(feeBuilder *exchange.FeeBuilder) (float64, error) { +func (b *BTCMarkets) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { var fee float64 switch feeBuilder.FeeType { case exchange.CryptocurrencyTradeFee: - temp, err := b.GetTradingFees() + temp, err := b.GetTradingFees(ctx) if err != nil { return fee, err } @@ -779,7 +779,7 @@ func (b *BTCMarkets) GetFee(feeBuilder *exchange.FeeBuilder) (float64, error) { } } case exchange.CryptocurrencyWithdrawalFee: - temp, err := b.GetWithdrawalFees() + temp, err := b.GetWithdrawalFees(ctx) if err != nil { return fee, err } diff --git a/exchanges/btcmarkets/btcmarkets_test.go b/exchanges/btcmarkets/btcmarkets_test.go index d0ca0dcb..d348f4ab 100644 --- a/exchanges/btcmarkets/btcmarkets_test.go +++ b/exchanges/btcmarkets/btcmarkets_test.go @@ -1,6 +1,7 @@ package btcmarkets import ( + "context" "fmt" "log" "os" @@ -49,7 +50,7 @@ func TestMain(m *testing.M) { if err != nil { log.Fatal(err) } - err = b.ValidateCredentials(asset.Spot) + err = b.ValidateCredentials(context.Background(), asset.Spot) if err != nil { fmt.Println("API credentials are invalid:", err) b.API.AuthenticatedSupport = false @@ -64,7 +65,7 @@ func areTestAPIKeysSet() bool { func TestGetMarkets(t *testing.T) { t.Parallel() - _, err := b.GetMarkets() + _, err := b.GetMarkets(context.Background()) if err != nil { t.Error("GetTicker() error", err) } @@ -72,7 +73,7 @@ func TestGetMarkets(t *testing.T) { func TestGetTicker(t *testing.T) { t.Parallel() - _, err := b.GetTicker(BTCAUD) + _, err := b.GetTicker(context.Background(), BTCAUD) if err != nil { t.Error("GetOrderbook() error", err) } @@ -80,7 +81,7 @@ func TestGetTicker(t *testing.T) { func TestGetTrades(t *testing.T) { t.Parallel() - _, err := b.GetTrades(BTCAUD, 0, 0, 5) + _, err := b.GetTrades(context.Background(), BTCAUD, 0, 0, 5) if err != nil { t.Error("GetTrades() error", err) } @@ -88,7 +89,7 @@ func TestGetTrades(t *testing.T) { func TestGetOrderbook(t *testing.T) { t.Parallel() - _, err := b.GetOrderbook(BTCAUD, 2) + _, err := b.GetOrderbook(context.Background(), BTCAUD, 2) if err != nil { t.Error("GetTrades() error", err) } @@ -96,7 +97,8 @@ func TestGetOrderbook(t *testing.T) { func TestGetMarketCandles(t *testing.T) { t.Parallel() - _, err := b.GetMarketCandles(BTCAUD, "1h", time.Now().UTC().Add(-time.Hour*24), time.Now().UTC(), -1, -1, -1) + _, err := b.GetMarketCandles(context.Background(), + BTCAUD, "1h", time.Now().UTC().Add(-time.Hour*24), time.Now().UTC(), -1, -1, -1) if err != nil { t.Error(err) } @@ -108,7 +110,7 @@ func TestGetTickers(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = b.GetTickers(temp) + _, err = b.GetTickers(context.Background(), temp) if err != nil { t.Error(err) } @@ -117,7 +119,7 @@ func TestGetTickers(t *testing.T) { func TestGetMultipleOrderbooks(t *testing.T) { t.Parallel() temp := []string{BTCAUD, LTCAUD, ETHAUD} - _, err := b.GetMultipleOrderbooks(temp) + _, err := b.GetMultipleOrderbooks(context.Background(), temp) if err != nil { t.Error(err) } @@ -125,7 +127,7 @@ func TestGetMultipleOrderbooks(t *testing.T) { func TestGetServerTime(t *testing.T) { t.Parallel() - _, err := b.GetServerTime() + _, err := b.GetServerTime(context.Background()) if err != nil { t.Error(err) } @@ -136,7 +138,7 @@ func TestGetAccountBalance(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys required but not set, skipping test") } - _, err := b.GetAccountBalance() + _, err := b.GetAccountBalance(context.Background()) if err != nil { t.Error(err) } @@ -147,7 +149,7 @@ func TestGetTradingFees(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys required but not set, skipping test") } - _, err := b.GetTradingFees() + _, err := b.GetTradingFees(context.Background()) if err != nil { t.Error(err) } @@ -158,15 +160,15 @@ func TestGetTradeHistory(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys required but not set, skipping test") } - _, err := b.GetTradeHistory(ETHAUD, "", -1, -1, -1) + _, err := b.GetTradeHistory(context.Background(), ETHAUD, "", -1, -1, -1) if err != nil { t.Error(err) } - _, err = b.GetTradeHistory(BTCAUD, "", -1, -1, 1) + _, err = b.GetTradeHistory(context.Background(), BTCAUD, "", -1, -1, 1) if err != nil { t.Error(err) } - _, err = b.GetTradeHistory(fakePair, "", -1, -1, -1) + _, err = b.GetTradeHistory(context.Background(), fakePair, "", -1, -1, -1) if err == nil { t.Error("expected an error due to invalid trading pair") } @@ -177,7 +179,7 @@ func TestGetTradeByID(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys required but not set, skipping test") } - _, err := b.GetTradeByID("4712043732") + _, err := b.GetTradeByID(context.Background(), "4712043732") if err != nil { t.Error(err) } @@ -188,15 +190,18 @@ func TestNewOrder(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test, either api keys or manipulaterealorders isnt set correctly") } - _, err := b.NewOrder(BTCAUD, 100, 1, limit, bid, 0, 0, "", true, "", "") + _, err := b.NewOrder(context.Background(), + BTCAUD, 100, 1, limit, bid, 0, 0, "", true, "", "") if err != nil { t.Error(err) } - _, err = b.NewOrder(BTCAUD, 100, 1, "invalid", bid, 0, 0, "", true, "", "") + _, err = b.NewOrder(context.Background(), + BTCAUD, 100, 1, "invalid", bid, 0, 0, "", true, "", "") if err == nil { t.Error("expected an error due to invalid ordertype") } - _, err = b.NewOrder(BTCAUD, 100, 1, limit, "invalid", 0, 0, "", true, "", "") + _, err = b.NewOrder(context.Background(), + BTCAUD, 100, 1, limit, "invalid", 0, 0, "", true, "", "") if err == nil { t.Error("expected an error due to invalid orderside") } @@ -207,11 +212,11 @@ func TestGetOrders(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys required but not set, skipping test") } - _, err := b.GetOrders("", -1, -1, 2, false) + _, err := b.GetOrders(context.Background(), "", -1, -1, 2, false) if err != nil { t.Error(err) } - _, err = b.GetOrders(LTCAUD, -1, -1, -1, true) + _, err = b.GetOrders(context.Background(), LTCAUD, -1, -1, -1, true) if err != nil { t.Error(err) } @@ -223,12 +228,12 @@ func TestCancelOpenOrders(t *testing.T) { t.Skip("skipping test, either api keys or manipulaterealorders isnt set correctly") } temp := []string{BTCAUD, LTCAUD} - _, err := b.CancelAllOpenOrdersByPairs(temp) + _, err := b.CancelAllOpenOrdersByPairs(context.Background(), temp) if err != nil { t.Error(err) } temp = []string{BTCAUD, fakePair} - _, err = b.CancelAllOpenOrdersByPairs(temp) + _, err = b.CancelAllOpenOrdersByPairs(context.Background(), temp) if err == nil { t.Error("expected an error due to invalid marketID") } @@ -239,11 +244,11 @@ func TestFetchOrder(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys required but not set, skipping test") } - _, err := b.FetchOrder("4477045999") + _, err := b.FetchOrder(context.Background(), "4477045999") if err != nil { t.Error(err) } - _, err = b.FetchOrder("696969") + _, err = b.FetchOrder(context.Background(), "696969") if err == nil { t.Error(err) } @@ -254,7 +259,7 @@ func TestRemoveOrder(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test, either api keys or manipulaterealorders isnt set correctly") } - _, err := b.RemoveOrder("") + _, err := b.RemoveOrder(context.Background(), "") if err != nil { t.Error(err) } @@ -265,7 +270,7 @@ func TestListWithdrawals(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys required but not set, skipping test") } - _, err := b.ListWithdrawals(-1, -1, -1) + _, err := b.ListWithdrawals(context.Background(), -1, -1, -1) if err != nil { t.Error(err) } @@ -276,7 +281,7 @@ func TestGetWithdrawal(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys required but not set, skipping test") } - _, err := b.GetWithdrawal("4477381751") + _, err := b.GetWithdrawal(context.Background(), "4477381751") if err != nil { t.Error(err) } @@ -287,7 +292,7 @@ func TestListDeposits(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys required but not set, skipping test") } - _, err := b.ListDeposits(-1, -1, -1) + _, err := b.ListDeposits(context.Background(), -1, -1, -1) if err != nil { t.Error(err) } @@ -298,7 +303,7 @@ func TestGetDeposit(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys required but not set, skipping test") } - _, err := b.GetDeposit("4476769607") + _, err := b.GetDeposit(context.Background(), "4476769607") if err != nil { t.Error(err) } @@ -309,7 +314,7 @@ func TestListTransfers(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys required but not set, skipping test") } - _, err := b.ListTransfers(-1, -1, -1) + _, err := b.ListTransfers(context.Background(), -1, -1, -1) if err != nil { t.Error(err) } @@ -320,11 +325,11 @@ func TestGetTransfer(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys required but not set, skipping test") } - _, err := b.GetTransfer("4476769607") + _, err := b.GetTransfer(context.Background(), "4476769607") if err != nil { t.Error(err) } - _, err = b.GetTransfer("6969696") + _, err = b.GetTransfer(context.Background(), "6969696") if err == nil { t.Error("expected an error due to invalid transferID") } @@ -335,11 +340,11 @@ func TestFetchDepositAddress(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys required but not set, skipping test") } - _, err := b.FetchDepositAddress("LTC", -1, -1, -1) + _, err := b.FetchDepositAddress(context.Background(), "LTC", -1, -1, -1) if err != nil { t.Error(err) } - _, err = b.FetchDepositAddress(fakePair, -1, -1, -1) + _, err = b.FetchDepositAddress(context.Background(), fakePair, -1, -1, -1) if err != nil { t.Error("expected an error due to invalid assetID") } @@ -347,7 +352,7 @@ func TestFetchDepositAddress(t *testing.T) { func TestGetWithdrawalFees(t *testing.T) { t.Parallel() - _, err := b.GetWithdrawalFees() + _, err := b.GetWithdrawalFees(context.Background()) if err != nil { t.Error(err) } @@ -358,7 +363,7 @@ func TestListAssets(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys required but not set, skipping test") } - _, err := b.ListAssets() + _, err := b.ListAssets(context.Background()) if err != nil { t.Error(err) } @@ -369,7 +374,7 @@ func TestGetTransactions(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys required but not set, skipping test") } - _, err := b.GetTransactions("", -1, -1, -1) + _, err := b.GetTransactions(context.Background(), "", -1, -1, -1) if err != nil { t.Error(err) } @@ -380,7 +385,7 @@ func TestCreateNewReport(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys required but not set, skipping test") } - _, err := b.CreateNewReport("TransactionReport", "json") + _, err := b.CreateNewReport(context.Background(), "TransactionReport", "json") if err != nil { t.Error(err) } @@ -391,7 +396,7 @@ func TestGetReport(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys required but not set, skipping test") } - _, err := b.GetReport("1kv38epne5v7lek9f18m60idg6") + _, err := b.GetReport(context.Background(), "1kv38epne5v7lek9f18m60idg6") if err != nil { t.Error(err) } @@ -402,7 +407,7 @@ func TestRequestWithdaw(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test, either api keys or manipulaterealorders isnt set correctly") } - _, err := b.RequestWithdraw("BTC", 1, "sdjflajdslfjld", "", "", "", "") + _, err := b.RequestWithdraw(context.Background(), "BTC", 1, "sdjflajdslfjld", "", "", "", "") if err == nil { t.Error("expected an error due to invalid toAddress") } @@ -421,7 +426,7 @@ func TestBatchPlaceCancelOrders(t *testing.T) { OrderType: order.Limit.String(), Side: bid, } - _, err := b.BatchPlaceCancelOrders(nil, append(temp, o)) + _, err := b.BatchPlaceCancelOrders(context.Background(), nil, append(temp, o)) if err != nil { t.Error(err) } @@ -433,7 +438,7 @@ func TestGetBatchTrades(t *testing.T) { t.Skip("API keys required but not set, skipping test") } temp := []string{"4477045999", "4477381751", "4476769607"} - _, err := b.GetBatchTrades(temp) + _, err := b.GetBatchTrades(context.Background(), temp) if err != nil { t.Error(err) } @@ -445,7 +450,7 @@ func TestCancelBatch(t *testing.T) { t.Skip("skipping test, either api keys or manipulaterealorders isnt set correctly") } temp := []string{"4477045999", "4477381751", "4477381751"} - _, err := b.CancelBatch(temp) + _, err := b.CancelBatch(context.Background(), temp) if err != nil { t.Error(err) } @@ -456,7 +461,7 @@ func TestFetchAccountInfo(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys required but not set, skipping test") } - _, err := b.FetchAccountInfo(asset.Spot) + _, err := b.FetchAccountInfo(context.Background(), asset.Spot) if err != nil { t.Error(err) } @@ -468,7 +473,7 @@ func TestGetOrderHistory(t *testing.T) { t.Skip("API keys required but not set, skipping test") } - _, err := b.GetOrderHistory(&order.GetOrdersRequest{ + _, err := b.GetOrderHistory(context.Background(), &order.GetOrdersRequest{ Side: order.Buy, AssetType: asset.Spot, }) @@ -480,7 +485,7 @@ func TestGetOrderHistory(t *testing.T) { func TestUpdateOrderbook(t *testing.T) { t.Parallel() cp := currency.NewPairWithDelimiter(currency.BTC.String(), currency.AUD.String(), "-") - _, err := b.UpdateOrderbook(cp, asset.Spot) + _, err := b.UpdateOrderbook(context.Background(), cp, asset.Spot) if err != nil { t.Error(err) } @@ -489,7 +494,7 @@ func TestUpdateOrderbook(t *testing.T) { func TestUpdateTicker(t *testing.T) { t.Parallel() cp := currency.NewPairWithDelimiter(currency.BTC.String(), currency.AUD.String(), "-") - _, err := b.UpdateTicker(cp, asset.Spot) + _, err := b.UpdateTicker(context.Background(), cp, asset.Spot) if err != nil { t.Error(err) } @@ -497,7 +502,7 @@ func TestUpdateTicker(t *testing.T) { func TestUpdateTickers(t *testing.T) { t.Parallel() - err := b.UpdateTickers(asset.Spot) + err := b.UpdateTickers(context.Background(), asset.Spot) if err != nil { t.Error(err) } @@ -509,7 +514,8 @@ func TestGetActiveOrders(t *testing.T) { t.Skip("API keys required but not set, skipping test") } - _, err := b.GetActiveOrders(&order.GetOrdersRequest{AssetType: asset.Spot}) + _, err := b.GetActiveOrders(context.Background(), + &order.GetOrdersRequest{AssetType: asset.Spot}) if err != nil { t.Fatal(err) } @@ -732,11 +738,21 @@ func TestBTCMarkets_GetHistoricCandles(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = b.GetHistoricCandles(p, asset.Spot, time.Now().Add(-time.Hour*24).UTC(), time.Now().UTC(), kline.OneHour) + _, err = b.GetHistoricCandles(context.Background(), + p, + asset.Spot, + time.Now().Add(-time.Hour*24).UTC(), + time.Now().UTC(), + kline.OneHour) if err != nil { t.Fatal(err) } - _, err = b.GetHistoricCandles(p, asset.Spot, time.Now().Add(-time.Hour*24).UTC(), time.Now().UTC(), kline.FifteenMin) + _, err = b.GetHistoricCandles(context.Background(), + p, + asset.Spot, + time.Now().Add(-time.Hour*24).UTC(), + time.Now().UTC(), + kline.FifteenMin) if err != nil { if err.Error() != "interval not supported" { t.Fatal(err) @@ -751,7 +767,8 @@ func TestBTCMarkets_GetHistoricCandlesExtended(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = b.GetHistoricCandlesExtended(p, asset.Spot, start, end, kline.OneDay) + _, err = b.GetHistoricCandlesExtended(context.Background(), + p, asset.Spot, start, end, kline.OneDay) if err != nil { t.Fatal(err) } @@ -794,7 +811,7 @@ func TestGetRecentTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = b.GetRecentTrades(currencyPair, asset.Spot) + _, err = b.GetRecentTrades(context.Background(), currencyPair, asset.Spot) if err != nil { t.Error(err) } @@ -806,7 +823,8 @@ func TestGetHistoricTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = b.GetHistoricTrades(currencyPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) + _, err = b.GetHistoricTrades(context.Background(), + currencyPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) if err != nil && err != common.ErrFunctionNotSupported { t.Error(err) } diff --git a/exchanges/btcmarkets/btcmarkets_wrapper.go b/exchanges/btcmarkets/btcmarkets_wrapper.go index 5b230e86..68c9f029 100644 --- a/exchanges/btcmarkets/btcmarkets_wrapper.go +++ b/exchanges/btcmarkets/btcmarkets_wrapper.go @@ -1,6 +1,7 @@ package btcmarkets import ( + "context" "errors" "fmt" "sort" @@ -41,7 +42,7 @@ func (b *BTCMarkets) GetDefaultConfig() (*config.ExchangeConfig, error) { } if b.Features.Supports.RESTCapabilities.AutoPairUpdates { - err = b.UpdateTradablePairs(true) + err = b.UpdateTradablePairs(context.TODO(), true) if err != nil { return nil, err } @@ -246,7 +247,7 @@ func (b *BTCMarkets) Run() { return } - err = b.UpdateTradablePairs(forceUpdate) + err = b.UpdateTradablePairs(context.TODO(), forceUpdate) if err != nil { log.Errorf(log.ExchangeSys, "%s failed to update tradable pairs. Err: %s", @@ -256,11 +257,11 @@ func (b *BTCMarkets) Run() { } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (b *BTCMarkets) FetchTradablePairs(a asset.Item) ([]string, error) { +func (b *BTCMarkets) FetchTradablePairs(ctx context.Context, a asset.Item) ([]string, error) { if a != asset.Spot { return nil, fmt.Errorf("asset type of %s is not supported by %s", a, b.Name) } - markets, err := b.GetMarkets() + markets, err := b.GetMarkets(ctx) if err != nil { return nil, err } @@ -274,8 +275,8 @@ func (b *BTCMarkets) FetchTradablePairs(a asset.Item) ([]string, error) { // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (b *BTCMarkets) UpdateTradablePairs(forceUpdate bool) error { - pairs, err := b.FetchTradablePairs(asset.Spot) +func (b *BTCMarkets) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { + pairs, err := b.FetchTradablePairs(ctx, asset.Spot) if err != nil { return err } @@ -288,13 +289,13 @@ func (b *BTCMarkets) UpdateTradablePairs(forceUpdate bool) error { } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (b *BTCMarkets) UpdateTickers(a asset.Item) error { +func (b *BTCMarkets) UpdateTickers(ctx context.Context, a asset.Item) error { allPairs, err := b.GetEnabledPairs(a) if err != nil { return err } - tickers, err := b.GetTickers(allPairs) + tickers, err := b.GetTickers(ctx, allPairs) if err != nil { return err } @@ -330,8 +331,8 @@ func (b *BTCMarkets) UpdateTickers(a asset.Item) error { } // UpdateTicker updates and returns the ticker for a currency pair -func (b *BTCMarkets) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) { - err := b.UpdateTickers(a) +func (b *BTCMarkets) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { + err := b.UpdateTickers(ctx, a) if err != nil { return nil, err } @@ -339,7 +340,7 @@ func (b *BTCMarkets) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, } // FetchTicker returns the ticker for a currency pair -func (b *BTCMarkets) FetchTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) { +func (b *BTCMarkets) FetchTicker(ctx context.Context, p currency.Pair, assetType asset.Item) (*ticker.Price, error) { fPair, err := b.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err @@ -347,13 +348,13 @@ func (b *BTCMarkets) FetchTicker(p currency.Pair, assetType asset.Item) (*ticker tickerNew, err := ticker.GetTicker(b.Name, fPair, assetType) if err != nil { - return b.UpdateTicker(p, assetType) + return b.UpdateTicker(ctx, p, assetType) } return tickerNew, nil } // FetchOrderbook returns orderbook base on the currency pair -func (b *BTCMarkets) FetchOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (b *BTCMarkets) FetchOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { fPair, err := b.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err @@ -361,13 +362,13 @@ func (b *BTCMarkets) FetchOrderbook(p currency.Pair, assetType asset.Item) (*ord ob, err := orderbook.Get(b.Name, fPair, assetType) if err != nil { - return b.UpdateOrderbook(p, assetType) + return b.UpdateOrderbook(ctx, p, assetType) } return ob, nil } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (b *BTCMarkets) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (b *BTCMarkets) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { book := &orderbook.Base{ Exchange: b.Name, Pair: p, @@ -381,7 +382,7 @@ func (b *BTCMarkets) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*or return book, err } - tempResp, err := b.GetOrderbook(fpair.String(), 2) + tempResp, err := b.GetOrderbook(ctx, fpair.String(), 2) if err != nil { return book, err } @@ -404,9 +405,9 @@ func (b *BTCMarkets) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*or } // UpdateAccountInfo retrieves balances for all enabled currencies -func (b *BTCMarkets) UpdateAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (b *BTCMarkets) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { var resp account.Holdings - data, err := b.GetAccountBalance() + data, err := b.GetAccountBalance(ctx) if err != nil { return resp, err } @@ -432,10 +433,10 @@ func (b *BTCMarkets) UpdateAccountInfo(assetType asset.Item) (account.Holdings, } // FetchAccountInfo retrieves balances for all enabled currencies -func (b *BTCMarkets) FetchAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (b *BTCMarkets) FetchAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { acc, err := account.GetHoldings(b.Name, assetType) if err != nil { - return b.UpdateAccountInfo(assetType) + return b.UpdateAccountInfo(ctx, assetType) } return acc, nil @@ -443,17 +444,17 @@ func (b *BTCMarkets) FetchAccountInfo(assetType asset.Item) (account.Holdings, e // GetFundingHistory returns funding history, deposits and // withdrawals -func (b *BTCMarkets) GetFundingHistory() ([]exchange.FundHistory, error) { +func (b *BTCMarkets) GetFundingHistory(ctx context.Context) ([]exchange.FundHistory, error) { return nil, common.ErrFunctionNotSupported } // GetWithdrawalsHistory returns previous withdrawals data -func (b *BTCMarkets) GetWithdrawalsHistory(c currency.Code) (resp []exchange.WithdrawalHistory, err error) { +func (b *BTCMarkets) GetWithdrawalsHistory(ctx context.Context, c currency.Code) (resp []exchange.WithdrawalHistory, err error) { return nil, common.ErrNotYetImplemented } // GetRecentTrades returns the most recent trades for a currency and asset -func (b *BTCMarkets) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade.Data, error) { +func (b *BTCMarkets) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { var err error p, err = b.FormatExchangeCurrency(p, assetType) if err != nil { @@ -461,7 +462,7 @@ func (b *BTCMarkets) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]t } var resp []trade.Data var tradeData []Trade - tradeData, err = b.GetTrades(p.String(), 0, 0, 200) + tradeData, err = b.GetTrades(ctx, p.String(), 0, 0, 200) if err != nil { return nil, err } @@ -495,12 +496,12 @@ func (b *BTCMarkets) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]t } // GetHistoricTrades returns historic trade data within the timeframe provided -func (b *BTCMarkets) GetHistoricTrades(_ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { +func (b *BTCMarkets) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { return nil, common.ErrFunctionNotSupported } // SubmitOrder submits a new order -func (b *BTCMarkets) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { +func (b *BTCMarkets) SubmitOrder(ctx context.Context, s *order.Submit) (order.SubmitResponse, error) { var resp order.SubmitResponse if err := s.Validate(); err != nil { return resp, err @@ -518,7 +519,8 @@ func (b *BTCMarkets) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) return resp, err } - tempResp, err := b.NewOrder(fpair.String(), + tempResp, err := b.NewOrder(ctx, + fpair.String(), s.Price, s.Amount, s.Type.String(), @@ -539,31 +541,31 @@ func (b *BTCMarkets) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (b *BTCMarkets) ModifyOrder(action *order.Modify) (order.Modify, error) { +func (b *BTCMarkets) ModifyOrder(ctx context.Context, action *order.Modify) (order.Modify, error) { return order.Modify{}, common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number -func (b *BTCMarkets) CancelOrder(o *order.Cancel) error { +func (b *BTCMarkets) CancelOrder(ctx context.Context, o *order.Cancel) error { err := o.Validate(o.StandardCancel()) if err != nil { return err } - _, err = b.RemoveOrder(o.ID) + _, err = b.RemoveOrder(ctx, o.ID) return err } // CancelBatchOrders cancels an orders by their corresponding ID numbers -func (b *BTCMarkets) CancelBatchOrders(o []order.Cancel) (order.CancelBatchResponse, error) { +func (b *BTCMarkets) CancelBatchOrders(ctx context.Context, o []order.Cancel) (order.CancelBatchResponse, error) { return order.CancelBatchResponse{}, common.ErrNotYetImplemented } // CancelAllOrders cancels all orders associated with a currency pair -func (b *BTCMarkets) CancelAllOrders(_ *order.Cancel) (order.CancelAllResponse, error) { +func (b *BTCMarkets) CancelAllOrders(ctx context.Context, _ *order.Cancel) (order.CancelAllResponse, error) { var resp order.CancelAllResponse tempMap := make(map[string]string) var orderIDs []string - orders, err := b.GetOrders("", -1, -1, -1, true) + orders, err := b.GetOrders(ctx, "", -1, -1, -1, true) if err != nil { return resp, err } @@ -572,7 +574,7 @@ func (b *BTCMarkets) CancelAllOrders(_ *order.Cancel) (order.CancelAllResponse, } splitOrders := common.SplitStringSliceByLimit(orderIDs, 20) for z := range splitOrders { - tempResp, err := b.CancelBatch(splitOrders[z]) + tempResp, err := b.CancelBatch(ctx, splitOrders[z]) if err != nil { return resp, err } @@ -588,9 +590,9 @@ func (b *BTCMarkets) CancelAllOrders(_ *order.Cancel) (order.CancelAllResponse, } // GetOrderInfo returns order information based on order ID -func (b *BTCMarkets) GetOrderInfo(orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { +func (b *BTCMarkets) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { var resp order.Detail - o, err := b.FetchOrder(orderID) + o, err := b.FetchOrder(ctx, orderID) if err != nil { return resp, err } @@ -647,8 +649,8 @@ func (b *BTCMarkets) GetOrderInfo(orderID string, pair currency.Pair, assetType } // GetDepositAddress returns a deposit address for a specified currency -func (b *BTCMarkets) GetDepositAddress(cryptocurrency currency.Code, accountID string) (string, error) { - temp, err := b.FetchDepositAddress(strings.ToUpper(cryptocurrency.String()), -1, -1, -1) +func (b *BTCMarkets) GetDepositAddress(ctx context.Context, c currency.Code, accountID string) (string, error) { + temp, err := b.FetchDepositAddress(ctx, strings.ToUpper(c.String()), -1, -1, -1) if err != nil { return "", err } @@ -656,11 +658,12 @@ func (b *BTCMarkets) GetDepositAddress(cryptocurrency currency.Code, accountID s } // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is submitted -func (b *BTCMarkets) WithdrawCryptocurrencyFunds(withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (b *BTCMarkets) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } - a, err := b.RequestWithdraw(withdrawRequest.Currency.String(), + a, err := b.RequestWithdraw(ctx, + withdrawRequest.Currency.String(), withdrawRequest.Amount, withdrawRequest.Crypto.Address, "", @@ -678,14 +681,15 @@ func (b *BTCMarkets) WithdrawCryptocurrencyFunds(withdrawRequest *withdraw.Reque // WithdrawFiatFunds returns a withdrawal ID when a // withdrawal is submitted -func (b *BTCMarkets) WithdrawFiatFunds(withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (b *BTCMarkets) WithdrawFiatFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } if withdrawRequest.Currency != currency.AUD { return nil, errors.New("only aud is supported for withdrawals") } - a, err := b.RequestWithdraw(withdrawRequest.Currency.String(), + a, err := b.RequestWithdraw(ctx, + withdrawRequest.Currency.String(), withdrawRequest.Amount, "", withdrawRequest.Fiat.Bank.AccountName, @@ -703,21 +707,21 @@ func (b *BTCMarkets) WithdrawFiatFunds(withdrawRequest *withdraw.Request) (*with // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a // withdrawal is submitted -func (b *BTCMarkets) WithdrawFiatFundsToInternationalBank(_ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (b *BTCMarkets) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // GetFeeByType returns an estimate of fee based on type of transaction -func (b *BTCMarkets) GetFeeByType(feeBuilder *exchange.FeeBuilder) (float64, error) { +func (b *BTCMarkets) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { if !b.AllowAuthenticatedRequest() && // Todo check connection status feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { feeBuilder.FeeType = exchange.OfflineTradeFee } - return b.GetFee(feeBuilder) + return b.GetFee(ctx, feeBuilder) } // GetActiveOrders retrieves any orders that are active/open -func (b *BTCMarkets) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, error) { +func (b *BTCMarkets) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) { if err := req.Validate(); err != nil { return nil, err } @@ -738,7 +742,7 @@ func (b *BTCMarkets) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detai if err != nil { return nil, err } - tempData, err := b.GetOrders(fpair.String(), -1, -1, -1, true) + tempData, err := b.GetOrders(ctx, fpair.String(), -1, -1, -1, true) if err != nil { return resp, err } @@ -795,7 +799,7 @@ func (b *BTCMarkets) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detai // GetOrderHistory retrieves account order information // Can Limit response to specific order status -func (b *BTCMarkets) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, error) { +func (b *BTCMarkets) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) { if err := req.Validate(); err != nil { return nil, err } @@ -803,7 +807,7 @@ func (b *BTCMarkets) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detai var tempResp order.Detail var tempArray []string if len(req.Pairs) == 0 { - orders, err := b.GetOrders("", -1, -1, -1, false) + orders, err := b.GetOrders(ctx, "", -1, -1, -1, false) if err != nil { return resp, err } @@ -817,7 +821,7 @@ func (b *BTCMarkets) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detai return nil, err } - orders, err := b.GetOrders(fpair.String(), -1, -1, -1, false) + orders, err := b.GetOrders(ctx, fpair.String(), -1, -1, -1, false) if err != nil { return resp, err } @@ -827,7 +831,7 @@ func (b *BTCMarkets) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detai } splitOrders := common.SplitStringSliceByLimit(tempArray, 50) for x := range splitOrders { - tempData, err := b.GetBatchTrades(splitOrders[x]) + tempData, err := b.GetBatchTrades(ctx, splitOrders[x]) if err != nil { return resp, err } @@ -872,8 +876,8 @@ func (b *BTCMarkets) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detai // ValidateCredentials validates current credentials used for wrapper // functionality -func (b *BTCMarkets) ValidateCredentials(assetType asset.Item) error { - _, err := b.UpdateAccountInfo(assetType) +func (b *BTCMarkets) ValidateCredentials(ctx context.Context, assetType asset.Item) error { + _, err := b.UpdateAccountInfo(ctx, assetType) if err != nil { if b.CheckTransientError(err) == nil { return nil @@ -900,7 +904,7 @@ func (b *BTCMarkets) FormatExchangeKlineInterval(in kline.Interval) string { } // GetHistoricCandles returns candles between a time period for a set time interval -func (b *BTCMarkets) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (b *BTCMarkets) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { if err := b.ValidateKline(pair, a, interval); err != nil { return kline.Item{}, err } @@ -914,7 +918,8 @@ func (b *BTCMarkets) GetHistoricCandles(pair currency.Pair, a asset.Item, start, return kline.Item{}, err } - candles, err := b.GetMarketCandles(formattedPair.String(), + candles, err := b.GetMarketCandles(ctx, + formattedPair.String(), b.FormatExchangeKlineInterval(interval), start, end, @@ -968,7 +973,7 @@ func (b *BTCMarkets) GetHistoricCandles(pair currency.Pair, a asset.Item, start, } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (b *BTCMarkets) GetHistoricCandlesExtended(p currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (b *BTCMarkets) GetHistoricCandlesExtended(ctx context.Context, p currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { if err := b.ValidateKline(p, a, interval); err != nil { return kline.Item{}, err } @@ -991,7 +996,8 @@ func (b *BTCMarkets) GetHistoricCandlesExtended(p currency.Pair, a asset.Item, s } for x := range dates.Ranges { var candles CandleResponse - candles, err = b.GetMarketCandles(fPair.String(), + candles, err = b.GetMarketCandles(ctx, + fPair.String(), b.FormatExchangeKlineInterval(interval), dates.Ranges[x].Start.Time, dates.Ranges[x].End.Time, -1, -1, -1) if err != nil { diff --git a/exchanges/btse/btse.go b/exchanges/btse/btse.go index 8297b534..a543bc66 100644 --- a/exchanges/btse/btse.go +++ b/exchanges/btse/btse.go @@ -57,27 +57,27 @@ const ( ) // FetchFundingHistory gets funding history -func (b *BTSE) FetchFundingHistory(symbol string) (map[string][]FundingHistoryData, error) { +func (b *BTSE) FetchFundingHistory(ctx context.Context, symbol string) (map[string][]FundingHistoryData, error) { var resp map[string][]FundingHistoryData params := url.Values{} if symbol != "" { params.Set("symbol", symbol) } - return resp, b.SendHTTPRequest(exchange.RestFutures, http.MethodGet, btseFuturesFunding+params.Encode(), &resp, false, queryFunc) + return resp, b.SendHTTPRequest(ctx, exchange.RestFutures, http.MethodGet, btseFuturesFunding+params.Encode(), &resp, false, queryFunc) } // GetMarketSummary stores market summary data -func (b *BTSE) GetMarketSummary(symbol string, spot bool) (MarketSummary, error) { +func (b *BTSE) GetMarketSummary(ctx context.Context, symbol string, spot bool) (MarketSummary, error) { var m MarketSummary path := btseMarketOverview if symbol != "" { path += "?symbol=" + url.QueryEscape(symbol) } - return m, b.SendHTTPRequest(exchange.RestSpot, http.MethodGet, path, &m, spot, queryFunc) + return m, b.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, path, &m, spot, queryFunc) } // FetchOrderBook gets orderbook data for a given pair -func (b *BTSE) FetchOrderBook(symbol string, group, limitBids, limitAsks int, spot bool) (*Orderbook, error) { +func (b *BTSE) FetchOrderBook(ctx context.Context, symbol string, group, limitBids, limitAsks int, spot bool) (*Orderbook, error) { var o Orderbook urlValues := url.Values{} urlValues.Add("symbol", symbol) @@ -90,22 +90,22 @@ func (b *BTSE) FetchOrderBook(symbol string, group, limitBids, limitAsks int, sp if group > 0 { urlValues.Add("group", strconv.Itoa(group)) } - return &o, b.SendHTTPRequest(exchange.RestSpot, http.MethodGet, + return &o, b.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, common.EncodeURLValues(btseOrderbook, urlValues), &o, spot, queryFunc) } // FetchOrderBookL2 retrieve level 2 orderbook for requested symbol and depth -func (b *BTSE) FetchOrderBookL2(symbol string, depth int) (*Orderbook, error) { +func (b *BTSE) FetchOrderBookL2(ctx context.Context, symbol string, depth int) (*Orderbook, error) { var o Orderbook urlValues := url.Values{} urlValues.Add("symbol", symbol) urlValues.Add("depth", strconv.FormatInt(int64(depth), 10)) endpoint := common.EncodeURLValues(btseOrderbook+"/L2", urlValues) - return &o, b.SendHTTPRequest(exchange.RestSpot, http.MethodGet, endpoint, &o, true, queryFunc) + return &o, b.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, endpoint, &o, true, queryFunc) } // GetTrades returns a list of trades for the specified symbol -func (b *BTSE) GetTrades(symbol string, start, end time.Time, beforeSerialID, afterSerialID, count int, includeOld, spot bool) ([]Trade, error) { +func (b *BTSE) GetTrades(ctx context.Context, symbol string, start, end time.Time, beforeSerialID, afterSerialID, count int, includeOld, spot bool) ([]Trade, error) { var t []Trade urlValues := url.Values{} urlValues.Add("symbol", symbol) @@ -130,12 +130,12 @@ func (b *BTSE) GetTrades(symbol string, start, end time.Time, beforeSerialID, af if includeOld { urlValues.Add("includeOld", "true") } - return t, b.SendHTTPRequest(exchange.RestSpot, http.MethodGet, + return t, b.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, common.EncodeURLValues(btseTrades, urlValues), &t, spot, queryFunc) } // OHLCV retrieve and return OHLCV candle data for requested symbol -func (b *BTSE) OHLCV(symbol string, start, end time.Time, resolution int) (OHLCV, error) { +func (b *BTSE) OHLCV(ctx context.Context, symbol string, start, end time.Time, resolution int) (OHLCV, error) { var o OHLCV urlValues := url.Values{} urlValues.Add("symbol", symbol) @@ -153,40 +153,40 @@ func (b *BTSE) OHLCV(symbol string, start, end time.Time, resolution int) (OHLCV } urlValues.Add("resolution", strconv.FormatInt(int64(res), 10)) endpoint := common.EncodeURLValues(btseOHLCV, urlValues) - return o, b.SendHTTPRequest(exchange.RestSpot, http.MethodGet, endpoint, &o, true, queryFunc) + return o, b.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, endpoint, &o, true, queryFunc) } // GetPrice get current price for requested symbol -func (b *BTSE) GetPrice(symbol string) (Price, error) { +func (b *BTSE) GetPrice(ctx context.Context, symbol string) (Price, error) { var p Price path := btsePrice + "?symbol=" + url.QueryEscape(symbol) - return p, b.SendHTTPRequest(exchange.RestSpot, http.MethodGet, path, &p, true, queryFunc) + return p, b.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, path, &p, true, queryFunc) } // GetServerTime returns the exchanges server time -func (b *BTSE) GetServerTime() (*ServerTime, error) { +func (b *BTSE) GetServerTime(ctx context.Context) (*ServerTime, error) { var s ServerTime - return &s, b.SendHTTPRequest(exchange.RestSpot, http.MethodGet, btseTime, &s, true, queryFunc) + return &s, b.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, btseTime, &s, true, queryFunc) } // GetWalletInformation returns the users account balance -func (b *BTSE) GetWalletInformation() ([]CurrencyBalance, error) { +func (b *BTSE) GetWalletInformation(ctx context.Context) ([]CurrencyBalance, error) { var a []CurrencyBalance - return a, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, btseWallet, true, nil, nil, &a, queryFunc) + return a, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, btseWallet, true, nil, nil, &a, queryFunc) } // GetFeeInformation retrieve fee's (maker/taker) for requested symbol -func (b *BTSE) GetFeeInformation(symbol string) ([]AccountFees, error) { +func (b *BTSE) GetFeeInformation(ctx context.Context, symbol string) ([]AccountFees, error) { var resp []AccountFees urlValues := url.Values{} if symbol != "" { urlValues.Add("symbol", symbol) } - return resp, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, btseUserFee, true, urlValues, nil, &resp, queryFunc) + return resp, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, btseUserFee, true, urlValues, nil, &resp, queryFunc) } // GetWalletHistory returns the users account balance -func (b *BTSE) GetWalletHistory(symbol string, start, end time.Time, count int) (WalletHistory, error) { +func (b *BTSE) GetWalletHistory(ctx context.Context, symbol string, start, end time.Time, count int) (WalletHistory, error) { var resp WalletHistory urlValues := url.Values{} @@ -203,11 +203,11 @@ func (b *BTSE) GetWalletHistory(symbol string, start, end time.Time, count int) if count > 0 { urlValues.Add("count", strconv.Itoa(count)) } - return resp, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, btseWalletHistory, true, urlValues, nil, &resp, queryFunc) + return resp, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, btseWalletHistory, true, urlValues, nil, &resp, queryFunc) } // GetWalletAddress returns the users account balance -func (b *BTSE) GetWalletAddress(currency string) (WalletAddress, error) { +func (b *BTSE) GetWalletAddress(ctx context.Context, currency string) (WalletAddress, error) { var resp WalletAddress urlValues := url.Values{} @@ -215,15 +215,15 @@ func (b *BTSE) GetWalletAddress(currency string) (WalletAddress, error) { urlValues.Add("currency", currency) } - return resp, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, btseWalletAddress, true, urlValues, nil, &resp, queryFunc) + return resp, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, btseWalletAddress, true, urlValues, nil, &resp, queryFunc) } // CreateWalletAddress create new deposit address for requested currency -func (b *BTSE) CreateWalletAddress(currency string) (WalletAddress, error) { +func (b *BTSE) CreateWalletAddress(ctx context.Context, currency string) (WalletAddress, error) { var resp WalletAddress req := make(map[string]interface{}, 1) req["currency"] = currency - err := b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, btseWalletAddress, true, nil, req, &resp, queryFunc) + err := b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, btseWalletAddress, true, nil, req, &resp, queryFunc) if err != nil { errResp := ErrorResponse{} errResponseStr := strings.Split(err.Error(), "raw response: ") @@ -246,18 +246,18 @@ func (b *BTSE) CreateWalletAddress(currency string) (WalletAddress, error) { } // WalletWithdrawal submit request to withdraw crypto currency -func (b *BTSE) WalletWithdrawal(currency, address, tag, amount string) (WithdrawalResponse, error) { +func (b *BTSE) WalletWithdrawal(ctx context.Context, currency, address, tag, amount string) (WithdrawalResponse, error) { var resp WithdrawalResponse req := make(map[string]interface{}, 4) req["currency"] = currency req["address"] = address req["tag"] = tag req["amount"] = amount - return resp, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, btseWalletWithdrawal, true, nil, req, &resp, queryFunc) + return resp, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, btseWalletWithdrawal, true, nil, req, &resp, queryFunc) } // CreateOrder creates an order -func (b *BTSE) CreateOrder(clOrderID string, deviation float64, postOnly bool, price float64, side string, size, stealth, stopPrice float64, symbol, timeInForce string, trailValue, triggerPrice float64, txType, orderType string) ([]Order, error) { +func (b *BTSE) CreateOrder(ctx context.Context, clOrderID string, deviation float64, postOnly bool, price float64, side string, size, stealth, stopPrice float64, symbol, timeInForce string, trailValue, triggerPrice float64, txType, orderType string) ([]Order, error) { req := make(map[string]interface{}) if clOrderID != "" { req["clOrderID"] = clOrderID @@ -303,11 +303,11 @@ func (b *BTSE) CreateOrder(clOrderID string, deviation float64, postOnly bool, p } var r []Order - return r, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, btseOrder, true, url.Values{}, req, &r, orderFunc) + return r, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, btseOrder, true, url.Values{}, req, &r, orderFunc) } // GetOrders returns all pending orders -func (b *BTSE) GetOrders(symbol, orderID, clOrderID string) ([]OpenOrder, error) { +func (b *BTSE) GetOrders(ctx context.Context, symbol, orderID, clOrderID string) ([]OpenOrder, error) { req := url.Values{} if orderID != "" { req.Add("orderID", orderID) @@ -317,11 +317,11 @@ func (b *BTSE) GetOrders(symbol, orderID, clOrderID string) ([]OpenOrder, error) req.Add("clOrderID", clOrderID) } var o []OpenOrder - return o, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, btsePendingOrders, true, req, nil, &o, orderFunc) + return o, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, btsePendingOrders, true, req, nil, &o, orderFunc) } // CancelExistingOrder cancels an order -func (b *BTSE) CancelExistingOrder(orderID, symbol, clOrderID string) (CancelOrder, error) { +func (b *BTSE) CancelExistingOrder(ctx context.Context, orderID, symbol, clOrderID string) (CancelOrder, error) { var c CancelOrder req := url.Values{} if orderID != "" { @@ -332,18 +332,18 @@ func (b *BTSE) CancelExistingOrder(orderID, symbol, clOrderID string) (CancelOrd req.Add("clOrderID", clOrderID) } - return c, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodDelete, btseOrder, true, req, nil, &c, orderFunc) + return c, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodDelete, btseOrder, true, req, nil, &c, orderFunc) } // CancelAllAfter cancels all orders after timeout -func (b *BTSE) CancelAllAfter(timeout int) error { +func (b *BTSE) CancelAllAfter(ctx context.Context, timeout int) error { req := make(map[string]interface{}) req["timeout"] = timeout - return b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, btseCancelAllAfter, true, url.Values{}, req, nil, orderFunc) + return b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, btseCancelAllAfter, true, url.Values{}, req, nil, orderFunc) } // IndexOrderPeg create peg order that will track a certain percentage above/below the index price -func (b *BTSE) IndexOrderPeg(clOrderID string, deviation float64, postOnly bool, price float64, side string, size, stealth, stopPrice float64, symbol, timeInForce string, trailValue, triggerPrice float64, txType, orderType string) ([]Order, error) { +func (b *BTSE) IndexOrderPeg(ctx context.Context, clOrderID string, deviation float64, postOnly bool, price float64, side string, size, stealth, stopPrice float64, symbol, timeInForce string, trailValue, triggerPrice float64, txType, orderType string) ([]Order, error) { var o []Order req := make(map[string]interface{}) if clOrderID != "" { @@ -389,11 +389,11 @@ func (b *BTSE) IndexOrderPeg(clOrderID string, deviation float64, postOnly bool, req["type"] = orderType } - return o, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, btsePegOrder, true, url.Values{}, req, nil, orderFunc) + return o, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, btsePegOrder, true, url.Values{}, req, nil, orderFunc) } // TradeHistory returns previous trades on exchange -func (b *BTSE) TradeHistory(symbol string, start, end time.Time, beforeSerialID, afterSerialID, count int, includeOld bool, clOrderID, orderID string) (TradeHistory, error) { +func (b *BTSE) TradeHistory(ctx context.Context, symbol string, start, end time.Time, beforeSerialID, afterSerialID, count int, includeOld bool, clOrderID, orderID string) (TradeHistory, error) { var resp TradeHistory urlValues := url.Values{} if symbol != "" { @@ -424,11 +424,11 @@ func (b *BTSE) TradeHistory(symbol string, start, end time.Time, beforeSerialID, if orderID != "" { urlValues.Add("orderID", orderID) } - return resp, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, btseExchangeHistory, true, urlValues, nil, &resp, queryFunc) + return resp, b.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, btseExchangeHistory, true, urlValues, nil, &resp, queryFunc) } // SendHTTPRequest sends an HTTP request to the desired endpoint -func (b *BTSE) SendHTTPRequest(ep exchange.URL, method, endpoint string, result interface{}, spotEndpoint bool, f request.EndpointLimit) error { +func (b *BTSE) SendHTTPRequest(ctx context.Context, ep exchange.URL, method, endpoint string, result interface{}, spotEndpoint bool, f request.EndpointLimit) error { ePoint, err := b.API.Endpoints.GetURL(ep) if err != nil { return err @@ -445,13 +445,13 @@ func (b *BTSE) SendHTTPRequest(ep exchange.URL, method, endpoint string, result HTTPDebugging: b.HTTPDebugging, HTTPRecording: b.HTTPRecording, } - return b.SendPayload(context.Background(), f, func() (*request.Item, error) { + return b.SendPayload(ctx, f, func() (*request.Item, error) { return item, nil }) } // SendAuthenticatedHTTPRequest sends an authenticated HTTP request to the desired endpoint -func (b *BTSE) SendAuthenticatedHTTPRequest(ep exchange.URL, method, endpoint string, isSpot bool, values url.Values, req map[string]interface{}, result interface{}, f request.EndpointLimit) error { +func (b *BTSE) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, method, endpoint string, isSpot bool, values url.Values, req map[string]interface{}, result interface{}, f request.EndpointLimit) error { if !b.AllowAuthenticatedRequest() { return fmt.Errorf("%s %w", b.Name, exchange.ErrAuthenticatedRequestWithoutCredentialsSet) } @@ -525,16 +525,16 @@ func (b *BTSE) SendAuthenticatedHTTPRequest(ep exchange.URL, method, endpoint st HTTPRecording: b.HTTPRecording, }, nil } - return b.SendPayload(context.Background(), f, newRequest) + return b.SendPayload(ctx, f, newRequest) } // GetFee returns an estimate of fee based on type of transaction -func (b *BTSE) GetFee(feeBuilder *exchange.FeeBuilder) (float64, error) { +func (b *BTSE) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { var fee float64 switch feeBuilder.FeeType { case exchange.CryptocurrencyTradeFee: - fee = b.calculateTradingFee(feeBuilder) * feeBuilder.Amount * feeBuilder.PurchasePrice + fee = b.calculateTradingFee(ctx, feeBuilder) * feeBuilder.Amount * feeBuilder.PurchasePrice case exchange.CryptocurrencyWithdrawalFee: switch feeBuilder.Pair.Base { case currency.USDT: @@ -590,7 +590,7 @@ func getInternationalBankWithdrawalFee(amount float64) float64 { } // calculateTradingFee return fee based on users current fee tier or default values -func (b *BTSE) calculateTradingFee(feeBuilder *exchange.FeeBuilder) float64 { +func (b *BTSE) calculateTradingFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) float64 { formattedPair, err := b.FormatExchangeCurrency(feeBuilder.Pair, asset.Spot) if err != nil { if feeBuilder.IsMaker { @@ -598,8 +598,9 @@ func (b *BTSE) calculateTradingFee(feeBuilder *exchange.FeeBuilder) float64 { } return 0.002 } - feeTiers, err := b.GetFeeInformation(formattedPair.String()) + feeTiers, err := b.GetFeeInformation(ctx, formattedPair.String()) if err != nil { + // TODO: Return actual error, we should't pivot around errors. if feeBuilder.IsMaker { return 0.001 } diff --git a/exchanges/btse/btse_test.go b/exchanges/btse/btse_test.go index d2572ee4..89b07f90 100644 --- a/exchanges/btse/btse_test.go +++ b/exchanges/btse/btse_test.go @@ -1,6 +1,7 @@ package btse import ( + "context" "errors" "log" "os" @@ -58,7 +59,7 @@ func areTestAPIKeysSet() bool { } func TestFetchFundingHistory(t *testing.T) { - _, err := b.FetchFundingHistory("") + _, err := b.FetchFundingHistory(context.Background(), "") if err != nil { t.Error(err) } @@ -66,12 +67,12 @@ func TestFetchFundingHistory(t *testing.T) { func TestGetMarketsSummary(t *testing.T) { t.Parallel() - _, err := b.GetMarketSummary("", true) + _, err := b.GetMarketSummary(context.Background(), "", true) if err != nil { t.Error(err) } - ret, err := b.GetMarketSummary(testSPOTPair, true) + ret, err := b.GetMarketSummary(context.Background(), testSPOTPair, true) if err != nil { t.Error(err) } @@ -82,17 +83,17 @@ func TestGetMarketsSummary(t *testing.T) { func TestFetchOrderBook(t *testing.T) { t.Parallel() - _, err := b.FetchOrderBook(testSPOTPair, 0, 1, 1, true) + _, err := b.FetchOrderBook(context.Background(), testSPOTPair, 0, 1, 1, true) if err != nil { t.Error(err) } - _, err = b.FetchOrderBook(testFUTURESPair, 0, 1, 1, false) + _, err = b.FetchOrderBook(context.Background(), testFUTURESPair, 0, 1, 1, false) if err != nil { t.Error(err) } - _, err = b.FetchOrderBook(testSPOTPair, 1, 1, 1, true) + _, err = b.FetchOrderBook(context.Background(), testSPOTPair, 1, 1, 1, true) if err != nil { t.Error(err) } @@ -105,7 +106,7 @@ func TestUpdateOrderbook(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = b.UpdateOrderbook(p, asset.Spot) + _, err = b.UpdateOrderbook(context.Background(), p, asset.Spot) if err != nil { t.Fatal(err) } @@ -114,7 +115,7 @@ func TestUpdateOrderbook(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = b.UpdateOrderbook(f, asset.Futures) + _, err = b.UpdateOrderbook(context.Background(), f, asset.Futures) if err != nil { if !errors.Is(err, common.ErrNotYetImplemented) { t.Fatal(err) @@ -124,7 +125,7 @@ func TestUpdateOrderbook(t *testing.T) { func TestFetchOrderBookL2(t *testing.T) { t.Parallel() - _, err := b.FetchOrderBookL2(testSPOTPair, 20) + _, err := b.FetchOrderBookL2(context.Background(), testSPOTPair, 20) if err != nil { t.Error(err) } @@ -132,14 +133,16 @@ func TestFetchOrderBookL2(t *testing.T) { func TestOHLCV(t *testing.T) { t.Parallel() - _, err := b.OHLCV(testSPOTPair, + _, err := b.OHLCV(context.Background(), + testSPOTPair, time.Now().AddDate(0, 0, -1), time.Now(), 60) if err != nil { t.Fatal(err) } - _, err = b.OHLCV(testSPOTPair, time.Now(), time.Now().AddDate(0, 0, -1), 60) + _, err = b.OHLCV(context.Background(), + testSPOTPair, time.Now(), time.Now().AddDate(0, 0, -1), 60) if err == nil { t.Fatal("expected error if start is after end date") } @@ -147,7 +150,7 @@ func TestOHLCV(t *testing.T) { func TestGetPrice(t *testing.T) { t.Parallel() - _, err := b.GetPrice(testSPOTPair) + _, err := b.GetPrice(context.Background(), testSPOTPair) if err != nil { t.Fatal(err) } @@ -167,7 +170,7 @@ func TestGetHistoricCandles(t *testing.T) { t.Fatal(err) } - _, err = b.GetHistoricCandles( + _, err = b.GetHistoricCandles(context.Background(), curr, asset.Spot, time.Time{}, time.Time{}, kline.OneMin) @@ -175,7 +178,7 @@ func TestGetHistoricCandles(t *testing.T) { t.Fatal(err) } - _, err = b.GetHistoricCandles( + _, err = b.GetHistoricCandles(context.Background(), curr, asset.Spot, time.Time{}, time.Time{}, kline.OneDay) @@ -184,7 +187,7 @@ func TestGetHistoricCandles(t *testing.T) { } curr.Quote = currency.XRP - _, err = b.GetHistoricCandles( + _, err = b.GetHistoricCandles(context.Background(), curr, asset.Spot, time.Time{}, time.Time{}, kline.OneMin) @@ -200,7 +203,7 @@ func TestGetHistoricCandlesExtended(t *testing.T) { t.Fatal(err) } - _, err = b.GetHistoricCandlesExtended( + _, err = b.GetHistoricCandlesExtended(context.Background(), curr, asset.Spot, time.Time{}, time.Time{}, kline.OneMin) @@ -211,21 +214,24 @@ func TestGetHistoricCandlesExtended(t *testing.T) { func TestGetTrades(t *testing.T) { t.Parallel() - _, err := b.GetTrades(testSPOTPair, + _, err := b.GetTrades(context.Background(), + testSPOTPair, time.Now().AddDate(0, 0, -1), time.Now(), 0, 0, 50, false, true) if err != nil { t.Error(err) } - _, err = b.GetTrades(testSPOTPair, + _, err = b.GetTrades(context.Background(), + testSPOTPair, time.Now(), time.Now().AddDate(0, -1, 0), 0, 0, 50, false, true) if err == nil { t.Error("expected error if start time is after end time") } - _, err = b.GetTrades(testFUTURESPair, + _, err = b.GetTrades(context.Background(), + testFUTURESPair, time.Now().AddDate(0, 0, -1), time.Now(), 0, 0, 50, false, false) if err != nil { @@ -240,7 +246,7 @@ func TestUpdateTicker(t *testing.T) { t.Fatal(err) } - _, err = b.UpdateTicker(curr, asset.Spot) + _, err = b.UpdateTicker(context.Background(), curr, asset.Spot) if err != nil { t.Fatal(err) } @@ -250,7 +256,7 @@ func TestUpdateTicker(t *testing.T) { t.Fatal(err) } - _, err = b.UpdateTicker(curr, asset.Futures) + _, err = b.UpdateTicker(context.Background(), curr, asset.Futures) if err != nil { t.Fatal(err) } @@ -259,12 +265,12 @@ func TestUpdateTicker(t *testing.T) { func TestUpdateTickers(t *testing.T) { t.Parallel() - err := b.UpdateTickers(asset.Spot) + err := b.UpdateTickers(context.Background(), asset.Spot) if err != nil { t.Fatal(err) } - err = b.UpdateTickers(asset.Futures) + err = b.UpdateTickers(context.Background(), asset.Futures) if err != nil { t.Fatal(err) } @@ -272,7 +278,7 @@ func TestUpdateTickers(t *testing.T) { func TestGetServerTime(t *testing.T) { t.Parallel() - _, err := b.GetServerTime() + _, err := b.GetServerTime(context.Background()) if err != nil { t.Error(err) } @@ -283,7 +289,7 @@ func TestGetWalletInformation(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys not set, skipping test") } - _, err := b.GetWalletInformation() + _, err := b.GetWalletInformation(context.Background()) if err != nil { t.Error(err) } @@ -294,7 +300,7 @@ func TestGetFeeInformation(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys not set, skipping test") } - _, err := b.GetFeeInformation("") + _, err := b.GetFeeInformation(context.Background(), "") if err != nil { t.Error(err) } @@ -305,7 +311,8 @@ func TestGetWalletHistory(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys not set, skipping test") } - _, err := b.GetWalletHistory(testSPOTPair, + _, err := b.GetWalletHistory(context.Background(), + testSPOTPair, time.Time{}, time.Time{}, 50) if err != nil { @@ -318,7 +325,7 @@ func TestGetWalletAddress(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys not set, skipping test") } - _, err := b.GetWalletAddress("XRP") + _, err := b.GetWalletAddress(context.Background(), "XRP") if err != nil { t.Error(err) } @@ -329,7 +336,7 @@ func TestCreateWalletAddress(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys not set, skipping test") } - _, err := b.CreateWalletAddress("XRP") + _, err := b.CreateWalletAddress(context.Background(), "XRP") if err != nil { t.Error(err) } @@ -340,7 +347,7 @@ func TestGetDepositAddress(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys not set, skipping test") } - _, err := b.GetDepositAddress(currency.XRP, "") + _, err := b.GetDepositAddress(context.Background(), currency.XRP, "") if err != nil { t.Error(err) } @@ -351,7 +358,8 @@ func TestCreateOrder(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test, either api keys are unset or canManipulateRealOrders is false") } - _, err := b.CreateOrder("", 0.0, + _, err := b.CreateOrder(context.Background(), + "", 0.0, false, -1, "BUY", 100, 0, 0, testSPOTPair, "GTC", @@ -367,7 +375,8 @@ func TestBTSEIndexOrderPeg(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test, either api keys are unset or canManipulateRealOrders is false") } - _, err := b.IndexOrderPeg("", 0.0, + _, err := b.IndexOrderPeg(context.Background(), + "", 0.0, false, -1, "BUY", 100, 0, 0, testSPOTPair, "GTC", @@ -383,7 +392,7 @@ func TestGetOrders(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys not set, skipping test") } - _, err := b.GetOrders(testSPOTPair, "", "") + _, err := b.GetOrders(context.Background(), testSPOTPair, "", "") if err != nil { t.Error(err) } @@ -411,7 +420,7 @@ func TestGetActiveOrders(t *testing.T) { AssetType: asset.Spot, } - _, err := b.GetActiveOrders(&getOrdersRequest) + _, err := b.GetActiveOrders(context.Background(), &getOrdersRequest) if err != nil { t.Error(err) } @@ -426,7 +435,7 @@ func TestGetOrderHistory(t *testing.T) { Type: order.AnyType, AssetType: asset.Spot, } - _, err := b.GetOrderHistory(&getOrdersRequest) + _, err := b.GetOrderHistory(context.Background(), &getOrdersRequest) if err != nil { t.Error(err) } @@ -437,7 +446,8 @@ func TestTradeHistory(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys not set, skipping test") } - _, err := b.TradeHistory("", + _, err := b.TradeHistory(context.Background(), + "", time.Time{}, time.Time{}, 0, 0, 0, false, @@ -466,7 +476,7 @@ func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { PurchasePrice: 1000, } - _, err := b.GetFeeByType(feeBuilder) + _, err := b.GetFeeByType(context.Background(), feeBuilder) if err != nil { t.Fatal(err) } @@ -492,42 +502,42 @@ func TestGetFee(t *testing.T) { PurchasePrice: 1000, } - if _, err := b.GetFee(feeBuilder); err != nil { + if _, err := b.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } feeBuilder.IsMaker = false - if _, err := b.GetFee(feeBuilder); err != nil { + if _, err := b.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee - if _, err := b.GetFee(feeBuilder); err != nil { + if _, err := b.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } feeBuilder.Pair.Base = currency.USDT - if _, err := b.GetFee(feeBuilder); err != nil { + if _, err := b.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } feeBuilder.FeeType = exchange.InternationalBankDepositFee - if _, err := b.GetFee(feeBuilder); err != nil { + if _, err := b.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } feeBuilder.Amount = 1000000 - if _, err := b.GetFee(feeBuilder); err != nil { + if _, err := b.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee - if _, err := b.GetFee(feeBuilder); err != nil { + if _, err := b.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } feeBuilder.Amount = 1000 - if _, err := b.GetFee(feeBuilder); err != nil { + if _, err := b.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } } @@ -560,7 +570,7 @@ func TestSubmitOrder(t *testing.T) { ClientID: "", AssetType: asset.Spot, } - response, err := b.SubmitOrder(orderSubmission) + response, err := b.SubmitOrder(context.Background(), orderSubmission) if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) { t.Errorf("Order failed to be placed: %v", err) } else if !areTestAPIKeysSet() && err == nil { @@ -574,7 +584,7 @@ func TestCancelAllAfter(t *testing.T) { t.Skip("skipping test, either api keys are unset or canManipulateRealOrders is false") } - err := b.CancelAllAfter(1) + err := b.CancelAllAfter(context.Background(), 1) if err != nil { t.Fatal(err) } @@ -595,7 +605,7 @@ func TestCancelExchangeOrder(t *testing.T) { Pair: currencyPair, AssetType: asset.Spot, } - err := b.CancelOrder(orderCancellation) + err := b.CancelOrder(context.Background(), orderCancellation) if err != nil { t.Error(err) } @@ -606,7 +616,7 @@ func TestCancelOrder(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test, either api keys are unset or canManipulateRealOrders is false") } - _, err := b.CancelExistingOrder("", testSPOTPair, "") + _, err := b.CancelExistingOrder(context.Background(), "", testSPOTPair, "") if err != nil { t.Fatal(err) } @@ -627,7 +637,7 @@ func TestCancelAllExchangeOrders(t *testing.T) { Pair: currencyPair, AssetType: asset.Spot, } - resp, err := b.CancelAllOrders(orderCancellation) + resp, err := b.CancelAllOrders(context.Background(), orderCancellation) if err != nil { t.Errorf("Could not cancel orders: %v", err) @@ -697,7 +707,7 @@ func TestFetchTradablePairs(t *testing.T) { t.Parallel() assets := b.GetAssetTypes(false) for i := range assets { - data, err := b.FetchTradablePairs(assets[i]) + data, err := b.FetchTradablePairs(context.Background(), assets[i]) if err != nil { t.Fatal(err) } @@ -732,7 +742,7 @@ func TestMatchType(t *testing.T) { func TestSeedOrderSizeLimits(t *testing.T) { t.Parallel() - err := b.seedOrderSizeLimits() + err := b.seedOrderSizeLimits(context.Background()) if err != nil { t.Fatal(err) } @@ -842,7 +852,7 @@ func TestGetRecentTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = b.GetRecentTrades(currencyPair, asset.Spot) + _, err = b.GetRecentTrades(context.Background(), currencyPair, asset.Spot) if err != nil { t.Error(err) } @@ -850,7 +860,7 @@ func TestGetRecentTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = b.GetRecentTrades(currencyPair, asset.Futures) + _, err = b.GetRecentTrades(context.Background(), currencyPair, asset.Futures) if err != nil { t.Error(err) } @@ -860,7 +870,8 @@ func TestGetHistoricTrades(t *testing.T) { t.Parallel() curr, _ := currency.NewPairFromString(testSPOTPair) - _, err := b.GetHistoricTrades(curr, asset.Spot, time.Now().Add(-time.Minute), time.Now()) + _, err := b.GetHistoricTrades(context.Background(), + curr, asset.Spot, time.Now().Add(-time.Minute), time.Now()) if err == nil { t.Fatal("expected error") } diff --git a/exchanges/btse/btse_wrapper.go b/exchanges/btse/btse_wrapper.go index 3fc5b74c..36907ad2 100644 --- a/exchanges/btse/btse_wrapper.go +++ b/exchanges/btse/btse_wrapper.go @@ -1,6 +1,7 @@ package btse import ( + "context" "errors" "fmt" "math" @@ -42,7 +43,7 @@ func (b *BTSE) GetDefaultConfig() (*config.ExchangeConfig, error) { } if b.Features.Supports.RESTCapabilities.AutoPairUpdates { - err = b.UpdateTradablePairs(true) + err = b.UpdateTradablePairs(context.TODO(), true) if err != nil { return nil, err } @@ -202,7 +203,7 @@ func (b *BTSE) Setup(exch *config.ExchangeConfig) error { return err } - err = b.seedOrderSizeLimits() + err = b.seedOrderSizeLimits(context.TODO()) if err != nil { return err } @@ -232,7 +233,7 @@ func (b *BTSE) Run() { return } - err := b.UpdateTradablePairs(false) + err := b.UpdateTradablePairs(context.TODO(), false) if err != nil { log.Errorf(log.ExchangeSys, "%s Failed to update tradable pairs. Error: %s", b.Name, err) @@ -240,9 +241,9 @@ func (b *BTSE) Run() { } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (b *BTSE) FetchTradablePairs(a asset.Item) ([]string, error) { +func (b *BTSE) FetchTradablePairs(ctx context.Context, a asset.Item) ([]string, error) { var currencies []string - m, err := b.GetMarketSummary("", a == asset.Spot) + m, err := b.GetMarketSummary(ctx, "", a == asset.Spot) if err != nil { return nil, err } @@ -258,10 +259,10 @@ func (b *BTSE) FetchTradablePairs(a asset.Item) ([]string, error) { // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (b *BTSE) UpdateTradablePairs(forceUpdate bool) error { +func (b *BTSE) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { a := b.GetAssetTypes(false) for i := range a { - pairs, err := b.FetchTradablePairs(a[i]) + pairs, err := b.FetchTradablePairs(ctx, a[i]) if err != nil { return err } @@ -280,8 +281,8 @@ func (b *BTSE) UpdateTradablePairs(forceUpdate bool) error { } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (b *BTSE) UpdateTickers(a asset.Item) error { - tickers, err := b.GetMarketSummary("", a == asset.Spot) +func (b *BTSE) UpdateTickers(ctx context.Context, a asset.Item) error { + tickers, err := b.GetMarketSummary(ctx, "", a == asset.Spot) if err != nil { return err } @@ -311,8 +312,8 @@ func (b *BTSE) UpdateTickers(a asset.Item) error { } // UpdateTicker updates and returns the ticker for a currency pair -func (b *BTSE) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) { - err := b.UpdateTickers(a) +func (b *BTSE) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { + err := b.UpdateTickers(ctx, a) if err != nil { return nil, err } @@ -320,25 +321,25 @@ func (b *BTSE) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error } // FetchTicker returns the ticker for a currency pair -func (b *BTSE) FetchTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) { +func (b *BTSE) FetchTicker(ctx context.Context, p currency.Pair, assetType asset.Item) (*ticker.Price, error) { tickerNew, err := ticker.GetTicker(b.Name, p, assetType) if err != nil { - return b.UpdateTicker(p, assetType) + return b.UpdateTicker(ctx, p, assetType) } return tickerNew, nil } // FetchOrderbook returns orderbook base on the currency pair -func (b *BTSE) FetchOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (b *BTSE) FetchOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { ob, err := orderbook.Get(b.Name, p, assetType) if err != nil { - return b.UpdateOrderbook(p, assetType) + return b.UpdateOrderbook(ctx, p, assetType) } return ob, nil } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (b *BTSE) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (b *BTSE) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { book := &orderbook.Base{ Exchange: b.Name, Pair: p, @@ -349,7 +350,7 @@ func (b *BTSE) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderboo if err != nil { return book, err } - a, err := b.FetchOrderBook(fPair.String(), 0, 0, 0, assetType == asset.Spot) + a, err := b.FetchOrderBook(ctx, fPair.String(), 0, 0, 0, assetType == asset.Spot) if err != nil { return book, err } @@ -383,9 +384,9 @@ func (b *BTSE) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderboo // UpdateAccountInfo retrieves balances for all enabled currencies for the // BTSE exchange -func (b *BTSE) UpdateAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (b *BTSE) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { var a account.Holdings - balance, err := b.GetWalletInformation() + balance, err := b.GetWalletInformation(ctx) if err != nil { return a, err } @@ -416,10 +417,10 @@ func (b *BTSE) UpdateAccountInfo(assetType asset.Item) (account.Holdings, error) } // FetchAccountInfo retrieves balances for all enabled currencies -func (b *BTSE) FetchAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (b *BTSE) FetchAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { acc, err := account.GetHoldings(b.Name, assetType) if err != nil { - return b.UpdateAccountInfo(assetType) + return b.UpdateAccountInfo(ctx, assetType) } return acc, nil @@ -427,7 +428,7 @@ func (b *BTSE) FetchAccountInfo(assetType asset.Item) (account.Holdings, error) // GetFundingHistory returns funding history, deposits and // withdrawals -func (b *BTSE) GetFundingHistory() ([]exchange.FundHistory, error) { +func (b *BTSE) GetFundingHistory(ctx context.Context) ([]exchange.FundHistory, error) { return nil, common.ErrFunctionNotSupported } @@ -442,12 +443,12 @@ func (b *BTSE) withinLimits(pair currency.Pair, amount float64) bool { } // GetWithdrawalsHistory returns previous withdrawals data -func (b *BTSE) GetWithdrawalsHistory(c currency.Code) (resp []exchange.WithdrawalHistory, err error) { +func (b *BTSE) GetWithdrawalsHistory(ctx context.Context, c currency.Code) (resp []exchange.WithdrawalHistory, err error) { return nil, common.ErrNotYetImplemented } // GetRecentTrades returns the most recent trades for a currency and asset -func (b *BTSE) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade.Data, error) { +func (b *BTSE) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { var err error p, err = b.FormatExchangeCurrency(p, assetType) if err != nil { @@ -457,7 +458,8 @@ func (b *BTSE) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade.D limit := 500 var tradeData []Trade - tradeData, err = b.GetTrades(p.String(), + tradeData, err = b.GetTrades(ctx, + p.String(), time.Time{}, time.Time{}, 0, 0, limit, false, @@ -493,12 +495,12 @@ func (b *BTSE) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade.D } // GetHistoricTrades returns historic trade data within the timeframe provided -func (b *BTSE) GetHistoricTrades(_ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { +func (b *BTSE) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { return nil, common.ErrFunctionNotSupported } // SubmitOrder submits a new order -func (b *BTSE) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { +func (b *BTSE) SubmitOrder(ctx context.Context, s *order.Submit) (order.SubmitResponse, error) { var resp order.SubmitResponse if err := s.Validate(); err != nil { return resp, err @@ -513,12 +515,18 @@ func (b *BTSE) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { return resp, errors.New("order outside of limits") } - r, err := b.CreateOrder(s.ClientID, 0.0, + r, err := b.CreateOrder(ctx, + s.ClientID, 0.0, false, - s.Price, s.Side.String(), s.Amount, 0, 0, - fPair.String(), goodTillCancel, - 0.0, s.TriggerPrice, - "", s.Type.String()) + s.Price, + s.Side.String(), + s.Amount, 0, 0, + fPair.String(), + goodTillCancel, + 0.0, + s.TriggerPrice, + "", + s.Type.String()) if err != nil { return resp, err } @@ -534,12 +542,12 @@ func (b *BTSE) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (b *BTSE) ModifyOrder(action *order.Modify) (order.Modify, error) { +func (b *BTSE) ModifyOrder(ctx context.Context, action *order.Modify) (order.Modify, error) { return order.Modify{}, common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number -func (b *BTSE) CancelOrder(o *order.Cancel) error { +func (b *BTSE) CancelOrder(ctx context.Context, o *order.Cancel) error { if err := o.Validate(o.StandardCancel()); err != nil { return err } @@ -550,7 +558,7 @@ func (b *BTSE) CancelOrder(o *order.Cancel) error { return err } - _, err = b.CancelExistingOrder(o.ID, fPair.String(), o.ClientOrderID) + _, err = b.CancelExistingOrder(ctx, o.ID, fPair.String(), o.ClientOrderID) if err != nil { return err } @@ -559,14 +567,14 @@ func (b *BTSE) CancelOrder(o *order.Cancel) error { } // CancelBatchOrders cancels an orders by their corresponding ID numbers -func (b *BTSE) CancelBatchOrders(o []order.Cancel) (order.CancelBatchResponse, error) { +func (b *BTSE) CancelBatchOrders(ctx context.Context, o []order.Cancel) (order.CancelBatchResponse, error) { return order.CancelBatchResponse{}, common.ErrNotYetImplemented } // CancelAllOrders cancels all orders associated with a currency pair // If product ID is sent, all orders of that specified market will be cancelled // If not specified, all orders of all markets will be cancelled -func (b *BTSE) CancelAllOrders(orderCancellation *order.Cancel) (order.CancelAllResponse, error) { +func (b *BTSE) CancelAllOrders(ctx context.Context, orderCancellation *order.Cancel) (order.CancelAllResponse, error) { if err := orderCancellation.Validate(); err != nil { return order.CancelAllResponse{}, err } @@ -579,7 +587,7 @@ func (b *BTSE) CancelAllOrders(orderCancellation *order.Cancel) (order.CancelAll return resp, err } - allOrders, err := b.CancelExistingOrder("", fPair.String(), "") + allOrders, err := b.CancelExistingOrder(ctx, "", fPair.String(), "") if err != nil { return resp, nil } @@ -603,8 +611,8 @@ func orderIntToType(i int) order.Type { } // GetOrderInfo returns order information based on order ID -func (b *BTSE) GetOrderInfo(orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { - o, err := b.GetOrders("", orderID, "") +func (b *BTSE) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { + o, err := b.GetOrders(ctx, "", orderID, "") if err != nil { return order.Detail{}, err } @@ -648,7 +656,8 @@ func (b *BTSE) GetOrderInfo(orderID string, pair currency.Pair, assetType asset. od.Price = o[i].Price od.Status = order.Status(o[i].OrderState) - th, err := b.TradeHistory("", + th, err := b.TradeHistory(ctx, + "", time.Time{}, time.Time{}, 0, 0, 0, false, @@ -679,13 +688,13 @@ func (b *BTSE) GetOrderInfo(orderID string, pair currency.Pair, assetType asset. } // GetDepositAddress returns a deposit address for a specified currency -func (b *BTSE) GetDepositAddress(cryptocurrency currency.Code, accountID string) (string, error) { - address, err := b.GetWalletAddress(cryptocurrency.String()) +func (b *BTSE) GetDepositAddress(ctx context.Context, c currency.Code, accountID string) (string, error) { + address, err := b.GetWalletAddress(ctx, c.String()) if err != nil { return "", err } if len(address) == 0 { - addressCreate, err := b.CreateWalletAddress(cryptocurrency.String()) + addressCreate, err := b.CreateWalletAddress(ctx, c.String()) if err != nil { return "", err } @@ -699,12 +708,13 @@ func (b *BTSE) GetDepositAddress(cryptocurrency currency.Code, accountID string) // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is // submitted -func (b *BTSE) WithdrawCryptocurrencyFunds(withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (b *BTSE) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } amountToString := strconv.FormatFloat(withdrawRequest.Amount, 'f', 8, 64) - resp, err := b.WalletWithdrawal(withdrawRequest.Currency.String(), + resp, err := b.WalletWithdrawal(ctx, + withdrawRequest.Currency.String(), withdrawRequest.Crypto.Address, withdrawRequest.Crypto.AddressTag, amountToString) @@ -719,18 +729,18 @@ func (b *BTSE) WithdrawCryptocurrencyFunds(withdrawRequest *withdraw.Request) (* // WithdrawFiatFunds returns a withdrawal ID when a withdrawal is // submitted -func (b *BTSE) WithdrawFiatFunds(_ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (b *BTSE) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a withdrawal is // submitted -func (b *BTSE) WithdrawFiatFundsToInternationalBank(_ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (b *BTSE) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // GetActiveOrders retrieves any orders that are active/open -func (b *BTSE) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, error) { +func (b *BTSE) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) { if err := req.Validate(); err != nil { return nil, err } @@ -745,7 +755,7 @@ func (b *BTSE) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, err if err != nil { return nil, err } - resp, err := b.GetOrders(formattedPair.String(), "", "") + resp, err := b.GetOrders(ctx, formattedPair.String(), "", "") if err != nil { return nil, err } @@ -787,7 +797,7 @@ func (b *BTSE) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, err openOrder.Type = order.Limit } - fills, err := b.TradeHistory( + fills, err := b.TradeHistory(ctx, "", time.Time{}, time.Time{}, 0, 0, 0, @@ -838,7 +848,7 @@ func matchType(input int, required order.Type) bool { // GetOrderHistory retrieves account order information // Can Limit response to specific order status -func (b *BTSE) GetOrderHistory(getOrdersRequest *order.GetOrdersRequest) ([]order.Detail, error) { +func (b *BTSE) GetOrderHistory(ctx context.Context, getOrdersRequest *order.GetOrdersRequest) ([]order.Detail, error) { if err := getOrdersRequest.Validate(); err != nil { return nil, err } @@ -857,7 +867,7 @@ func (b *BTSE) GetOrderHistory(getOrdersRequest *order.GetOrdersRequest) ([]orde if err != nil { return nil, err } - currentOrder, err := b.GetOrders(fPair.String(), "", "") + currentOrder, err := b.GetOrders(ctx, fPair.String(), "", "") if err != nil { return nil, err } @@ -890,18 +900,18 @@ func (b *BTSE) GetOrderHistory(getOrdersRequest *order.GetOrdersRequest) ([]orde } // GetFeeByType returns an estimate of fee based on type of transaction -func (b *BTSE) GetFeeByType(feeBuilder *exchange.FeeBuilder) (float64, error) { +func (b *BTSE) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { if !b.AllowAuthenticatedRequest() && // Todo check connection status feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { feeBuilder.FeeType = exchange.OfflineTradeFee } - return b.GetFee(feeBuilder) + return b.GetFee(ctx, feeBuilder) } // ValidateCredentials validates current credentials used for wrapper // functionality -func (b *BTSE) ValidateCredentials(assetType asset.Item) error { - _, err := b.UpdateAccountInfo(assetType) +func (b *BTSE) ValidateCredentials(ctx context.Context, assetType asset.Item) error { + _, err := b.UpdateAccountInfo(ctx, assetType) return b.CheckTransientError(err) } @@ -911,7 +921,7 @@ func (b *BTSE) FormatExchangeKlineInterval(in kline.Interval) string { } // GetHistoricCandles returns candles between a time period for a set time interval -func (b *BTSE) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (b *BTSE) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { if err := b.ValidateKline(pair, a, interval); err != nil { return kline.Item{}, err } @@ -934,7 +944,8 @@ func (b *BTSE) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end t switch a { case asset.Spot: - req, err := b.OHLCV(fPair.String(), + req, err := b.OHLCV(ctx, + fPair.String(), start, end, intervalInt) @@ -962,7 +973,7 @@ func (b *BTSE) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end t } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (b *BTSE) GetHistoricCandlesExtended(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (b *BTSE) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { if err := b.ValidateKline(pair, a, interval); err != nil { return kline.Item{}, err } @@ -989,7 +1000,8 @@ func (b *BTSE) GetHistoricCandlesExtended(pair currency.Pair, a asset.Item, star switch a { case asset.Spot: - req, err := b.OHLCV(fPair.String(), + req, err := b.OHLCV(ctx, + fPair.String(), start, end, intervalInt) @@ -1016,8 +1028,8 @@ func (b *BTSE) GetHistoricCandlesExtended(pair currency.Pair, a asset.Item, star return klineRet, nil } -func (b *BTSE) seedOrderSizeLimits() error { - pairs, err := b.GetMarketSummary("", true) +func (b *BTSE) seedOrderSizeLimits(ctx context.Context) error { + pairs, err := b.GetMarketSummary(ctx, "", true) if err != nil { return err } @@ -1030,7 +1042,7 @@ func (b *BTSE) seedOrderSizeLimits() error { orderSizeLimitMap.Store(pairs[x].Symbol, tempValues) } - pairs, err = b.GetMarketSummary("", false) + pairs, err = b.GetMarketSummary(ctx, "", false) if err != nil { return err } diff --git a/exchanges/coinbasepro/coinbasepro.go b/exchanges/coinbasepro/coinbasepro.go index 2a7652d1..0c629c5b 100644 --- a/exchanges/coinbasepro/coinbasepro.go +++ b/exchanges/coinbasepro/coinbasepro.go @@ -59,14 +59,14 @@ type CoinbasePro struct { // GetProducts returns supported currency pairs on the exchange with specific // information about the pair -func (c *CoinbasePro) GetProducts() ([]Product, error) { +func (c *CoinbasePro) GetProducts(ctx context.Context) ([]Product, error) { var products []Product - return products, c.SendHTTPRequest(exchange.RestSpot, coinbaseproProducts, &products) + return products, c.SendHTTPRequest(ctx, exchange.RestSpot, coinbaseproProducts, &products) } // GetOrderbook returns orderbook by currency pair and level -func (c *CoinbasePro) GetOrderbook(symbol string, level int) (interface{}, error) { +func (c *CoinbasePro) GetOrderbook(ctx context.Context, symbol string, level int) (interface{}, error) { orderbook := OrderbookResponse{} path := fmt.Sprintf("%s/%s/%s", coinbaseproProducts, symbol, coinbaseproOrderbook) @@ -75,7 +75,7 @@ func (c *CoinbasePro) GetOrderbook(symbol string, level int) (interface{}, error path = fmt.Sprintf("%s/%s/%s?level=%s", coinbaseproProducts, symbol, coinbaseproOrderbook, levelStr) } - if err := c.SendHTTPRequest(exchange.RestSpot, path, &orderbook); err != nil { + if err := c.SendHTTPRequest(ctx, exchange.RestSpot, path, &orderbook); err != nil { return nil, err } @@ -139,25 +139,25 @@ func (c *CoinbasePro) GetOrderbook(symbol string, level int) (interface{}, error // GetTicker returns ticker by currency pair // currencyPair - example "BTC-USD" -func (c *CoinbasePro) GetTicker(currencyPair string) (Ticker, error) { +func (c *CoinbasePro) GetTicker(ctx context.Context, currencyPair string) (Ticker, error) { tick := Ticker{} path := fmt.Sprintf( "%s/%s/%s", coinbaseproProducts, currencyPair, coinbaseproTicker) - return tick, c.SendHTTPRequest(exchange.RestSpot, path, &tick) + return tick, c.SendHTTPRequest(ctx, exchange.RestSpot, path, &tick) } // GetTrades listd the latest trades for a product // currencyPair - example "BTC-USD" -func (c *CoinbasePro) GetTrades(currencyPair string) ([]Trade, error) { +func (c *CoinbasePro) GetTrades(ctx context.Context, currencyPair string) ([]Trade, error) { var trades []Trade path := fmt.Sprintf( "%s/%s/%s", coinbaseproProducts, currencyPair, coinbaseproTrades) - return trades, c.SendHTTPRequest(exchange.RestSpot, path, &trades) + return trades, c.SendHTTPRequest(ctx, exchange.RestSpot, path, &trades) } // GetHistoricRates returns historic rates for a product. Rates are returned in // grouped buckets based on requested granularity. -func (c *CoinbasePro) GetHistoricRates(currencyPair, start, end string, granularity int64) ([]History, error) { +func (c *CoinbasePro) GetHistoricRates(ctx context.Context, currencyPair, start, end string, granularity int64) ([]History, error) { var resp [][]interface{} var history []History values := url.Values{} @@ -187,7 +187,7 @@ func (c *CoinbasePro) GetHistoricRates(currencyPair, start, end string, granular fmt.Sprintf("%s/%s/%s", coinbaseproProducts, currencyPair, coinbaseproHistory), values) - if err := c.SendHTTPRequest(exchange.RestSpot, path, &resp); err != nil { + if err := c.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp); err != nil { return history, err } @@ -213,65 +213,65 @@ func (c *CoinbasePro) GetHistoricRates(currencyPair, start, end string, granular // GetStats returns a 24 hr stat for the product. Volume is in base currency // units. open, high, low are in quote currency units. -func (c *CoinbasePro) GetStats(currencyPair string) (Stats, error) { +func (c *CoinbasePro) GetStats(ctx context.Context, currencyPair string) (Stats, error) { stats := Stats{} path := fmt.Sprintf( "%s/%s/%s", coinbaseproProducts, currencyPair, coinbaseproStats) - return stats, c.SendHTTPRequest(exchange.RestSpot, path, &stats) + return stats, c.SendHTTPRequest(ctx, exchange.RestSpot, path, &stats) } // GetCurrencies returns a list of supported currency on the exchange // Warning: Not all currencies may be currently in use for tradinc. -func (c *CoinbasePro) GetCurrencies() ([]Currency, error) { +func (c *CoinbasePro) GetCurrencies(ctx context.Context) ([]Currency, error) { var currencies []Currency - return currencies, c.SendHTTPRequest(exchange.RestSpot, coinbaseproCurrencies, ¤cies) + return currencies, c.SendHTTPRequest(ctx, exchange.RestSpot, coinbaseproCurrencies, ¤cies) } // GetServerTime returns the API server time -func (c *CoinbasePro) GetServerTime() (ServerTime, error) { +func (c *CoinbasePro) GetServerTime(ctx context.Context) (ServerTime, error) { serverTime := ServerTime{} - return serverTime, c.SendHTTPRequest(exchange.RestSpot, coinbaseproTime, &serverTime) + return serverTime, c.SendHTTPRequest(ctx, exchange.RestSpot, coinbaseproTime, &serverTime) } // GetAccounts returns a list of trading accounts associated with the APIKEYS -func (c *CoinbasePro) GetAccounts() ([]AccountResponse, error) { +func (c *CoinbasePro) GetAccounts(ctx context.Context) ([]AccountResponse, error) { var resp []AccountResponse return resp, - c.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, coinbaseproAccounts, nil, &resp) + c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, coinbaseproAccounts, nil, &resp) } // GetAccount returns information for a single account. Use this endpoint when // account_id is known -func (c *CoinbasePro) GetAccount(accountID string) (AccountResponse, error) { +func (c *CoinbasePro) GetAccount(ctx context.Context, accountID string) (AccountResponse, error) { resp := AccountResponse{} path := fmt.Sprintf("%s/%s", coinbaseproAccounts, accountID) - return resp, c.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, path, nil, &resp) + return resp, c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, path, nil, &resp) } // GetAccountHistory returns a list of account activity. Account activity either // increases or decreases your account balance. Items are paginated and sorted // latest first. -func (c *CoinbasePro) GetAccountHistory(accountID string) ([]AccountLedgerResponse, error) { +func (c *CoinbasePro) GetAccountHistory(ctx context.Context, accountID string) ([]AccountLedgerResponse, error) { var resp []AccountLedgerResponse path := fmt.Sprintf("%s/%s/%s", coinbaseproAccounts, accountID, coinbaseproLedger) - return resp, c.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, path, nil, &resp) + return resp, c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, path, nil, &resp) } // GetHolds returns the holds that are placed on an account for any active // orders or pending withdraw requests. As an order is filled, the hold amount // is updated. If an order is canceled, any remaining hold is removed. For a // withdraw, once it is completed, the hold is removed. -func (c *CoinbasePro) GetHolds(accountID string) ([]AccountHolds, error) { +func (c *CoinbasePro) GetHolds(ctx context.Context, accountID string) ([]AccountHolds, error) { var resp []AccountHolds path := fmt.Sprintf("%s/%s/%s", coinbaseproAccounts, accountID, coinbaseproHolds) - return resp, c.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, path, nil, &resp) + return resp, c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, path, nil, &resp) } // PlaceLimitOrder places a new limit order. Orders can only be placed if the @@ -291,7 +291,7 @@ func (c *CoinbasePro) GetHolds(accountID string) ([]AccountHolds, error) { // timeInforce - [optional] GTC, GTT, IOC, or FOK (default is GTC) // cancelAfter - [optional] min, hour, day * Requires time_in_force to be GTT // postOnly - [optional] Post only flag Invalid when time_in_force is IOC or FOK -func (c *CoinbasePro) PlaceLimitOrder(clientRef string, price, amount float64, side, timeInforce, cancelAfter, productID, stp string, postOnly bool) (string, error) { +func (c *CoinbasePro) PlaceLimitOrder(ctx context.Context, clientRef string, price, amount float64, side, timeInforce, cancelAfter, productID, stp string, postOnly bool) (string, error) { resp := GeneralizedOrderResponse{} req := make(map[string]interface{}) req["type"] = order.Limit.Lower() @@ -316,7 +316,7 @@ func (c *CoinbasePro) PlaceLimitOrder(clientRef string, price, amount float64, s req["post_only"] = postOnly } - err := c.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, coinbaseproOrders, req, &resp) + err := c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, coinbaseproOrders, req, &resp) if err != nil { return "", err } @@ -340,7 +340,7 @@ func (c *CoinbasePro) PlaceLimitOrder(clientRef string, price, amount float64, s // size - [optional]* Desired amount in BTC // funds [optional]* Desired amount of quote currency to use // * One of size or funds is required. -func (c *CoinbasePro) PlaceMarketOrder(clientRef string, size, funds float64, side, productID, stp string) (string, error) { +func (c *CoinbasePro) PlaceMarketOrder(ctx context.Context, clientRef string, size, funds float64, side, productID, stp string) (string, error) { resp := GeneralizedOrderResponse{} req := make(map[string]interface{}) req["side"] = side @@ -360,7 +360,7 @@ func (c *CoinbasePro) PlaceMarketOrder(clientRef string, size, funds float64, si req["stp"] = stp } - err := c.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, coinbaseproOrders, req, &resp) + err := c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, coinbaseproOrders, req, &resp) if err != nil { return "", err } @@ -383,7 +383,7 @@ func (c *CoinbasePro) PlaceMarketOrder(clientRef string, size, funds float64, si // MARGIN ORDER PARAMS // size - [optional]* Desired amount in BTC // funds - [optional]* Desired amount of quote currency to use -func (c *CoinbasePro) PlaceMarginOrder(clientRef string, size, funds float64, side, productID, stp string) (string, error) { +func (c *CoinbasePro) PlaceMarginOrder(ctx context.Context, clientRef string, size, funds float64, side, productID, stp string) (string, error) { resp := GeneralizedOrderResponse{} req := make(map[string]interface{}) req["side"] = side @@ -403,7 +403,7 @@ func (c *CoinbasePro) PlaceMarginOrder(clientRef string, size, funds float64, si req["stp"] = stp } - err := c.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, coinbaseproOrders, req, &resp) + err := c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, coinbaseproOrders, req, &resp) if err != nil { return "", err } @@ -412,24 +412,24 @@ func (c *CoinbasePro) PlaceMarginOrder(clientRef string, size, funds float64, si } // CancelExistingOrder cancels order by orderID -func (c *CoinbasePro) CancelExistingOrder(orderID string) error { +func (c *CoinbasePro) CancelExistingOrder(ctx context.Context, orderID string) error { path := fmt.Sprintf("%s/%s", coinbaseproOrders, orderID) - return c.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodDelete, path, nil, nil) + return c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodDelete, path, nil, nil) } // CancelAllExistingOrders cancels all open orders on the exchange and returns // and array of order IDs // currencyPair - [optional] all orders for a currencyPair string will be // canceled -func (c *CoinbasePro) CancelAllExistingOrders(currencyPair string) ([]string, error) { +func (c *CoinbasePro) CancelAllExistingOrders(ctx context.Context, currencyPair string) ([]string, error) { var resp []string req := make(map[string]interface{}) if len(currencyPair) > 0 { req["product_id"] = currencyPair } - return resp, c.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodDelete, coinbaseproOrders, req, &resp) + return resp, c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodDelete, coinbaseproOrders, req, &resp) } // GetOrders lists current open orders. Only open or un-settled orders are @@ -437,7 +437,7 @@ func (c *CoinbasePro) CancelAllExistingOrders(currencyPair string) ([]string, er // longer appear in the default request. // status - can be a range of "open", "pending", "done" or "active" // currencyPair - [optional] for example "BTC-USD" -func (c *CoinbasePro) GetOrders(status []string, currencyPair string) ([]GeneralizedOrderResponse, error) { +func (c *CoinbasePro) GetOrders(ctx context.Context, status []string, currencyPair string) ([]GeneralizedOrderResponse, error) { var resp []GeneralizedOrderResponse params := url.Values{} @@ -450,19 +450,19 @@ func (c *CoinbasePro) GetOrders(status []string, currencyPair string) ([]General path := common.EncodeURLValues(coinbaseproOrders, params) return resp, - c.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, path, nil, &resp) + c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, path, nil, &resp) } // GetOrder returns a single order by order id. -func (c *CoinbasePro) GetOrder(orderID string) (GeneralizedOrderResponse, error) { +func (c *CoinbasePro) GetOrder(ctx context.Context, orderID string) (GeneralizedOrderResponse, error) { resp := GeneralizedOrderResponse{} path := fmt.Sprintf("%s/%s", coinbaseproOrders, orderID) - return resp, c.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, path, nil, &resp) + return resp, c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, path, nil, &resp) } // GetFills returns a list of recent fills -func (c *CoinbasePro) GetFills(orderID, currencyPair string) ([]FillResponse, error) { +func (c *CoinbasePro) GetFills(ctx context.Context, orderID, currencyPair string) ([]FillResponse, error) { var resp []FillResponse params := url.Values{} @@ -478,7 +478,7 @@ func (c *CoinbasePro) GetFills(orderID, currencyPair string) ([]FillResponse, er path := common.EncodeURLValues(coinbaseproFills, params) return resp, - c.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, path, nil, &resp) + c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, path, nil, &resp) } // MarginTransfer sends funds between a standard/default profile and a margin @@ -492,7 +492,7 @@ func (c *CoinbasePro) GetFills(orderID, currencyPair string) ([]FillResponse, er // transferType - either "deposit" or "withdraw" // profileID - The id of the margin profile to deposit or withdraw from // currency - currency to transfer, currently on "BTC" or "USD" -func (c *CoinbasePro) MarginTransfer(amount float64, transferType, profileID, currency string) (MarginTransfer, error) { +func (c *CoinbasePro) MarginTransfer(ctx context.Context, amount float64, transferType, profileID, currency string) (MarginTransfer, error) { resp := MarginTransfer{} req := make(map[string]interface{}) req["type"] = transferType @@ -501,34 +501,34 @@ func (c *CoinbasePro) MarginTransfer(amount float64, transferType, profileID, cu req["margin_profile_id"] = profileID return resp, - c.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, coinbaseproMarginTransfer, req, &resp) + c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, coinbaseproMarginTransfer, req, &resp) } // GetPosition returns an overview of account profile. -func (c *CoinbasePro) GetPosition() (AccountOverview, error) { +func (c *CoinbasePro) GetPosition(ctx context.Context) (AccountOverview, error) { resp := AccountOverview{} return resp, - c.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, coinbaseproPosition, nil, &resp) + c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, coinbaseproPosition, nil, &resp) } // ClosePosition closes a position and allowing you to repay position as well // repayOnly - allows the position to be repaid -func (c *CoinbasePro) ClosePosition(repayOnly bool) (AccountOverview, error) { +func (c *CoinbasePro) ClosePosition(ctx context.Context, repayOnly bool) (AccountOverview, error) { resp := AccountOverview{} req := make(map[string]interface{}) req["repay_only"] = repayOnly return resp, - c.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, coinbaseproPositionClose, req, &resp) + c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, coinbaseproPositionClose, req, &resp) } // GetPayMethods returns a full list of payment methods -func (c *CoinbasePro) GetPayMethods() ([]PaymentMethod, error) { +func (c *CoinbasePro) GetPayMethods(ctx context.Context) ([]PaymentMethod, error) { var resp []PaymentMethod return resp, - c.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, coinbaseproPaymentMethod, nil, &resp) + c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, coinbaseproPaymentMethod, nil, &resp) } // DepositViaPaymentMethod deposits funds from a payment method. See the Payment @@ -537,7 +537,7 @@ func (c *CoinbasePro) GetPayMethods() ([]PaymentMethod, error) { // amount - The amount to deposit // currency - The type of currency // paymentID - ID of the payment method -func (c *CoinbasePro) DepositViaPaymentMethod(amount float64, currency, paymentID string) (DepositWithdrawalInfo, error) { +func (c *CoinbasePro) DepositViaPaymentMethod(ctx context.Context, amount float64, currency, paymentID string) (DepositWithdrawalInfo, error) { resp := DepositWithdrawalInfo{} req := make(map[string]interface{}) req["amount"] = amount @@ -545,7 +545,7 @@ func (c *CoinbasePro) DepositViaPaymentMethod(amount float64, currency, paymentI req["payment_method_id"] = paymentID return resp, - c.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, coinbaseproPaymentMethodDeposit, req, &resp) + c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, coinbaseproPaymentMethodDeposit, req, &resp) } // DepositViaCoinbase deposits funds from a coinbase account. Move funds between @@ -556,7 +556,7 @@ func (c *CoinbasePro) DepositViaPaymentMethod(amount float64, currency, paymentI // amount - The amount to deposit // currency - The type of currency // accountID - ID of the coinbase account -func (c *CoinbasePro) DepositViaCoinbase(amount float64, currency, accountID string) (DepositWithdrawalInfo, error) { +func (c *CoinbasePro) DepositViaCoinbase(ctx context.Context, amount float64, currency, accountID string) (DepositWithdrawalInfo, error) { resp := DepositWithdrawalInfo{} req := make(map[string]interface{}) req["amount"] = amount @@ -564,7 +564,7 @@ func (c *CoinbasePro) DepositViaCoinbase(amount float64, currency, accountID str req["coinbase_account_id"] = accountID return resp, - c.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, coinbaseproDepositCoinbase, req, &resp) + c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, coinbaseproDepositCoinbase, req, &resp) } // WithdrawViaPaymentMethod withdraws funds to a payment method @@ -572,7 +572,7 @@ func (c *CoinbasePro) DepositViaCoinbase(amount float64, currency, accountID str // amount - The amount to withdraw // currency - The type of currency // paymentID - ID of the payment method -func (c *CoinbasePro) WithdrawViaPaymentMethod(amount float64, currency, paymentID string) (DepositWithdrawalInfo, error) { +func (c *CoinbasePro) WithdrawViaPaymentMethod(ctx context.Context, amount float64, currency, paymentID string) (DepositWithdrawalInfo, error) { resp := DepositWithdrawalInfo{} req := make(map[string]interface{}) req["amount"] = amount @@ -580,7 +580,7 @@ func (c *CoinbasePro) WithdrawViaPaymentMethod(amount float64, currency, payment req["payment_method_id"] = paymentID return resp, - c.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, coinbaseproWithdrawalPaymentMethod, req, &resp) + c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, coinbaseproWithdrawalPaymentMethod, req, &resp) } // /////////////////////// NO ROUTE FOUND ERROR //////////////////////////////// @@ -597,7 +597,7 @@ func (c *CoinbasePro) WithdrawViaPaymentMethod(amount float64, currency, payment // req["coinbase_account_id"] = accountID // // return resp, -// c.SendAuthenticatedHTTPRequest(http.MethodPost, coinbaseproWithdrawalCoinbase, req, &resp) +// c.SendAuthenticatedHTTPRequest(ctx,http.MethodPost, coinbaseproWithdrawalCoinbase, req, &resp) // } // WithdrawCrypto withdraws funds to a crypto address @@ -605,7 +605,7 @@ func (c *CoinbasePro) WithdrawViaPaymentMethod(amount float64, currency, payment // amount - The amount to withdraw // currency - The type of currency // cryptoAddress - A crypto address of the recipient -func (c *CoinbasePro) WithdrawCrypto(amount float64, currency, cryptoAddress string) (DepositWithdrawalInfo, error) { +func (c *CoinbasePro) WithdrawCrypto(ctx context.Context, amount float64, currency, cryptoAddress string) (DepositWithdrawalInfo, error) { resp := DepositWithdrawalInfo{} req := make(map[string]interface{}) req["amount"] = amount @@ -613,15 +613,15 @@ func (c *CoinbasePro) WithdrawCrypto(amount float64, currency, cryptoAddress str req["crypto_address"] = cryptoAddress return resp, - c.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, coinbaseproWithdrawalCrypto, req, &resp) + c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, coinbaseproWithdrawalCrypto, req, &resp) } // GetCoinbaseAccounts returns a list of coinbase accounts -func (c *CoinbasePro) GetCoinbaseAccounts() ([]CoinbaseAccounts, error) { +func (c *CoinbasePro) GetCoinbaseAccounts(ctx context.Context) ([]CoinbaseAccounts, error) { var resp []CoinbaseAccounts return resp, - c.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, coinbaseproCoinbaseAccounts, nil, &resp) + c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, coinbaseproCoinbaseAccounts, nil, &resp) } // GetReport returns batches of historic information about your account in @@ -636,7 +636,7 @@ func (c *CoinbasePro) GetCoinbaseAccounts() ([]CoinbaseAccounts, error) { // if type is account // format - pdf or csv (default is pdf) // email - [optional] Email address to send the report to -func (c *CoinbasePro) GetReport(reportType, startDate, endDate, currencyPair, accountID, format, email string) (Report, error) { +func (c *CoinbasePro) GetReport(ctx context.Context, reportType, startDate, endDate, currencyPair, accountID, format, email string) (Report, error) { resp := Report{} req := make(map[string]interface{}) req["type"] = reportType @@ -658,29 +658,29 @@ func (c *CoinbasePro) GetReport(reportType, startDate, endDate, currencyPair, ac } return resp, - c.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, coinbaseproReports, req, &resp) + c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, coinbaseproReports, req, &resp) } // GetReportStatus once a report request has been accepted for processing, the // status is available by polling the report resource endpoint. -func (c *CoinbasePro) GetReportStatus(reportID string) (Report, error) { +func (c *CoinbasePro) GetReportStatus(ctx context.Context, reportID string) (Report, error) { resp := Report{} path := fmt.Sprintf("%s/%s", coinbaseproReports, reportID) - return resp, c.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, path, nil, &resp) + return resp, c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, path, nil, &resp) } // GetTrailingVolume this request will return your 30-day trailing volume for // all products. -func (c *CoinbasePro) GetTrailingVolume() ([]Volume, error) { +func (c *CoinbasePro) GetTrailingVolume(ctx context.Context) ([]Volume, error) { var resp []Volume return resp, - c.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, coinbaseproTrailingVolume, nil, &resp) + c.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, coinbaseproTrailingVolume, nil, &resp) } // SendHTTPRequest sends an unauthenticated HTTP request -func (c *CoinbasePro) SendHTTPRequest(ep exchange.URL, path string, result interface{}) error { +func (c *CoinbasePro) SendHTTPRequest(ctx context.Context, ep exchange.URL, path string, result interface{}) error { endpoint, err := c.API.Endpoints.GetURL(ep) if err != nil { return err @@ -695,13 +695,13 @@ func (c *CoinbasePro) SendHTTPRequest(ep exchange.URL, path string, result inter HTTPRecording: c.HTTPRecording, } - return c.SendPayload(context.Background(), request.Unset, func() (*request.Item, error) { + return c.SendPayload(ctx, request.Unset, func() (*request.Item, error) { return item, nil }) } // SendAuthenticatedHTTPRequest sends an authenticated HTTP request -func (c *CoinbasePro) SendAuthenticatedHTTPRequest(ep exchange.URL, method, path string, params map[string]interface{}, result interface{}) (err error) { +func (c *CoinbasePro) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, method, path string, params map[string]interface{}, result interface{}) (err error) { if !c.AllowAuthenticatedRequest() { return fmt.Errorf("%s %w", c.Name, exchange.ErrAuthenticatedRequestWithoutCredentialsSet) } @@ -749,15 +749,15 @@ func (c *CoinbasePro) SendAuthenticatedHTTPRequest(ep exchange.URL, method, path HTTPRecording: c.HTTPRecording, }, nil } - return c.SendPayload(context.Background(), request.Unset, newRequest) + return c.SendPayload(ctx, request.Unset, newRequest) } // GetFee returns an estimate of fee based on type of transaction -func (c *CoinbasePro) GetFee(feeBuilder *exchange.FeeBuilder) (float64, error) { +func (c *CoinbasePro) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { var fee float64 switch feeBuilder.FeeType { case exchange.CryptocurrencyTradeFee: - trailingVolume, err := c.GetTrailingVolume() + trailingVolume, err := c.GetTrailingVolume(ctx) if err != nil { return 0, err } diff --git a/exchanges/coinbasepro/coinbasepro_test.go b/exchanges/coinbasepro/coinbasepro_test.go index 82b64cd7..aa592d33 100644 --- a/exchanges/coinbasepro/coinbasepro_test.go +++ b/exchanges/coinbasepro/coinbasepro_test.go @@ -1,6 +1,7 @@ package coinbasepro import ( + "context" "log" "net/http" "os" @@ -61,21 +62,21 @@ func TestMain(m *testing.M) { } func TestGetProducts(t *testing.T) { - _, err := c.GetProducts() + _, err := c.GetProducts(context.Background()) if err != nil { t.Errorf("Coinbase, GetProducts() Error: %s", err) } } func TestGetTicker(t *testing.T) { - _, err := c.GetTicker(testPair.String()) + _, err := c.GetTicker(context.Background(), testPair.String()) if err != nil { t.Error("GetTicker() error", err) } } func TestGetTrades(t *testing.T) { - _, err := c.GetTrades(testPair.String()) + _, err := c.GetTrades(context.Background(), testPair.String()) if err != nil { t.Error("GetTrades() error", err) } @@ -84,7 +85,8 @@ func TestGetTrades(t *testing.T) { func TestGetHistoricRatesGranularityCheck(t *testing.T) { end := time.Now() start := end.Add(-time.Hour * 2) - _, err := c.GetHistoricCandles(testPair, asset.Spot, start, end, kline.OneHour) + _, err := c.GetHistoricCandles(context.Background(), + testPair, asset.Spot, start, end, kline.OneHour) if err != nil { t.Fatal(err) } @@ -94,28 +96,29 @@ func TestCoinbasePro_GetHistoricCandlesExtended(t *testing.T) { start := time.Unix(1546300800, 0) end := time.Unix(1577836799, 0) - _, err := c.GetHistoricCandlesExtended(testPair, asset.Spot, start, end, kline.OneDay) + _, err := c.GetHistoricCandlesExtended(context.Background(), + testPair, asset.Spot, start, end, kline.OneDay) if err != nil { t.Fatal(err) } } func TestGetStats(t *testing.T) { - _, err := c.GetStats(testPair.String()) + _, err := c.GetStats(context.Background(), testPair.String()) if err != nil { t.Error("GetStats() error", err) } } func TestGetCurrencies(t *testing.T) { - _, err := c.GetCurrencies() + _, err := c.GetCurrencies(context.Background()) if err != nil { t.Error("GetCurrencies() error", err) } } func TestGetServerTime(t *testing.T) { - _, err := c.GetServerTime() + _, err := c.GetServerTime(context.Background()) if err != nil { t.Error("GetServerTime() error", err) } @@ -125,32 +128,36 @@ func TestAuthRequests(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys not set, skipping test") } - _, err := c.GetAccounts() + _, err := c.GetAccounts(context.Background()) if err != nil { t.Error("GetAccounts() error", err) } - accountResponse, err := c.GetAccount("13371337-1337-1337-1337-133713371337") + accountResponse, err := c.GetAccount(context.Background(), + "13371337-1337-1337-1337-133713371337") if accountResponse.ID != "" { t.Error("Expecting no data returned") } if err == nil { t.Error("Expecting error") } - accountHistoryResponse, err := c.GetAccountHistory("13371337-1337-1337-1337-133713371337") + accountHistoryResponse, err := c.GetAccountHistory(context.Background(), + "13371337-1337-1337-1337-133713371337") if len(accountHistoryResponse) > 0 { t.Error("Expecting no data returned") } if err == nil { t.Error("Expecting error") } - getHoldsResponse, err := c.GetHolds("13371337-1337-1337-1337-133713371337") + getHoldsResponse, err := c.GetHolds(context.Background(), + "13371337-1337-1337-1337-133713371337") if len(getHoldsResponse) > 0 { t.Error("Expecting no data returned") } if err == nil { t.Error("Expecting error") } - orderResponse, err := c.PlaceLimitOrder("", 0.001, 0.001, + orderResponse, err := c.PlaceLimitOrder(context.Background(), + "", 0.001, 0.001, order.Buy.Lower(), "", "", testPair.String(), "", false) if orderResponse != "" { t.Error("Expecting no data returned") @@ -158,7 +165,8 @@ func TestAuthRequests(t *testing.T) { if err == nil { t.Error("Expecting error") } - marketOrderResponse, err := c.PlaceMarketOrder("", 1, 0, + marketOrderResponse, err := c.PlaceMarketOrder(context.Background(), + "", 1, 0, order.Buy.Lower(), testPair.String(), "") if marketOrderResponse != "" { t.Error("Expecting no data returned") @@ -166,37 +174,39 @@ func TestAuthRequests(t *testing.T) { if err == nil { t.Error("Expecting error") } - fillsResponse, err := c.GetFills("1337", testPair.String()) + fillsResponse, err := c.GetFills(context.Background(), + "1337", testPair.String()) if len(fillsResponse) > 0 { t.Error("Expecting no data returned") } if err == nil { t.Error("Expecting error") } - _, err = c.GetFills("", "") + _, err = c.GetFills(context.Background(), "", "") if err == nil { t.Error("Expecting error") } - marginTransferResponse, err := c.MarginTransfer(1, "withdraw", "13371337-1337-1337-1337-133713371337", "BTC") + marginTransferResponse, err := c.MarginTransfer(context.Background(), + 1, "withdraw", "13371337-1337-1337-1337-133713371337", "BTC") if marginTransferResponse.ID != "" { t.Error("Expecting no data returned") } if err == nil { t.Error("Expecting error") } - _, err = c.GetPosition() + _, err = c.GetPosition(context.Background()) if err == nil { t.Error("Expecting error") } - _, err = c.ClosePosition(false) + _, err = c.ClosePosition(context.Background(), false) if err == nil { t.Error("Expecting error") } - _, err = c.GetPayMethods() + _, err = c.GetPayMethods(context.Background()) if err != nil { t.Error("GetPayMethods() error", err) } - _, err = c.GetCoinbaseAccounts() + _, err = c.GetCoinbaseAccounts(context.Background()) if err != nil { t.Error("GetCoinbaseAccounts() error", err) } @@ -214,7 +224,7 @@ func setFeeBuilder() *exchange.FeeBuilder { // TestGetFeeByTypeOfflineTradeFee logic test func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { var feeBuilder = setFeeBuilder() - _, err := c.GetFeeByType(feeBuilder) + _, err := c.GetFeeByType(context.Background(), feeBuilder) if err != nil { t.Fatal(err) } @@ -234,7 +244,7 @@ func TestGetFee(t *testing.T) { if areTestAPIKeysSet() { // CryptocurrencyTradeFee Basic - if _, err := c.GetFee(feeBuilder); err != nil { + if _, err := c.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } @@ -242,21 +252,21 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.Amount = 1000 feeBuilder.PurchasePrice = 1000 - if _, err := c.GetFee(feeBuilder); err != nil { + if _, err := c.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyTradeFee IsMaker feeBuilder = setFeeBuilder() feeBuilder.IsMaker = true - if _, err := c.GetFee(feeBuilder); err != nil { + if _, err := c.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyTradeFee Negative purchase price feeBuilder = setFeeBuilder() feeBuilder.PurchasePrice = -1000 - if _, err := c.GetFee(feeBuilder); err != nil { + if _, err := c.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } } @@ -264,14 +274,14 @@ func TestGetFee(t *testing.T) { // CryptocurrencyWithdrawalFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee - if _, err := c.GetFee(feeBuilder); err != nil { + if _, err := c.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyDepositFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.CryptocurrencyDepositFee - if _, err := c.GetFee(feeBuilder); err != nil { + if _, err := c.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } @@ -279,7 +289,7 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankDepositFee feeBuilder.FiatCurrency = currency.EUR - if _, err := c.GetFee(feeBuilder); err != nil { + if _, err := c.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } @@ -287,7 +297,7 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee feeBuilder.FiatCurrency = currency.USD - if _, err := c.GetFee(feeBuilder); err != nil { + if _, err := c.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } } @@ -394,7 +404,7 @@ func TestGetActiveOrders(t *testing.T) { Pairs: []currency.Pair{testPair}, } - _, err := c.GetActiveOrders(&getOrdersRequest) + _, err := c.GetActiveOrders(context.Background(), &getOrdersRequest) if areTestAPIKeysSet() && err != nil { t.Errorf("Could not get open orders: %s", err) } else if !areTestAPIKeysSet() && err == nil { @@ -409,7 +419,7 @@ func TestGetOrderHistory(t *testing.T) { Pairs: []currency.Pair{testPair}, } - _, err := c.GetOrderHistory(&getOrdersRequest) + _, err := c.GetOrderHistory(context.Background(), &getOrdersRequest) if areTestAPIKeysSet() && err != nil { t.Errorf("Could not get order history: %s", err) } else if !areTestAPIKeysSet() && err == nil { @@ -441,7 +451,7 @@ func TestSubmitOrder(t *testing.T) { ClientID: "meowOrder", AssetType: asset.Spot, } - response, err := c.SubmitOrder(orderSubmission) + response, err := c.SubmitOrder(context.Background(), orderSubmission) if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) { t.Errorf("Order failed to be placed: %v", err) } else if !areTestAPIKeysSet() && err == nil { @@ -462,7 +472,7 @@ func TestCancelExchangeOrder(t *testing.T) { AssetType: asset.Spot, } - err := c.CancelOrder(orderCancellation) + err := c.CancelOrder(context.Background(), orderCancellation) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") } @@ -484,7 +494,7 @@ func TestCancelAllExchangeOrders(t *testing.T) { AssetType: asset.Spot, } - resp, err := c.CancelAllOrders(orderCancellation) + resp, err := c.CancelAllOrders(context.Background(), orderCancellation) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") @@ -502,7 +512,8 @@ func TestModifyOrder(t *testing.T) { if areTestAPIKeysSet() && !canManipulateRealOrders { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - _, err := c.ModifyOrder(&order.Modify{AssetType: asset.Spot}) + _, err := c.ModifyOrder(context.Background(), + &order.Modify{AssetType: asset.Spot}) if err == nil { t.Error("ModifyOrder() Expected error") } @@ -522,7 +533,8 @@ func TestWithdraw(t *testing.T) { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - _, err := c.WithdrawCryptocurrencyFunds(&withdrawCryptoRequest) + _, err := c.WithdrawCryptocurrencyFunds(context.Background(), + &withdrawCryptoRequest) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") } @@ -546,7 +558,7 @@ func TestWithdrawFiat(t *testing.T) { }, } - _, err := c.WithdrawFiatFunds(&withdrawFiatRequest) + _, err := c.WithdrawFiatFunds(context.Background(), &withdrawFiatRequest) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") } @@ -570,7 +582,8 @@ func TestWithdrawInternationalBank(t *testing.T) { }, } - _, err := c.WithdrawFiatFundsToInternationalBank(&withdrawFiatRequest) + _, err := c.WithdrawFiatFundsToInternationalBank(context.Background(), + &withdrawFiatRequest) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") } @@ -580,7 +593,7 @@ func TestWithdrawInternationalBank(t *testing.T) { } func TestGetDepositAddress(t *testing.T) { - _, err := c.GetDepositAddress(currency.BTC, "") + _, err := c.GetDepositAddress(context.Background(), currency.BTC, "") if err == nil { t.Error("GetDepositAddress() error", err) } @@ -1001,7 +1014,7 @@ func TestCheckInterval(t *testing.T) { func TestGetRecentTrades(t *testing.T) { t.Parallel() - _, err := c.GetRecentTrades(testPair, asset.Spot) + _, err := c.GetRecentTrades(context.Background(), testPair, asset.Spot) if err != nil { t.Error(err) } @@ -1009,7 +1022,8 @@ func TestGetRecentTrades(t *testing.T) { func TestGetHistoricTrades(t *testing.T) { t.Parallel() - _, err := c.GetHistoricTrades(testPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) + _, err := c.GetHistoricTrades(context.Background(), + testPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) if err != nil && err != common.ErrFunctionNotSupported { t.Error(err) } diff --git a/exchanges/coinbasepro/coinbasepro_wrapper.go b/exchanges/coinbasepro/coinbasepro_wrapper.go index 30168999..6a0a591b 100644 --- a/exchanges/coinbasepro/coinbasepro_wrapper.go +++ b/exchanges/coinbasepro/coinbasepro_wrapper.go @@ -1,6 +1,7 @@ package coinbasepro import ( + "context" "errors" "fmt" "sort" @@ -41,7 +42,7 @@ func (c *CoinbasePro) GetDefaultConfig() (*config.ExchangeConfig, error) { } if c.Features.Supports.RESTCapabilities.AutoPairUpdates { - err = c.UpdateTradablePairs(true) + err = c.UpdateTradablePairs(context.TODO(), true) if err != nil { return nil, err } @@ -267,15 +268,15 @@ func (c *CoinbasePro) Run() { return } - err = c.UpdateTradablePairs(forceUpdate) + err = c.UpdateTradablePairs(context.TODO(), forceUpdate) if err != nil { log.Errorf(log.ExchangeSys, "%s failed to update tradable pairs. Err: %s", c.Name, err) } } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (c *CoinbasePro) FetchTradablePairs(asset asset.Item) ([]string, error) { - pairs, err := c.GetProducts() +func (c *CoinbasePro) FetchTradablePairs(ctx context.Context, asset asset.Item) ([]string, error) { + pairs, err := c.GetProducts(ctx) if err != nil { return nil, err } @@ -297,8 +298,8 @@ func (c *CoinbasePro) FetchTradablePairs(asset asset.Item) ([]string, error) { // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (c *CoinbasePro) UpdateTradablePairs(forceUpdate bool) error { - pairs, err := c.FetchTradablePairs(asset.Spot) +func (c *CoinbasePro) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { + pairs, err := c.FetchTradablePairs(ctx, asset.Spot) if err != nil { return err } @@ -313,10 +314,10 @@ func (c *CoinbasePro) UpdateTradablePairs(forceUpdate bool) error { // UpdateAccountInfo retrieves balances for all enabled currencies for the // coinbasepro exchange -func (c *CoinbasePro) UpdateAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (c *CoinbasePro) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { var response account.Holdings response.Exchange = c.Name - accountBalance, err := c.GetAccounts() + accountBalance, err := c.GetAccounts(ctx) if err != nil { return response, err } @@ -344,32 +345,32 @@ func (c *CoinbasePro) UpdateAccountInfo(assetType asset.Item) (account.Holdings, } // FetchAccountInfo retrieves balances for all enabled currencies -func (c *CoinbasePro) FetchAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (c *CoinbasePro) FetchAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { acc, err := account.GetHoldings(c.Name, assetType) if err != nil { - return c.UpdateAccountInfo(assetType) + return c.UpdateAccountInfo(ctx, assetType) } return acc, nil } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (c *CoinbasePro) UpdateTickers(a asset.Item) error { +func (c *CoinbasePro) UpdateTickers(ctx context.Context, a asset.Item) error { return common.ErrFunctionNotSupported } // UpdateTicker updates and returns the ticker for a currency pair -func (c *CoinbasePro) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) { +func (c *CoinbasePro) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { fpair, err := c.FormatExchangeCurrency(p, a) if err != nil { return nil, err } - tick, err := c.GetTicker(fpair.String()) + tick, err := c.GetTicker(ctx, fpair.String()) if err != nil { return nil, err } - stats, err := c.GetStats(fpair.String()) + stats, err := c.GetStats(ctx, fpair.String()) if err != nil { return nil, err } @@ -396,25 +397,25 @@ func (c *CoinbasePro) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price } // FetchTicker returns the ticker for a currency pair -func (c *CoinbasePro) FetchTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) { +func (c *CoinbasePro) FetchTicker(ctx context.Context, p currency.Pair, assetType asset.Item) (*ticker.Price, error) { tickerNew, err := ticker.GetTicker(c.Name, p, assetType) if err != nil { - return c.UpdateTicker(p, assetType) + return c.UpdateTicker(ctx, p, assetType) } return tickerNew, nil } // FetchOrderbook returns orderbook base on the currency pair -func (c *CoinbasePro) FetchOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (c *CoinbasePro) FetchOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { ob, err := orderbook.Get(c.Name, p, assetType) if err != nil { - return c.UpdateOrderbook(p, assetType) + return c.UpdateOrderbook(ctx, p, assetType) } return ob, nil } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (c *CoinbasePro) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (c *CoinbasePro) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { book := &orderbook.Base{ Exchange: c.Name, Pair: p, @@ -426,7 +427,7 @@ func (c *CoinbasePro) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*o return book, err } - orderbookNew, err := c.GetOrderbook(fpair.String(), 2) + orderbookNew, err := c.GetOrderbook(ctx, fpair.String(), 2) if err != nil { return book, err } @@ -452,24 +453,24 @@ func (c *CoinbasePro) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*o // GetFundingHistory returns funding history, deposits and // withdrawals -func (c *CoinbasePro) GetFundingHistory() ([]exchange.FundHistory, error) { +func (c *CoinbasePro) GetFundingHistory(_ context.Context) ([]exchange.FundHistory, error) { return nil, common.ErrFunctionNotSupported } // GetWithdrawalsHistory returns previous withdrawals data -func (c *CoinbasePro) GetWithdrawalsHistory(cur currency.Code) (resp []exchange.WithdrawalHistory, err error) { +func (c *CoinbasePro) GetWithdrawalsHistory(_ context.Context, _ currency.Code) (resp []exchange.WithdrawalHistory, err error) { return nil, common.ErrNotYetImplemented } // GetRecentTrades returns the most recent trades for a currency and asset -func (c *CoinbasePro) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade.Data, error) { +func (c *CoinbasePro) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { var err error p, err = c.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err } var tradeData []Trade - tradeData, err = c.GetTrades(p.String()) + tradeData, err = c.GetTrades(ctx, p.String()) if err != nil { return nil, err } @@ -502,12 +503,12 @@ func (c *CoinbasePro) GetRecentTrades(p currency.Pair, assetType asset.Item) ([] } // GetHistoricTrades returns historic trade data within the timeframe provided -func (c *CoinbasePro) GetHistoricTrades(_ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { +func (c *CoinbasePro) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { return nil, common.ErrFunctionNotSupported } // SubmitOrder submits a new order -func (c *CoinbasePro) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { +func (c *CoinbasePro) SubmitOrder(ctx context.Context, s *order.Submit) (order.SubmitResponse, error) { var submitOrderResponse order.SubmitResponse if err := s.Validate(); err != nil { return submitOrderResponse, err @@ -521,14 +522,16 @@ func (c *CoinbasePro) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) var response string switch s.Type { case order.Market: - response, err = c.PlaceMarketOrder("", + response, err = c.PlaceMarketOrder(ctx, + "", s.Amount, s.Amount, s.Side.Lower(), fpair.String(), "") case order.Limit: - response, err = c.PlaceLimitOrder("", + response, err = c.PlaceLimitOrder(ctx, + "", s.Price, s.Amount, s.Side.Lower(), @@ -557,33 +560,33 @@ func (c *CoinbasePro) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (c *CoinbasePro) ModifyOrder(action *order.Modify) (order.Modify, error) { +func (c *CoinbasePro) ModifyOrder(ctx context.Context, action *order.Modify) (order.Modify, error) { return order.Modify{}, common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number -func (c *CoinbasePro) CancelOrder(o *order.Cancel) error { +func (c *CoinbasePro) CancelOrder(ctx context.Context, o *order.Cancel) error { if err := o.Validate(o.StandardCancel()); err != nil { return err } - return c.CancelExistingOrder(o.ID) + return c.CancelExistingOrder(ctx, o.ID) } // CancelBatchOrders cancels an orders by their corresponding ID numbers -func (c *CoinbasePro) CancelBatchOrders(o []order.Cancel) (order.CancelBatchResponse, error) { +func (c *CoinbasePro) CancelBatchOrders(ctx context.Context, o []order.Cancel) (order.CancelBatchResponse, error) { return order.CancelBatchResponse{}, common.ErrNotYetImplemented } // CancelAllOrders cancels all orders associated with a currency pair -func (c *CoinbasePro) CancelAllOrders(_ *order.Cancel) (order.CancelAllResponse, error) { +func (c *CoinbasePro) CancelAllOrders(ctx context.Context, _ *order.Cancel) (order.CancelAllResponse, error) { // CancellAllExisting orders returns a list of successful cancellations, we're only interested in failures - _, err := c.CancelAllExistingOrders("") + _, err := c.CancelAllExistingOrders(ctx, "") return order.CancelAllResponse{}, err } // GetOrderInfo returns order information based on order ID -func (c *CoinbasePro) GetOrderInfo(orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { - genOrderDetail, errGo := c.GetOrder(orderID) +func (c *CoinbasePro) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { + genOrderDetail, errGo := c.GetOrder(ctx, orderID) if errGo != nil { return order.Detail{}, fmt.Errorf("error retrieving order %s : %s", orderID, errGo) } @@ -622,7 +625,7 @@ func (c *CoinbasePro) GetOrderInfo(orderID string, pair currency.Pair, assetType RemainingAmount: genOrderDetail.Size - genOrderDetail.FilledSize, Fee: genOrderDetail.FillFees, } - fillResponse, errGF := c.GetFills(orderID, genOrderDetail.ProductID) + fillResponse, errGF := c.GetFills(ctx, orderID, genOrderDetail.ProductID) if errGF != nil { return response, fmt.Errorf("error retrieving the order fills: %s", errGF) } @@ -646,17 +649,20 @@ func (c *CoinbasePro) GetOrderInfo(orderID string, pair currency.Pair, assetType } // GetDepositAddress returns a deposit address for a specified currency -func (c *CoinbasePro) GetDepositAddress(cryptocurrency currency.Code, accountID string) (string, error) { +func (c *CoinbasePro) GetDepositAddress(_ context.Context, _ currency.Code, accountID string) (string, error) { return "", common.ErrFunctionNotSupported } // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is // submitted -func (c *CoinbasePro) WithdrawCryptocurrencyFunds(withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (c *CoinbasePro) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } - resp, err := c.WithdrawCrypto(withdrawRequest.Amount, withdrawRequest.Currency.String(), withdrawRequest.Crypto.Address) + resp, err := c.WithdrawCrypto(ctx, + withdrawRequest.Amount, + withdrawRequest.Currency.String(), + withdrawRequest.Crypto.Address) if err != nil { return nil, err } @@ -667,11 +673,11 @@ func (c *CoinbasePro) WithdrawCryptocurrencyFunds(withdrawRequest *withdraw.Requ // WithdrawFiatFunds returns a withdrawal ID when a withdrawal is // submitted -func (c *CoinbasePro) WithdrawFiatFunds(withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (c *CoinbasePro) WithdrawFiatFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } - paymentMethods, err := c.GetPayMethods() + paymentMethods, err := c.GetPayMethods(ctx) if err != nil { return nil, err } @@ -687,7 +693,10 @@ func (c *CoinbasePro) WithdrawFiatFunds(withdrawRequest *withdraw.Request) (*wit return nil, fmt.Errorf("could not find payment method '%v'. Check the name via the website and try again", withdrawRequest.Fiat.Bank.BankName) } - resp, err := c.WithdrawViaPaymentMethod(withdrawRequest.Amount, withdrawRequest.Currency.String(), selectedWithdrawalMethod.ID) + resp, err := c.WithdrawViaPaymentMethod(ctx, + withdrawRequest.Amount, + withdrawRequest.Currency.String(), + selectedWithdrawalMethod.ID) if err != nil { return nil, err } @@ -699,11 +708,11 @@ func (c *CoinbasePro) WithdrawFiatFunds(withdrawRequest *withdraw.Request) (*wit // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a // withdrawal is submitted -func (c *CoinbasePro) WithdrawFiatFundsToInternationalBank(withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (c *CoinbasePro) WithdrawFiatFundsToInternationalBank(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } - v, err := c.WithdrawFiatFunds(withdrawRequest) + v, err := c.WithdrawFiatFunds(ctx, withdrawRequest) if err != nil { return nil, err } @@ -714,16 +723,16 @@ func (c *CoinbasePro) WithdrawFiatFundsToInternationalBank(withdrawRequest *with } // GetFeeByType returns an estimate of fee based on type of transaction -func (c *CoinbasePro) GetFeeByType(feeBuilder *exchange.FeeBuilder) (float64, error) { +func (c *CoinbasePro) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { if !c.AllowAuthenticatedRequest() && // Todo check connection status feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { feeBuilder.FeeType = exchange.OfflineTradeFee } - return c.GetFee(feeBuilder) + return c.GetFee(ctx, feeBuilder) } // GetActiveOrders retrieves any orders that are active/open -func (c *CoinbasePro) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, error) { +func (c *CoinbasePro) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) { if err := req.Validate(); err != nil { return nil, err } @@ -734,7 +743,8 @@ func (c *CoinbasePro) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Deta return nil, err } - resp, err := c.GetOrders([]string{"open", "pending", "active"}, + resp, err := c.GetOrders(ctx, + []string{"open", "pending", "active"}, fpair.String()) if err != nil { return nil, err @@ -777,7 +787,7 @@ func (c *CoinbasePro) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Deta // GetOrderHistory retrieves account order information // Can Limit response to specific order status -func (c *CoinbasePro) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, error) { +func (c *CoinbasePro) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) { if err := req.Validate(); err != nil { return nil, err } @@ -787,7 +797,8 @@ func (c *CoinbasePro) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Deta if err != nil { return nil, err } - resp, err := c.GetOrders([]string{"done", "settled"}, + resp, err := c.GetOrders(ctx, + []string{"done", "settled"}, fpair.String()) if err != nil { return nil, err @@ -849,7 +860,7 @@ func checkInterval(i time.Duration) (int64, error) { // GetHistoricCandles returns a set of candle between two time periods for a // designated time period -func (c *CoinbasePro) GetHistoricCandles(p currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (c *CoinbasePro) GetHistoricCandles(ctx context.Context, p currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { if err := c.ValidateKline(p, a, interval); err != nil { return kline.Item{}, err } @@ -875,7 +886,8 @@ func (c *CoinbasePro) GetHistoricCandles(p currency.Pair, a asset.Item, start, e return kline.Item{}, err } - history, err := c.GetHistoricRates(formatP.String(), + history, err := c.GetHistoricRates(ctx, + formatP.String(), start.Format(time.RFC3339), end.Format(time.RFC3339), gran) @@ -899,7 +911,7 @@ func (c *CoinbasePro) GetHistoricCandles(p currency.Pair, a asset.Item, start, e } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (c *CoinbasePro) GetHistoricCandlesExtended(p currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (c *CoinbasePro) GetHistoricCandlesExtended(ctx context.Context, p currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { if err := c.ValidateKline(p, a, interval); err != nil { return kline.Item{}, err } @@ -927,7 +939,8 @@ func (c *CoinbasePro) GetHistoricCandlesExtended(p currency.Pair, a asset.Item, for x := range dates.Ranges { var history []History - history, err = c.GetHistoricRates(formattedPair.String(), + history, err = c.GetHistoricRates(ctx, + formattedPair.String(), dates.Ranges[x].Start.Time.Format(time.RFC3339), dates.Ranges[x].End.Time.Format(time.RFC3339), gran) @@ -959,7 +972,7 @@ func (c *CoinbasePro) GetHistoricCandlesExtended(p currency.Pair, a asset.Item, // ValidateCredentials validates current credentials used for wrapper // functionality -func (c *CoinbasePro) ValidateCredentials(assetType asset.Item) error { - _, err := c.UpdateAccountInfo(assetType) +func (c *CoinbasePro) ValidateCredentials(ctx context.Context, assetType asset.Item) error { + _, err := c.UpdateAccountInfo(ctx, assetType) return c.CheckTransientError(err) } diff --git a/exchanges/coinbene/coinbene.go b/exchanges/coinbene/coinbene.go index 4a142c70..44a16a39 100644 --- a/exchanges/coinbene/coinbene.go +++ b/exchanges/coinbene/coinbene.go @@ -77,27 +77,27 @@ const ( ) // GetAllPairs gets all pairs on the exchange -func (c *Coinbene) GetAllPairs() ([]PairData, error) { +func (c *Coinbene) GetAllPairs(ctx context.Context) ([]PairData, error) { resp := struct { Data []PairData `json:"data"` }{} path := coinbeneAPIVersion + coinbeneGetAllPairs - return resp.Data, c.SendHTTPRequest(exchange.RestSpot, path, spotPairs, &resp) + return resp.Data, c.SendHTTPRequest(ctx, exchange.RestSpot, path, spotPairs, &resp) } // GetPairInfo gets info about a single pair -func (c *Coinbene) GetPairInfo(symbol string) (PairData, error) { +func (c *Coinbene) GetPairInfo(ctx context.Context, symbol string) (PairData, error) { resp := struct { Data PairData `json:"data"` }{} params := url.Values{} params.Set("symbol", symbol) path := common.EncodeURLValues(coinbeneAPIVersion+coinbenePairInfo, params) - return resp.Data, c.SendHTTPRequest(exchange.RestSpot, path, spotPairInfo, &resp) + return resp.Data, c.SendHTTPRequest(ctx, exchange.RestSpot, path, spotPairInfo, &resp) } // GetOrderbook gets and stores orderbook data for given pair -func (c *Coinbene) GetOrderbook(symbol string, size int64) (Orderbook, error) { +func (c *Coinbene) GetOrderbook(ctx context.Context, symbol string, size int64) (Orderbook, error) { resp := struct { Data struct { Asks [][]string `json:"asks"` @@ -110,7 +110,7 @@ func (c *Coinbene) GetOrderbook(symbol string, size int64) (Orderbook, error) { params.Set("symbol", symbol) params.Set("depth", strconv.FormatInt(size, 10)) path := common.EncodeURLValues(coinbeneAPIVersion+coinbeneGetOrderBook, params) - err := c.SendHTTPRequest(exchange.RestSpot, path, spotOrderbook, &resp) + err := c.SendHTTPRequest(ctx, exchange.RestSpot, path, spotOrderbook, &resp) if err != nil { return Orderbook{}, err } @@ -149,28 +149,28 @@ func (c *Coinbene) GetOrderbook(symbol string, size int64) (Orderbook, error) { } // GetTicker gets and stores ticker data for a currency pair -func (c *Coinbene) GetTicker(symbol string) (TickerData, error) { +func (c *Coinbene) GetTicker(ctx context.Context, symbol string) (TickerData, error) { resp := struct { TickerData TickerData `json:"data"` }{} params := url.Values{} params.Set("symbol", symbol) path := common.EncodeURLValues(coinbeneAPIVersion+coinbeneGetTicker, params) - return resp.TickerData, c.SendHTTPRequest(exchange.RestSpot, path, spotSpecificTicker, &resp) + return resp.TickerData, c.SendHTTPRequest(ctx, exchange.RestSpot, path, spotSpecificTicker, &resp) } // GetTickers gets and all spot tickers supported by the exchange -func (c *Coinbene) GetTickers() ([]TickerData, error) { +func (c *Coinbene) GetTickers(ctx context.Context) ([]TickerData, error) { resp := struct { TickerData []TickerData `json:"data"` }{} path := coinbeneAPIVersion + coinbeneGetTickersSpot - return resp.TickerData, c.SendHTTPRequest(exchange.RestSpot, path, spotTickerList, &resp) + return resp.TickerData, c.SendHTTPRequest(ctx, exchange.RestSpot, path, spotTickerList, &resp) } // GetTrades gets recent trades from the exchange -func (c *Coinbene) GetTrades(symbol string, limit int64) (Trades, error) { +func (c *Coinbene) GetTrades(ctx context.Context, symbol string, limit int64) (Trades, error) { resp := struct { Data [][]string `json:"data"` }{} @@ -179,7 +179,7 @@ func (c *Coinbene) GetTrades(symbol string, limit int64) (Trades, error) { params.Set("symbol", symbol) params.Set("limit", strconv.FormatInt(limit, 10)) path := common.EncodeURLValues(coinbeneAPIVersion+coinbeneGetTrades, params) - err := c.SendHTTPRequest(exchange.RestSpot, path, spotMarketTrades, &resp) + err := c.SendHTTPRequest(ctx, exchange.RestSpot, path, spotMarketTrades, &resp) if err != nil { return nil, err } @@ -210,12 +210,12 @@ func (c *Coinbene) GetTrades(symbol string, limit int64) (Trades, error) { } // GetAccountBalances gets user balanace info -func (c *Coinbene) GetAccountBalances() ([]UserBalanceData, error) { +func (c *Coinbene) GetAccountBalances(ctx context.Context) ([]UserBalanceData, error) { resp := struct { Data []UserBalanceData `json:"data"` }{} path := coinbeneAPIVersion + coinbeneGetUserBalance - err := c.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, + err := c.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, path, coinbeneGetUserBalance, false, @@ -229,14 +229,16 @@ func (c *Coinbene) GetAccountBalances() ([]UserBalanceData, error) { } // GetAccountAssetBalance gets user balanace info -func (c *Coinbene) GetAccountAssetBalance(symbol string) (UserBalanceData, error) { +func (c *Coinbene) GetAccountAssetBalance(ctx context.Context, symbol string) (UserBalanceData, error) { v := url.Values{} v.Set("asset", symbol) resp := struct { Data UserBalanceData `json:"data"` }{} path := coinbeneAPIVersion + coinbeneAccountBalanceOne - err := c.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, + err := c.SendAuthHTTPRequest(ctx, + exchange.RestSpot, + http.MethodGet, path, coinbeneAccountBalanceOne, false, @@ -250,7 +252,7 @@ func (c *Coinbene) GetAccountAssetBalance(symbol string) (UserBalanceData, error } // PlaceSpotOrder creates an order -func (c *Coinbene) PlaceSpotOrder(price, quantity float64, symbol, direction, +func (c *Coinbene) PlaceSpotOrder(ctx context.Context, price, quantity float64, symbol, direction, orderType, clientID string, notional int) (OrderPlacementResponse, error) { var resp OrderPlacementResponse params := url.Values{} @@ -291,7 +293,7 @@ func (c *Coinbene) PlaceSpotOrder(price, quantity float64, symbol, direction, params.Set("notional", strconv.Itoa(notional)) } path := coinbeneAPIVersion + coinbenePlaceOrder - err := c.SendAuthHTTPRequest(exchange.RestSpot, http.MethodPost, + err := c.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, path, coinbenePlaceOrder, false, @@ -305,7 +307,7 @@ func (c *Coinbene) PlaceSpotOrder(price, quantity float64, symbol, direction, } // PlaceSpotOrders sets a batchful order request -func (c *Coinbene) PlaceSpotOrders(orders []PlaceOrderRequest) ([]OrderPlacementResponse, error) { +func (c *Coinbene) PlaceSpotOrders(ctx context.Context, orders []PlaceOrderRequest) ([]OrderPlacementResponse, error) { if len(orders) == 0 { return nil, errors.New("orders is nil") } @@ -361,7 +363,9 @@ func (c *Coinbene) PlaceSpotOrders(orders []PlaceOrderRequest) ([]OrderPlacement Data []OrderPlacementResponse `json:"data"` }{} path := coinbeneAPIVersion + coinbeneBatchPlaceOrder - err := c.SendAuthHTTPRequest(exchange.RestSpot, http.MethodPost, + err := c.SendAuthHTTPRequest(ctx, + exchange.RestSpot, + http.MethodPost, path, coinbeneBatchPlaceOrder, false, @@ -375,7 +379,7 @@ func (c *Coinbene) PlaceSpotOrders(orders []PlaceOrderRequest) ([]OrderPlacement } // FetchOpenSpotOrders finds open orders -func (c *Coinbene) FetchOpenSpotOrders(symbol string) (OrdersInfo, error) { +func (c *Coinbene) FetchOpenSpotOrders(ctx context.Context, symbol string) (OrdersInfo, error) { params := url.Values{} params.Set("symbol", symbol) path := coinbeneAPIVersion + coinbeneOpenOrders @@ -385,7 +389,7 @@ func (c *Coinbene) FetchOpenSpotOrders(symbol string) (OrdersInfo, error) { Data OrdersInfo `json:"data"` }{} params.Set("pageNum", strconv.FormatInt(i, 10)) - err := c.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, + err := c.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, path, coinbeneOpenOrders, false, @@ -407,7 +411,7 @@ func (c *Coinbene) FetchOpenSpotOrders(symbol string) (OrdersInfo, error) { } // FetchClosedOrders finds open orders -func (c *Coinbene) FetchClosedOrders(symbol, latestID string) (OrdersInfo, error) { +func (c *Coinbene) FetchClosedOrders(ctx context.Context, symbol, latestID string) (OrdersInfo, error) { params := url.Values{} params.Set("symbol", symbol) params.Set("latestOrderId", latestID) @@ -418,7 +422,9 @@ func (c *Coinbene) FetchClosedOrders(symbol, latestID string) (OrdersInfo, error Data OrdersInfo `json:"data"` }{} params.Set("pageNum", strconv.FormatInt(i, 10)) - err := c.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, + err := c.SendAuthHTTPRequest(ctx, + exchange.RestSpot, + http.MethodGet, path, coinbeneClosedOrders, false, @@ -439,14 +445,16 @@ func (c *Coinbene) FetchClosedOrders(symbol, latestID string) (OrdersInfo, error } // FetchSpotOrderInfo gets order info -func (c *Coinbene) FetchSpotOrderInfo(orderID string) (OrderInfo, error) { +func (c *Coinbene) FetchSpotOrderInfo(ctx context.Context, orderID string) (OrderInfo, error) { resp := struct { Data OrderInfo `json:"data"` }{} params := url.Values{} params.Set("orderId", orderID) path := coinbeneAPIVersion + coinbeneOrderInfo - err := c.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, + err := c.SendAuthHTTPRequest(ctx, + exchange.RestSpot, + http.MethodGet, path, coinbeneOrderInfo, false, @@ -464,14 +472,16 @@ func (c *Coinbene) FetchSpotOrderInfo(orderID string) (OrderInfo, error) { } // GetSpotOrderFills returns a list of fills related to an order ID -func (c *Coinbene) GetSpotOrderFills(orderID string) ([]OrderFills, error) { +func (c *Coinbene) GetSpotOrderFills(ctx context.Context, orderID string) ([]OrderFills, error) { resp := struct { Data []OrderFills `json:"data"` }{} params := url.Values{} params.Set("orderId", orderID) path := coinbeneAPIVersion + coinbeneTradeFills - err := c.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, + err := c.SendAuthHTTPRequest(ctx, + exchange.RestSpot, + http.MethodGet, path, coinbeneTradeFills, false, @@ -485,14 +495,16 @@ func (c *Coinbene) GetSpotOrderFills(orderID string) ([]OrderFills, error) { } // CancelSpotOrder removes a given order -func (c *Coinbene) CancelSpotOrder(orderID string) (string, error) { +func (c *Coinbene) CancelSpotOrder(ctx context.Context, orderID string) (string, error) { resp := struct { Data string `json:"data"` }{} req := make(map[string]interface{}) req["orderId"] = orderID path := coinbeneAPIVersion + coinbeneCancelOrder - err := c.SendAuthHTTPRequest(exchange.RestSpot, http.MethodPost, + err := c.SendAuthHTTPRequest(ctx, + exchange.RestSpot, + http.MethodPost, path, coinbeneCancelOrder, false, @@ -506,7 +518,7 @@ func (c *Coinbene) CancelSpotOrder(orderID string) (string, error) { } // CancelSpotOrders cancels a batch of orders -func (c *Coinbene) CancelSpotOrders(orderIDs []string) ([]OrderCancellationResponse, error) { +func (c *Coinbene) CancelSpotOrders(ctx context.Context, orderIDs []string) ([]OrderCancellationResponse, error) { req := make(map[string]interface{}) req["orderIds"] = orderIDs type resp struct { @@ -515,7 +527,9 @@ func (c *Coinbene) CancelSpotOrders(orderIDs []string) ([]OrderCancellationRespo var r resp path := coinbeneAPIVersion + coinbeneBatchCancel - err := c.SendAuthHTTPRequest(exchange.RestSpot, http.MethodPost, + err := c.SendAuthHTTPRequest(ctx, + exchange.RestSpot, + http.MethodPost, path, coinbeneBatchCancel, false, @@ -529,13 +543,13 @@ func (c *Coinbene) CancelSpotOrders(orderIDs []string) ([]OrderCancellationRespo } // GetSwapTickers returns a map of swap tickers -func (c *Coinbene) GetSwapTickers() (SwapTickers, error) { +func (c *Coinbene) GetSwapTickers(ctx context.Context) (SwapTickers, error) { type resp struct { Data SwapTickers `json:"data"` } var r resp path := coinbeneAPIVersion + coinbeneGetTickers - err := c.SendHTTPRequest(exchange.RestSwap, path, contractTickers, &r) + err := c.SendHTTPRequest(ctx, exchange.RestSwap, path, contractTickers, &r) if err != nil { return nil, err } @@ -543,8 +557,8 @@ func (c *Coinbene) GetSwapTickers() (SwapTickers, error) { } // GetSwapTicker returns a specific swap ticker -func (c *Coinbene) GetSwapTicker(symbol string) (SwapTicker, error) { - tickers, err := c.GetSwapTickers() +func (c *Coinbene) GetSwapTicker(ctx context.Context, symbol string) (SwapTicker, error) { + tickers, err := c.GetSwapTickers(ctx) if err != nil { return SwapTicker{}, err } @@ -557,16 +571,20 @@ func (c *Coinbene) GetSwapTicker(symbol string) (SwapTicker, error) { } // GetSwapInstruments returns a list of tradable instruments -func (c *Coinbene) GetSwapInstruments() ([]Instrument, error) { +func (c *Coinbene) GetSwapInstruments(ctx context.Context) ([]Instrument, error) { resp := struct { Data []Instrument `json:"data"` }{} - return resp.Data, c.SendHTTPRequest(exchange.RestSwap, - coinbeneAPIVersion+coinbeneGetInstruments, contractInstruments, &resp) + return resp.Data, + c.SendHTTPRequest(ctx, + exchange.RestSwap, + coinbeneAPIVersion+coinbeneGetInstruments, + contractInstruments, + &resp) } // GetSwapOrderbook returns an orderbook for the specified currency -func (c *Coinbene) GetSwapOrderbook(symbol string, size int64) (Orderbook, error) { +func (c *Coinbene) GetSwapOrderbook(ctx context.Context, symbol string, size int64) (Orderbook, error) { var s Orderbook if symbol == "" { return s, fmt.Errorf("a symbol must be specified") @@ -589,7 +607,7 @@ func (c *Coinbene) GetSwapOrderbook(symbol string, size int64) (Orderbook, error var r resp path := common.EncodeURLValues(coinbeneAPIVersion+coinbeneGetOrderBook, v) - err := c.SendHTTPRequest(exchange.RestSwap, path, contractOrderbook, &r) + err := c.SendHTTPRequest(ctx, exchange.RestSwap, path, contractOrderbook, &r) if err != nil { return s, err } @@ -633,7 +651,7 @@ func (c *Coinbene) GetSwapOrderbook(symbol string, size int64) (Orderbook, error } // GetKlines data returns the kline data for a specific symbol -func (c *Coinbene) GetKlines(pair string, start, end time.Time, period string) (resp CandleResponse, err error) { +func (c *Coinbene) GetKlines(ctx context.Context, pair string, start, end time.Time, period string) (resp CandleResponse, err error) { v := url.Values{} v.Add("symbol", pair) if !start.IsZero() { @@ -645,7 +663,7 @@ func (c *Coinbene) GetKlines(pair string, start, end time.Time, period string) ( v.Add("period", period) path := common.EncodeURLValues(coinbeneAPIVersion+coinbeneSpotKlines, v) - if err = c.SendHTTPRequest(exchange.RestSpot, path, contractKline, &resp); err != nil { + if err = c.SendHTTPRequest(ctx, exchange.RestSpot, path, contractKline, &resp); err != nil { return } @@ -657,7 +675,7 @@ func (c *Coinbene) GetKlines(pair string, start, end time.Time, period string) ( } // GetSwapKlines data returns the kline data for a specific symbol -func (c *Coinbene) GetSwapKlines(symbol string, start, end time.Time, resolution string) (resp CandleResponse, err error) { +func (c *Coinbene) GetSwapKlines(ctx context.Context, symbol string, start, end time.Time, resolution string) (resp CandleResponse, err error) { v := url.Values{} v.Set("symbol", symbol) if !start.IsZero() { @@ -669,7 +687,7 @@ func (c *Coinbene) GetSwapKlines(symbol string, start, end time.Time, resolution v.Set("resolution", resolution) path := common.EncodeURLValues(coinbeneAPIVersion+coinbeneGetKlines, v) - if err = c.SendHTTPRequest(exchange.RestSwap, path, contractKline, &resp); err != nil { + if err = c.SendHTTPRequest(ctx, exchange.RestSwap, path, contractKline, &resp); err != nil { return } @@ -677,7 +695,7 @@ func (c *Coinbene) GetSwapKlines(symbol string, start, end time.Time, resolution } // GetSwapTrades returns a list of trades for a swap symbol -func (c *Coinbene) GetSwapTrades(symbol string, limit int) (SwapTrades, error) { +func (c *Coinbene) GetSwapTrades(ctx context.Context, symbol string, limit int) (SwapTrades, error) { v := url.Values{} v.Set("symbol", symbol) if limit != 0 { @@ -688,7 +706,7 @@ func (c *Coinbene) GetSwapTrades(symbol string, limit int) (SwapTrades, error) { } var r resp path := common.EncodeURLValues(coinbeneAPIVersion+coinbeneGetTrades, v) - if err := c.SendHTTPRequest(exchange.RestSwap, path, contractTrades, &r); err != nil { + if err := c.SendHTTPRequest(ctx, exchange.RestSwap, path, contractTrades, &r); err != nil { return nil, err } @@ -721,13 +739,13 @@ func (c *Coinbene) GetSwapTrades(symbol string, limit int) (SwapTrades, error) { } // GetSwapAccountInfo returns a users swap account balance info -func (c *Coinbene) GetSwapAccountInfo() (SwapAccountInfo, error) { +func (c *Coinbene) GetSwapAccountInfo(ctx context.Context) (SwapAccountInfo, error) { type resp struct { Data SwapAccountInfo `json:"data"` } var r resp path := coinbeneAPIVersion + coinbeneAccountInfo - err := c.SendAuthHTTPRequest(exchange.RestSwap, http.MethodGet, + err := c.SendAuthHTTPRequest(ctx, exchange.RestSwap, http.MethodGet, path, coinbeneAccountInfo, true, @@ -741,7 +759,7 @@ func (c *Coinbene) GetSwapAccountInfo() (SwapAccountInfo, error) { } // GetSwapPositions returns a list of open swap positions -func (c *Coinbene) GetSwapPositions(symbol string) (SwapPositions, error) { +func (c *Coinbene) GetSwapPositions(ctx context.Context, symbol string) (SwapPositions, error) { v := url.Values{} v.Set("symbol", symbol) type resp struct { @@ -749,7 +767,7 @@ func (c *Coinbene) GetSwapPositions(symbol string) (SwapPositions, error) { } var r resp path := coinbeneAPIVersion + coinbeneListSwapPositions - err := c.SendAuthHTTPRequest(exchange.RestSwap, http.MethodGet, + err := c.SendAuthHTTPRequest(ctx, exchange.RestSwap, http.MethodGet, path, coinbeneListSwapPositions, true, @@ -763,7 +781,7 @@ func (c *Coinbene) GetSwapPositions(symbol string) (SwapPositions, error) { } // PlaceSwapOrder places a swap order -func (c *Coinbene) PlaceSwapOrder(symbol, direction, orderType, marginMode, +func (c *Coinbene) PlaceSwapOrder(ctx context.Context, symbol, direction, orderType, marginMode, clientID string, price, quantity float64, leverage int) (SwapPlaceOrderResponse, error) { v := url.Values{} v.Set("symbol", symbol) @@ -804,7 +822,9 @@ func (c *Coinbene) PlaceSwapOrder(symbol, direction, orderType, marginMode, } var r resp path := coinbeneAPIVersion + coinbenePlaceOrder - err := c.SendAuthHTTPRequest(exchange.RestSwap, http.MethodPost, + err := c.SendAuthHTTPRequest(ctx, + exchange.RestSwap, + http.MethodPost, path, coinbenePlaceOrder, true, @@ -818,7 +838,7 @@ func (c *Coinbene) PlaceSwapOrder(symbol, direction, orderType, marginMode, } // CancelSwapOrder cancels a swap order -func (c *Coinbene) CancelSwapOrder(orderID string) (string, error) { +func (c *Coinbene) CancelSwapOrder(ctx context.Context, orderID string) (string, error) { params := make(map[string]interface{}) params["orderId"] = orderID type resp struct { @@ -826,7 +846,7 @@ func (c *Coinbene) CancelSwapOrder(orderID string) (string, error) { } var r resp path := coinbeneAPIVersion + coinbeneCancelOrder - err := c.SendAuthHTTPRequest(exchange.RestSwap, http.MethodPost, + err := c.SendAuthHTTPRequest(ctx, exchange.RestSwap, http.MethodPost, path, coinbeneCancelOrder, true, @@ -840,7 +860,7 @@ func (c *Coinbene) CancelSwapOrder(orderID string) (string, error) { } // GetSwapOpenOrders gets a list of open swap orders -func (c *Coinbene) GetSwapOpenOrders(symbol string, pageNum, pageSize int) (SwapOrders, error) { +func (c *Coinbene) GetSwapOpenOrders(ctx context.Context, symbol string, pageNum, pageSize int) (SwapOrders, error) { v := url.Values{} v.Set("symbol", symbol) if pageNum != 0 { @@ -854,7 +874,9 @@ func (c *Coinbene) GetSwapOpenOrders(symbol string, pageNum, pageSize int) (Swap } var r resp path := coinbeneAPIVersion + coinbeneOpenOrders - err := c.SendAuthHTTPRequest(exchange.RestSwap, http.MethodGet, + err := c.SendAuthHTTPRequest(ctx, + exchange.RestSwap, + http.MethodGet, path, coinbeneOpenOrders, true, @@ -868,7 +890,7 @@ func (c *Coinbene) GetSwapOpenOrders(symbol string, pageNum, pageSize int) (Swap } // GetSwapOpenOrdersByPage gets a list of open orders by page -func (c *Coinbene) GetSwapOpenOrdersByPage(symbol string, latestOrderID int64) (SwapOrders, error) { +func (c *Coinbene) GetSwapOpenOrdersByPage(ctx context.Context, symbol string, latestOrderID int64) (SwapOrders, error) { v := url.Values{} if symbol != "" { v.Set("symbol", symbol) @@ -881,7 +903,9 @@ func (c *Coinbene) GetSwapOpenOrdersByPage(symbol string, latestOrderID int64) ( } var r resp path := coinbeneAPIVersion + coinbeneOpenOrdersByPage - err := c.SendAuthHTTPRequest(exchange.RestSwap, http.MethodGet, + err := c.SendAuthHTTPRequest(ctx, + exchange.RestSwap, + http.MethodGet, path, coinbeneOpenOrdersByPage, true, @@ -895,7 +919,7 @@ func (c *Coinbene) GetSwapOpenOrdersByPage(symbol string, latestOrderID int64) ( } // GetSwapOrderInfo gets order info for a specific order -func (c *Coinbene) GetSwapOrderInfo(orderID string) (SwapOrder, error) { +func (c *Coinbene) GetSwapOrderInfo(ctx context.Context, orderID string) (SwapOrder, error) { v := url.Values{} v.Set("orderId", orderID) type resp struct { @@ -903,7 +927,9 @@ func (c *Coinbene) GetSwapOrderInfo(orderID string) (SwapOrder, error) { } var r resp path := coinbeneAPIVersion + coinbeneOrderInfo - err := c.SendAuthHTTPRequest(exchange.RestSwap, http.MethodGet, + err := c.SendAuthHTTPRequest(ctx, + exchange.RestSwap, + http.MethodGet, path, coinbeneOrderInfo, true, @@ -917,7 +943,7 @@ func (c *Coinbene) GetSwapOrderInfo(orderID string) (SwapOrder, error) { } // GetSwapOrderHistory returns the swap order history for a given symbol -func (c *Coinbene) GetSwapOrderHistory(beginTime, endTime, symbol string, pageNum, +func (c *Coinbene) GetSwapOrderHistory(ctx context.Context, beginTime, endTime, symbol string, pageNum, pageSize int, direction, orderType string) (SwapOrders, error) { v := url.Values{} if beginTime != "" { @@ -946,7 +972,7 @@ func (c *Coinbene) GetSwapOrderHistory(beginTime, endTime, symbol string, pageNu var r resp path := coinbeneAPIVersion + coinbeneClosedOrders - err := c.SendAuthHTTPRequest(exchange.RestSwap, http.MethodGet, + err := c.SendAuthHTTPRequest(ctx, exchange.RestSwap, http.MethodGet, path, coinbeneClosedOrders, true, @@ -960,7 +986,7 @@ func (c *Coinbene) GetSwapOrderHistory(beginTime, endTime, symbol string, pageNu } // GetSwapOrderHistoryByOrderID returns a list of historic orders based on user params -func (c *Coinbene) GetSwapOrderHistoryByOrderID(beginTime, endTime, symbol, status string, +func (c *Coinbene) GetSwapOrderHistoryByOrderID(ctx context.Context, beginTime, endTime, symbol, status string, latestOrderID int64) (SwapOrders, error) { v := url.Values{} if beginTime != "" { @@ -984,7 +1010,9 @@ func (c *Coinbene) GetSwapOrderHistoryByOrderID(beginTime, endTime, symbol, stat var r resp path := coinbeneAPIVersion + coinbeneClosedOrdersByPage - err := c.SendAuthHTTPRequest(exchange.RestSwap, http.MethodGet, + err := c.SendAuthHTTPRequest(ctx, + exchange.RestSwap, + http.MethodGet, path, coinbeneClosedOrdersByPage, true, @@ -998,7 +1026,7 @@ func (c *Coinbene) GetSwapOrderHistoryByOrderID(beginTime, endTime, symbol, stat } // CancelSwapOrders cancels multiple swap order IDs -func (c *Coinbene) CancelSwapOrders(orderIDs []string) ([]OrderCancellationResponse, error) { +func (c *Coinbene) CancelSwapOrders(ctx context.Context, orderIDs []string) ([]OrderCancellationResponse, error) { if len(orderIDs) > 10 { return nil, errors.New("only 10 orderIDs are allowed at a time") } @@ -1010,7 +1038,9 @@ func (c *Coinbene) CancelSwapOrders(orderIDs []string) ([]OrderCancellationRespo var r resp path := coinbeneAPIVersion + coinbeneBatchCancel - err := c.SendAuthHTTPRequest(exchange.RestSwap, http.MethodPost, + err := c.SendAuthHTTPRequest(ctx, + exchange.RestSwap, + http.MethodPost, path, coinbeneBatchCancel, true, @@ -1024,7 +1054,7 @@ func (c *Coinbene) CancelSwapOrders(orderIDs []string) ([]OrderCancellationRespo } // GetSwapOrderFills returns a list of swap order fills -func (c *Coinbene) GetSwapOrderFills(symbol, orderID string, lastTradeID int64) (SwapOrderFills, error) { +func (c *Coinbene) GetSwapOrderFills(ctx context.Context, symbol, orderID string, lastTradeID int64) (SwapOrderFills, error) { v := url.Values{} if symbol != "" { v.Set("symbol", symbol) @@ -1041,7 +1071,9 @@ func (c *Coinbene) GetSwapOrderFills(symbol, orderID string, lastTradeID int64) var r resp path := coinbeneAPIVersion + coinbeneOrderFills - err := c.SendAuthHTTPRequest(exchange.RestSwap, http.MethodGet, + err := c.SendAuthHTTPRequest(ctx, + exchange.RestSwap, + http.MethodGet, path, coinbeneOrderFills, true, @@ -1055,7 +1087,7 @@ func (c *Coinbene) GetSwapOrderFills(symbol, orderID string, lastTradeID int64) } // GetSwapFundingRates returns a list of funding rates -func (c *Coinbene) GetSwapFundingRates(pageNum, pageSize int) ([]SwapFundingRate, error) { +func (c *Coinbene) GetSwapFundingRates(ctx context.Context, pageNum, pageSize int) ([]SwapFundingRate, error) { v := url.Values{} if pageNum != 0 { v.Set("pageNum", strconv.Itoa(pageNum)) @@ -1069,7 +1101,9 @@ func (c *Coinbene) GetSwapFundingRates(pageNum, pageSize int) ([]SwapFundingRate var r resp path := coinbeneAPIVersion + coinbenePositionFeeRate - err := c.SendAuthHTTPRequest(exchange.RestSwap, http.MethodGet, + err := c.SendAuthHTTPRequest(ctx, + exchange.RestSwap, + http.MethodGet, path, coinbenePositionFeeRate, true, @@ -1083,7 +1117,7 @@ func (c *Coinbene) GetSwapFundingRates(pageNum, pageSize int) ([]SwapFundingRate } // SendHTTPRequest sends an unauthenticated HTTP request -func (c *Coinbene) SendHTTPRequest(ep exchange.URL, path string, f request.EndpointLimit, result interface{}) error { +func (c *Coinbene) SendHTTPRequest(ctx context.Context, ep exchange.URL, path string, f request.EndpointLimit, result interface{}) error { endpoint, err := c.API.Endpoints.GetURL(ep) if err != nil { return err @@ -1098,7 +1132,7 @@ func (c *Coinbene) SendHTTPRequest(ep exchange.URL, path string, f request.Endpo HTTPDebugging: c.HTTPDebugging, HTTPRecording: c.HTTPRecording, } - if err := c.SendPayload(context.Background(), f, func() (*request.Item, error) { + if err := c.SendPayload(ctx, f, func() (*request.Item, error) { return item, nil }); err != nil { return err @@ -1117,7 +1151,7 @@ func (c *Coinbene) SendHTTPRequest(ep exchange.URL, path string, f request.Endpo } // SendAuthHTTPRequest sends an authenticated HTTP request -func (c *Coinbene) SendAuthHTTPRequest(ep exchange.URL, method, path, epPath string, isSwap bool, +func (c *Coinbene) SendAuthHTTPRequest(ctx context.Context, ep exchange.URL, method, path, epPath string, isSwap bool, params, result interface{}, f request.EndpointLimit) error { if !c.AllowAuthenticatedRequest() { return fmt.Errorf("%s %w", c.Name, exchange.ErrAuthenticatedRequestWithoutCredentialsSet) @@ -1192,7 +1226,7 @@ func (c *Coinbene) SendAuthHTTPRequest(ep exchange.URL, method, path, epPath str }, nil } - if err := c.SendPayload(context.Background(), f, newRequest); err != nil { + if err := c.SendPayload(ctx, f, newRequest); err != nil { return err } diff --git a/exchanges/coinbene/coinbene_test.go b/exchanges/coinbene/coinbene_test.go index 0b41b006..61de7945 100644 --- a/exchanges/coinbene/coinbene_test.go +++ b/exchanges/coinbene/coinbene_test.go @@ -1,6 +1,7 @@ package coinbene import ( + "context" "log" "os" "testing" @@ -55,7 +56,7 @@ func areTestAPIKeysSet() bool { func TestGetAllPairs(t *testing.T) { t.Parallel() - _, err := c.GetAllPairs() + _, err := c.GetAllPairs(context.Background()) if err != nil { t.Error(err) } @@ -63,7 +64,7 @@ func TestGetAllPairs(t *testing.T) { func TestGetPairInfo(t *testing.T) { t.Parallel() - _, err := c.GetPairInfo(spotTestPair) + _, err := c.GetPairInfo(context.Background(), spotTestPair) if err != nil { t.Error(err) } @@ -71,7 +72,7 @@ func TestGetPairInfo(t *testing.T) { func TestGetOrderbook(t *testing.T) { t.Parallel() - _, err := c.GetOrderbook(spotTestPair, 100) + _, err := c.GetOrderbook(context.Background(), spotTestPair, 100) if err != nil { t.Error(err) } @@ -79,7 +80,7 @@ func TestGetOrderbook(t *testing.T) { func TestGetTicker(t *testing.T) { t.Parallel() - _, err := c.GetTicker(spotTestPair) + _, err := c.GetTicker(context.Background(), spotTestPair) if err != nil { t.Error(err) } @@ -87,7 +88,7 @@ func TestGetTicker(t *testing.T) { func TestGetTrades(t *testing.T) { t.Parallel() - _, err := c.GetTrades(spotTestPair, 100) + _, err := c.GetTrades(context.Background(), spotTestPair, 100) if err != nil { t.Error(err) } @@ -98,7 +99,7 @@ func TestGetAcounntBalances(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys required but not set, skipping test") } - _, err := c.GetAccountBalances() + _, err := c.GetAccountBalances(context.Background()) if err != nil { t.Error(err) } @@ -109,7 +110,7 @@ func TestGetAccountAssetBalance(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys required but not set, skipping test") } - _, err := c.GetAccountAssetBalance(currency.BTC.String()) + _, err := c.GetAccountAssetBalance(context.Background(), currency.BTC.String()) if err != nil { t.Error(err) } @@ -120,7 +121,7 @@ func TestPlaceOrder(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test, either api keys or manipulaterealorders isnt set correctly") } - _, err := c.PlaceSpotOrder( + _, err := c.PlaceSpotOrder(context.Background(), 1, 1, spotTestPair, @@ -140,7 +141,7 @@ func TestPlaceOrders(t *testing.T) { t.Skip("skipping test, either api keys or manipulaterealorders isnt set correctly") } - _, err := c.PlaceSpotOrders( + _, err := c.PlaceSpotOrders(context.Background(), []PlaceOrderRequest{ { 1, @@ -162,7 +163,7 @@ func TestFetchOpenOrders(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys required but not set, skipping test") } - _, err := c.FetchOpenSpotOrders(spotTestPair) + _, err := c.FetchOpenSpotOrders(context.Background(), spotTestPair) if err != nil { t.Error(err) } @@ -173,7 +174,7 @@ func TestFetchClosedOrders(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys required but not set, skipping test") } - _, err := c.FetchClosedOrders(spotTestPair, "") + _, err := c.FetchClosedOrders(context.Background(), spotTestPair, "") if err != nil { t.Error(err) } @@ -184,7 +185,7 @@ func TestFetchOrderInfo(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys required but not set, skipping test") } - _, err := c.FetchSpotOrderInfo("adfjashjgsag") + _, err := c.FetchSpotOrderInfo(context.Background(), "adfjashjgsag") if err != nil { t.Error(err) } @@ -195,7 +196,7 @@ func TestGetSpotOrderFills(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys required but not set, skipping test") } - _, err := c.GetSpotOrderFills("1912131427156307968") + _, err := c.GetSpotOrderFills(context.Background(), "1912131427156307968") if err != nil { t.Error(err) } @@ -206,7 +207,7 @@ func TestCancelSpotOrder(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test, either api keys or manipulaterealorders isnt set correctly") } - _, err := c.CancelSpotOrder("adfjashjgsag") + _, err := c.CancelSpotOrder(context.Background(), "adfjashjgsag") if err != nil { t.Error(err) } @@ -218,7 +219,8 @@ func TestCancelSpotOrders(t *testing.T) { t.Skip("skipping test, either api keys or manipulaterealorders isnt set correctly") } - _, err := c.CancelSpotOrders([]string{"578639816552972288", "578639902896914432"}) + _, err := c.CancelSpotOrders(context.Background(), + []string{"578639816552972288", "578639902896914432"}) if err != nil { t.Error(err) } @@ -230,7 +232,7 @@ func TestUpdateTicker(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = c.UpdateTicker(cp, asset.Spot) + _, err = c.UpdateTicker(context.Background(), cp, asset.Spot) if err != nil { t.Error(err) } @@ -238,7 +240,7 @@ func TestUpdateTicker(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = c.UpdateTicker(cp, asset.PerpetualSwap) + _, err = c.UpdateTicker(context.Background(), cp, asset.PerpetualSwap) if err != nil { t.Error(err) } @@ -248,12 +250,12 @@ func TestUpdateTickers(t *testing.T) { // TODO: fix Coinbene rate limiting that will allow to uncomment the next line // and enable parallel testing // t.Parallel() - err := c.UpdateTickers(asset.Spot) + err := c.UpdateTickers(context.Background(), asset.Spot) if err != nil { t.Error(err) } - err = c.UpdateTickers(asset.PerpetualSwap) + err = c.UpdateTickers(context.Background(), asset.PerpetualSwap) if err != nil { t.Error(err) } @@ -264,7 +266,7 @@ func TestGetAccountInfo(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys required but not set, skipping test") } - _, err := c.UpdateAccountInfo(asset.Spot) + _, err := c.UpdateAccountInfo(context.Background(), asset.Spot) if err != nil { t.Error(err) } @@ -276,7 +278,7 @@ func TestUpdateOrderbook(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = c.UpdateOrderbook(cp, asset.Spot) + _, err = c.UpdateOrderbook(context.Background(), cp, asset.Spot) if err != nil { t.Error(err) } @@ -284,7 +286,7 @@ func TestUpdateOrderbook(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = c.UpdateOrderbook(cp, asset.PerpetualSwap) + _, err = c.UpdateOrderbook(context.Background(), cp, asset.PerpetualSwap) if err != nil { t.Error(err) } @@ -292,7 +294,7 @@ func TestUpdateOrderbook(t *testing.T) { func TestGetSwapTickers(t *testing.T) { t.Parallel() - _, err := c.GetSwapTickers() + _, err := c.GetSwapTickers(context.Background()) if err != nil { t.Error(err) } @@ -300,7 +302,7 @@ func TestGetSwapTickers(t *testing.T) { func TestGetSwapTicker(t *testing.T) { t.Parallel() - _, err := c.GetSwapTicker(swapTestPair) + _, err := c.GetSwapTicker(context.Background(), swapTestPair) if err != nil { t.Error(err) } @@ -308,7 +310,7 @@ func TestGetSwapTicker(t *testing.T) { func TestGetSwapOrderbook(t *testing.T) { t.Parallel() - _, err := c.GetSwapOrderbook(swapTestPair, 100) + _, err := c.GetSwapOrderbook(context.Background(), swapTestPair, 100) if err != nil { t.Error(err) } @@ -320,8 +322,11 @@ func TestGetKlines(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = c.GetKlines(p.String(), - time.Now().Add(-time.Hour*1), time.Now(), "1") + _, err = c.GetKlines(context.Background(), + p.String(), + time.Now().Add(-time.Hour*1), + time.Now(), + "1") if err != nil { t.Fatal(err) } @@ -333,8 +338,11 @@ func TestGetSwapKlines(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = c.GetSwapKlines(p.String(), - time.Now().Add(-time.Hour*1), time.Now(), "1") + _, err = c.GetSwapKlines(context.Background(), + p.String(), + time.Now().Add(-time.Hour*1), + time.Now(), + "1") if err != nil { t.Error(err) } @@ -342,7 +350,7 @@ func TestGetSwapKlines(t *testing.T) { func TestGetSwapTrades(t *testing.T) { t.Parallel() - _, err := c.GetSwapTrades(swapTestPair, 10) + _, err := c.GetSwapTrades(context.Background(), swapTestPair, 10) if err != nil { t.Error(err) } @@ -350,7 +358,7 @@ func TestGetSwapTrades(t *testing.T) { func TestGetSwapInstruments(t *testing.T) { t.Parallel() - _, err := c.GetSwapInstruments() + _, err := c.GetSwapInstruments(context.Background()) if err != nil { t.Error(err) } @@ -361,7 +369,7 @@ func TestGetSwapAccountInfo(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys required but not set, skipping test") } - _, err := c.GetSwapAccountInfo() + _, err := c.GetSwapAccountInfo(context.Background()) if err != nil { t.Error(err) } @@ -372,7 +380,7 @@ func TestGetSwapPositions(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys required but not set, skipping test") } - _, err := c.GetSwapPositions(swapTestPair) + _, err := c.GetSwapPositions(context.Background(), swapTestPair) if err != nil { t.Error(err) } @@ -384,7 +392,8 @@ func TestPlaceSwapOrder(t *testing.T) { t.Skip("skipping test, either api keys or manipulaterealorders isnt set correctly") } - _, err := c.PlaceSwapOrder(swapTestPair, + _, err := c.PlaceSwapOrder(context.Background(), + swapTestPair, order.Buy.Lower(), "limit", "fixed", @@ -403,7 +412,7 @@ func TestCancelSwapOrder(t *testing.T) { t.Skip("skipping test, either api keys or manipulaterealorders isnt set correctly") } - _, err := c.CancelSwapOrder("1337") + _, err := c.CancelSwapOrder(context.Background(), "1337") if err != nil { t.Error(err) } @@ -415,7 +424,7 @@ func TestGetOpenSwapOrders(t *testing.T) { t.Skip("skipping test, either api keys or manipulaterealorders isnt set correctly") } - _, err := c.GetSwapOpenOrders(swapTestPair, 0, 0) + _, err := c.GetSwapOpenOrders(context.Background(), swapTestPair, 0, 0) if err != nil { t.Error(err) } @@ -427,7 +436,7 @@ func TestGetSwapOpenOrdersByPage(t *testing.T) { t.Skip("skipping test, either api keys or manipulaterealorders isnt set correctly") } - _, err := c.GetSwapOpenOrdersByPage(swapTestPair, 0) + _, err := c.GetSwapOpenOrdersByPage(context.Background(), swapTestPair, 0) if err != nil { t.Error(err) } @@ -439,7 +448,7 @@ func TestGetSwapOrderInfo(t *testing.T) { t.Skip("skipping test, either api keys or manipulaterealorders isnt set correctly") } - _, err := c.GetSwapOrderInfo("1337") + _, err := c.GetSwapOrderInfo(context.Background(), "1337") if err != nil { t.Error(err) } @@ -451,7 +460,8 @@ func TestGetSwapOrderHistory(t *testing.T) { t.Skip("skipping test, either api keys or manipulaterealorders isnt set correctly") } - _, err := c.GetSwapOrderHistory("", "", swapTestPair, 1, 10, "", "") + _, err := c.GetSwapOrderHistory(context.Background(), + "", "", swapTestPair, 1, 10, "", "") if err != nil { t.Error(err) } @@ -463,7 +473,8 @@ func TestGetSwapOrderHistoryByOrderID(t *testing.T) { t.Skip("skipping test, either api keys or manipulaterealorders isnt set correctly") } - _, err := c.GetSwapOrderHistoryByOrderID("", "", swapTestPair, "", 0) + _, err := c.GetSwapOrderHistoryByOrderID(context.Background(), + "", "", swapTestPair, "", 0) if err != nil { t.Error(err) } @@ -475,7 +486,8 @@ func TestCancelSwapOrders(t *testing.T) { t.Skip("skipping test, either api keys or manipulaterealorders isnt set correctly") } - _, err := c.CancelSwapOrders([]string{"578639816552972288", "578639902896914432"}) + _, err := c.CancelSwapOrders(context.Background(), + []string{"578639816552972288", "578639902896914432"}) if err != nil { t.Error(err) } @@ -487,7 +499,8 @@ func TestGetSwapOrderFills(t *testing.T) { t.Skip("skipping test, either api keys or manipulaterealorders isnt set correctly") } - _, err := c.GetSwapOrderFills(swapTestPair, "5807143157122003", 580714315825905664) + _, err := c.GetSwapOrderFills(context.Background(), + swapTestPair, "5807143157122003", 580714315825905664) if err != nil { t.Error(err) } @@ -499,7 +512,7 @@ func TestGetSwapFundingRates(t *testing.T) { t.Skip("skipping test, either api keys or manipulaterealorders isnt set correctly") } - _, err := c.GetSwapFundingRates(1, 2) + _, err := c.GetSwapFundingRates(context.Background(), 1, 2) if err != nil { t.Error(err) } @@ -648,7 +661,8 @@ func TestGetHistoricCandles(t *testing.T) { t.Fatal(err) } startTime := time.Now().Add(-time.Hour * 24) - _, err = c.GetHistoricCandles(currencyPair, asset.Spot, startTime, time.Now(), kline.OneHour) + _, err = c.GetHistoricCandles(context.Background(), + currencyPair, asset.Spot, startTime, time.Now(), kline.OneHour) if err != nil { t.Fatal(err) } @@ -657,7 +671,8 @@ func TestGetHistoricCandles(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = c.GetHistoricCandles(currencyPairSwap, asset.PerpetualSwap, startTime, time.Now(), kline.OneHour) + _, err = c.GetHistoricCandles(context.Background(), + currencyPairSwap, asset.PerpetualSwap, startTime, time.Now(), kline.OneHour) if err != nil { t.Fatal(err) } @@ -669,7 +684,8 @@ func TestGetHistoricCandlesExtended(t *testing.T) { t.Fatal(err) } startTime := time.Now().Add(-time.Hour * 2) - _, err = c.GetHistoricCandlesExtended(currencyPair, asset.Spot, startTime, time.Now(), kline.OneHour) + _, err = c.GetHistoricCandlesExtended(context.Background(), + currencyPair, asset.Spot, startTime, time.Now(), kline.OneHour) if err != nil { t.Fatal(err) } @@ -780,7 +796,7 @@ func TestGetRecentTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = c.GetRecentTrades(currencyPair, asset.Spot) + _, err = c.GetRecentTrades(context.Background(), currencyPair, asset.Spot) if err != nil { t.Error(err) } @@ -792,7 +808,8 @@ func TestGetHistoricTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = c.GetHistoricTrades(currencyPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) + _, err = c.GetHistoricTrades(context.Background(), + currencyPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) if err != nil && err != common.ErrFunctionNotSupported { t.Error(err) } diff --git a/exchanges/coinbene/coinbene_wrapper.go b/exchanges/coinbene/coinbene_wrapper.go index b0a16fd8..de5935c0 100644 --- a/exchanges/coinbene/coinbene_wrapper.go +++ b/exchanges/coinbene/coinbene_wrapper.go @@ -1,6 +1,7 @@ package coinbene import ( + "context" "errors" "fmt" "sort" @@ -41,7 +42,7 @@ func (c *Coinbene) GetDefaultConfig() (*config.ExchangeConfig, error) { } if c.Features.Supports.RESTCapabilities.AutoPairUpdates { - err = c.UpdateTradablePairs(true) + err = c.UpdateTradablePairs(context.TODO(), true) if err != nil { return nil, err } @@ -231,7 +232,7 @@ func (c *Coinbene) Run() { return } - err := c.UpdateTradablePairs(false) + err := c.UpdateTradablePairs(context.TODO(), false) if err != nil { log.Errorf(log.ExchangeSys, "%s Failed to update tradable pairs. Error: %s", @@ -241,7 +242,7 @@ func (c *Coinbene) Run() { } // FetchTradablePairs returns a list of exchange tradable pairs -func (c *Coinbene) FetchTradablePairs(a asset.Item) ([]string, error) { +func (c *Coinbene) FetchTradablePairs(ctx context.Context, a asset.Item) ([]string, error) { if !c.SupportsAsset(a) { return nil, fmt.Errorf("%s does not support asset type %s", c.Name, a) } @@ -249,7 +250,7 @@ func (c *Coinbene) FetchTradablePairs(a asset.Item) ([]string, error) { var currencies []string switch a { case asset.Spot: - pairs, err := c.GetAllPairs() + pairs, err := c.GetAllPairs(ctx) if err != nil { return nil, err } @@ -258,7 +259,7 @@ func (c *Coinbene) FetchTradablePairs(a asset.Item) ([]string, error) { currencies = append(currencies, pairs[x].Symbol) } case asset.PerpetualSwap: - instruments, err := c.GetSwapInstruments() + instruments, err := c.GetSwapInstruments(ctx) if err != nil { return nil, err } @@ -276,10 +277,10 @@ func (c *Coinbene) FetchTradablePairs(a asset.Item) ([]string, error) { // UpdateTradablePairs updates the exchanges available pairs and stores // them -func (c *Coinbene) UpdateTradablePairs(forceUpdate bool) error { +func (c *Coinbene) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { assets := c.GetAssetTypes(false) for x := range assets { - pairs, err := c.FetchTradablePairs(assets[x]) + pairs, err := c.FetchTradablePairs(ctx, assets[x]) if err != nil { return err } @@ -298,7 +299,7 @@ func (c *Coinbene) UpdateTradablePairs(forceUpdate bool) error { } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (c *Coinbene) UpdateTickers(a asset.Item) error { +func (c *Coinbene) UpdateTickers(ctx context.Context, a asset.Item) error { if !c.SupportsAsset(a) { return fmt.Errorf("%s does not support asset type %s", c.Name, a) } @@ -310,7 +311,7 @@ func (c *Coinbene) UpdateTickers(a asset.Item) error { switch a { case asset.Spot: - tickers, err := c.GetTickers() + tickers, err := c.GetTickers(ctx) if err != nil { return err } @@ -341,7 +342,7 @@ func (c *Coinbene) UpdateTickers(a asset.Item) error { } } case asset.PerpetualSwap: - tickers, err := c.GetSwapTickers() + tickers, err := c.GetSwapTickers(ctx) if err != nil { return err } @@ -380,8 +381,8 @@ func (c *Coinbene) UpdateTickers(a asset.Item) error { } // UpdateTicker updates and returns the ticker for a currency pair -func (c *Coinbene) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) { - err := c.UpdateTickers(a) +func (c *Coinbene) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { + err := c.UpdateTickers(ctx, a) if err != nil { return nil, err } @@ -389,7 +390,7 @@ func (c *Coinbene) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, e } // FetchTicker returns the ticker for a currency pair -func (c *Coinbene) FetchTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) { +func (c *Coinbene) FetchTicker(ctx context.Context, p currency.Pair, assetType asset.Item) (*ticker.Price, error) { if !c.SupportsAsset(assetType) { return nil, fmt.Errorf("%s does not support asset type %s", c.Name, assetType) @@ -397,13 +398,13 @@ func (c *Coinbene) FetchTicker(p currency.Pair, assetType asset.Item) (*ticker.P tickerNew, err := ticker.GetTicker(c.Name, p, assetType) if err != nil { - return c.UpdateTicker(p, assetType) + return c.UpdateTicker(ctx, p, assetType) } return tickerNew, nil } // FetchOrderbook returns orderbook base on the currency pair -func (c *Coinbene) FetchOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (c *Coinbene) FetchOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { if !c.SupportsAsset(assetType) { return nil, fmt.Errorf("%s does not support asset type %s", c.Name, assetType) @@ -411,13 +412,13 @@ func (c *Coinbene) FetchOrderbook(p currency.Pair, assetType asset.Item) (*order ob, err := orderbook.Get(c.Name, p, assetType) if err != nil { - return c.UpdateOrderbook(p, assetType) + return c.UpdateOrderbook(ctx, p, assetType) } return ob, nil } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (c *Coinbene) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (c *Coinbene) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { book := &orderbook.Base{ Exchange: c.Name, Pair: p, @@ -437,11 +438,13 @@ func (c *Coinbene) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orde var tempResp Orderbook switch assetType { case asset.Spot: - tempResp, err = c.GetOrderbook(fpair.String(), + tempResp, err = c.GetOrderbook(ctx, + fpair.String(), 100, // TO-DO: Update this once we support configurable orderbook depth ) case asset.PerpetualSwap: - tempResp, err = c.GetSwapOrderbook(fpair.String(), + tempResp, err = c.GetSwapOrderbook(ctx, + fpair.String(), 100, // TO-DO: Update this once we support configurable orderbook depth ) } @@ -477,9 +480,9 @@ func (c *Coinbene) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orde // UpdateAccountInfo retrieves balances for all enabled currencies for the // Coinbene exchange -func (c *Coinbene) UpdateAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (c *Coinbene) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { var info account.Holdings - balance, err := c.GetAccountBalances() + balance, err := c.GetAccountBalances(ctx) if err != nil { return info, err } @@ -507,10 +510,10 @@ func (c *Coinbene) UpdateAccountInfo(assetType asset.Item) (account.Holdings, er } // FetchAccountInfo retrieves balances for all enabled currencies -func (c *Coinbene) FetchAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (c *Coinbene) FetchAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { acc, err := account.GetHoldings(c.Name, assetType) if err != nil { - return c.UpdateAccountInfo(assetType) + return c.UpdateAccountInfo(ctx, assetType) } return acc, nil @@ -518,24 +521,24 @@ func (c *Coinbene) FetchAccountInfo(assetType asset.Item) (account.Holdings, err // GetFundingHistory returns funding history, deposits and // withdrawals -func (c *Coinbene) GetFundingHistory() ([]exchange.FundHistory, error) { +func (c *Coinbene) GetFundingHistory(ctx context.Context) ([]exchange.FundHistory, error) { return nil, common.ErrFunctionNotSupported } // GetWithdrawalsHistory returns previous withdrawals data -func (c *Coinbene) GetWithdrawalsHistory(cur currency.Code) (resp []exchange.WithdrawalHistory, err error) { +func (c *Coinbene) GetWithdrawalsHistory(_ context.Context, _ currency.Code) (resp []exchange.WithdrawalHistory, err error) { return nil, common.ErrNotYetImplemented } // GetRecentTrades returns the most recent trades for a currency and asset -func (c *Coinbene) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade.Data, error) { +func (c *Coinbene) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { var err error p, err = c.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err } var tradeData Trades - tradeData, err = c.GetTrades(p.String(), 100) + tradeData, err = c.GetTrades(ctx, p.String(), 100) if err != nil { return nil, err } @@ -566,12 +569,12 @@ func (c *Coinbene) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]tra } // GetHistoricTrades returns historic trade data within the timeframe provided -func (c *Coinbene) GetHistoricTrades(_ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { +func (c *Coinbene) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { return nil, common.ErrFunctionNotSupported } // SubmitOrder submits a new order -func (c *Coinbene) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { +func (c *Coinbene) SubmitOrder(ctx context.Context, s *order.Submit) (order.SubmitResponse, error) { var resp order.SubmitResponse if err := s.Validate(); err != nil { return resp, err @@ -588,7 +591,8 @@ func (c *Coinbene) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { return resp, err } - tempResp, err := c.PlaceSpotOrder(s.Price, + tempResp, err := c.PlaceSpotOrder(ctx, + s.Price, s.Amount, fpair.String(), s.Side.String(), @@ -605,26 +609,26 @@ func (c *Coinbene) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (c *Coinbene) ModifyOrder(action *order.Modify) (order.Modify, error) { +func (c *Coinbene) ModifyOrder(ctx context.Context, action *order.Modify) (order.Modify, error) { return order.Modify{}, common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number -func (c *Coinbene) CancelOrder(o *order.Cancel) error { +func (c *Coinbene) CancelOrder(ctx context.Context, o *order.Cancel) error { if err := o.Validate(o.StandardCancel()); err != nil { return err } - _, err := c.CancelSpotOrder(o.ID) + _, err := c.CancelSpotOrder(ctx, o.ID) return err } // CancelBatchOrders cancels an orders by their corresponding ID numbers -func (c *Coinbene) CancelBatchOrders(o []order.Cancel) (order.CancelBatchResponse, error) { +func (c *Coinbene) CancelBatchOrders(ctx context.Context, o []order.Cancel) (order.CancelBatchResponse, error) { return order.CancelBatchResponse{}, common.ErrNotYetImplemented } // CancelAllOrders cancels all orders associated with a currency pair -func (c *Coinbene) CancelAllOrders(orderCancellation *order.Cancel) (order.CancelAllResponse, error) { +func (c *Coinbene) CancelAllOrders(ctx context.Context, orderCancellation *order.Cancel) (order.CancelAllResponse, error) { if err := orderCancellation.Validate(); err != nil { return order.CancelAllResponse{}, err } @@ -636,14 +640,14 @@ func (c *Coinbene) CancelAllOrders(orderCancellation *order.Cancel) (order.Cance return resp, err } - orders, err := c.FetchOpenSpotOrders(fpair.String()) + orders, err := c.FetchOpenSpotOrders(ctx, fpair.String()) if err != nil { return resp, err } tempMap := make(map[string]string) for x := range orders { - _, err := c.CancelSpotOrder(orders[x].OrderID) + _, err := c.CancelSpotOrder(ctx, orders[x].OrderID) if err != nil { tempMap[orders[x].OrderID] = "Failed" } else { @@ -655,9 +659,9 @@ func (c *Coinbene) CancelAllOrders(orderCancellation *order.Cancel) (order.Cance } // GetOrderInfo returns order information based on order ID -func (c *Coinbene) GetOrderInfo(orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { +func (c *Coinbene) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { var resp order.Detail - tempResp, err := c.FetchSpotOrderInfo(orderID) + tempResp, err := c.FetchSpotOrderInfo(ctx, orderID) if err != nil { return resp, err } @@ -674,36 +678,36 @@ func (c *Coinbene) GetOrderInfo(orderID string, pair currency.Pair, assetType as } // GetDepositAddress returns a deposit address for a specified currency -func (c *Coinbene) GetDepositAddress(_ currency.Code, _ string) (string, error) { +func (c *Coinbene) GetDepositAddress(_ context.Context, _ currency.Code, _ string) (string, error) { return "", common.ErrFunctionNotSupported } // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is // submitted -func (c *Coinbene) WithdrawCryptocurrencyFunds(_ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (c *Coinbene) WithdrawCryptocurrencyFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // WithdrawFiatFunds returns a withdrawal ID when a withdrawal is // submitted -func (c *Coinbene) WithdrawFiatFunds(_ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (c *Coinbene) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a withdrawal is // submitted -func (c *Coinbene) WithdrawFiatFundsToInternationalBank(_ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (c *Coinbene) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // GetActiveOrders retrieves any orders that are active/open -func (c *Coinbene) GetActiveOrders(getOrdersRequest *order.GetOrdersRequest) ([]order.Detail, error) { +func (c *Coinbene) GetActiveOrders(ctx context.Context, getOrdersRequest *order.GetOrdersRequest) ([]order.Detail, error) { if err := getOrdersRequest.Validate(); err != nil { return nil, err } if len(getOrdersRequest.Pairs) == 0 { - allPairs, err := c.GetAllPairs() + allPairs, err := c.GetAllPairs(ctx) if err != nil { return nil, err } @@ -725,7 +729,7 @@ func (c *Coinbene) GetActiveOrders(getOrdersRequest *order.GetOrdersRequest) ([] } var tempData OrdersInfo - tempData, err = c.FetchOpenSpotOrders(fpair.String()) + tempData, err = c.FetchOpenSpotOrders(ctx, fpair.String()) if err != nil { return nil, err } @@ -753,13 +757,13 @@ func (c *Coinbene) GetActiveOrders(getOrdersRequest *order.GetOrdersRequest) ([] // GetOrderHistory retrieves account order information // Can Limit response to specific order status -func (c *Coinbene) GetOrderHistory(getOrdersRequest *order.GetOrdersRequest) ([]order.Detail, error) { +func (c *Coinbene) GetOrderHistory(ctx context.Context, getOrdersRequest *order.GetOrdersRequest) ([]order.Detail, error) { if err := getOrdersRequest.Validate(); err != nil { return nil, err } if len(getOrdersRequest.Pairs) == 0 { - allPairs, err := c.GetAllPairs() + allPairs, err := c.GetAllPairs(ctx) if err != nil { return nil, err } @@ -782,7 +786,7 @@ func (c *Coinbene) GetOrderHistory(getOrdersRequest *order.GetOrdersRequest) ([] return nil, err } - tempData, err = c.FetchClosedOrders(fpair.String(), "") + tempData, err = c.FetchClosedOrders(ctx, fpair.String(), "") if err != nil { return nil, err } @@ -809,13 +813,13 @@ func (c *Coinbene) GetOrderHistory(getOrdersRequest *order.GetOrdersRequest) ([] } // GetFeeByType returns an estimate of fee based on the type of transaction -func (c *Coinbene) GetFeeByType(feeBuilder *exchange.FeeBuilder) (float64, error) { +func (c *Coinbene) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { fpair, err := c.FormatExchangeCurrency(feeBuilder.Pair, asset.Spot) if err != nil { return 0, err } - tempData, err := c.GetPairInfo(fpair.String()) + tempData, err := c.GetPairInfo(ctx, fpair.String()) if err != nil { return 0, err } @@ -827,14 +831,14 @@ func (c *Coinbene) GetFeeByType(feeBuilder *exchange.FeeBuilder) (float64, error } // AuthenticateWebsocket sends an authentication message to the websocket -func (c *Coinbene) AuthenticateWebsocket() error { +func (c *Coinbene) AuthenticateWebsocket(_ context.Context) error { return c.Login() } // ValidateCredentials validates current credentials used for wrapper // functionality -func (c *Coinbene) ValidateCredentials(assetType asset.Item) error { - _, err := c.UpdateAccountInfo(assetType) +func (c *Coinbene) ValidateCredentials(ctx context.Context, assetType asset.Item) error { + _, err := c.UpdateAccountInfo(ctx, assetType) return c.CheckTransientError(err) } @@ -855,7 +859,7 @@ func (c *Coinbene) FormatExchangeKlineInterval(in kline.Interval) string { } // GetHistoricCandles returns candles between a time period for a set time interval -func (c *Coinbene) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (c *Coinbene) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { if err := c.ValidateKline(pair, a, interval); err != nil { return kline.Item{}, err } @@ -867,11 +871,13 @@ func (c *Coinbene) GetHistoricCandles(pair currency.Pair, a asset.Item, start, e var candles CandleResponse if a == asset.PerpetualSwap { - candles, err = c.GetSwapKlines(formattedPair.String(), + candles, err = c.GetSwapKlines(ctx, + formattedPair.String(), start, end, c.FormatExchangeKlineInterval(interval)) } else { - candles, err = c.GetKlines(formattedPair.String(), + candles, err = c.GetKlines(ctx, + formattedPair.String(), start, end, c.FormatExchangeKlineInterval(interval)) } @@ -946,6 +952,6 @@ func (c *Coinbene) GetHistoricCandles(pair currency.Pair, a asset.Item, start, e } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (c *Coinbene) GetHistoricCandlesExtended(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { - return c.GetHistoricCandles(pair, a, start, end, interval) +func (c *Coinbene) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { + return c.GetHistoricCandles(ctx, pair, a, start, end, interval) } diff --git a/exchanges/coinut/coinut.go b/exchanges/coinut/coinut.go index d9688edc..f347684b 100644 --- a/exchanges/coinut/coinut.go +++ b/exchanges/coinut/coinut.go @@ -53,8 +53,8 @@ type COINUT struct { } // SeedInstruments seeds the instrument map -func (c *COINUT) SeedInstruments() error { - i, err := c.GetInstruments() +func (c *COINUT) SeedInstruments(ctx context.Context) error { + i, err := c.GetInstruments(ctx) if err != nil { return err } @@ -66,23 +66,23 @@ func (c *COINUT) SeedInstruments() error { } // GetInstruments returns instruments -func (c *COINUT) GetInstruments() (Instruments, error) { +func (c *COINUT) GetInstruments(ctx context.Context) (Instruments, error) { var result Instruments params := make(map[string]interface{}) params["sec_type"] = strings.ToUpper(asset.Spot.String()) - return result, c.SendHTTPRequest(exchange.RestSpot, coinutInstruments, params, false, &result) + return result, c.SendHTTPRequest(ctx, exchange.RestSpot, coinutInstruments, params, false, &result) } // GetInstrumentTicker returns a ticker for a specific instrument -func (c *COINUT) GetInstrumentTicker(instrumentID int64) (Ticker, error) { +func (c *COINUT) GetInstrumentTicker(ctx context.Context, instrumentID int64) (Ticker, error) { var result Ticker params := make(map[string]interface{}) params["inst_id"] = instrumentID - return result, c.SendHTTPRequest(exchange.RestSpot, coinutTicker, params, false, &result) + return result, c.SendHTTPRequest(ctx, exchange.RestSpot, coinutTicker, params, false, &result) } // GetInstrumentOrderbook returns the orderbooks for a specific instrument -func (c *COINUT) GetInstrumentOrderbook(instrumentID, limit int64) (Orderbook, error) { +func (c *COINUT) GetInstrumentOrderbook(ctx context.Context, instrumentID, limit int64) (Orderbook, error) { var result Orderbook params := make(map[string]interface{}) params["inst_id"] = instrumentID @@ -90,26 +90,26 @@ func (c *COINUT) GetInstrumentOrderbook(instrumentID, limit int64) (Orderbook, e params["top_n"] = limit } - return result, c.SendHTTPRequest(exchange.RestSpot, coinutOrderbook, params, false, &result) + return result, c.SendHTTPRequest(ctx, exchange.RestSpot, coinutOrderbook, params, false, &result) } // GetTrades returns trade information -func (c *COINUT) GetTrades(instrumentID int64) (Trades, error) { +func (c *COINUT) GetTrades(ctx context.Context, instrumentID int64) (Trades, error) { var result Trades params := make(map[string]interface{}) params["inst_id"] = instrumentID - return result, c.SendHTTPRequest(exchange.RestSpot, coinutTrades, params, false, &result) + return result, c.SendHTTPRequest(ctx, exchange.RestSpot, coinutTrades, params, false, &result) } // GetUserBalance returns the full user balance -func (c *COINUT) GetUserBalance() (*UserBalance, error) { +func (c *COINUT) GetUserBalance(ctx context.Context) (*UserBalance, error) { var result *UserBalance - return result, c.SendHTTPRequest(exchange.RestSpot, coinutBalance, nil, true, &result) + return result, c.SendHTTPRequest(ctx, exchange.RestSpot, coinutBalance, nil, true, &result) } // NewOrder places a new order on the exchange -func (c *COINUT) NewOrder(instrumentID int64, quantity, price float64, buy bool, orderID uint32) (interface{}, error) { +func (c *COINUT) NewOrder(ctx context.Context, instrumentID int64, quantity, price float64, buy bool, orderID uint32) (interface{}, error) { var result interface{} params := make(map[string]interface{}) params["inst_id"] = instrumentID @@ -123,28 +123,28 @@ func (c *COINUT) NewOrder(instrumentID int64, quantity, price float64, buy bool, } params["client_ord_id"] = orderID - return result, c.SendHTTPRequest(exchange.RestSpot, coinutOrder, params, true, &result) + return result, c.SendHTTPRequest(ctx, exchange.RestSpot, coinutOrder, params, true, &result) } // NewOrders places multiple orders on the exchange -func (c *COINUT) NewOrders(orders []Order) ([]OrdersBase, error) { +func (c *COINUT) NewOrders(ctx context.Context, orders []Order) ([]OrdersBase, error) { var result OrdersResponse params := make(map[string]interface{}) params["orders"] = orders - return result.Data, c.SendHTTPRequest(exchange.RestSpot, coinutOrders, params, true, &result.Data) + return result.Data, c.SendHTTPRequest(ctx, exchange.RestSpot, coinutOrders, params, true, &result.Data) } // GetOpenOrders returns a list of open order and relevant information -func (c *COINUT) GetOpenOrders(instrumentID int64) (GetOpenOrdersResponse, error) { +func (c *COINUT) GetOpenOrders(ctx context.Context, instrumentID int64) (GetOpenOrdersResponse, error) { var result GetOpenOrdersResponse params := make(map[string]interface{}) params["inst_id"] = instrumentID - return result, c.SendHTTPRequest(exchange.RestSpot, coinutOrdersOpen, params, true, &result) + return result, c.SendHTTPRequest(ctx, exchange.RestSpot, coinutOrdersOpen, params, true, &result) } // CancelExistingOrder cancels a specific order and returns if it was actioned -func (c *COINUT) CancelExistingOrder(instrumentID, orderID int64) (bool, error) { +func (c *COINUT) CancelExistingOrder(ctx context.Context, instrumentID, orderID int64) (bool, error) { var result GenericResponse params := make(map[string]interface{}) type Request struct { @@ -160,7 +160,7 @@ func (c *COINUT) CancelExistingOrder(instrumentID, orderID int64) (bool, error) entries := []Request{entry} params["entries"] = entries - err := c.SendHTTPRequest(exchange.RestSpot, coinutOrdersCancel, params, true, &result) + err := c.SendHTTPRequest(ctx, exchange.RestSpot, coinutOrdersCancel, params, true, &result) if err != nil { return false, err } @@ -168,18 +168,18 @@ func (c *COINUT) CancelExistingOrder(instrumentID, orderID int64) (bool, error) } // CancelOrders cancels multiple orders -func (c *COINUT) CancelOrders(orders []CancelOrders) (CancelOrdersResponse, error) { +func (c *COINUT) CancelOrders(ctx context.Context, orders []CancelOrders) (CancelOrdersResponse, error) { var result CancelOrdersResponse params := make(map[string]interface{}) var entries []CancelOrders entries = append(entries, orders...) params["entries"] = entries - return result, c.SendHTTPRequest(exchange.RestSpot, coinutOrdersCancel, params, true, &result) + return result, c.SendHTTPRequest(ctx, exchange.RestSpot, coinutOrdersCancel, params, true, &result) } // GetTradeHistory returns trade history for a specific instrument. -func (c *COINUT) GetTradeHistory(instrumentID, start, limit int64) (TradeHistory, error) { +func (c *COINUT) GetTradeHistory(ctx context.Context, instrumentID, start, limit int64) (TradeHistory, error) { var result TradeHistory params := make(map[string]interface{}) params["inst_id"] = instrumentID @@ -190,39 +190,39 @@ func (c *COINUT) GetTradeHistory(instrumentID, start, limit int64) (TradeHistory params["limit"] = limit } - return result, c.SendHTTPRequest(exchange.RestSpot, coinutTradeHistory, params, true, &result) + return result, c.SendHTTPRequest(ctx, exchange.RestSpot, coinutTradeHistory, params, true, &result) } // GetIndexTicker returns the index ticker for an asset -func (c *COINUT) GetIndexTicker(asset string) (IndexTicker, error) { +func (c *COINUT) GetIndexTicker(ctx context.Context, asset string) (IndexTicker, error) { var result IndexTicker params := make(map[string]interface{}) params["asset"] = asset - return result, c.SendHTTPRequest(exchange.RestSpot, coinutIndexTicker, params, false, &result) + return result, c.SendHTTPRequest(ctx, exchange.RestSpot, coinutIndexTicker, params, false, &result) } // GetDerivativeInstruments returns a list of derivative instruments -func (c *COINUT) GetDerivativeInstruments(secType string) (interface{}, error) { +func (c *COINUT) GetDerivativeInstruments(ctx context.Context, secType string) (interface{}, error) { var result interface{} // to-do params := make(map[string]interface{}) params["sec_type"] = secType - return result, c.SendHTTPRequest(exchange.RestSpot, coinutInstruments, params, false, &result) + return result, c.SendHTTPRequest(ctx, exchange.RestSpot, coinutInstruments, params, false, &result) } // GetOptionChain returns option chain -func (c *COINUT) GetOptionChain(asset, secType string) (OptionChainResponse, error) { +func (c *COINUT) GetOptionChain(ctx context.Context, asset, secType string) (OptionChainResponse, error) { var result OptionChainResponse params := make(map[string]interface{}) params["asset"] = asset params["sec_type"] = secType - return result, c.SendHTTPRequest(exchange.RestSpot, coinutOptionChain, params, false, &result) + return result, c.SendHTTPRequest(ctx, exchange.RestSpot, coinutOptionChain, params, false, &result) } // GetPositionHistory returns position history -func (c *COINUT) GetPositionHistory(secType string, start, limit int) (PositionHistory, error) { +func (c *COINUT) GetPositionHistory(ctx context.Context, secType string, start, limit int) (PositionHistory, error) { var result PositionHistory params := make(map[string]interface{}) params["sec_type"] = secType @@ -233,11 +233,11 @@ func (c *COINUT) GetPositionHistory(secType string, start, limit int) (PositionH params["limit"] = limit } - return result, c.SendHTTPRequest(exchange.RestSpot, coinutPositionHistory, params, true, &result) + return result, c.SendHTTPRequest(ctx, exchange.RestSpot, coinutPositionHistory, params, true, &result) } // GetOpenPositions returns all your current opened positions -func (c *COINUT) GetOpenPositions(instrumentID int) ([]OpenPosition, error) { +func (c *COINUT) GetOpenPositions(ctx context.Context, instrumentID int) ([]OpenPosition, error) { type Response struct { Positions []OpenPosition `json:"positions"` } @@ -246,13 +246,13 @@ func (c *COINUT) GetOpenPositions(instrumentID int) ([]OpenPosition, error) { params["inst_id"] = instrumentID return result.Positions, - c.SendHTTPRequest(exchange.RestSpot, coinutPositionOpen, params, true, &result) + c.SendHTTPRequest(ctx, exchange.RestSpot, coinutPositionOpen, params, true, &result) } // to-do: user position update via websocket // SendHTTPRequest sends either an authenticated or unauthenticated HTTP request -func (c *COINUT) SendHTTPRequest(ep exchange.URL, apiRequest string, params map[string]interface{}, authenticated bool, result interface{}) (err error) { +func (c *COINUT) SendHTTPRequest(ctx context.Context, ep exchange.URL, apiRequest string, params map[string]interface{}, authenticated bool, result interface{}) (err error) { if !c.API.AuthenticatedSupport && authenticated { return fmt.Errorf("%s %w", c.Name, exchange.ErrAuthenticatedRequestWithoutCredentialsSet) } @@ -267,7 +267,7 @@ func (c *COINUT) SendHTTPRequest(ep exchange.URL, apiRequest string, params map[ } var rawMsg json.RawMessage - err = c.SendPayload(context.Background(), request.Unset, func() (*request.Item, error) { + err = c.SendPayload(ctx, request.Unset, func() (*request.Item, error) { params["nonce"] = getNonce() params["request"] = apiRequest @@ -315,7 +315,8 @@ func (c *COINUT) SendHTTPRequest(ep exchange.URL, apiRequest string, params map[ } if genResp.Status[0] != coinutStatusOK { - return fmt.Errorf("%s SendHTTPRequest error: %s", c.Name, + return fmt.Errorf("%s SendHTTPRequest error: %s", + c.Name, genResp.Status[0]) } diff --git a/exchanges/coinut/coinut_test.go b/exchanges/coinut/coinut_test.go index d79c0485..64b77bd8 100644 --- a/exchanges/coinut/coinut_test.go +++ b/exchanges/coinut/coinut_test.go @@ -1,6 +1,7 @@ package coinut import ( + "context" "log" "net/http" "os" @@ -50,7 +51,7 @@ func TestMain(m *testing.M) { if err != nil { log.Fatal("Coinut setup error", err) } - err = c.SeedInstruments() + err = c.SeedInstruments(context.Background()) if err != nil { log.Fatal("Coinut setup error ", err) } @@ -87,14 +88,14 @@ func setupWSTestAuth(t *testing.T) { } func TestGetInstruments(t *testing.T) { - _, err := c.GetInstruments() + _, err := c.GetInstruments(context.Background()) if err != nil { t.Error("GetInstruments() error", err) } } func TestSeedInstruments(t *testing.T) { - err := c.SeedInstruments() + err := c.SeedInstruments(context.Background()) if err != nil { // No point checking the next condition t.Fatal(err) @@ -117,7 +118,7 @@ func setFeeBuilder() *exchange.FeeBuilder { // TestGetFeeByTypeOfflineTradeFee logic test func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { var feeBuilder = setFeeBuilder() - _, err := c.GetFeeByType(feeBuilder) + _, err := c.GetFeeByType(context.Background(), feeBuilder) if err != nil { t.Fatal(err) } @@ -246,7 +247,7 @@ func TestGetActiveOrders(t *testing.T) { Type: order.AnyType, AssetType: asset.Spot, } - _, err := c.GetActiveOrders(&getOrdersRequest) + _, err := c.GetActiveOrders(context.Background(), &getOrdersRequest) if areTestAPIKeysSet() && err != nil { t.Errorf("Could not get open orders: %s", err) } @@ -261,7 +262,7 @@ func TestGetOrderHistoryWrapper(t *testing.T) { currency.USD)}, } - _, err := c.GetOrderHistory(&getOrdersRequest) + _, err := c.GetOrderHistory(context.Background(), &getOrdersRequest) if areTestAPIKeysSet() && err != nil { t.Errorf("Could not get order history: %s", err) } @@ -290,7 +291,7 @@ func TestSubmitOrder(t *testing.T) { ClientID: "123", AssetType: asset.Spot, } - response, err := c.SubmitOrder(orderSubmission) + response, err := c.SubmitOrder(context.Background(), orderSubmission) if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) { t.Errorf("Order failed to be placed: %v", err) } else if !areTestAPIKeysSet() && err == nil { @@ -311,7 +312,7 @@ func TestCancelExchangeOrder(t *testing.T) { AssetType: asset.Spot, } - err := c.CancelOrder(orderCancellation) + err := c.CancelOrder(context.Background(), orderCancellation) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") } @@ -334,7 +335,7 @@ func TestCancelAllExchangeOrders(t *testing.T) { AssetType: asset.Spot, } - resp, err := c.CancelAllOrders(orderCancellation) + resp, err := c.CancelAllOrders(context.Background(), orderCancellation) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") @@ -350,12 +351,12 @@ func TestCancelAllExchangeOrders(t *testing.T) { func TestGetAccountInfo(t *testing.T) { if apiKey != "" || clientID != "" { - _, err := c.UpdateAccountInfo(asset.Spot) + _, err := c.UpdateAccountInfo(context.Background(), asset.Spot) if err != nil { t.Error("GetAccountInfo() error", err) } } else { - _, err := c.UpdateAccountInfo(asset.Spot) + _, err := c.UpdateAccountInfo(context.Background(), asset.Spot) if err == nil { t.Error("GetAccountInfo() Expected error") } @@ -366,7 +367,8 @@ func TestModifyOrder(t *testing.T) { if areTestAPIKeysSet() && !canManipulateRealOrders { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - _, err := c.ModifyOrder(&order.Modify{AssetType: asset.Spot}) + _, err := c.ModifyOrder(context.Background(), + &order.Modify{AssetType: asset.Spot}) if err == nil { t.Error("ModifyOrder() Expected error") } @@ -386,7 +388,8 @@ func TestWithdraw(t *testing.T) { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - _, err := c.WithdrawCryptocurrencyFunds(&withdrawCryptoRequest) + _, err := c.WithdrawCryptocurrencyFunds(context.Background(), + &withdrawCryptoRequest) if err != common.ErrFunctionNotSupported { t.Errorf("Expected 'Not supported', received %v", err) } @@ -398,7 +401,7 @@ func TestWithdrawFiat(t *testing.T) { } var withdrawFiatRequest = withdraw.Request{} - _, err := c.WithdrawFiatFunds(&withdrawFiatRequest) + _, err := c.WithdrawFiatFunds(context.Background(), &withdrawFiatRequest) if err != common.ErrFunctionNotSupported { t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err) } @@ -410,14 +413,15 @@ func TestWithdrawInternationalBank(t *testing.T) { } var withdrawFiatRequest = withdraw.Request{} - _, err := c.WithdrawFiatFundsToInternationalBank(&withdrawFiatRequest) + _, err := c.WithdrawFiatFundsToInternationalBank(context.Background(), + &withdrawFiatRequest) if err != common.ErrFunctionNotSupported { t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err) } } func TestGetDepositAddress(t *testing.T) { - _, err := c.GetDepositAddress(currency.BTC, "") + _, err := c.GetDepositAddress(context.Background(), currency.BTC, "") if err == nil { t.Error("GetDepositAddress() function unsupported cannot be nil") } @@ -511,7 +515,7 @@ func TestWsAuthCancelOrdersWrapper(t *testing.T) { orderDetails := order.Cancel{ Pair: currency.NewPair(currency.LTC, currency.BTC), } - _, err := c.CancelAllOrders(&orderDetails) + _, err := c.CancelAllOrders(context.Background(), &orderDetails) if err != nil { t.Error(err) } @@ -1122,7 +1126,7 @@ func TestGetRecentTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = c.GetRecentTrades(currencyPair, asset.Spot) + _, err = c.GetRecentTrades(context.Background(), currencyPair, asset.Spot) if err != nil { t.Error(err) } @@ -1134,7 +1138,8 @@ func TestGetHistoricTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = c.GetHistoricTrades(currencyPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) + _, err = c.GetHistoricTrades(context.Background(), + currencyPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) if err != nil && err != common.ErrFunctionNotSupported { t.Error(err) } diff --git a/exchanges/coinut/coinut_wrapper.go b/exchanges/coinut/coinut_wrapper.go index f2d89935..4f65da57 100644 --- a/exchanges/coinut/coinut_wrapper.go +++ b/exchanges/coinut/coinut_wrapper.go @@ -1,6 +1,7 @@ package coinut import ( + "context" "errors" "fmt" "math/rand" @@ -42,7 +43,7 @@ func (c *COINUT) GetDefaultConfig() (*config.ExchangeConfig, error) { } if c.Features.Supports.RESTCapabilities.AutoPairUpdates { - err = c.UpdateTradablePairs(true) + err = c.UpdateTradablePairs(context.TODO(), true) if err != nil { return nil, err } @@ -247,14 +248,14 @@ func (c *COINUT) Run() { return } - err = c.UpdateTradablePairs(forceUpdate) + err = c.UpdateTradablePairs(context.TODO(), forceUpdate) if err != nil { log.Errorf(log.ExchangeSys, "%s failed to update tradable pairs. Err: %s", c.Name, err) } } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (c *COINUT) FetchTradablePairs(asset asset.Item) ([]string, error) { +func (c *COINUT) FetchTradablePairs(ctx context.Context, asset asset.Item) ([]string, error) { var instruments map[string][]InstrumentBase var resp Instruments var err error @@ -264,7 +265,7 @@ func (c *COINUT) FetchTradablePairs(asset asset.Item) ([]string, error) { return nil, err } } else { - resp, err = c.GetInstruments() + resp, err = c.GetInstruments(ctx) if err != nil { return nil, err } @@ -288,8 +289,8 @@ func (c *COINUT) FetchTradablePairs(asset asset.Item) ([]string, error) { // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (c *COINUT) UpdateTradablePairs(forceUpdate bool) error { - pairs, err := c.FetchTradablePairs(asset.Spot) +func (c *COINUT) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { + pairs, err := c.FetchTradablePairs(ctx, asset.Spot) if err != nil { return err } @@ -303,7 +304,7 @@ func (c *COINUT) UpdateTradablePairs(forceUpdate bool) error { // UpdateAccountInfo retrieves balances for all enabled currencies for the // COINUT exchange -func (c *COINUT) UpdateAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (c *COINUT) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { var info account.Holdings var bal *UserBalance var err error @@ -315,7 +316,7 @@ func (c *COINUT) UpdateAccountInfo(assetType asset.Item) (account.Holdings, erro } bal = resp } else { - bal, err = c.GetUserBalance() + bal, err = c.GetUserBalance(ctx) if err != nil { return info, err } @@ -393,22 +394,22 @@ func (c *COINUT) UpdateAccountInfo(assetType asset.Item) (account.Holdings, erro } // FetchAccountInfo retrieves balances for all enabled currencies -func (c *COINUT) FetchAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (c *COINUT) FetchAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { acc, err := account.GetHoldings(c.Name, assetType) if err != nil { - return c.UpdateAccountInfo(assetType) + return c.UpdateAccountInfo(ctx, assetType) } return acc, nil } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (c *COINUT) UpdateTickers(a asset.Item) error { +func (c *COINUT) UpdateTickers(ctx context.Context, a asset.Item) error { return common.ErrFunctionNotSupported } // UpdateTicker updates and returns the ticker for a currency pair -func (c *COINUT) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) { +func (c *COINUT) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { err := c.loadInstrumentsIfNotLoaded() if err != nil { return nil, err @@ -424,7 +425,7 @@ func (c *COINUT) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, err return nil, errors.New("unable to lookup instrument ID") } var tick Ticker - tick, err = c.GetInstrumentTicker(instID) + tick, err = c.GetInstrumentTicker(ctx, instID) if err != nil { return nil, err } @@ -448,25 +449,25 @@ func (c *COINUT) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, err } // FetchTicker returns the ticker for a currency pair -func (c *COINUT) FetchTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) { +func (c *COINUT) FetchTicker(ctx context.Context, p currency.Pair, assetType asset.Item) (*ticker.Price, error) { tickerNew, err := ticker.GetTicker(c.Name, p, assetType) if err != nil { - return c.UpdateTicker(p, assetType) + return c.UpdateTicker(ctx, p, assetType) } return tickerNew, nil } // FetchOrderbook returns orderbook base on the currency pair -func (c *COINUT) FetchOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (c *COINUT) FetchOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { ob, err := orderbook.Get(c.Name, p, assetType) if err != nil { - return c.UpdateOrderbook(p, assetType) + return c.UpdateOrderbook(ctx, p, assetType) } return ob, nil } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (c *COINUT) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (c *COINUT) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { book := &orderbook.Base{ Exchange: c.Name, Pair: p, @@ -488,7 +489,7 @@ func (c *COINUT) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderb return book, errLookupInstrumentID } - orderbookNew, err := c.GetInstrumentOrderbook(instID, 200) + orderbookNew, err := c.GetInstrumentOrderbook(ctx, instID, 200) if err != nil { return book, err } @@ -513,17 +514,17 @@ func (c *COINUT) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderb // GetFundingHistory returns funding history, deposits and // withdrawals -func (c *COINUT) GetFundingHistory() ([]exchange.FundHistory, error) { +func (c *COINUT) GetFundingHistory(ctx context.Context) ([]exchange.FundHistory, error) { return nil, common.ErrFunctionNotSupported } // GetWithdrawalsHistory returns previous withdrawals data -func (c *COINUT) GetWithdrawalsHistory(cur currency.Code) (resp []exchange.WithdrawalHistory, err error) { +func (c *COINUT) GetWithdrawalsHistory(_ context.Context, _ currency.Code) (resp []exchange.WithdrawalHistory, err error) { return nil, common.ErrNotYetImplemented } // GetRecentTrades returns the most recent trades for a currency and asset -func (c *COINUT) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade.Data, error) { +func (c *COINUT) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { var err error p, err = c.FormatExchangeCurrency(p, assetType) if err != nil { @@ -534,7 +535,7 @@ func (c *COINUT) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade return nil, errLookupInstrumentID } var tradeData Trades - tradeData, err = c.GetTrades(currencyID) + tradeData, err = c.GetTrades(ctx, currencyID) if err != nil { return nil, err } @@ -567,12 +568,12 @@ func (c *COINUT) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade } // GetHistoricTrades returns historic trade data within the timeframe provided -func (c *COINUT) GetHistoricTrades(_ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { +func (c *COINUT) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { return nil, common.ErrFunctionNotSupported } // SubmitOrder submits a new order -func (c *COINUT) SubmitOrder(o *order.Submit) (order.SubmitResponse, error) { +func (c *COINUT) SubmitOrder(ctx context.Context, o *order.Submit) (order.SubmitResponse, error) { if err := o.Validate(); err != nil { return order.SubmitResponse{}, err } @@ -620,8 +621,12 @@ func (c *COINUT) SubmitOrder(o *order.Submit) (order.SubmitResponse, error) { return submitOrderResponse, err } clientIDUint := uint32(clientIDInt) - APIResponse, err = c.NewOrder(currencyID, o.Amount, o.Price, - isBuyOrder, clientIDUint) + APIResponse, err = c.NewOrder(ctx, + currencyID, + o.Amount, + o.Price, + isBuyOrder, + clientIDUint) if err != nil { return submitOrderResponse, err } @@ -647,12 +652,12 @@ func (c *COINUT) SubmitOrder(o *order.Submit) (order.SubmitResponse, error) { // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (c *COINUT) ModifyOrder(action *order.Modify) (order.Modify, error) { +func (c *COINUT) ModifyOrder(ctx context.Context, action *order.Modify) (order.Modify, error) { return order.Modify{}, common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number -func (c *COINUT) CancelOrder(o *order.Cancel) error { +func (c *COINUT) CancelOrder(ctx context.Context, o *order.Cancel) error { if err := o.Validate(o.StandardCancel()); err != nil { return err } @@ -689,7 +694,7 @@ func (c *COINUT) CancelOrder(o *order.Cancel) error { if currencyID == 0 { return errLookupInstrumentID } - _, err = c.CancelExistingOrder(currencyID, orderIDInt) + _, err = c.CancelExistingOrder(ctx, currencyID, orderIDInt) if err != nil { return err } @@ -699,12 +704,12 @@ func (c *COINUT) CancelOrder(o *order.Cancel) error { } // CancelBatchOrders cancels an orders by their corresponding ID numbers -func (c *COINUT) CancelBatchOrders(o []order.Cancel) (order.CancelBatchResponse, error) { +func (c *COINUT) CancelBatchOrders(_ context.Context, _ []order.Cancel) (order.CancelBatchResponse, error) { return order.CancelBatchResponse{}, common.ErrNotYetImplemented } // CancelAllOrders cancels all orders associated with a currency pair -func (c *COINUT) CancelAllOrders(details *order.Cancel) (order.CancelAllResponse, error) { +func (c *COINUT) CancelAllOrders(ctx context.Context, details *order.Cancel) (order.CancelAllResponse, error) { if err := details.Validate(); err != nil { return order.CancelAllResponse{}, err } @@ -752,7 +757,7 @@ func (c *COINUT) CancelAllOrders(details *order.Cancel) (order.CancelAllResponse return cancelAllOrdersResponse, err } if ids[x] == c.instrumentMap.LookupID(fpair.String()) { - openOrders, err := c.GetOpenOrders(ids[x]) + openOrders, err := c.GetOpenOrders(ctx, ids[x]) if err != nil { return cancelAllOrdersResponse, err } @@ -770,7 +775,7 @@ func (c *COINUT) CancelAllOrders(details *order.Cancel) (order.CancelAllResponse } if len(allTheOrdersToCancel) > 0 { - resp, err := c.CancelOrders(allTheOrdersToCancel) + resp, err := c.CancelOrders(ctx, allTheOrdersToCancel) if err != nil { return cancelAllOrdersResponse, err } @@ -787,35 +792,35 @@ func (c *COINUT) CancelAllOrders(details *order.Cancel) (order.CancelAllResponse } // GetOrderInfo returns order information based on order ID -func (c *COINUT) GetOrderInfo(_ string, _ currency.Pair, _ asset.Item) (order.Detail, error) { +func (c *COINUT) GetOrderInfo(_ context.Context, _ string, _ currency.Pair, _ asset.Item) (order.Detail, error) { return order.Detail{}, common.ErrNotYetImplemented } // GetDepositAddress returns a deposit address for a specified currency -func (c *COINUT) GetDepositAddress(_ currency.Code, _ string) (string, error) { +func (c *COINUT) GetDepositAddress(_ context.Context, _ currency.Code, _ string) (string, error) { return "", common.ErrFunctionNotSupported } // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is // submitted -func (c *COINUT) WithdrawCryptocurrencyFunds(_ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (c *COINUT) WithdrawCryptocurrencyFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // WithdrawFiatFunds returns a withdrawal ID when a // withdrawal is submitted -func (c *COINUT) WithdrawFiatFunds(_ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (c *COINUT) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a // withdrawal is submitted -func (c *COINUT) WithdrawFiatFundsToInternationalBank(_ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (c *COINUT) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // GetFeeByType returns an estimate of fee based on type of transaction -func (c *COINUT) GetFeeByType(feeBuilder *exchange.FeeBuilder) (float64, error) { +func (c *COINUT) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { if !c.AllowAuthenticatedRequest() && // Todo check connection status feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { feeBuilder.FeeType = exchange.OfflineTradeFee @@ -824,7 +829,7 @@ func (c *COINUT) GetFeeByType(feeBuilder *exchange.FeeBuilder) (float64, error) } // GetActiveOrders retrieves any orders that are active/open -func (c *COINUT) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, error) { +func (c *COINUT) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) { if err := req.Validate(); err != nil { return nil, err } @@ -905,7 +910,7 @@ func (c *COINUT) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, e } for x := range instrumentsToUse { - openOrders, err := c.GetOpenOrders(instrumentsToUse[x]) + openOrders, err := c.GetOpenOrders(ctx, instrumentsToUse[x]) if err != nil { return nil, err } @@ -940,7 +945,7 @@ func (c *COINUT) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, e // GetOrderHistory retrieves account order information // Can Limit response to specific order status -func (c *COINUT) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, error) { +func (c *COINUT) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) { if err := req.Validate(); err != nil { return nil, err } @@ -1011,7 +1016,7 @@ func (c *COINUT) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, e } for x := range instrumentsToUse { - orders, err := c.GetTradeHistory(instrumentsToUse[x], -1, -1) + orders, err := c.GetTradeHistory(ctx, instrumentsToUse[x], -1, -1) if err != nil { return nil, err } @@ -1045,7 +1050,7 @@ func (c *COINUT) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, e } // AuthenticateWebsocket sends an authentication message to the websocket -func (c *COINUT) AuthenticateWebsocket() error { +func (c *COINUT) AuthenticateWebsocket(_ context.Context) error { return c.wsAuthenticate() } @@ -1057,7 +1062,7 @@ func (c *COINUT) loadInstrumentsIfNotLoaded() error { return err } } else { - err := c.SeedInstruments() + err := c.SeedInstruments(context.TODO()) if err != nil { return err } @@ -1068,17 +1073,17 @@ func (c *COINUT) loadInstrumentsIfNotLoaded() error { // ValidateCredentials validates current credentials used for wrapper // functionality -func (c *COINUT) ValidateCredentials(assetType asset.Item) error { - _, err := c.UpdateAccountInfo(assetType) +func (c *COINUT) ValidateCredentials(ctx context.Context, assetType asset.Item) error { + _, err := c.UpdateAccountInfo(ctx, assetType) return c.CheckTransientError(err) } // GetHistoricCandles returns candles between a time period for a set time interval -func (c *COINUT) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (c *COINUT) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { return kline.Item{}, common.ErrFunctionNotSupported } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (c *COINUT) GetHistoricCandlesExtended(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (c *COINUT) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { return kline.Item{}, common.ErrFunctionNotSupported } diff --git a/exchanges/exchange.go b/exchanges/exchange.go index f1ee3d82..16f702a6 100644 --- a/exchanges/exchange.go +++ b/exchanges/exchange.go @@ -1,6 +1,7 @@ package exchange import ( + "context" "errors" "fmt" "net" @@ -1136,7 +1137,7 @@ func (b *Base) GetSubscriptions() ([]stream.ChannelSubscription, error) { } // AuthenticateWebsocket sends an authentication message to the websocket -func (b *Base) AuthenticateWebsocket() error { +func (b *Base) AuthenticateWebsocket(_ context.Context) error { return common.ErrFunctionNotSupported } @@ -1354,7 +1355,7 @@ func getURLTypeFromString(ep string) (URL, error) { } // UpdateOrderExecutionLimits updates order execution limits this is overridable -func (b *Base) UpdateOrderExecutionLimits(a asset.Item) error { +func (b *Base) UpdateOrderExecutionLimits(_ context.Context, _ asset.Item) error { return common.ErrNotYetImplemented } diff --git a/exchanges/exchange_test.go b/exchanges/exchange_test.go index f274b10c..50d08505 100644 --- a/exchanges/exchange_test.go +++ b/exchanges/exchange_test.go @@ -1,6 +1,7 @@ package exchange import ( + "context" "errors" "net" "net/http" @@ -2138,7 +2139,7 @@ func TestGetSubscriptions(t *testing.T) { func TestAuthenticateWebsocket(t *testing.T) { b := Base{} - if err := b.AuthenticateWebsocket(); err == nil { + if err := b.AuthenticateWebsocket(context.Background()); err == nil { t.Fatal("error cannot be nil") } } diff --git a/exchanges/exmo/exmo.go b/exchanges/exmo/exmo.go index a97b7513..6467485a 100644 --- a/exchanges/exmo/exmo.go +++ b/exchanges/exmo/exmo.go @@ -52,56 +52,56 @@ type EXMO struct { } // GetTrades returns the trades for a symbol or symbols -func (e *EXMO) GetTrades(symbol string) (map[string][]Trades, error) { +func (e *EXMO) GetTrades(ctx context.Context, symbol string) (map[string][]Trades, error) { v := url.Values{} v.Set("pair", symbol) result := make(map[string][]Trades) urlPath := fmt.Sprintf("/v%s/%s", exmoAPIVersion, exmoTrades) - return result, e.SendHTTPRequest(exchange.RestSpot, common.EncodeURLValues(urlPath, v), &result) + return result, e.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues(urlPath, v), &result) } // GetOrderbook returns the orderbook for a symbol or symbols -func (e *EXMO) GetOrderbook(symbol string) (map[string]Orderbook, error) { +func (e *EXMO) GetOrderbook(ctx context.Context, symbol string) (map[string]Orderbook, error) { v := url.Values{} v.Set("pair", symbol) result := make(map[string]Orderbook) urlPath := fmt.Sprintf("/v%s/%s", exmoAPIVersion, exmoOrderbook) - return result, e.SendHTTPRequest(exchange.RestSpot, common.EncodeURLValues(urlPath, v), &result) + return result, e.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues(urlPath, v), &result) } // GetTicker returns the ticker for a symbol or symbols -func (e *EXMO) GetTicker() (map[string]Ticker, error) { +func (e *EXMO) GetTicker(ctx context.Context) (map[string]Ticker, error) { v := url.Values{} result := make(map[string]Ticker) urlPath := fmt.Sprintf("/v%s/%s", exmoAPIVersion, exmoTicker) - return result, e.SendHTTPRequest(exchange.RestSpot, common.EncodeURLValues(urlPath, v), &result) + return result, e.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues(urlPath, v), &result) } // GetPairSettings returns the pair settings for a symbol or symbols -func (e *EXMO) GetPairSettings() (map[string]PairSettings, error) { +func (e *EXMO) GetPairSettings(ctx context.Context) (map[string]PairSettings, error) { result := make(map[string]PairSettings) urlPath := fmt.Sprintf("/v%s/%s", exmoAPIVersion, exmoPairSettings) - return result, e.SendHTTPRequest(exchange.RestSpot, urlPath, &result) + return result, e.SendHTTPRequest(ctx, exchange.RestSpot, urlPath, &result) } // GetCurrency returns a list of currencies -func (e *EXMO) GetCurrency() ([]string, error) { +func (e *EXMO) GetCurrency(ctx context.Context) ([]string, error) { var result []string urlPath := fmt.Sprintf("/v%s/%s", exmoAPIVersion, exmoCurrency) - return result, e.SendHTTPRequest(exchange.RestSpot, urlPath, &result) + return result, e.SendHTTPRequest(ctx, exchange.RestSpot, urlPath, &result) } // GetUserInfo returns the user info -func (e *EXMO) GetUserInfo() (UserInfo, error) { +func (e *EXMO) GetUserInfo(ctx context.Context) (UserInfo, error) { var result UserInfo - err := e.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, exmoUserInfo, url.Values{}, &result) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, exmoUserInfo, url.Values{}, &result) return result, err } // CreateOrder creates an order // Params: pair, quantity, price and type // Type can be buy, sell, market_buy, market_sell, market_buy_total and market_sell_total -func (e *EXMO) CreateOrder(pair, orderType string, price, amount float64) (int64, error) { +func (e *EXMO) CreateOrder(ctx context.Context, pair, orderType string, price, amount float64) (int64, error) { type response struct { OrderID int64 `json:"order_id"` Result bool `json:"result"` @@ -115,7 +115,7 @@ func (e *EXMO) CreateOrder(pair, orderType string, price, amount float64) (int64 v.Set("quantity", strconv.FormatFloat(amount, 'f', -1, 64)) var resp response - err := e.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, exmoOrderCreate, v, &resp) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, exmoOrderCreate, v, &resp) if !resp.Result { return -1, errors.New(resp.Error) } @@ -123,7 +123,7 @@ func (e *EXMO) CreateOrder(pair, orderType string, price, amount float64) (int64 } // CancelExistingOrder cancels an order by the orderID -func (e *EXMO) CancelExistingOrder(orderID int64) error { +func (e *EXMO) CancelExistingOrder(ctx context.Context, orderID int64) error { v := url.Values{} v.Set("order_id", strconv.FormatInt(orderID, 10)) type response struct { @@ -131,7 +131,7 @@ func (e *EXMO) CancelExistingOrder(orderID int64) error { Error string `json:"error"` } var resp response - err := e.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, exmoOrderCancel, v, &resp) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, exmoOrderCancel, v, &resp) if !resp.Result { return errors.New(resp.Error) } @@ -139,14 +139,14 @@ func (e *EXMO) CancelExistingOrder(orderID int64) error { } // GetOpenOrders returns the users open orders -func (e *EXMO) GetOpenOrders() (map[string]OpenOrders, error) { +func (e *EXMO) GetOpenOrders(ctx context.Context) (map[string]OpenOrders, error) { result := make(map[string]OpenOrders) - err := e.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, exmoOpenOrders, url.Values{}, &result) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, exmoOpenOrders, url.Values{}, &result) return result, err } // GetUserTrades returns the user trades -func (e *EXMO) GetUserTrades(pair, offset, limit string) (map[string][]UserTrades, error) { +func (e *EXMO) GetUserTrades(ctx context.Context, pair, offset, limit string) (map[string][]UserTrades, error) { result := make(map[string][]UserTrades) v := url.Values{} v.Set("pair", pair) @@ -159,12 +159,12 @@ func (e *EXMO) GetUserTrades(pair, offset, limit string) (map[string][]UserTrade v.Set("limit", limit) } - err := e.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, exmoUserTrades, v, &result) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, exmoUserTrades, v, &result) return result, err } // GetCancelledOrders returns a list of cancelled orders -func (e *EXMO) GetCancelledOrders(offset, limit string) ([]CancelledOrder, error) { +func (e *EXMO) GetCancelledOrders(ctx context.Context, offset, limit string) ([]CancelledOrder, error) { var result []CancelledOrder v := url.Values{} @@ -176,35 +176,35 @@ func (e *EXMO) GetCancelledOrders(offset, limit string) ([]CancelledOrder, error v.Set("limit", limit) } - err := e.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, exmoCancelledOrders, v, &result) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, exmoCancelledOrders, v, &result) return result, err } // GetOrderTrades returns a history of order trade details for the specific orderID -func (e *EXMO) GetOrderTrades(orderID int64) (OrderTrades, error) { +func (e *EXMO) GetOrderTrades(ctx context.Context, orderID int64) (OrderTrades, error) { var result OrderTrades v := url.Values{} v.Set("order_id", strconv.FormatInt(orderID, 10)) - err := e.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, exmoOrderTrades, v, &result) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, exmoOrderTrades, v, &result) return result, err } // GetRequiredAmount calculates the sum of buying a certain amount of currency // for the particular currency pair -func (e *EXMO) GetRequiredAmount(pair string, amount float64) (RequiredAmount, error) { +func (e *EXMO) GetRequiredAmount(ctx context.Context, pair string, amount float64) (RequiredAmount, error) { v := url.Values{} v.Set("pair", pair) v.Set("quantity", strconv.FormatFloat(amount, 'f', -1, 64)) var result RequiredAmount - err := e.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, exmoRequiredAmount, v, &result) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, exmoRequiredAmount, v, &result) return result, err } // GetCryptoDepositAddress returns a list of addresses for cryptocurrency deposits -func (e *EXMO) GetCryptoDepositAddress() (map[string]string, error) { +func (e *EXMO) GetCryptoDepositAddress(ctx context.Context) (map[string]string, error) { var result interface{} - err := e.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, exmoDepositAddress, url.Values{}, &result) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, exmoDepositAddress, url.Values{}, &result) if err != nil { return nil, err } @@ -224,7 +224,7 @@ func (e *EXMO) GetCryptoDepositAddress() (map[string]string, error) { // WithdrawCryptocurrency withdraws a cryptocurrency from the exchange to the desired address // NOTE: This API function is available only after request to their tech support team -func (e *EXMO) WithdrawCryptocurrency(currency, address, invoice string, amount float64) (int64, error) { +func (e *EXMO) WithdrawCryptocurrency(ctx context.Context, currency, address, invoice string, amount float64) (int64, error) { type response struct { TaskID int64 `json:"task_id,string"` Result bool `json:"result"` @@ -242,7 +242,7 @@ func (e *EXMO) WithdrawCryptocurrency(currency, address, invoice string, amount v.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) var resp response - err := e.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, exmoWithdrawCrypt, v, &resp) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, exmoWithdrawCrypt, v, &resp) if err != nil { return -1, err } @@ -253,7 +253,7 @@ func (e *EXMO) WithdrawCryptocurrency(currency, address, invoice string, amount } // GetWithdrawTXID gets the result of a withdrawal request -func (e *EXMO) GetWithdrawTXID(taskID int64) (string, error) { +func (e *EXMO) GetWithdrawTXID(ctx context.Context, taskID int64) (string, error) { type response struct { Status bool `json:"status"` TXID string `json:"txid"` @@ -263,43 +263,43 @@ func (e *EXMO) GetWithdrawTXID(taskID int64) (string, error) { v.Set("task_id", strconv.FormatInt(taskID, 10)) var result response - err := e.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, exmoGetWithdrawTXID, v, &result) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, exmoGetWithdrawTXID, v, &result) return result.TXID, err } // ExcodeCreate creates an EXMO coupon -func (e *EXMO) ExcodeCreate(currency string, amount float64) (ExcodeCreate, error) { +func (e *EXMO) ExcodeCreate(ctx context.Context, currency string, amount float64) (ExcodeCreate, error) { v := url.Values{} v.Set("currency", currency) v.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) var result ExcodeCreate - err := e.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, exmoExcodeCreate, v, &result) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, exmoExcodeCreate, v, &result) return result, err } // ExcodeLoad loads an EXMO coupon -func (e *EXMO) ExcodeLoad(excode string) (ExcodeLoad, error) { +func (e *EXMO) ExcodeLoad(ctx context.Context, excode string) (ExcodeLoad, error) { v := url.Values{} v.Set("code", excode) var result ExcodeLoad - err := e.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, exmoExcodeLoad, v, &result) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, exmoExcodeLoad, v, &result) return result, err } // GetWalletHistory returns the users deposit/withdrawal history -func (e *EXMO) GetWalletHistory(date int64) (WalletHistory, error) { +func (e *EXMO) GetWalletHistory(ctx context.Context, date int64) (WalletHistory, error) { v := url.Values{} v.Set("date", strconv.FormatInt(date, 10)) var result WalletHistory - err := e.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, exmoWalletHistory, v, &result) + err := e.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, exmoWalletHistory, v, &result) return result, err } // SendHTTPRequest sends an unauthenticated HTTP request -func (e *EXMO) SendHTTPRequest(endpoint exchange.URL, path string, result interface{}) error { +func (e *EXMO) SendHTTPRequest(ctx context.Context, endpoint exchange.URL, path string, result interface{}) error { urlPath, err := e.API.Endpoints.GetURL(endpoint) if err != nil { return err @@ -313,13 +313,13 @@ func (e *EXMO) SendHTTPRequest(endpoint exchange.URL, path string, result interf HTTPDebugging: e.HTTPDebugging, HTTPRecording: e.HTTPRecording, } - return e.SendPayload(context.Background(), request.Unset, func() (*request.Item, error) { + return e.SendPayload(ctx, request.Unset, func() (*request.Item, error) { return item, nil }) } // SendAuthenticatedHTTPRequest sends an authenticated HTTP request -func (e *EXMO) SendAuthenticatedHTTPRequest(epath exchange.URL, method, endpoint string, vals url.Values, result interface{}) error { +func (e *EXMO) SendAuthenticatedHTTPRequest(ctx context.Context, epath exchange.URL, method, endpoint string, vals url.Values, result interface{}) error { if !e.AllowAuthenticatedRequest() { return fmt.Errorf("%s %w", e.Name, exchange.ErrAuthenticatedRequestWithoutCredentialsSet) } @@ -331,7 +331,7 @@ func (e *EXMO) SendAuthenticatedHTTPRequest(epath exchange.URL, method, endpoint path := urlPath + fmt.Sprintf("/v%s/%s", exmoAPIVersion, endpoint) - return e.SendPayload(context.Background(), request.Unset, func() (*request.Item, error) { + return e.SendPayload(ctx, request.Unset, func() (*request.Item, error) { n := e.Requester.GetNonce(true).String() vals.Set("nonce", n) diff --git a/exchanges/exmo/exmo_test.go b/exchanges/exmo/exmo_test.go index e3db1350..b3d5a4b5 100644 --- a/exchanges/exmo/exmo_test.go +++ b/exchanges/exmo/exmo_test.go @@ -1,6 +1,7 @@ package exmo import ( + "context" "log" "os" "testing" @@ -52,7 +53,7 @@ func TestMain(m *testing.M) { func TestGetTrades(t *testing.T) { t.Parallel() - _, err := e.GetTrades("BTC_USD") + _, err := e.GetTrades(context.Background(), "BTC_USD") if err != nil { t.Errorf("Err: %s", err) } @@ -60,7 +61,7 @@ func TestGetTrades(t *testing.T) { func TestGetOrderbook(t *testing.T) { t.Parallel() - _, err := e.GetOrderbook("BTC_USD") + _, err := e.GetOrderbook(context.Background(), "BTC_USD") if err != nil { t.Errorf("Err: %s", err) } @@ -68,7 +69,7 @@ func TestGetOrderbook(t *testing.T) { func TestGetTicker(t *testing.T) { t.Parallel() - _, err := e.GetTicker() + _, err := e.GetTicker(context.Background()) if err != nil { t.Errorf("Err: %s", err) } @@ -76,7 +77,7 @@ func TestGetTicker(t *testing.T) { func TestGetPairSettings(t *testing.T) { t.Parallel() - _, err := e.GetPairSettings() + _, err := e.GetPairSettings(context.Background()) if err != nil { t.Errorf("Err: %s", err) } @@ -84,7 +85,7 @@ func TestGetPairSettings(t *testing.T) { func TestGetCurrency(t *testing.T) { t.Parallel() - _, err := e.GetCurrency() + _, err := e.GetCurrency(context.Background()) if err != nil { t.Errorf("Err: %s", err) } @@ -95,7 +96,7 @@ func TestGetUserInfo(t *testing.T) { if !areTestAPIKeysSet() { t.Skip() } - _, err := e.GetUserInfo() + _, err := e.GetUserInfo(context.Background()) if err != nil { t.Errorf("Err: %s", err) } @@ -106,7 +107,7 @@ func TestGetRequiredAmount(t *testing.T) { if !areTestAPIKeysSet() { t.Skip() } - _, err := e.GetRequiredAmount("BTC_USD", 100) + _, err := e.GetRequiredAmount(context.Background(), "BTC_USD", 100) if err != nil { t.Errorf("Err: %s", err) } @@ -126,7 +127,7 @@ func setFeeBuilder() *exchange.FeeBuilder { // TestGetFeeByTypeOfflineTradeFee logic test func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { var feeBuilder = setFeeBuilder() - _, err := e.GetFeeByType(feeBuilder) + _, err := e.GetFeeByType(context.Background(), feeBuilder) if err != nil { t.Fatal(err) } @@ -258,7 +259,7 @@ func TestGetActiveOrders(t *testing.T) { AssetType: asset.Spot, } - _, err := e.GetActiveOrders(&getOrdersRequest) + _, err := e.GetActiveOrders(context.Background(), &getOrdersRequest) if areTestAPIKeysSet() && err != nil { t.Errorf("Could not get open orders: %s", err) } else if !areTestAPIKeysSet() && err == nil { @@ -275,7 +276,7 @@ func TestGetOrderHistory(t *testing.T) { currPair.Delimiter = "_" getOrdersRequest.Pairs = []currency.Pair{currPair} - _, err := e.GetOrderHistory(&getOrdersRequest) + _, err := e.GetOrderHistory(context.Background(), &getOrdersRequest) if areTestAPIKeysSet() && err != nil { t.Errorf("Could not get order history: %s", err) } else if !areTestAPIKeysSet() && err == nil { @@ -307,7 +308,7 @@ func TestSubmitOrder(t *testing.T) { ClientID: "meowOrder", AssetType: asset.Spot, } - response, err := e.SubmitOrder(orderSubmission) + response, err := e.SubmitOrder(context.Background(), orderSubmission) if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) { t.Errorf("Order failed to be placed: %v", err) } else if !areTestAPIKeysSet() && err == nil { @@ -329,7 +330,7 @@ func TestCancelExchangeOrder(t *testing.T) { AssetType: asset.Spot, } - err := e.CancelOrder(orderCancellation) + err := e.CancelOrder(context.Background(), orderCancellation) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") } @@ -352,7 +353,7 @@ func TestCancelAllExchangeOrders(t *testing.T) { AssetType: asset.Spot, } - resp, err := e.CancelAllOrders(orderCancellation) + resp, err := e.CancelAllOrders(context.Background(), orderCancellation) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") @@ -370,7 +371,7 @@ func TestModifyOrder(t *testing.T) { if areTestAPIKeysSet() && !canManipulateRealOrders { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - _, err := e.ModifyOrder(&order.Modify{AssetType: asset.Spot}) + _, err := e.ModifyOrder(context.Background(), &order.Modify{AssetType: asset.Spot}) if err == nil { t.Error("ModifyOrder() Expected error") } @@ -390,7 +391,8 @@ func TestWithdraw(t *testing.T) { }, } - _, err := e.WithdrawCryptocurrencyFunds(&withdrawCryptoRequest) + _, err := e.WithdrawCryptocurrencyFunds(context.Background(), + &withdrawCryptoRequest) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") } @@ -405,7 +407,7 @@ func TestWithdrawFiat(t *testing.T) { } var withdrawFiatRequest = withdraw.Request{} - _, err := e.WithdrawFiatFunds(&withdrawFiatRequest) + _, err := e.WithdrawFiatFunds(context.Background(), &withdrawFiatRequest) if err != common.ErrFunctionNotSupported { t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err) } @@ -417,7 +419,8 @@ func TestWithdrawInternationalBank(t *testing.T) { } var withdrawFiatRequest = withdraw.Request{} - _, err := e.WithdrawFiatFundsToInternationalBank(&withdrawFiatRequest) + _, err := e.WithdrawFiatFundsToInternationalBank(context.Background(), + &withdrawFiatRequest) if err != common.ErrFunctionNotSupported { t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err) } @@ -425,12 +428,12 @@ func TestWithdrawInternationalBank(t *testing.T) { func TestGetDepositAddress(t *testing.T) { if areTestAPIKeysSet() { - _, err := e.GetDepositAddress(currency.LTC, "") + _, err := e.GetDepositAddress(context.Background(), currency.LTC, "") if err != nil { t.Error("GetDepositAddress() error", err) } } else { - _, err := e.GetDepositAddress(currency.LTC, "") + _, err := e.GetDepositAddress(context.Background(), currency.LTC, "") if err == nil { t.Error("GetDepositAddress() error cannot be nil") } @@ -443,7 +446,7 @@ func TestGetRecentTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = e.GetRecentTrades(currencyPair, asset.Spot) + _, err = e.GetRecentTrades(context.Background(), currencyPair, asset.Spot) if err != nil { t.Error(err) } @@ -455,7 +458,8 @@ func TestGetHistoricTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = e.GetHistoricTrades(currencyPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) + _, err = e.GetHistoricTrades(context.Background(), + currencyPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) if err != nil && err != common.ErrFunctionNotSupported { t.Error(err) } @@ -467,14 +471,14 @@ func TestUpdateTicker(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = e.UpdateTicker(cp, asset.Spot) + _, err = e.UpdateTicker(context.Background(), cp, asset.Spot) if err != nil { t.Error(err) } } func TestUpdateTickers(t *testing.T) { - err := e.UpdateTickers(asset.Spot) + err := e.UpdateTickers(context.Background(), asset.Spot) if err != nil { t.Error(err) } diff --git a/exchanges/exmo/exmo_wrapper.go b/exchanges/exmo/exmo_wrapper.go index 7b4ac61f..bf8eb2ab 100644 --- a/exchanges/exmo/exmo_wrapper.go +++ b/exchanges/exmo/exmo_wrapper.go @@ -1,6 +1,7 @@ package exmo import ( + "context" "errors" "fmt" "sort" @@ -40,7 +41,7 @@ func (e *EXMO) GetDefaultConfig() (*config.ExchangeConfig, error) { } if e.Features.Supports.RESTCapabilities.AutoPairUpdates { - err = e.UpdateTradablePairs(true) + err = e.UpdateTradablePairs(context.TODO(), true) if err != nil { return nil, err } @@ -145,15 +146,15 @@ func (e *EXMO) Run() { return } - err := e.UpdateTradablePairs(false) + err := e.UpdateTradablePairs(context.TODO(), false) if err != nil { log.Errorf(log.ExchangeSys, "%s failed to update tradable pairs. Err: %s", e.Name, err) } } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (e *EXMO) FetchTradablePairs(asset asset.Item) ([]string, error) { - pairs, err := e.GetPairSettings() +func (e *EXMO) FetchTradablePairs(ctx context.Context, asset asset.Item) ([]string, error) { + pairs, err := e.GetPairSettings(ctx) if err != nil { return nil, err } @@ -168,8 +169,8 @@ func (e *EXMO) FetchTradablePairs(asset asset.Item) ([]string, error) { // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (e *EXMO) UpdateTradablePairs(forceUpdate bool) error { - pairs, err := e.FetchTradablePairs(asset.Spot) +func (e *EXMO) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { + pairs, err := e.FetchTradablePairs(ctx, asset.Spot) if err != nil { return err } @@ -183,8 +184,8 @@ func (e *EXMO) UpdateTradablePairs(forceUpdate bool) error { } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (e *EXMO) UpdateTickers(a asset.Item) error { - result, err := e.GetTicker() +func (e *EXMO) UpdateTickers(ctx context.Context, a asset.Item) error { + result, err := e.GetTicker(ctx) if err != nil { return err } @@ -217,8 +218,8 @@ func (e *EXMO) UpdateTickers(a asset.Item) error { } // UpdateTicker updates and returns the ticker for a currency pair -func (e *EXMO) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) { - err := e.UpdateTickers(a) +func (e *EXMO) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { + err := e.UpdateTickers(ctx, a) if err != nil { return nil, err } @@ -226,25 +227,25 @@ func (e *EXMO) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error } // FetchTicker returns the ticker for a currency pair -func (e *EXMO) FetchTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) { +func (e *EXMO) FetchTicker(ctx context.Context, p currency.Pair, assetType asset.Item) (*ticker.Price, error) { tick, err := ticker.GetTicker(e.Name, p, assetType) if err != nil { - return e.UpdateTicker(p, assetType) + return e.UpdateTicker(ctx, p, assetType) } return tick, nil } // FetchOrderbook returns the orderbook for a currency pair -func (e *EXMO) FetchOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (e *EXMO) FetchOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { ob, err := orderbook.Get(e.Name, p, assetType) if err != nil { - return e.UpdateOrderbook(p, assetType) + return e.UpdateOrderbook(ctx, p, assetType) } return ob, nil } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (e *EXMO) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (e *EXMO) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { callingBook := &orderbook.Base{ Exchange: e.Name, Pair: p, @@ -261,7 +262,7 @@ func (e *EXMO) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderboo return callingBook, err } - result, err := e.GetOrderbook(pairsCollated) + result, err := e.GetOrderbook(ctx, pairsCollated) if err != nil { return callingBook, err } @@ -330,10 +331,10 @@ func (e *EXMO) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderboo // UpdateAccountInfo retrieves balances for all enabled currencies for the // Exmo exchange -func (e *EXMO) UpdateAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (e *EXMO) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { var response account.Holdings response.Exchange = e.Name - result, err := e.GetUserInfo() + result, err := e.GetUserInfo(ctx) if err != nil { return response, err } @@ -366,10 +367,10 @@ func (e *EXMO) UpdateAccountInfo(assetType asset.Item) (account.Holdings, error) } // FetchAccountInfo retrieves balances for all enabled currencies -func (e *EXMO) FetchAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (e *EXMO) FetchAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { acc, err := account.GetHoldings(e.Name, assetType) if err != nil { - return e.UpdateAccountInfo(assetType) + return e.UpdateAccountInfo(ctx, assetType) } return acc, nil @@ -377,24 +378,24 @@ func (e *EXMO) FetchAccountInfo(assetType asset.Item) (account.Holdings, error) // GetFundingHistory returns funding history, deposits and // withdrawals -func (e *EXMO) GetFundingHistory() ([]exchange.FundHistory, error) { +func (e *EXMO) GetFundingHistory(ctx context.Context) ([]exchange.FundHistory, error) { return nil, common.ErrFunctionNotSupported } // GetWithdrawalsHistory returns previous withdrawals data -func (e *EXMO) GetWithdrawalsHistory(c currency.Code) (resp []exchange.WithdrawalHistory, err error) { +func (e *EXMO) GetWithdrawalsHistory(ctx context.Context, c currency.Code) (resp []exchange.WithdrawalHistory, err error) { return nil, common.ErrNotYetImplemented } // GetRecentTrades returns the most recent trades for a currency and asset -func (e *EXMO) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade.Data, error) { +func (e *EXMO) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { var err error p, err = e.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err } var tradeData map[string][]Trades - tradeData, err = e.GetTrades(p.String()) + tradeData, err = e.GetTrades(ctx, p.String()) if err != nil { return nil, err } @@ -428,12 +429,12 @@ func (e *EXMO) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade.D } // GetHistoricTrades returns historic trade data within the timeframe provided -func (e *EXMO) GetHistoricTrades(_ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { +func (e *EXMO) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { return nil, common.ErrFunctionNotSupported } // SubmitOrder submits a new order -func (e *EXMO) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { +func (e *EXMO) SubmitOrder(ctx context.Context, s *order.Submit) (order.SubmitResponse, error) { var submitOrderResponse order.SubmitResponse if err := s.Validate(); err != nil { return submitOrderResponse, err @@ -456,7 +457,7 @@ func (e *EXMO) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { return submitOrderResponse, err } - response, err := e.CreateOrder(fPair.String(), oT, s.Price, s.Amount) + response, err := e.CreateOrder(ctx, fPair.String(), oT, s.Price, s.Amount) if err != nil { return submitOrderResponse, err } @@ -473,12 +474,12 @@ func (e *EXMO) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (e *EXMO) ModifyOrder(action *order.Modify) (order.Modify, error) { +func (e *EXMO) ModifyOrder(ctx context.Context, action *order.Modify) (order.Modify, error) { return order.Modify{}, common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number -func (e *EXMO) CancelOrder(o *order.Cancel) error { +func (e *EXMO) CancelOrder(ctx context.Context, o *order.Cancel) error { if err := o.Validate(o.StandardCancel()); err != nil { return err } @@ -488,27 +489,27 @@ func (e *EXMO) CancelOrder(o *order.Cancel) error { return err } - return e.CancelExistingOrder(orderIDInt) + return e.CancelExistingOrder(ctx, orderIDInt) } // CancelBatchOrders cancels an orders by their corresponding ID numbers -func (e *EXMO) CancelBatchOrders(o []order.Cancel) (order.CancelBatchResponse, error) { +func (e *EXMO) CancelBatchOrders(ctx context.Context, o []order.Cancel) (order.CancelBatchResponse, error) { return order.CancelBatchResponse{}, common.ErrNotYetImplemented } // CancelAllOrders cancels all orders associated with a currency pair -func (e *EXMO) CancelAllOrders(_ *order.Cancel) (order.CancelAllResponse, error) { +func (e *EXMO) CancelAllOrders(ctx context.Context, _ *order.Cancel) (order.CancelAllResponse, error) { cancelAllOrdersResponse := order.CancelAllResponse{ Status: make(map[string]string), } - openOrders, err := e.GetOpenOrders() + openOrders, err := e.GetOpenOrders(ctx) if err != nil { return cancelAllOrdersResponse, err } for i := range openOrders { - err = e.CancelExistingOrder(openOrders[i].OrderID) + err = e.CancelExistingOrder(ctx, openOrders[i].OrderID) if err != nil { cancelAllOrdersResponse.Status[strconv.FormatInt(openOrders[i].OrderID, 10)] = err.Error() } @@ -518,18 +519,19 @@ func (e *EXMO) CancelAllOrders(_ *order.Cancel) (order.CancelAllResponse, error) } // GetOrderInfo returns order information based on order ID -func (e *EXMO) GetOrderInfo(orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { +func (e *EXMO) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { var orderDetail order.Detail return orderDetail, common.ErrNotYetImplemented } // GetDepositAddress returns a deposit address for a specified currency -func (e *EXMO) GetDepositAddress(cryptocurrency currency.Code, _ string) (string, error) { - fullAddr, err := e.GetCryptoDepositAddress() +func (e *EXMO) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _ string) (string, error) { + fullAddr, err := e.GetCryptoDepositAddress(ctx) if err != nil { return "", err } + // TODO: Protect map with mutex addr, ok := fullAddr[cryptocurrency.String()] if !ok { return "", fmt.Errorf("currency %s could not be found, please generate via the exmo website", cryptocurrency.String()) @@ -540,11 +542,12 @@ func (e *EXMO) GetDepositAddress(cryptocurrency currency.Code, _ string) (string // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is // submitted -func (e *EXMO) WithdrawCryptocurrencyFunds(withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *EXMO) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } - resp, err := e.WithdrawCryptocurrency(withdrawRequest.Currency.String(), + resp, err := e.WithdrawCryptocurrency(ctx, + withdrawRequest.Currency.String(), withdrawRequest.Crypto.Address, withdrawRequest.Crypto.AddressTag, withdrawRequest.Amount) @@ -556,18 +559,18 @@ func (e *EXMO) WithdrawCryptocurrencyFunds(withdrawRequest *withdraw.Request) (* // WithdrawFiatFunds returns a withdrawal ID when a // withdrawal is submitted -func (e *EXMO) WithdrawFiatFunds(_ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *EXMO) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a // withdrawal is submitted -func (e *EXMO) WithdrawFiatFundsToInternationalBank(_ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (e *EXMO) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // GetFeeByType returns an estimate of fee based on type of transaction -func (e *EXMO) GetFeeByType(feeBuilder *exchange.FeeBuilder) (float64, error) { +func (e *EXMO) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { if !e.AllowAuthenticatedRequest() && // Todo check connection status feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { feeBuilder.FeeType = exchange.OfflineTradeFee @@ -576,12 +579,12 @@ func (e *EXMO) GetFeeByType(feeBuilder *exchange.FeeBuilder) (float64, error) { } // GetActiveOrders retrieves any orders that are active/open -func (e *EXMO) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, error) { +func (e *EXMO) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) { if err := req.Validate(); err != nil { return nil, err } - resp, err := e.GetOpenOrders() + resp, err := e.GetOpenOrders(ctx) if err != nil { return nil, err } @@ -613,7 +616,7 @@ func (e *EXMO) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, err // GetOrderHistory retrieves account order information // Can Limit response to specific order status -func (e *EXMO) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, error) { +func (e *EXMO) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) { if err := req.Validate(); err != nil { return nil, err } @@ -629,7 +632,7 @@ func (e *EXMO) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, err return nil, err } - resp, err := e.GetUserTrades(fpair.String(), "", "10000") + resp, err := e.GetUserTrades(ctx, fpair.String(), "", "10000") if err != nil { return nil, err } @@ -664,17 +667,17 @@ func (e *EXMO) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, err // ValidateCredentials validates current credentials used for wrapper // functionality -func (e *EXMO) ValidateCredentials(assetType asset.Item) error { - _, err := e.UpdateAccountInfo(assetType) +func (e *EXMO) ValidateCredentials(ctx context.Context, assetType asset.Item) error { + _, err := e.UpdateAccountInfo(ctx, assetType) return e.CheckTransientError(err) } // GetHistoricCandles returns candles between a time period for a set time interval -func (e *EXMO) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (e *EXMO) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { return kline.Item{}, common.ErrFunctionNotSupported } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (e *EXMO) GetHistoricCandlesExtended(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (e *EXMO) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { return kline.Item{}, common.ErrFunctionNotSupported } diff --git a/exchanges/ftx/ftx.go b/exchanges/ftx/ftx.go index c8ad3f19..adaf1c47 100644 --- a/exchanges/ftx/ftx.go +++ b/exchanges/ftx/ftx.go @@ -144,7 +144,7 @@ var ( ) // GetHistoricalIndex gets historical index data -func (f *FTX) GetHistoricalIndex(indexName string, resolution int64, startTime, endTime time.Time) ([]OHLCVData, error) { +func (f *FTX) GetHistoricalIndex(ctx context.Context, indexName string, resolution int64, startTime, endTime time.Time) ([]OHLCVData, error) { params := url.Values{} if indexName == "" { return nil, errors.New("indexName is a mandatory field") @@ -166,7 +166,7 @@ func (f *FTX) GetHistoricalIndex(indexName string, resolution int64, startTime, Data []OHLCVData `json:"result"` }{} endpoint := common.EncodeURLValues(fmt.Sprintf(getIndexCandles, indexName), params) - return resp.Data, f.SendHTTPRequest(exchange.RestSpot, endpoint, &resp) + return resp.Data, f.SendHTTPRequest(ctx, exchange.RestSpot, endpoint, &resp) } func checkResolution(res int64) error { @@ -179,24 +179,24 @@ func checkResolution(res int64) error { } // GetMarkets gets market data -func (f *FTX) GetMarkets() ([]MarketData, error) { +func (f *FTX) GetMarkets(ctx context.Context) ([]MarketData, error) { resp := struct { Data []MarketData `json:"result"` }{} - return resp.Data, f.SendHTTPRequest(exchange.RestSpot, getMarkets, &resp) + return resp.Data, f.SendHTTPRequest(ctx, exchange.RestSpot, getMarkets, &resp) } // GetMarket gets market data for a provided asset type -func (f *FTX) GetMarket(marketName string) (MarketData, error) { +func (f *FTX) GetMarket(ctx context.Context, marketName string) (MarketData, error) { resp := struct { Data MarketData `json:"result"` }{} - return resp.Data, f.SendHTTPRequest(exchange.RestSpot, getMarket+marketName, + return resp.Data, f.SendHTTPRequest(ctx, exchange.RestSpot, getMarket+marketName, &resp) } // GetOrderbook gets orderbook for a given market with a given depth (default depth 20) -func (f *FTX) GetOrderbook(marketName string, depth int64) (OrderbookData, error) { +func (f *FTX) GetOrderbook(ctx context.Context, marketName string, depth int64) (OrderbookData, error) { result := struct { Data TempOBData `json:"result"` }{} @@ -208,7 +208,7 @@ func (f *FTX) GetOrderbook(marketName string, depth int64) (OrderbookData, error } var resp OrderbookData - err := f.SendHTTPRequest(exchange.RestSpot, fmt.Sprintf(getOrderbook, marketName, strDepth), &result) + err := f.SendHTTPRequest(ctx, exchange.RestSpot, fmt.Sprintf(getOrderbook, marketName, strDepth), &result) if err != nil { return resp, err } @@ -229,7 +229,7 @@ func (f *FTX) GetOrderbook(marketName string, depth int64) (OrderbookData, error } // GetTrades gets trades based on the conditions specified -func (f *FTX) GetTrades(marketName string, startTime, endTime, limit int64) ([]TradeData, error) { +func (f *FTX) GetTrades(ctx context.Context, marketName string, startTime, endTime, limit int64) ([]TradeData, error) { if marketName == "" { return nil, errors.New("a market pair must be specified") } @@ -249,11 +249,11 @@ func (f *FTX) GetTrades(marketName string, startTime, endTime, limit int64) ([]T Data []TradeData `json:"result"` }{} endpoint := common.EncodeURLValues(fmt.Sprintf(getTrades, marketName), params) - return resp.Data, f.SendHTTPRequest(exchange.RestSpot, endpoint, &resp) + return resp.Data, f.SendHTTPRequest(ctx, exchange.RestSpot, endpoint, &resp) } // GetHistoricalData gets historical OHLCV data for a given market pair -func (f *FTX) GetHistoricalData(marketName string, timeInterval, limit int64, startTime, endTime time.Time) ([]OHLCVData, error) { +func (f *FTX) GetHistoricalData(ctx context.Context, marketName string, timeInterval, limit int64, startTime, endTime time.Time) ([]OHLCVData, error) { if marketName == "" { return nil, errors.New("a market pair must be specified") } @@ -279,35 +279,35 @@ func (f *FTX) GetHistoricalData(marketName string, timeInterval, limit int64, st Data []OHLCVData `json:"result"` }{} endpoint := common.EncodeURLValues(fmt.Sprintf(getHistoricalData, marketName), params) - return resp.Data, f.SendHTTPRequest(exchange.RestSpot, endpoint, &resp) + return resp.Data, f.SendHTTPRequest(ctx, exchange.RestSpot, endpoint, &resp) } // GetFutures gets data on futures -func (f *FTX) GetFutures() ([]FuturesData, error) { +func (f *FTX) GetFutures(ctx context.Context) ([]FuturesData, error) { resp := struct { Data []FuturesData `json:"result"` }{} - return resp.Data, f.SendHTTPRequest(exchange.RestSpot, getFutures, &resp) + return resp.Data, f.SendHTTPRequest(ctx, exchange.RestSpot, getFutures, &resp) } // GetFuture gets data on a given future -func (f *FTX) GetFuture(futureName string) (FuturesData, error) { +func (f *FTX) GetFuture(ctx context.Context, futureName string) (FuturesData, error) { resp := struct { Data FuturesData `json:"result"` }{} - return resp.Data, f.SendHTTPRequest(exchange.RestSpot, getFuture+futureName, &resp) + return resp.Data, f.SendHTTPRequest(ctx, exchange.RestSpot, getFuture+futureName, &resp) } // GetFutureStats gets data on a given future's stats -func (f *FTX) GetFutureStats(futureName string) (FutureStatsData, error) { +func (f *FTX) GetFutureStats(ctx context.Context, futureName string) (FutureStatsData, error) { resp := struct { Data FutureStatsData `json:"result"` }{} - return resp.Data, f.SendHTTPRequest(exchange.RestSpot, fmt.Sprintf(getFutureStats, futureName), &resp) + return resp.Data, f.SendHTTPRequest(ctx, exchange.RestSpot, fmt.Sprintf(getFutureStats, futureName), &resp) } // GetFundingRates gets data on funding rates -func (f *FTX) GetFundingRates(startTime, endTime time.Time, future string) ([]FundingRatesData, error) { +func (f *FTX) GetFundingRates(ctx context.Context, startTime, endTime time.Time, future string) ([]FundingRatesData, error) { resp := struct { Data []FundingRatesData `json:"result"` }{} @@ -323,17 +323,17 @@ func (f *FTX) GetFundingRates(startTime, endTime time.Time, future string) ([]Fu params.Set("future", future) } endpoint := common.EncodeURLValues(getFundingRates, params) - return resp.Data, f.SendHTTPRequest(exchange.RestSpot, endpoint, &resp) + return resp.Data, f.SendHTTPRequest(ctx, exchange.RestSpot, endpoint, &resp) } // GetIndexWeights gets index weights -func (f *FTX) GetIndexWeights(index string) (IndexWeights, error) { +func (f *FTX) GetIndexWeights(ctx context.Context, index string) (IndexWeights, error) { var resp IndexWeights - return resp, f.SendHTTPRequest(exchange.RestSpot, fmt.Sprintf(getIndexWeights, index), &resp) + return resp, f.SendHTTPRequest(ctx, exchange.RestSpot, fmt.Sprintf(getIndexWeights, index), &resp) } // SendHTTPRequest sends an unauthenticated HTTP request -func (f *FTX) SendHTTPRequest(ep exchange.URL, path string, result interface{}) error { +func (f *FTX) SendHTTPRequest(ctx context.Context, ep exchange.URL, path string, result interface{}) error { endpoint, err := f.API.Endpoints.GetURL(ep) if err != nil { return err @@ -346,45 +346,45 @@ func (f *FTX) SendHTTPRequest(ep exchange.URL, path string, result interface{}) HTTPDebugging: f.HTTPDebugging, HTTPRecording: f.HTTPRecording, } - return f.SendPayload(context.Background(), request.Unset, func() (*request.Item, error) { + return f.SendPayload(ctx, request.Unset, func() (*request.Item, error) { return item, nil }) } // GetMarginBorrowRates gets borrowing rates for margin trading -func (f *FTX) GetMarginBorrowRates() ([]MarginFundingData, error) { +func (f *FTX) GetMarginBorrowRates(ctx context.Context) ([]MarginFundingData, error) { r := struct { Data []MarginFundingData `json:"result"` }{} - return r.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, marginBorrowRates, nil, &r) + return r.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, marginBorrowRates, nil, &r) } // GetMarginLendingRates gets lending rates for margin trading -func (f *FTX) GetMarginLendingRates() ([]MarginFundingData, error) { +func (f *FTX) GetMarginLendingRates(ctx context.Context) ([]MarginFundingData, error) { r := struct { Data []MarginFundingData `json:"result"` }{} - return r.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, marginLendingRates, nil, &r) + return r.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, marginLendingRates, nil, &r) } // MarginDailyBorrowedAmounts gets daily borrowed amounts for margin -func (f *FTX) MarginDailyBorrowedAmounts() ([]MarginDailyBorrowStats, error) { +func (f *FTX) MarginDailyBorrowedAmounts(ctx context.Context) ([]MarginDailyBorrowStats, error) { r := struct { Data []MarginDailyBorrowStats `json:"result"` }{} - return r.Data, f.SendHTTPRequest(exchange.RestSpot, dailyBorrowedAmounts, &r) + return r.Data, f.SendHTTPRequest(ctx, exchange.RestSpot, dailyBorrowedAmounts, &r) } // GetMarginMarketInfo gets margin market data -func (f *FTX) GetMarginMarketInfo(market string) ([]MarginMarketInfo, error) { +func (f *FTX) GetMarginMarketInfo(ctx context.Context, market string) ([]MarginMarketInfo, error) { r := struct { Data []MarginMarketInfo `json:"result"` }{} - return r.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, fmt.Sprintf(marginMarketInfo, market), nil, &r) + return r.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, fmt.Sprintf(marginMarketInfo, market), nil, &r) } // GetMarginBorrowHistory gets the margin borrow history data -func (f *FTX) GetMarginBorrowHistory(startTime, endTime time.Time) ([]MarginTransactionHistoryData, error) { +func (f *FTX) GetMarginBorrowHistory(ctx context.Context, startTime, endTime time.Time) ([]MarginTransactionHistoryData, error) { r := struct { Data []MarginTransactionHistoryData `json:"result"` }{} @@ -398,11 +398,11 @@ func (f *FTX) GetMarginBorrowHistory(startTime, endTime time.Time) ([]MarginTran params.Set("end_time", strconv.FormatInt(endTime.Unix(), 10)) } endpoint := common.EncodeURLValues(marginBorrowHistory, params) - return r.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, endpoint, nil, &r) + return r.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, endpoint, nil, &r) } // GetMarginMarketLendingHistory gets the markets margin lending rate history -func (f *FTX) GetMarginMarketLendingHistory(coin currency.Code, startTime, endTime time.Time) ([]MarginTransactionHistoryData, error) { +func (f *FTX) GetMarginMarketLendingHistory(ctx context.Context, coin currency.Code, startTime, endTime time.Time) ([]MarginTransactionHistoryData, error) { r := struct { Data []MarginTransactionHistoryData `json:"result"` }{} @@ -418,11 +418,11 @@ func (f *FTX) GetMarginMarketLendingHistory(coin currency.Code, startTime, endTi params.Set("end_time", strconv.FormatInt(endTime.Unix(), 10)) } endpoint := common.EncodeURLValues(marginLendingHistory, params) - return r.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, endpoint, params, &r) + return r.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, endpoint, params, &r) } // GetMarginLendingHistory gets margin lending history -func (f *FTX) GetMarginLendingHistory(coin currency.Code, startTime, endTime time.Time) ([]MarginTransactionHistoryData, error) { +func (f *FTX) GetMarginLendingHistory(ctx context.Context, coin currency.Code, startTime, endTime time.Time) ([]MarginTransactionHistoryData, error) { r := struct { Data []MarginTransactionHistoryData `json:"result"` }{} @@ -438,27 +438,27 @@ func (f *FTX) GetMarginLendingHistory(coin currency.Code, startTime, endTime tim params.Set("end_time", strconv.FormatInt(endTime.Unix(), 10)) } endpoint := common.EncodeURLValues(marginLendHistory, params) - return r.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, marginLendHistory, endpoint, &r) + return r.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, marginLendHistory, endpoint, &r) } // GetMarginLendingOffers gets margin lending offers -func (f *FTX) GetMarginLendingOffers() ([]LendingOffersData, error) { +func (f *FTX) GetMarginLendingOffers(ctx context.Context) ([]LendingOffersData, error) { r := struct { Data []LendingOffersData `json:"result"` }{} - return r.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, marginLendingOffers, nil, &r) + return r.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, marginLendingOffers, nil, &r) } // GetLendingInfo gets margin lending info -func (f *FTX) GetLendingInfo() ([]LendingInfoData, error) { +func (f *FTX) GetLendingInfo(ctx context.Context) ([]LendingInfoData, error) { r := struct { Data []LendingInfoData `json:"result"` }{} - return r.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, marginLendingInfo, nil, &r) + return r.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, marginLendingInfo, nil, &r) } // SubmitLendingOffer submits an offer for margin lending -func (f *FTX) SubmitLendingOffer(coin currency.Code, size, rate float64) error { +func (f *FTX) SubmitLendingOffer(ctx context.Context, coin currency.Code, size, rate float64) error { resp := struct { Result string `json:"result"` Success bool `json:"success"` @@ -468,7 +468,7 @@ func (f *FTX) SubmitLendingOffer(coin currency.Code, size, rate float64) error { req["size"] = size req["rate"] = rate - if err := f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodPost, marginLendingOffers, req, &resp); err != nil { + if err := f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, marginLendingOffers, req, &resp); err != nil { return err } @@ -479,78 +479,78 @@ func (f *FTX) SubmitLendingOffer(coin currency.Code, size, rate float64) error { } // GetAccountInfo gets account info -func (f *FTX) GetAccountInfo() (AccountInfoData, error) { +func (f *FTX) GetAccountInfo(ctx context.Context) (AccountInfoData, error) { resp := struct { Data AccountInfoData `json:"result"` }{} - return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getAccountInfo, nil, &resp) + return resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, getAccountInfo, nil, &resp) } // GetPositions gets the users positions -func (f *FTX) GetPositions() ([]PositionData, error) { +func (f *FTX) GetPositions(ctx context.Context) ([]PositionData, error) { resp := struct { Data []PositionData `json:"result"` }{} - return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getPositions, nil, &resp) + return resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, getPositions, nil, &resp) } // ChangeAccountLeverage changes default leverage used by account -func (f *FTX) ChangeAccountLeverage(leverage float64) error { +func (f *FTX) ChangeAccountLeverage(ctx context.Context, leverage float64) error { req := make(map[string]interface{}) req["leverage"] = leverage - return f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodPost, setLeverage, req, nil) + return f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, setLeverage, req, nil) } // GetCoins gets coins' data in the account wallet -func (f *FTX) GetCoins() ([]WalletCoinsData, error) { +func (f *FTX) GetCoins(ctx context.Context) ([]WalletCoinsData, error) { resp := struct { Data []WalletCoinsData `json:"result"` }{} - return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getCoins, nil, &resp) + return resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, getCoins, nil, &resp) } // GetBalances gets balances of the account -func (f *FTX) GetBalances() ([]WalletBalance, error) { +func (f *FTX) GetBalances(ctx context.Context) ([]WalletBalance, error) { resp := struct { Data []WalletBalance `json:"result"` }{} - return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getBalances, nil, &resp) + return resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, getBalances, nil, &resp) } // GetAllWalletBalances gets all wallets' balances -func (f *FTX) GetAllWalletBalances() (AllWalletBalances, error) { +func (f *FTX) GetAllWalletBalances(ctx context.Context) (AllWalletBalances, error) { resp := struct { Data AllWalletBalances `json:"result"` }{} - return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getAllWalletBalances, nil, &resp) + return resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, getAllWalletBalances, nil, &resp) } // FetchDepositAddress gets deposit address for a given coin -func (f *FTX) FetchDepositAddress(coin currency.Code) (DepositData, error) { +func (f *FTX) FetchDepositAddress(ctx context.Context, coin currency.Code) (DepositData, error) { resp := struct { Data DepositData `json:"result"` }{} - return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getDepositAddress+coin.Upper().String(), nil, &resp) + return resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, getDepositAddress+coin.Upper().String(), nil, &resp) } // FetchDepositHistory gets deposit history -func (f *FTX) FetchDepositHistory() ([]TransactionData, error) { +func (f *FTX) FetchDepositHistory(ctx context.Context) ([]TransactionData, error) { resp := struct { Data []TransactionData `json:"result"` }{} - return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getDepositHistory, nil, &resp) + return resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, getDepositHistory, nil, &resp) } // FetchWithdrawalHistory gets withdrawal history -func (f *FTX) FetchWithdrawalHistory() ([]TransactionData, error) { +func (f *FTX) FetchWithdrawalHistory(ctx context.Context) ([]TransactionData, error) { resp := struct { Data []TransactionData `json:"result"` }{} - return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getWithdrawalHistory, nil, &resp) + return resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, getWithdrawalHistory, nil, &resp) } // Withdraw sends a withdrawal request -func (f *FTX) Withdraw(coin currency.Code, address, tag, password, code string, size float64) (TransactionData, error) { +func (f *FTX) Withdraw(ctx context.Context, coin currency.Code, address, tag, password, code string, size float64) (TransactionData, error) { req := make(map[string]interface{}) req["coin"] = coin.Upper().String() req["address"] = address @@ -567,11 +567,11 @@ func (f *FTX) Withdraw(coin currency.Code, address, tag, password, code string, resp := struct { Data TransactionData `json:"result"` }{} - return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodPost, withdrawRequest, req, &resp) + return resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, withdrawRequest, req, &resp) } // GetOpenOrders gets open orders -func (f *FTX) GetOpenOrders(marketName string) ([]OrderData, error) { +func (f *FTX) GetOpenOrders(ctx context.Context, marketName string) ([]OrderData, error) { params := url.Values{} if marketName != "" { params.Set("market", marketName) @@ -580,11 +580,11 @@ func (f *FTX) GetOpenOrders(marketName string) ([]OrderData, error) { Data []OrderData `json:"result"` }{} endpoint := common.EncodeURLValues(getOpenOrders, params) - return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, endpoint, nil, &resp) + return resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, endpoint, nil, &resp) } // FetchOrderHistory gets order history -func (f *FTX) FetchOrderHistory(marketName string, startTime, endTime time.Time, limit string) ([]OrderData, error) { +func (f *FTX) FetchOrderHistory(ctx context.Context, marketName string, startTime, endTime time.Time, limit string) ([]OrderData, error) { resp := struct { Data []OrderData `json:"result"` }{} @@ -603,11 +603,11 @@ func (f *FTX) FetchOrderHistory(marketName string, startTime, endTime time.Time, params.Set("limit", limit) } endpoint := common.EncodeURLValues(getOrderHistory, params) - return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, endpoint, nil, &resp) + return resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, endpoint, nil, &resp) } // GetOpenTriggerOrders gets trigger orders that are currently open -func (f *FTX) GetOpenTriggerOrders(marketName, orderType string) ([]TriggerOrderData, error) { +func (f *FTX) GetOpenTriggerOrders(ctx context.Context, marketName, orderType string) ([]TriggerOrderData, error) { params := url.Values{} if marketName != "" { params.Set("market", marketName) @@ -619,19 +619,19 @@ func (f *FTX) GetOpenTriggerOrders(marketName, orderType string) ([]TriggerOrder Data []TriggerOrderData `json:"result"` }{} endpoint := common.EncodeURLValues(getOpenTriggerOrders, params) - return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, endpoint, nil, &resp) + return resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, endpoint, nil, &resp) } // GetTriggerOrderTriggers gets trigger orders that are currently open -func (f *FTX) GetTriggerOrderTriggers(orderID string) ([]TriggerData, error) { +func (f *FTX) GetTriggerOrderTriggers(ctx context.Context, orderID string) ([]TriggerData, error) { resp := struct { Data []TriggerData `json:"result"` }{} - return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, fmt.Sprintf(getTriggerOrderTriggers, orderID), nil, &resp) + return resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, fmt.Sprintf(getTriggerOrderTriggers, orderID), nil, &resp) } // GetTriggerOrderHistory gets trigger orders that are currently open -func (f *FTX) GetTriggerOrderHistory(marketName string, startTime, endTime time.Time, side, orderType, limit string) ([]TriggerOrderData, error) { +func (f *FTX) GetTriggerOrderHistory(ctx context.Context, marketName string, startTime, endTime time.Time, side, orderType, limit string) ([]TriggerOrderData, error) { params := url.Values{} if marketName != "" { params.Set("market", marketName) @@ -656,11 +656,12 @@ func (f *FTX) GetTriggerOrderHistory(marketName string, startTime, endTime time. Data []TriggerOrderData `json:"result"` }{} endpoint := common.EncodeURLValues(getTriggerOrderHistory, params) - return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, endpoint, nil, &resp) + return resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, endpoint, nil, &resp) } // Order places an order func (f *FTX) Order( + ctx context.Context, marketName, side, orderType string, reduceOnly, ioc, postOnly bool, clientID string, @@ -687,11 +688,11 @@ func (f *FTX) Order( resp := struct { Data OrderData `json:"result"` }{} - return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodPost, placeOrder, req, &resp) + return resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, placeOrder, req, &resp) } // TriggerOrder places an order -func (f *FTX) TriggerOrder(marketName, side, orderType, reduceOnly, retryUntilFilled string, size, triggerPrice, orderPrice, trailValue float64) (TriggerOrderData, error) { +func (f *FTX) TriggerOrder(ctx context.Context, marketName, side, orderType, reduceOnly, retryUntilFilled string, size, triggerPrice, orderPrice, trailValue float64) (TriggerOrderData, error) { req := make(map[string]interface{}) req["market"] = marketName req["side"] = side @@ -717,11 +718,11 @@ func (f *FTX) TriggerOrder(marketName, side, orderType, reduceOnly, retryUntilFi resp := struct { Data TriggerOrderData `json:"result"` }{} - return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodPost, placeTriggerOrder, req, &resp) + return resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, placeTriggerOrder, req, &resp) } // ModifyPlacedOrder modifies a placed order -func (f *FTX) ModifyPlacedOrder(orderID, clientID string, price, size float64) (OrderData, error) { +func (f *FTX) ModifyPlacedOrder(ctx context.Context, orderID, clientID string, price, size float64) (OrderData, error) { req := make(map[string]interface{}) req["price"] = price req["size"] = size @@ -731,11 +732,11 @@ func (f *FTX) ModifyPlacedOrder(orderID, clientID string, price, size float64) ( resp := struct { Data OrderData `json:"result"` }{} - return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodPost, fmt.Sprintf(modifyOrder, orderID), req, &resp) + return resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, fmt.Sprintf(modifyOrder, orderID), req, &resp) } // ModifyOrderByClientID modifies a placed order via clientOrderID -func (f *FTX) ModifyOrderByClientID(clientOrderID, clientID string, price, size float64) (OrderData, error) { +func (f *FTX) ModifyOrderByClientID(ctx context.Context, clientOrderID, clientID string, price, size float64) (OrderData, error) { req := make(map[string]interface{}) req["price"] = price req["size"] = size @@ -745,12 +746,12 @@ func (f *FTX) ModifyOrderByClientID(clientOrderID, clientID string, price, size resp := struct { Data OrderData `json:"result"` }{} - return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodPost, fmt.Sprintf(modifyOrderByClientID, clientOrderID), req, &resp) + return resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, fmt.Sprintf(modifyOrderByClientID, clientOrderID), req, &resp) } // ModifyTriggerOrder modifies an existing trigger order // Choices for ordertype include stop, trailingStop, takeProfit -func (f *FTX) ModifyTriggerOrder(orderID, orderType string, size, triggerPrice, orderPrice, trailValue float64) (TriggerOrderData, error) { +func (f *FTX) ModifyTriggerOrder(ctx context.Context, orderID, orderType string, size, triggerPrice, orderPrice, trailValue float64) (TriggerOrderData, error) { req := make(map[string]interface{}) req["size"] = size if orderType == order.Stop.Lower() || orderType == "" { @@ -767,32 +768,32 @@ func (f *FTX) ModifyTriggerOrder(orderID, orderType string, size, triggerPrice, resp := struct { Data TriggerOrderData `json:"result"` }{} - return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodPost, fmt.Sprintf(modifyTriggerOrder, orderID), req, &resp) + return resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, fmt.Sprintf(modifyTriggerOrder, orderID), req, &resp) } // GetOrderStatus gets the order status of a given orderID -func (f *FTX) GetOrderStatus(orderID string) (OrderData, error) { +func (f *FTX) GetOrderStatus(ctx context.Context, orderID string) (OrderData, error) { resp := struct { Data OrderData `json:"result"` }{} - return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getOrderStatus+orderID, nil, &resp) + return resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, getOrderStatus+orderID, nil, &resp) } // GetOrderStatusByClientID gets the order status of a given clientOrderID -func (f *FTX) GetOrderStatusByClientID(clientOrderID string) (OrderData, error) { +func (f *FTX) GetOrderStatusByClientID(ctx context.Context, clientOrderID string) (OrderData, error) { resp := struct { Data OrderData `json:"result"` }{} - return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getOrderStatusByClientID+clientOrderID, nil, &resp) + return resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, getOrderStatusByClientID+clientOrderID, nil, &resp) } -func (f *FTX) deleteOrderByPath(path string) (string, error) { +func (f *FTX) deleteOrderByPath(ctx context.Context, path string) (string, error) { resp := struct { Result string `json:"result"` Success bool `json:"success"` Error string `json:"error"` }{} - err := f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodDelete, path, nil, &resp) + err := f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodDelete, path, nil, &resp) // If there is an error reported, but the resp struct reports one of a very few // specific error causes, we still consider this a successful cancellation. if err != nil && !resp.Success && (resp.Error == "Order already closed" || resp.Error == "Order already queued for cancellation") { @@ -802,31 +803,31 @@ func (f *FTX) deleteOrderByPath(path string) (string, error) { } // DeleteOrder deletes an order -func (f *FTX) DeleteOrder(orderID string) (string, error) { +func (f *FTX) DeleteOrder(ctx context.Context, orderID string) (string, error) { if orderID == "" { return "", errInvalidOrderID } - return f.deleteOrderByPath(deleteOrder + orderID) + return f.deleteOrderByPath(ctx, deleteOrder+orderID) } // DeleteOrderByClientID deletes an order -func (f *FTX) DeleteOrderByClientID(clientID string) (string, error) { +func (f *FTX) DeleteOrderByClientID(ctx context.Context, clientID string) (string, error) { if clientID == "" { return "", errInvalidOrderID } - return f.deleteOrderByPath(deleteOrderByClientID + clientID) + return f.deleteOrderByPath(ctx, deleteOrderByClientID+clientID) } // DeleteTriggerOrder deletes an order -func (f *FTX) DeleteTriggerOrder(orderID string) (string, error) { +func (f *FTX) DeleteTriggerOrder(ctx context.Context, orderID string) (string, error) { if orderID == "" { return "", errInvalidOrderID } - return f.deleteOrderByPath(cancelTriggerOrder + orderID) + return f.deleteOrderByPath(ctx, cancelTriggerOrder+orderID) } // GetFills gets fills' data -func (f *FTX) GetFills(market, limit string, startTime, endTime time.Time) ([]FillsData, error) { +func (f *FTX) GetFills(ctx context.Context, market, limit string, startTime, endTime time.Time) ([]FillsData, error) { resp := struct { Data []FillsData `json:"result"` }{} @@ -845,11 +846,11 @@ func (f *FTX) GetFills(market, limit string, startTime, endTime time.Time) ([]Fi params.Set("end_time", strconv.FormatInt(endTime.Unix(), 10)) } endpoint := common.EncodeURLValues(getFills, params) - return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, endpoint, nil, &resp) + return resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, endpoint, nil, &resp) } // GetFundingPayments gets funding payments -func (f *FTX) GetFundingPayments(startTime, endTime time.Time, future string) ([]FundingPaymentsData, error) { +func (f *FTX) GetFundingPayments(ctx context.Context, startTime, endTime time.Time, future string) ([]FundingPaymentsData, error) { resp := struct { Data []FundingPaymentsData `json:"result"` }{} @@ -865,87 +866,87 @@ func (f *FTX) GetFundingPayments(startTime, endTime time.Time, future string) ([ params.Set("future", future) } endpoint := common.EncodeURLValues(getFundingPayments, params) - return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, endpoint, nil, &resp) + return resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, endpoint, nil, &resp) } // ListLeveragedTokens lists leveraged tokens -func (f *FTX) ListLeveragedTokens() ([]LeveragedTokensData, error) { +func (f *FTX) ListLeveragedTokens(ctx context.Context) ([]LeveragedTokensData, error) { resp := struct { Data []LeveragedTokensData `json:"result"` }{} - return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getLeveragedTokens, nil, &resp) + return resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, getLeveragedTokens, nil, &resp) } // GetTokenInfo gets token info -func (f *FTX) GetTokenInfo(tokenName string) ([]LeveragedTokensData, error) { +func (f *FTX) GetTokenInfo(ctx context.Context, tokenName string) ([]LeveragedTokensData, error) { resp := struct { Data []LeveragedTokensData `json:"result"` }{} - return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getTokenInfo+tokenName, nil, &resp) + return resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, getTokenInfo+tokenName, nil, &resp) } // ListLTBalances gets leveraged tokens' balances -func (f *FTX) ListLTBalances() ([]LTBalanceData, error) { +func (f *FTX) ListLTBalances(ctx context.Context) ([]LTBalanceData, error) { resp := struct { Data []LTBalanceData `json:"result"` }{} - return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getLTBalances, nil, &resp) + return resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, getLTBalances, nil, &resp) } // ListLTCreations lists the leveraged tokens' creation requests -func (f *FTX) ListLTCreations() ([]LTCreationData, error) { +func (f *FTX) ListLTCreations(ctx context.Context) ([]LTCreationData, error) { resp := struct { Data []LTCreationData `json:"result"` }{} - return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getLTCreations, nil, &resp) + return resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, getLTCreations, nil, &resp) } // RequestLTCreation sends a request to create a leveraged token -func (f *FTX) RequestLTCreation(tokenName string, size float64) (RequestTokenCreationData, error) { +func (f *FTX) RequestLTCreation(ctx context.Context, tokenName string, size float64) (RequestTokenCreationData, error) { req := make(map[string]interface{}) req["size"] = size resp := struct { Data RequestTokenCreationData `json:"result"` }{} - return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodPost, fmt.Sprintf(requestLTCreation, tokenName), req, &resp) + return resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, fmt.Sprintf(requestLTCreation, tokenName), req, &resp) } // ListLTRedemptions lists the leveraged tokens' redemption requests -func (f *FTX) ListLTRedemptions() ([]LTRedemptionData, error) { +func (f *FTX) ListLTRedemptions(ctx context.Context) ([]LTRedemptionData, error) { resp := struct { Data []LTRedemptionData `json:"result"` }{} - return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getLTRedemptions, nil, &resp) + return resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, getLTRedemptions, nil, &resp) } // RequestLTRedemption sends a request to redeem a leveraged token -func (f *FTX) RequestLTRedemption(tokenName string, size float64) (LTRedemptionRequestData, error) { +func (f *FTX) RequestLTRedemption(ctx context.Context, tokenName string, size float64) (LTRedemptionRequestData, error) { req := make(map[string]interface{}) req["size"] = size resp := struct { Data LTRedemptionRequestData `json:"result"` }{} - return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodPost, fmt.Sprintf(requestLTRedemption, tokenName), req, &resp) + return resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, fmt.Sprintf(requestLTRedemption, tokenName), req, &resp) } // GetQuoteRequests gets a list of quote requests -func (f *FTX) GetQuoteRequests() ([]QuoteRequestData, error) { +func (f *FTX) GetQuoteRequests(ctx context.Context) ([]QuoteRequestData, error) { resp := struct { Data []QuoteRequestData `json:"result"` }{} - return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getListQuotes, nil, &resp) + return resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, getListQuotes, nil, &resp) } // GetYourQuoteRequests gets a list of your quote requests -func (f *FTX) GetYourQuoteRequests() ([]PersonalQuotesData, error) { +func (f *FTX) GetYourQuoteRequests(ctx context.Context) ([]PersonalQuotesData, error) { resp := struct { Data []PersonalQuotesData `json:"result"` }{} - return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getMyQuotesRequests, nil, &resp) + return resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, getMyQuotesRequests, nil, &resp) } // CreateQuoteRequest sends a request to create a quote -func (f *FTX) CreateQuoteRequest(underlying currency.Code, optionType, side string, expiry int64, requestExpiry string, strike, size, limitPrice, counterPartyID float64, hideLimitPrice bool) (CreateQuoteRequestData, error) { +func (f *FTX) CreateQuoteRequest(ctx context.Context, underlying currency.Code, optionType, side string, expiry int64, requestExpiry string, strike, size, limitPrice, counterPartyID float64, hideLimitPrice bool) (CreateQuoteRequestData, error) { req := make(map[string]interface{}) req["underlying"] = underlying.Upper().String() req["type"] = optionType @@ -966,75 +967,75 @@ func (f *FTX) CreateQuoteRequest(underlying currency.Code, optionType, side stri resp := struct { Data CreateQuoteRequestData `json:"result"` }{} - return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodPost, createQuoteRequest, req, &resp) + return resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, createQuoteRequest, req, &resp) } // DeleteQuote sends request to cancel a quote -func (f *FTX) DeleteQuote(requestID string) (CancelQuoteRequestData, error) { +func (f *FTX) DeleteQuote(ctx context.Context, requestID string) (CancelQuoteRequestData, error) { resp := struct { Data CancelQuoteRequestData `json:"result"` }{} - return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodDelete, deleteQuote+requestID, nil, &resp) + return resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodDelete, deleteQuote+requestID, nil, &resp) } // GetQuotesForYourQuote gets a list of quotes for your quote -func (f *FTX) GetQuotesForYourQuote(requestID string) (QuoteForQuoteData, error) { +func (f *FTX) GetQuotesForYourQuote(ctx context.Context, requestID string) (QuoteForQuoteData, error) { var resp QuoteForQuoteData - return resp, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, fmt.Sprintf(endpointQuote, requestID), nil, &resp) + return resp, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, fmt.Sprintf(endpointQuote, requestID), nil, &resp) } // MakeQuote makes a quote for a quote -func (f *FTX) MakeQuote(requestID, price string) ([]QuoteForQuoteData, error) { +func (f *FTX) MakeQuote(ctx context.Context, requestID, price string) ([]QuoteForQuoteData, error) { params := url.Values{} params.Set("price", price) resp := struct { Data []QuoteForQuoteData `json:"result"` }{} - return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodPost, fmt.Sprintf(endpointQuote, requestID), nil, &resp) + return resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, fmt.Sprintf(endpointQuote, requestID), nil, &resp) } // MyQuotes gets a list of my quotes for quotes -func (f *FTX) MyQuotes() ([]QuoteForQuoteData, error) { +func (f *FTX) MyQuotes(ctx context.Context) ([]QuoteForQuoteData, error) { resp := struct { Data []QuoteForQuoteData `json:"result"` }{} - return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getMyQuotes, nil, &resp) + return resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, getMyQuotes, nil, &resp) } // DeleteMyQuote deletes my quote for quotes -func (f *FTX) DeleteMyQuote(quoteID string) ([]QuoteForQuoteData, error) { +func (f *FTX) DeleteMyQuote(ctx context.Context, quoteID string) ([]QuoteForQuoteData, error) { resp := struct { Data []QuoteForQuoteData `json:"result"` }{} - return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodDelete, deleteMyQuote+quoteID, nil, &resp) + return resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodDelete, deleteMyQuote+quoteID, nil, &resp) } // AcceptQuote accepts the quote for quote -func (f *FTX) AcceptQuote(quoteID string) ([]QuoteForQuoteData, error) { +func (f *FTX) AcceptQuote(ctx context.Context, quoteID string) ([]QuoteForQuoteData, error) { resp := struct { Data []QuoteForQuoteData `json:"result"` }{} - return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodPost, fmt.Sprintf(acceptQuote, quoteID), nil, &resp) + return resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, fmt.Sprintf(acceptQuote, quoteID), nil, &resp) } // GetAccountOptionsInfo gets account's options' info -func (f *FTX) GetAccountOptionsInfo() (AccountOptionsInfoData, error) { +func (f *FTX) GetAccountOptionsInfo(ctx context.Context) (AccountOptionsInfoData, error) { resp := struct { Data AccountOptionsInfoData `json:"result"` }{} - return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getOptionsInfo, nil, &resp) + return resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, getOptionsInfo, nil, &resp) } // GetOptionsPositions gets options' positions -func (f *FTX) GetOptionsPositions() ([]OptionsPositionsData, error) { +func (f *FTX) GetOptionsPositions(ctx context.Context) ([]OptionsPositionsData, error) { resp := struct { Data []OptionsPositionsData `json:"result"` }{} - return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getOptionsPositions, nil, &resp) + return resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, getOptionsPositions, nil, &resp) } // GetPublicOptionsTrades gets options' trades from public -func (f *FTX) GetPublicOptionsTrades(startTime, endTime time.Time, limit string) ([]OptionsTradesData, error) { +func (f *FTX) GetPublicOptionsTrades(ctx context.Context, startTime, endTime time.Time, limit string) ([]OptionsTradesData, error) { params := url.Values{} if !startTime.IsZero() && !endTime.IsZero() { if startTime.After(endTime) { @@ -1050,11 +1051,11 @@ func (f *FTX) GetPublicOptionsTrades(startTime, endTime time.Time, limit string) Data []OptionsTradesData `json:"result"` }{} endpoint := common.EncodeURLValues(getPublicOptionsTrades, params) - return resp.Data, f.SendHTTPRequest(exchange.RestSpot, endpoint, &resp) + return resp.Data, f.SendHTTPRequest(ctx, exchange.RestSpot, endpoint, &resp) } // GetOptionsFills gets fills data for options -func (f *FTX) GetOptionsFills(startTime, endTime time.Time, limit string) ([]OptionFillsData, error) { +func (f *FTX) GetOptionsFills(ctx context.Context, startTime, endTime time.Time, limit string) ([]OptionFillsData, error) { resp := struct { Data []OptionFillsData `json:"result"` }{} @@ -1069,51 +1070,51 @@ func (f *FTX) GetOptionsFills(startTime, endTime time.Time, limit string) ([]Opt if limit != "" { req["limit"] = limit } - return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getOptionsFills, req, &resp) + return resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, getOptionsFills, req, &resp) } // GetStakes returns a list of staked assets -func (f *FTX) GetStakes() ([]Stake, error) { +func (f *FTX) GetStakes(ctx context.Context) ([]Stake, error) { resp := struct { Data []Stake `json:"result"` }{} - return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, stakes, nil, &resp) + return resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, stakes, nil, &resp) } // GetUnstakeRequests returns a collection of unstake requests -func (f *FTX) GetUnstakeRequests() ([]UnstakeRequest, error) { +func (f *FTX) GetUnstakeRequests(ctx context.Context) ([]UnstakeRequest, error) { resp := struct { Data []UnstakeRequest `json:"result"` }{} - return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, unstakeRequests, nil, &resp) + return resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, unstakeRequests, nil, &resp) } // GetStakeBalances returns a collection of staked coin balances -func (f *FTX) GetStakeBalances() ([]StakeBalance, error) { +func (f *FTX) GetStakeBalances(ctx context.Context) ([]StakeBalance, error) { resp := struct { Data []StakeBalance `json:"result"` }{} - return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, stakeBalances, nil, &resp) + return resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, stakeBalances, nil, &resp) } // UnstakeRequest unstakes an existing staked coin -func (f *FTX) UnstakeRequest(coin currency.Code, size float64) (*UnstakeRequest, error) { +func (f *FTX) UnstakeRequest(ctx context.Context, coin currency.Code, size float64) (*UnstakeRequest, error) { resp := struct { Data UnstakeRequest `json:"result"` }{} req := make(map[string]interface{}) req["coin"] = coin.Upper().String() req["size"] = strconv.FormatFloat(size, 'f', -1, 64) - return &resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodPost, unstakeRequests, req, &resp) + return &resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, unstakeRequests, req, &resp) } // CancelUnstakeRequest cancels a pending unstake request -func (f *FTX) CancelUnstakeRequest(requestID int64) (bool, error) { +func (f *FTX) CancelUnstakeRequest(ctx context.Context, requestID int64) (bool, error) { resp := struct { Result string }{} path := unstakeRequests + "/" + strconv.FormatInt(requestID, 10) - if err := f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodDelete, path, nil, &resp); err != nil { + if err := f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodDelete, path, nil, &resp); err != nil { return false, err } @@ -1124,26 +1125,26 @@ func (f *FTX) CancelUnstakeRequest(requestID int64) (bool, error) { } // GetStakingRewards returns a collection of staking rewards -func (f *FTX) GetStakingRewards() ([]StakeReward, error) { +func (f *FTX) GetStakingRewards(ctx context.Context) ([]StakeReward, error) { resp := struct { Data []StakeReward `json:"result"` }{} - return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, stakingRewards, nil, &resp) + return resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, stakingRewards, nil, &resp) } // StakeRequest submits a stake request based on the specified currency and size -func (f *FTX) StakeRequest(coin currency.Code, size float64) (*Stake, error) { +func (f *FTX) StakeRequest(ctx context.Context, coin currency.Code, size float64) (*Stake, error) { resp := struct { Data Stake `json:"result"` }{} req := make(map[string]interface{}) req["coin"] = coin.Upper().String() req["size"] = strconv.FormatFloat(size, 'f', -1, 64) - return &resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodPost, serumStakes, req, &resp) + return &resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, serumStakes, req, &resp) } // SendAuthHTTPRequest sends an authenticated request -func (f *FTX) SendAuthHTTPRequest(ep exchange.URL, method, path string, data, result interface{}) error { +func (f *FTX) SendAuthHTTPRequest(ctx context.Context, ep exchange.URL, method, path string, data, result interface{}) error { endpoint, err := f.API.Endpoints.GetURL(ep) if err != nil { return err @@ -1192,11 +1193,11 @@ func (f *FTX) SendAuthHTTPRequest(ep exchange.URL, method, path string, data, re HTTPRecording: f.HTTPRecording, }, nil } - return f.SendPayload(context.Background(), request.Unset, newRequest) + return f.SendPayload(ctx, request.Unset, newRequest) } // GetFee returns an estimate of fee based on type of transaction -func (f *FTX) GetFee(feeBuilder *exchange.FeeBuilder) (float64, error) { +func (f *FTX) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { var fee float64 if !f.GetAuthenticatedAPISupport(exchange.RestAuthentication) { feeBuilder.FeeType = exchange.OfflineTradeFee @@ -1205,7 +1206,7 @@ func (f *FTX) GetFee(feeBuilder *exchange.FeeBuilder) (float64, error) { case exchange.OfflineTradeFee: fee = getOfflineTradeFee(feeBuilder) default: - feeData, err := f.GetAccountInfo() + feeData, err := f.GetAccountInfo(ctx) if err != nil { return 0, err } @@ -1230,7 +1231,7 @@ func getOfflineTradeFee(feeBuilder *exchange.FeeBuilder) float64 { return 0.0007 * feeBuilder.PurchasePrice * feeBuilder.Amount } -func (f *FTX) compatibleOrderVars(orderSide, orderStatus, orderType string, amount, filledAmount, avgFillPrice float64) (OrderVars, error) { +func (f *FTX) compatibleOrderVars(ctx context.Context, orderSide, orderStatus, orderType string, amount, filledAmount, avgFillPrice float64) (OrderVars, error) { if filledAmount > amount { return OrderVars{}, fmt.Errorf("%w, amount: %f filled: %f", errInvalidOrderAmounts, amount, filledAmount) } @@ -1273,7 +1274,7 @@ func (f *FTX) compatibleOrderVars(orderSide, orderStatus, orderType string, amou resp.OrderType = order.Limit feeBuilder.IsMaker = true } - fee, err := f.GetFee(&feeBuilder) + fee, err := f.GetFee(ctx, &feeBuilder) if err != nil { return resp, err } @@ -1282,7 +1283,7 @@ func (f *FTX) compatibleOrderVars(orderSide, orderStatus, orderType string, amou } // RequestForQuotes requests for otc quotes -func (f *FTX) RequestForQuotes(base, quote currency.Code, amount float64) (RequestQuoteData, error) { +func (f *FTX) RequestForQuotes(ctx context.Context, base, quote currency.Code, amount float64) (RequestQuoteData, error) { resp := struct { Data RequestQuoteData `json:"result"` }{} @@ -1290,34 +1291,34 @@ func (f *FTX) RequestForQuotes(base, quote currency.Code, amount float64) (Reque req["fromCoin"] = base.Upper().String() req["toCoin"] = quote.Upper().String() req["size"] = amount - return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodPost, requestOTCQuote, req, &resp) + return resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, requestOTCQuote, req, &resp) } // GetOTCQuoteStatus gets quote status of a quote -func (f *FTX) GetOTCQuoteStatus(marketName, quoteID string) ([]QuoteStatusData, error) { +func (f *FTX) GetOTCQuoteStatus(ctx context.Context, marketName, quoteID string) ([]QuoteStatusData, error) { resp := struct { Data []QuoteStatusData `json:"result"` }{} params := url.Values{} params.Set("market", marketName) - return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getOTCQuoteStatus+quoteID, params, &resp) + return resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, getOTCQuoteStatus+quoteID, params, &resp) } // AcceptOTCQuote requests for otc quotes -func (f *FTX) AcceptOTCQuote(quoteID string) error { - return f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodPost, fmt.Sprintf(acceptOTCQuote, quoteID), nil, nil) +func (f *FTX) AcceptOTCQuote(ctx context.Context, quoteID string) error { + return f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, fmt.Sprintf(acceptOTCQuote, quoteID), nil, nil) } // GetSubaccounts returns the users subaccounts -func (f *FTX) GetSubaccounts() ([]Subaccount, error) { +func (f *FTX) GetSubaccounts(ctx context.Context) ([]Subaccount, error) { resp := struct { Data []Subaccount `json:"result"` }{} - return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, subaccounts, nil, &resp) + return resp.Data, f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, subaccounts, nil, &resp) } // CreateSubaccount creates a new subaccount -func (f *FTX) CreateSubaccount(name string) (*Subaccount, error) { +func (f *FTX) CreateSubaccount(ctx context.Context, name string) (*Subaccount, error) { if name == "" { return nil, errSubaccountNameMustBeSpecified } @@ -1327,14 +1328,14 @@ func (f *FTX) CreateSubaccount(name string) (*Subaccount, error) { resp := struct { Data Subaccount `json:"result"` }{} - if err := f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodPost, subaccounts, d, &resp); err != nil { + if err := f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, subaccounts, d, &resp); err != nil { return nil, err } return &resp.Data, nil } // UpdateSubaccountName updates an existing subaccount name -func (f *FTX) UpdateSubaccountName(oldName, newName string) (*Subaccount, error) { +func (f *FTX) UpdateSubaccountName(ctx context.Context, oldName, newName string) (*Subaccount, error) { if oldName == "" || newName == "" || oldName == newName { return nil, errSubaccountUpdateNameInvalid } @@ -1345,14 +1346,14 @@ func (f *FTX) UpdateSubaccountName(oldName, newName string) (*Subaccount, error) resp := struct { Data Subaccount `json:"result"` }{} - if err := f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodPost, subaccountsUpdateName, d, &resp); err != nil { + if err := f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, subaccountsUpdateName, d, &resp); err != nil { return nil, err } return &resp.Data, nil } // DeleteSubaccount deletes the specified subaccount name -func (f *FTX) DeleteSubaccount(name string) error { +func (f *FTX) DeleteSubaccount(ctx context.Context, name string) error { if name == "" { return errSubaccountNameMustBeSpecified } @@ -1361,25 +1362,25 @@ func (f *FTX) DeleteSubaccount(name string) error { resp := struct { Data Subaccount `json:"result"` }{} - return f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodDelete, subaccounts, d, &resp) + return f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodDelete, subaccounts, d, &resp) } // SubaccountBalances returns the user's subaccount balances -func (f *FTX) SubaccountBalances(name string) ([]SubaccountBalance, error) { +func (f *FTX) SubaccountBalances(ctx context.Context, name string) ([]SubaccountBalance, error) { if name == "" { return nil, errSubaccountNameMustBeSpecified } resp := struct { Data []SubaccountBalance `json:"result"` }{} - if err := f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, fmt.Sprintf(subaccountsBalance, name), nil, &resp); err != nil { + if err := f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, fmt.Sprintf(subaccountsBalance, name), nil, &resp); err != nil { return nil, err } return resp.Data, nil } // SubaccountTransfer transfers a desired coin to the specified subaccount -func (f *FTX) SubaccountTransfer(coin currency.Code, source, destination string, size float64) (*SubaccountTransferStatus, error) { +func (f *FTX) SubaccountTransfer(ctx context.Context, coin currency.Code, source, destination string, size float64) (*SubaccountTransferStatus, error) { if coin.IsEmpty() { return nil, errCoinMustBeSpecified } @@ -1403,15 +1404,15 @@ func (f *FTX) SubaccountTransfer(coin currency.Code, source, destination string, resp := struct { Data SubaccountTransferStatus `json:"result"` }{} - if err := f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodPost, subaccountsTransfer, d, &resp); err != nil { + if err := f.SendAuthHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, subaccountsTransfer, d, &resp); err != nil { return nil, err } return &resp.Data, nil } // FetchExchangeLimits fetches spot order execution limits -func (f *FTX) FetchExchangeLimits() ([]order.MinMaxLevel, error) { - data, err := f.GetMarkets() +func (f *FTX) FetchExchangeLimits(ctx context.Context) ([]order.MinMaxLevel, error) { + data, err := f.GetMarkets(ctx) if err != nil { return nil, err } diff --git a/exchanges/ftx/ftx_test.go b/exchanges/ftx/ftx_test.go index b9ef5b3f..f76c6aff 100644 --- a/exchanges/ftx/ftx_test.go +++ b/exchanges/ftx/ftx_test.go @@ -1,6 +1,7 @@ package ftx import ( + "context" "errors" "log" "os" @@ -77,7 +78,7 @@ func areTestAPIKeysSet() bool { func TestGetMarkets(t *testing.T) { t.Parallel() - _, err := f.GetMarkets() + _, err := f.GetMarkets(context.Background()) if err != nil { t.Error(err) } @@ -85,11 +86,13 @@ func TestGetMarkets(t *testing.T) { func TestGetHistoricalIndex(t *testing.T) { t.Parallel() - _, err := f.GetHistoricalIndex("BTC", 3600, time.Now().Add(-time.Hour*2), time.Now().Add(-time.Hour*1)) + _, err := f.GetHistoricalIndex(context.Background(), + "BTC", 3600, time.Now().Add(-time.Hour*2), time.Now().Add(-time.Hour*1)) if err != nil { t.Error(err) } - _, err = f.GetHistoricalIndex("BTC", 3600, time.Time{}, time.Time{}) + _, err = f.GetHistoricalIndex(context.Background(), + "BTC", 3600, time.Time{}, time.Time{}) if err != nil { t.Error(err) } @@ -97,7 +100,7 @@ func TestGetHistoricalIndex(t *testing.T) { func TestGetMarket(t *testing.T) { t.Parallel() - _, err := f.GetMarket(spotPair) + _, err := f.GetMarket(context.Background(), spotPair) if err != nil { t.Error(err) } @@ -105,7 +108,7 @@ func TestGetMarket(t *testing.T) { func TestGetOrderbook(t *testing.T) { t.Parallel() - _, err := f.GetOrderbook(spotPair, 5) + _, err := f.GetOrderbook(context.Background(), spotPair, 5) if err != nil { t.Error(err) } @@ -114,31 +117,34 @@ func TestGetOrderbook(t *testing.T) { func TestGetTrades(t *testing.T) { t.Parallel() // test empty market - _, err := f.GetTrades("", 0, 0, 200) + _, err := f.GetTrades(context.Background(), "", 0, 0, 200) if err == nil { t.Error("empty market should return an error") } - _, err = f.GetTrades(spotPair, validFTTBTCEndTime, validFTTBTCStartTime, 5) + _, err = f.GetTrades(context.Background(), + spotPair, validFTTBTCEndTime, validFTTBTCStartTime, 5) if err != errStartTimeCannotBeAfterEndTime { t.Errorf("should have thrown errStartTimeCannotBeAfterEndTime, got %v", err) } // test optional params var trades []TradeData - trades, err = f.GetTrades(spotPair, 0, 0, 0) + trades, err = f.GetTrades(context.Background(), spotPair, 0, 0, 0) if err != nil { t.Error(err) } if len(trades) != 20 { t.Error("default limit should return 20 items") } - trades, err = f.GetTrades(spotPair, validFTTBTCStartTime, validFTTBTCEndTime, 5) + trades, err = f.GetTrades(context.Background(), + spotPair, validFTTBTCStartTime, validFTTBTCEndTime, 5) if err != nil { t.Error(err) } if len(trades) != 5 { t.Error("limit of 5 should return 5 items") } - trades, err = f.GetTrades(spotPair, invalidFTTBTCStartTime, invalidFTTBTCEndTime, 5) + trades, err = f.GetTrades(context.Background(), + spotPair, invalidFTTBTCStartTime, invalidFTTBTCEndTime, 5) if err != nil { t.Error(err) } @@ -150,28 +156,35 @@ func TestGetTrades(t *testing.T) { func TestGetHistoricalData(t *testing.T) { t.Parallel() // test empty market - _, err := f.GetHistoricalData("", 86400, 5, time.Time{}, time.Time{}) + _, err := f.GetHistoricalData(context.Background(), + "", 86400, 5, time.Time{}, time.Time{}) if err == nil { t.Error("empty market should return an error") } // test empty resolution - _, err = f.GetHistoricalData(spotPair, 0, 5, time.Time{}, time.Time{}) + _, err = f.GetHistoricalData(context.Background(), + spotPair, 0, 5, time.Time{}, time.Time{}) if err == nil { t.Error("empty resolution should return an error") } - _, err = f.GetHistoricalData(spotPair, 86400, 5, time.Unix(validFTTBTCEndTime, 0), time.Unix(validFTTBTCStartTime, 0)) + _, err = f.GetHistoricalData(context.Background(), + spotPair, 86400, 5, time.Unix(validFTTBTCEndTime, 0), + time.Unix(validFTTBTCStartTime, 0)) if err != errStartTimeCannotBeAfterEndTime { t.Errorf("should have thrown errStartTimeCannotBeAfterEndTime, got %v", err) } var o []OHLCVData - o, err = f.GetHistoricalData(spotPair, 86400, 5, time.Time{}, time.Time{}) + o, err = f.GetHistoricalData(context.Background(), + spotPair, 86400, 5, time.Time{}, time.Time{}) if err != nil { t.Error(err) } if len(o) != 5 { t.Error("limit of 5 should return 5 items") } - o, err = f.GetHistoricalData(spotPair, 86400, 5, time.Unix(invalidFTTBTCStartTime, 0), time.Unix(invalidFTTBTCEndTime, 0)) + o, err = f.GetHistoricalData(context.Background(), + spotPair, 86400, 5, time.Unix(invalidFTTBTCStartTime, 0), + time.Unix(invalidFTTBTCEndTime, 0)) if err != nil { t.Error(err) } @@ -182,7 +195,7 @@ func TestGetHistoricalData(t *testing.T) { func TestGetFutures(t *testing.T) { t.Parallel() - _, err := f.GetFutures() + _, err := f.GetFutures(context.Background()) if err != nil { t.Error(err) } @@ -190,7 +203,7 @@ func TestGetFutures(t *testing.T) { func TestGetFuture(t *testing.T) { t.Parallel() - _, err := f.GetFuture(futuresPair) + _, err := f.GetFuture(context.Background(), futuresPair) if err != nil { t.Error(err) } @@ -198,7 +211,7 @@ func TestGetFuture(t *testing.T) { func TestGetFutureStats(t *testing.T) { t.Parallel() - _, err := f.GetFutureStats("BTC-PERP") + _, err := f.GetFutureStats(context.Background(), "BTC-PERP") if err != nil { t.Error(err) } @@ -207,11 +220,12 @@ func TestGetFutureStats(t *testing.T) { func TestGetFundingRates(t *testing.T) { t.Parallel() // optional params - _, err := f.GetFundingRates(time.Time{}, time.Time{}, "") + _, err := f.GetFundingRates(context.Background(), time.Time{}, time.Time{}, "") if err != nil { t.Error(err) } - _, err = f.GetFundingRates(time.Now().Add(-time.Hour), time.Now(), "BTC-PERP") + _, err = f.GetFundingRates(context.Background(), + time.Now().Add(-time.Hour), time.Now(), "BTC-PERP") if err != nil { t.Error(err) } @@ -222,7 +236,7 @@ func TestGetAccountInfo(t *testing.T) { if !areTestAPIKeysSet() { t.Skip() } - _, err := f.GetAccountInfo() + _, err := f.GetAccountInfo(context.Background()) if err != nil { t.Error(err) } @@ -233,7 +247,7 @@ func TestGetPositions(t *testing.T) { if !areTestAPIKeysSet() { t.Skip() } - _, err := f.GetPositions() + _, err := f.GetPositions(context.Background()) if err != nil { t.Error(err) } @@ -244,7 +258,7 @@ func TestGetBalances(t *testing.T) { if !areTestAPIKeysSet() { t.Skip() } - _, err := f.GetBalances() + _, err := f.GetBalances(context.Background()) if err != nil { t.Error(err) } @@ -255,7 +269,7 @@ func TestGetAllWalletBalances(t *testing.T) { if !areTestAPIKeysSet() { t.Skip() } - _, err := f.GetAllWalletBalances() + _, err := f.GetAllWalletBalances(context.Background()) if err != nil { t.Error(err) } @@ -266,7 +280,7 @@ func TestChangeAccountLeverage(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test, either api keys or canManipulateRealOrders isnt set correctly") } - err := f.ChangeAccountLeverage(50) + err := f.ChangeAccountLeverage(context.Background(), 50) if err != nil { t.Error(err) } @@ -277,7 +291,7 @@ func TestGetCoins(t *testing.T) { if !areTestAPIKeysSet() { t.Skip() } - _, err := f.GetCoins() + _, err := f.GetCoins(context.Background()) if err != nil { t.Error(err) } @@ -288,7 +302,7 @@ func TestGetMarginBorrowRates(t *testing.T) { if !areTestAPIKeysSet() { t.Skip() } - _, err := f.GetMarginBorrowRates() + _, err := f.GetMarginBorrowRates(context.Background()) if err != nil { t.Error(err) } @@ -299,7 +313,7 @@ func TestGetMarginLendingRates(t *testing.T) { if !areTestAPIKeysSet() { t.Skip() } - _, err := f.GetMarginLendingRates() + _, err := f.GetMarginLendingRates(context.Background()) if err != nil { t.Error(err) } @@ -307,7 +321,7 @@ func TestGetMarginLendingRates(t *testing.T) { func TestMarginDailyBorrowedAmounts(t *testing.T) { t.Parallel() - _, err := f.MarginDailyBorrowedAmounts() + _, err := f.MarginDailyBorrowedAmounts(context.Background()) if err != nil { t.Error(err) } @@ -318,7 +332,7 @@ func TestGetMarginMarketInfo(t *testing.T) { if !areTestAPIKeysSet() { t.Skip() } - _, err := f.GetMarginMarketInfo("BTC_USD") + _, err := f.GetMarginMarketInfo(context.Background(), "BTC_USD") if err != nil { t.Error(err) } @@ -328,7 +342,9 @@ func TestGetMarginBorrowHistory(t *testing.T) { t.Parallel() tmNow := time.Now() - _, err := f.GetMarginBorrowHistory(tmNow.AddDate(0, 0, 1), tmNow) + _, err := f.GetMarginBorrowHistory(context.Background(), + tmNow.AddDate(0, 0, 1), + tmNow) if !errors.Is(err, errStartTimeCannotBeAfterEndTime) { t.Errorf("expected %s, got %s", errStartTimeCannotBeAfterEndTime, err) } @@ -336,7 +352,9 @@ func TestGetMarginBorrowHistory(t *testing.T) { if !areTestAPIKeysSet() { t.Skip() } - _, err = f.GetMarginBorrowHistory(tmNow.AddDate(0, 0, -1), tmNow) + _, err = f.GetMarginBorrowHistory(context.Background(), + tmNow.AddDate(0, 0, -1), + tmNow) if err != nil { t.Error(err) } @@ -346,12 +364,14 @@ func TestGetMarginMarketLendingHistory(t *testing.T) { t.Parallel() tmNow := time.Now() - _, err := f.GetMarginMarketLendingHistory(currency.USD, tmNow.AddDate(0, 0, 1), tmNow) + _, err := f.GetMarginMarketLendingHistory(context.Background(), + currency.USD, tmNow.AddDate(0, 0, 1), tmNow) if !errors.Is(err, errStartTimeCannotBeAfterEndTime) { t.Errorf("expected %s, got %s", errStartTimeCannotBeAfterEndTime, err) } - _, err = f.GetMarginMarketLendingHistory(currency.USD, tmNow.AddDate(0, 0, -1), tmNow) + _, err = f.GetMarginMarketLendingHistory(context.Background(), + currency.USD, tmNow.AddDate(0, 0, -1), tmNow) if err != nil { t.Error(err) } @@ -361,7 +381,8 @@ func TestGetMarginLendingHistory(t *testing.T) { t.Parallel() tmNow := time.Now() - _, err := f.GetMarginLendingHistory(currency.USD, tmNow.AddDate(0, 0, 1), tmNow) + _, err := f.GetMarginLendingHistory(context.Background(), + currency.USD, tmNow.AddDate(0, 0, 1), tmNow) if !errors.Is(err, errStartTimeCannotBeAfterEndTime) { t.Errorf("expected %s, got %s", errStartTimeCannotBeAfterEndTime, err) } @@ -369,7 +390,8 @@ func TestGetMarginLendingHistory(t *testing.T) { if !areTestAPIKeysSet() { t.Skip() } - _, err = f.GetMarginLendingHistory(currency.USD, tmNow.AddDate(0, 0, -1), tmNow) + _, err = f.GetMarginLendingHistory(context.Background(), + currency.USD, tmNow.AddDate(0, 0, -1), tmNow) if err != nil { t.Error(err) } @@ -380,7 +402,7 @@ func TestGetMarginLendingOffers(t *testing.T) { if !areTestAPIKeysSet() { t.Skip() } - _, err := f.GetMarginLendingOffers() + _, err := f.GetMarginLendingOffers(context.Background()) if err != nil { t.Error(err) } @@ -391,7 +413,7 @@ func TestGetLendingInfo(t *testing.T) { if !areTestAPIKeysSet() { t.Skip() } - _, err := f.GetLendingInfo() + _, err := f.GetLendingInfo(context.Background()) if err != nil { t.Error(err) } @@ -402,7 +424,8 @@ func TestSubmitLendingOffer(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip() } - if err := f.SubmitLendingOffer(currency.NewCode("bTc"), 0.1, 500); err != nil { + if err := f.SubmitLendingOffer(context.Background(), + currency.NewCode("bTc"), 0.1, 500); err != nil { t.Error(err) } } @@ -412,7 +435,7 @@ func TestFetchDepositAddress(t *testing.T) { if !areTestAPIKeysSet() { t.Skip() } - _, err := f.FetchDepositAddress(currency.NewCode("tUsD")) + _, err := f.FetchDepositAddress(context.Background(), currency.NewCode("tUsD")) if err != nil { t.Error(err) } @@ -423,7 +446,7 @@ func TestFetchDepositHistory(t *testing.T) { if !areTestAPIKeysSet() { t.Skip() } - _, err := f.FetchDepositHistory() + _, err := f.FetchDepositHistory(context.Background()) if err != nil { t.Error(err) } @@ -434,7 +457,7 @@ func TestFetchWithdrawalHistory(t *testing.T) { if !areTestAPIKeysSet() { t.Skip() } - _, err := f.FetchWithdrawalHistory() + _, err := f.FetchWithdrawalHistory(context.Background()) if err != nil { t.Error(err) } @@ -445,7 +468,8 @@ func TestWithdraw(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test, either api keys or canManipulateRealOrders isnt set correctly") } - _, err := f.Withdraw(currency.NewCode("bTc"), core.BitcoinDonationAddress, "", "", "957378", 0.0009) + _, err := f.Withdraw(context.Background(), + currency.NewCode("bTc"), core.BitcoinDonationAddress, "", "", "957378", 0.0009) if err != nil { t.Error(err) } @@ -456,11 +480,11 @@ func TestGetOpenOrders(t *testing.T) { if !areTestAPIKeysSet() { t.Skip() } - _, err := f.GetOpenOrders("") + _, err := f.GetOpenOrders(context.Background(), "") if err != nil { t.Error(err) } - _, err = f.GetOpenOrders(spotPair) + _, err = f.GetOpenOrders(context.Background(), spotPair) if err != nil { t.Error(err) } @@ -471,15 +495,18 @@ func TestFetchOrderHistory(t *testing.T) { if !areTestAPIKeysSet() { t.Skip() } - _, err := f.FetchOrderHistory("", time.Time{}, time.Time{}, "2") + _, err := f.FetchOrderHistory(context.Background(), + "", time.Time{}, time.Time{}, "2") if err != nil { t.Error(err) } - _, err = f.FetchOrderHistory(spotPair, time.Unix(authStartTime, 0), time.Unix(authEndTime, 0), "2") + _, err = f.FetchOrderHistory(context.Background(), + spotPair, time.Unix(authStartTime, 0), time.Unix(authEndTime, 0), "2") if err != nil { t.Error(err) } - _, err = f.FetchOrderHistory(spotPair, time.Unix(authEndTime, 0), time.Unix(authStartTime, 0), "2") + _, err = f.FetchOrderHistory(context.Background(), + spotPair, time.Unix(authEndTime, 0), time.Unix(authStartTime, 0), "2") if err != errStartTimeCannotBeAfterEndTime { t.Errorf("should have thrown errStartTimeCannotBeAfterEndTime, got %v", err) } @@ -491,11 +518,11 @@ func TestGetOpenTriggerOrders(t *testing.T) { t.Skip() } // optional params - _, err := f.GetOpenTriggerOrders("", "") + _, err := f.GetOpenTriggerOrders(context.Background(), "", "") if err != nil { t.Error(err) } - _, err = f.GetOpenTriggerOrders(spotPair, "") + _, err = f.GetOpenTriggerOrders(context.Background(), spotPair, "") if err != nil { t.Error(err) } @@ -506,7 +533,7 @@ func TestGetTriggerOrderTriggers(t *testing.T) { if !areTestAPIKeysSet() { t.Skip() } - _, err := f.GetTriggerOrderTriggers("1031") + _, err := f.GetTriggerOrderTriggers(context.Background(), "1031") if err != nil { t.Error(err) } @@ -517,19 +544,33 @@ func TestGetTriggerOrderHistory(t *testing.T) { if !areTestAPIKeysSet() { t.Skip() } - _, err := f.GetTriggerOrderHistory("", time.Time{}, time.Time{}, "", "", "") + _, err := f.GetTriggerOrderHistory(context.Background(), + "", time.Time{}, time.Time{}, "", "", "") if err != nil { t.Error(err) } - _, err = f.GetTriggerOrderHistory(spotPair, time.Time{}, time.Time{}, order.Buy.Lower(), "stop", "1") + _, err = f.GetTriggerOrderHistory(context.Background(), + spotPair, time.Time{}, time.Time{}, order.Buy.Lower(), "stop", "1") if err != nil { t.Error(err) } - _, err = f.GetTriggerOrderHistory(spotPair, time.Unix(authStartTime, 0), time.Unix(authEndTime, 0), order.Buy.Lower(), "stop", "1") + _, err = f.GetTriggerOrderHistory(context.Background(), + spotPair, + time.Unix(authStartTime, 0), + time.Unix(authEndTime, 0), + order.Buy.Lower(), + "stop", + "1") if err != nil { t.Error(err) } - _, err = f.GetTriggerOrderHistory(spotPair, time.Unix(authEndTime, 0), time.Unix(authStartTime, 0), order.Buy.Lower(), "stop", "1") + _, err = f.GetTriggerOrderHistory(context.Background(), + spotPair, + time.Unix(authEndTime, 0), + time.Unix(authStartTime, 0), + order.Buy.Lower(), + "stop", + "1") if err != errStartTimeCannotBeAfterEndTime { t.Errorf("should have thrown errStartTimeCannotBeAfterEndTime, got %v", err) } @@ -540,7 +581,12 @@ func TestOrder(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test, either api keys or canManipulateRealOrders isnt set correctly") } - _, err := f.Order(spotPair, order.Buy.Lower(), "limit", false, false, false, "", 0.0001, 500) + _, err := f.Order(context.Background(), + spotPair, + order.Buy.Lower(), + "limit", + false, false, false, + "", 0.0001, 500) if err != nil { t.Error(err) } @@ -567,7 +613,7 @@ func TestSubmitOrder(t *testing.T) { AssetType: asset.Spot, ClientOrderID: "order12345679$$$$$", } - _, err = f.SubmitOrder(orderSubmission) + _, err = f.SubmitOrder(context.Background(), orderSubmission) if err != nil { t.Error(err) } @@ -578,7 +624,12 @@ func TestTriggerOrder(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test, either api keys or canManipulateRealOrders isnt set correctly") } - _, err := f.TriggerOrder(spotPair, order.Buy.Lower(), order.Stop.Lower(), "", "", 500, 0.0004, 0.0001, 0) + _, err := f.TriggerOrder(context.Background(), + spotPair, + order.Buy.Lower(), + order.Stop.Lower(), + "", "", + 500, 0.0004, 0.0001, 0) if err != nil { t.Error(err) } @@ -600,12 +651,12 @@ func TestCancelOrder(t *testing.T) { Pair: currencyPair, AssetType: asset.Spot, } - if err := f.CancelOrder(&c); err != nil { + if err := f.CancelOrder(context.Background(), &c); err != nil { t.Error(err) } c.ClientOrderID = "1337" - if err := f.CancelOrder(&c); err != nil { + if err := f.CancelOrder(context.Background(), &c); err != nil { t.Error(err) } } @@ -615,7 +666,7 @@ func TestDeleteOrder(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test, either api keys or canManipulateRealOrders isnt set correctly") } - _, err := f.DeleteOrder("1031") + _, err := f.DeleteOrder(context.Background(), "1031") if err != nil { t.Error(err) } @@ -626,7 +677,7 @@ func TestDeleteOrderByClientID(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test, either api keys or canManipulateRealOrders isnt set correctly") } - _, err := f.DeleteOrderByClientID("clientID123") + _, err := f.DeleteOrderByClientID(context.Background(), "clientID123") if err != nil { t.Error(err) } @@ -637,7 +688,7 @@ func TestDeleteTriggerOrder(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test, either api keys or canManipulateRealOrders isnt set correctly") } - _, err := f.DeleteTriggerOrder("1031") + _, err := f.DeleteTriggerOrder(context.Background(), "1031") if err != nil { t.Error(err) } @@ -649,19 +700,21 @@ func TestGetFills(t *testing.T) { t.Skip() } // optional params - _, err := f.GetFills("", "", time.Time{}, time.Time{}) + _, err := f.GetFills(context.Background(), "", "", time.Time{}, time.Time{}) if err != nil { t.Error(err) } - _, err = f.GetFills(spotPair, "", time.Time{}, time.Time{}) + _, err = f.GetFills(context.Background(), spotPair, "", time.Time{}, time.Time{}) if err != nil { t.Error(err) } - _, err = f.GetFills(spotPair, "", time.Unix(authStartTime, 0), time.Unix(authEndTime, 0)) + _, err = f.GetFills(context.Background(), + spotPair, "", time.Unix(authStartTime, 0), time.Unix(authEndTime, 0)) if err != nil { t.Error(err) } - _, err = f.GetFills(spotPair, "", time.Unix(authEndTime, 0), time.Unix(authStartTime, 0)) + _, err = f.GetFills(context.Background(), + spotPair, "", time.Unix(authEndTime, 0), time.Unix(authStartTime, 0)) if err != errStartTimeCannotBeAfterEndTime { t.Errorf("should have thrown errStartTimeCannotBeAfterEndTime, got %v", err) } @@ -673,15 +726,18 @@ func TestGetFundingPayments(t *testing.T) { t.Skip() } // optional params - _, err := f.GetFundingPayments(time.Time{}, time.Time{}, "") + _, err := f.GetFundingPayments(context.Background(), + time.Time{}, time.Time{}, "") if err != nil { t.Error(err) } - _, err = f.GetFundingPayments(time.Unix(authStartTime, 0), time.Unix(authEndTime, 0), futuresPair) + _, err = f.GetFundingPayments(context.Background(), + time.Unix(authStartTime, 0), time.Unix(authEndTime, 0), futuresPair) if err != nil { t.Error(err) } - _, err = f.GetFundingPayments(time.Unix(authEndTime, 0), time.Unix(authStartTime, 0), futuresPair) + _, err = f.GetFundingPayments(context.Background(), + time.Unix(authEndTime, 0), time.Unix(authStartTime, 0), futuresPair) if err != errStartTimeCannotBeAfterEndTime { t.Errorf("should have thrown errStartTimeCannotBeAfterEndTime, got %v", err) } @@ -692,7 +748,7 @@ func TestListLeveragedTokens(t *testing.T) { if !areTestAPIKeysSet() { t.Skip() } - _, err := f.ListLeveragedTokens() + _, err := f.ListLeveragedTokens(context.Background()) if err != nil { t.Error(err) } @@ -703,7 +759,7 @@ func TestGetTokenInfo(t *testing.T) { if !areTestAPIKeysSet() { t.Skip() } - _, err := f.GetTokenInfo("") + _, err := f.GetTokenInfo(context.Background(), "") if err != nil { t.Error(err) } @@ -714,7 +770,7 @@ func TestListLTBalances(t *testing.T) { if !areTestAPIKeysSet() { t.Skip() } - _, err := f.ListLTBalances() + _, err := f.ListLTBalances(context.Background()) if err != nil { t.Error(err) } @@ -725,7 +781,7 @@ func TestListLTCreations(t *testing.T) { if !areTestAPIKeysSet() { t.Skip() } - _, err := f.ListLTCreations() + _, err := f.ListLTCreations(context.Background()) if err != nil { t.Error(err) } @@ -736,7 +792,7 @@ func TestRequestLTCreation(t *testing.T) { if !areTestAPIKeysSet() { t.Skip() } - _, err := f.RequestLTCreation(testLeverageToken, 1) + _, err := f.RequestLTCreation(context.Background(), testLeverageToken, 1) if err != nil { t.Error(err) } @@ -747,7 +803,7 @@ func TestListLTRedemptions(t *testing.T) { if !areTestAPIKeysSet() { t.Skip() } - _, err := f.ListLTRedemptions() + _, err := f.ListLTRedemptions(context.Background()) if err != nil { t.Error(err) } @@ -758,7 +814,7 @@ func TestGetQuoteRequests(t *testing.T) { if !areTestAPIKeysSet() { t.Skip() } - _, err := f.GetQuoteRequests() + _, err := f.GetQuoteRequests(context.Background()) if err != nil { t.Error(err) } @@ -769,7 +825,7 @@ func TestGetYourQuoteRequests(t *testing.T) { if !areTestAPIKeysSet() { t.Skip() } - _, err := f.GetYourQuoteRequests() + _, err := f.GetYourQuoteRequests(context.Background()) if err != nil { t.Error(err) } @@ -780,7 +836,8 @@ func TestCreateQuoteRequest(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test, either api keys or canManipulateRealOrders isnt set correctly") } - _, err := f.CreateQuoteRequest(currency.BTC, "call", order.Buy.Lower(), 1593140400, "", 10, 10, 5, 0, false) + _, err := f.CreateQuoteRequest(context.Background(), + currency.BTC, "call", order.Buy.Lower(), 1593140400, "", 10, 10, 5, 0, false) if err != nil { t.Error(err) } @@ -791,7 +848,7 @@ func TestDeleteQuote(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test, either api keys or canManipulateRealOrders isnt set correctly") } - _, err := f.DeleteQuote("1031") + _, err := f.DeleteQuote(context.Background(), "1031") if err != nil { t.Error(err) } @@ -802,7 +859,7 @@ func TestGetQuotesForYourQuote(t *testing.T) { if !areTestAPIKeysSet() { t.Skip() } - _, err := f.GetQuotesForYourQuote("1031") + _, err := f.GetQuotesForYourQuote(context.Background(), "1031") if err != nil { t.Error(err) } @@ -813,7 +870,7 @@ func TestMakeQuote(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test, either api keys or canManipulateRealOrders isnt set correctly") } - _, err := f.MakeQuote("1031", "5") + _, err := f.MakeQuote(context.Background(), "1031", "5") if err != nil { t.Error(err) } @@ -824,7 +881,7 @@ func TestMyQuotes(t *testing.T) { if !areTestAPIKeysSet() { t.Skip() } - _, err := f.MyQuotes() + _, err := f.MyQuotes(context.Background()) if err != nil { t.Error(err) } @@ -835,7 +892,7 @@ func TestDeleteMyQuote(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test, either api keys or canManipulateRealOrders isnt set correctly") } - _, err := f.DeleteMyQuote("1031") + _, err := f.DeleteMyQuote(context.Background(), "1031") if err != nil { t.Error(err) } @@ -846,7 +903,7 @@ func TestAcceptQuote(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test, either api keys or canManipulateRealOrders isnt set correctly") } - _, err := f.AcceptQuote("1031") + _, err := f.AcceptQuote(context.Background(), "1031") if err != nil { t.Error(err) } @@ -857,7 +914,7 @@ func TestGetAccountOptionsInfo(t *testing.T) { if !areTestAPIKeysSet() { t.Skip() } - _, err := f.GetAccountOptionsInfo() + _, err := f.GetAccountOptionsInfo(context.Background()) if err != nil { t.Error(err) } @@ -868,7 +925,7 @@ func TestGetOptionsPositions(t *testing.T) { if !areTestAPIKeysSet() { t.Skip() } - _, err := f.GetOptionsPositions() + _, err := f.GetOptionsPositions(context.Background()) if err != nil { t.Error(err) } @@ -877,7 +934,8 @@ func TestGetOptionsPositions(t *testing.T) { func TestGetPublicOptionsTrades(t *testing.T) { t.Parallel() // test optional params - result, err := f.GetPublicOptionsTrades(time.Time{}, time.Time{}, "") + result, err := f.GetPublicOptionsTrades(context.Background(), + time.Time{}, time.Time{}, "") if err != nil { t.Error(err) } @@ -885,14 +943,16 @@ func TestGetPublicOptionsTrades(t *testing.T) { t.Error("default limit should have returned 20 items") } tmNow := time.Now() - result, err = f.GetPublicOptionsTrades(tmNow.AddDate(0, 0, -1), tmNow, "5") + result, err = f.GetPublicOptionsTrades(context.Background(), + tmNow.AddDate(0, 0, -1), tmNow, "5") if err != nil { t.Error(err) } if len(result) != 5 { t.Error("limit of 5 should return 5 items") } - _, err = f.GetPublicOptionsTrades(time.Unix(validFTTBTCEndTime, 0), time.Unix(validFTTBTCStartTime, 0), "5") + _, err = f.GetPublicOptionsTrades(context.Background(), + time.Unix(validFTTBTCEndTime, 0), time.Unix(validFTTBTCStartTime, 0), "5") if err != errStartTimeCannotBeAfterEndTime { t.Errorf("should have thrown errStartTimeCannotBeAfterEndTime, got %v", err) } @@ -903,15 +963,17 @@ func TestGetOptionsFills(t *testing.T) { if !areTestAPIKeysSet() { t.Skip() } - _, err := f.GetOptionsFills(time.Time{}, time.Time{}, "5") + _, err := f.GetOptionsFills(context.Background(), time.Time{}, time.Time{}, "5") if err != nil { t.Error(err) } - _, err = f.GetOptionsFills(time.Unix(authStartTime, 0), time.Unix(authEndTime, 0), "5") + _, err = f.GetOptionsFills(context.Background(), + time.Unix(authStartTime, 0), time.Unix(authEndTime, 0), "5") if err != nil { t.Error(err) } - _, err = f.GetOptionsFills(time.Unix(authEndTime, 0), time.Unix(authStartTime, 0), "5") + _, err = f.GetOptionsFills(context.Background(), + time.Unix(authEndTime, 0), time.Unix(authStartTime, 0), "5") if err != errStartTimeCannotBeAfterEndTime { t.Errorf("should have thrown errStartTimeCannotBeAfterEndTime, got %v", err) } @@ -920,7 +982,7 @@ func TestGetOptionsFills(t *testing.T) { func TestUpdateOrderbook(t *testing.T) { t.Parallel() cp := currency.NewPairWithDelimiter(currency.BTC.String(), currency.USDT.String(), "/") - _, err := f.UpdateOrderbook(cp, asset.Spot) + _, err := f.UpdateOrderbook(context.Background(), cp, asset.Spot) if err != nil { t.Error(err) } @@ -929,7 +991,7 @@ func TestUpdateOrderbook(t *testing.T) { func TestUpdateTicker(t *testing.T) { t.Parallel() cp := currency.NewPairWithDelimiter(currency.BTC.String(), currency.USDT.String(), "/") - _, err := f.UpdateTicker(cp, asset.Spot) + _, err := f.UpdateTicker(context.Background(), cp, asset.Spot) if err != nil { t.Error(err) } @@ -937,7 +999,7 @@ func TestUpdateTicker(t *testing.T) { func TestUpdateTickers(t *testing.T) { t.Parallel() - err := f.UpdateTickers(asset.Spot) + err := f.UpdateTickers(context.Background(), asset.Spot) if err != nil { t.Error(err) } @@ -952,7 +1014,7 @@ func TestGetActiveOrders(t *testing.T) { cp := currency.NewPairWithDelimiter(currency.BTC.String(), currency.USDT.String(), "/") orderReq.Pairs = append(orderReq.Pairs, cp) orderReq.AssetType = asset.Spot - _, err := f.GetActiveOrders(&orderReq) + _, err := f.GetActiveOrders(context.Background(), &orderReq) if err != nil { t.Fatal(err) } @@ -967,7 +1029,7 @@ func TestGetOrderHistory(t *testing.T) { cp := currency.NewPairWithDelimiter(currency.BTC.String(), currency.USDT.String(), "/") orderReq.Pairs = append(orderReq.Pairs, cp) orderReq.AssetType = asset.Spot - _, err := f.GetOrderHistory(&orderReq) + _, err := f.GetOrderHistory(context.Background(), &orderReq) if err != nil { t.Fatal(err) } @@ -978,7 +1040,7 @@ func TestUpdateAccountHoldings(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys required but not set, skipping test") } - _, err := f.UpdateAccountInfo(asset.Spot) + _, err := f.UpdateAccountInfo(context.Background(), asset.Spot) if err != nil { t.Error(err) } @@ -989,7 +1051,7 @@ func TestFetchAccountInfo(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys required but not set, skipping test") } - _, err := f.FetchAccountInfo(asset.Spot) + _, err := f.FetchAccountInfo(context.Background(), asset.Spot) if err != nil { t.Error(err) } @@ -1002,7 +1064,7 @@ func TestGetFee(t *testing.T) { Amount: 1, IsMaker: true, } - fee, err := f.GetFee(feeBuilder) + fee, err := f.GetFee(context.Background(), feeBuilder) if err != nil { t.Error(err) } @@ -1011,7 +1073,7 @@ func TestGetFee(t *testing.T) { } feeBuilder.IsMaker = false - if fee, err = f.GetFee(feeBuilder); err != nil { + if fee, err = f.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } if fee <= 0 { @@ -1019,7 +1081,7 @@ func TestGetFee(t *testing.T) { } feeBuilder.FeeType = exchange.OfflineTradeFee - fee, err = f.GetFee(feeBuilder) + fee, err = f.GetFee(context.Background(), feeBuilder) if err != nil { t.Error(err) } @@ -1028,7 +1090,7 @@ func TestGetFee(t *testing.T) { } feeBuilder.IsMaker = true - fee, err = f.GetFee(feeBuilder) + fee, err = f.GetFee(context.Background(), feeBuilder) if err != nil { t.Error(err) } @@ -1059,7 +1121,7 @@ func TestGetOrderStatus(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys required but not set, skipping test") } - _, err := f.GetOrderStatus("1031") + _, err := f.GetOrderStatus(context.Background(), "1031") if err != nil { t.Error(err) } @@ -1070,7 +1132,7 @@ func TestGetOrderStatusByClientID(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys required but not set, skipping test") } - _, err := f.GetOrderStatusByClientID("testID") + _, err := f.GetOrderStatusByClientID(context.Background(), "testID") if err != nil { t.Error(err) } @@ -1081,7 +1143,7 @@ func TestRequestLTRedemption(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys required but not set, skipping test") } - _, err := f.RequestLTRedemption("ETHBULL", 5) + _, err := f.RequestLTRedemption(context.Background(), "ETHBULL", 5) if err != nil { t.Error(err) } @@ -1101,7 +1163,7 @@ func TestWithdrawCryptocurrencyFunds(t *testing.T) { request.Crypto = cryptoData request.OneTimePassword = 123456 request.TradePassword = "incorrectTradePassword" - _, err := f.WithdrawCryptocurrencyFunds(request) + _, err := f.WithdrawCryptocurrencyFunds(context.Background(), request) if err != nil { t.Error(err) } @@ -1112,7 +1174,7 @@ func TestGetDepositAddress(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys required but not set, skipping test") } - _, err := f.GetDepositAddress(currency.NewCode("FTT"), "") + _, err := f.GetDepositAddress(context.Background(), currency.NewCode("FTT"), "") if err != nil { t.Error(err) } @@ -1123,7 +1185,7 @@ func TestGetFundingHistory(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys required but not set, skipping test") } - _, err := f.GetFundingHistory() + _, err := f.GetFundingHistory(context.Background()) if err != nil { t.Error(err) } @@ -1137,7 +1199,8 @@ func TestGetHistoricCandles(t *testing.T) { } start := time.Date(2019, 11, 12, 0, 0, 0, 0, time.UTC) end := start.AddDate(0, 0, 2) - _, err = f.GetHistoricCandles(currencyPair, asset.Spot, start, end, kline.OneDay) + _, err = f.GetHistoricCandles(context.Background(), + currencyPair, asset.Spot, start, end, kline.OneDay) if err != nil { t.Fatal(err) } @@ -1151,7 +1214,8 @@ func TestGetHistoricCandlesExtended(t *testing.T) { } start := time.Date(2019, 11, 12, 0, 0, 0, 0, time.UTC) end := start.AddDate(0, 0, 2) - _, err = f.GetHistoricCandlesExtended(currencyPair, asset.Spot, start, end, kline.OneDay) + _, err = f.GetHistoricCandlesExtended(context.Background(), + currencyPair, asset.Spot, start, end, kline.OneDay) if err != nil { t.Fatal(err) } @@ -1162,7 +1226,7 @@ func TestGetOTCQuoteStatus(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys required but not set, skipping test") } - _, err := f.GetOTCQuoteStatus(spotPair, "1") + _, err := f.GetOTCQuoteStatus(context.Background(), spotPair, "1") if err != nil { t.Error(err) } @@ -1173,7 +1237,8 @@ func TestRequestForQuotes(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test, either api keys or canManipulateRealOrders isnt set correctly") } - _, err := f.RequestForQuotes(currency.NewCode("BtC"), currency.NewCode("UsD"), 0.5) + _, err := f.RequestForQuotes(context.Background(), + currency.NewCode("BtC"), currency.NewCode("UsD"), 0.5) if err != nil { t.Error(err) } @@ -1184,7 +1249,7 @@ func TestAcceptOTCQuote(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test, either api keys or canManipulateRealOrders isnt set correctly") } - err := f.AcceptOTCQuote("1031") + err := f.AcceptOTCQuote(context.Background(), "1031") if err != nil { t.Error(err) } @@ -1198,7 +1263,8 @@ func TestGetHistoricTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = f.GetHistoricTrades(enabledPairs.GetRandomPair(), + _, err = f.GetHistoricTrades(context.Background(), + enabledPairs.GetRandomPair(), assets[i], time.Now().Add(-time.Minute*15), time.Now()) @@ -1216,7 +1282,8 @@ func TestGetRecentTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = f.GetRecentTrades(enabledPairs.GetRandomPair(), assets[i]) + _, err = f.GetRecentTrades(context.Background(), + enabledPairs.GetRandomPair(), assets[i]) if err != nil { t.Error(err) } @@ -1235,7 +1302,7 @@ func TestTimestampFromFloat64(t *testing.T) { func TestCompatibleOrderVars(t *testing.T) { t.Parallel() - orderVars, err := f.compatibleOrderVars( + orderVars, err := f.compatibleOrderVars(context.Background(), "buy", "closed", "limit", @@ -1255,7 +1322,7 @@ func TestCompatibleOrderVars(t *testing.T) { t.Errorf("received %v expected %v", orderVars.Status, order.Filled) } - orderVars, err = f.compatibleOrderVars( + orderVars, err = f.compatibleOrderVars(context.Background(), "buy", "closed", "limit", @@ -1269,7 +1336,7 @@ func TestCompatibleOrderVars(t *testing.T) { t.Errorf("received %v expected %v", orderVars.Status, order.Cancelled) } - orderVars, err = f.compatibleOrderVars( + orderVars, err = f.compatibleOrderVars(context.Background(), "buy", "closed", "limit", @@ -1283,7 +1350,7 @@ func TestCompatibleOrderVars(t *testing.T) { t.Errorf("received %v expected %v", orderVars.Status, order.PartiallyCancelled) } - orderVars, err = f.compatibleOrderVars( + orderVars, err = f.compatibleOrderVars(context.Background(), "sell", "closed", "limit", @@ -1297,7 +1364,7 @@ func TestCompatibleOrderVars(t *testing.T) { t.Errorf("received %v expected %v", orderVars.Status, order.Filled) } - orderVars, err = f.compatibleOrderVars( + orderVars, err = f.compatibleOrderVars(context.Background(), "buy", "closed", "limit", @@ -1308,7 +1375,7 @@ func TestCompatibleOrderVars(t *testing.T) { t.Errorf("received %v expected %v", err, errInvalidOrderAmounts) } - orderVars, err = f.compatibleOrderVars( + orderVars, err = f.compatibleOrderVars(context.Background(), "buy", "fake", "limit", @@ -1319,7 +1386,7 @@ func TestCompatibleOrderVars(t *testing.T) { t.Errorf("received %v expected %v", err, errUnrecognisedOrderStatus) } - orderVars, err = f.compatibleOrderVars( + orderVars, err = f.compatibleOrderVars(context.Background(), "buy", "new", "limit", @@ -1333,7 +1400,7 @@ func TestCompatibleOrderVars(t *testing.T) { t.Errorf("received %v expected %v", orderVars.Status, order.New) } - orderVars, err = f.compatibleOrderVars( + orderVars, err = f.compatibleOrderVars(context.Background(), "buy", "open", "limit", @@ -1350,7 +1417,7 @@ func TestCompatibleOrderVars(t *testing.T) { func TestGetIndexWeights(t *testing.T) { t.Parallel() - _, err := f.GetIndexWeights("SHIT") + _, err := f.GetIndexWeights(context.Background(), "SHIT") if err != nil { t.Error(err) } @@ -1361,7 +1428,7 @@ func TestModifyPlacedOrder(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test, either api keys or canManipulateRealOrders isnt set correctly") } - _, err := f.ModifyPlacedOrder("1234", "", -0.1, 0.1) + _, err := f.ModifyPlacedOrder(context.Background(), "1234", "", -0.1, 0.1) if err != nil { t.Error(err) } @@ -1372,7 +1439,7 @@ func TestModifyOrderByClientID(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test, either api keys or canManipulateRealOrders isnt set correctly") } - _, err := f.ModifyOrderByClientID("1234", "", -0.1, 0.1) + _, err := f.ModifyOrderByClientID(context.Background(), "1234", "", -0.1, 0.1) if err != nil { t.Error(err) } @@ -1383,7 +1450,8 @@ func TestModifyTriggerOrder(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test, either api keys or canManipulateRealOrders isnt set correctly") } - _, err := f.ModifyTriggerOrder("1234", "stop", -0.1, 0.1, 0.02, 0) + _, err := f.ModifyTriggerOrder(context.Background(), + "1234", "stop", -0.1, 0.1, 0.02, 0) if err != nil { t.Error(err) } @@ -1394,7 +1462,7 @@ func TestGetSubaccounts(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("skipping test, api keys not set") } - _, err := f.GetSubaccounts() + _, err := f.GetSubaccounts(context.Background()) if err != nil { t.Error(err) } @@ -1402,7 +1470,7 @@ func TestGetSubaccounts(t *testing.T) { func TestCreateSubaccount(t *testing.T) { t.Parallel() - _, err := f.CreateSubaccount("") + _, err := f.CreateSubaccount(context.Background(), "") if !errors.Is(err, errSubaccountNameMustBeSpecified) { t.Errorf("expected %v, but received: %s", errSubaccountNameMustBeSpecified, err) } @@ -1410,18 +1478,18 @@ func TestCreateSubaccount(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test, either api keys or canManipulateRealOrders isn't set") } - _, err = f.CreateSubaccount("subzero") + _, err = f.CreateSubaccount(context.Background(), "subzero") if err != nil { t.Fatal(err) } - if err = f.DeleteSubaccount("subzero"); err != nil { + if err = f.DeleteSubaccount(context.Background(), "subzero"); err != nil { t.Error(err) } } func TestUpdateSubaccountName(t *testing.T) { t.Parallel() - _, err := f.UpdateSubaccountName("", "") + _, err := f.UpdateSubaccountName(context.Background(), "", "") if !errors.Is(err, errSubaccountUpdateNameInvalid) { t.Errorf("expected %v, but received: %s", errSubaccountUpdateNameInvalid, err) } @@ -1429,58 +1497,58 @@ func TestUpdateSubaccountName(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test, either api keys or canManipulateRealOrders isn't set") } - _, err = f.CreateSubaccount("subzero") + _, err = f.CreateSubaccount(context.Background(), "subzero") if err != nil { t.Fatal(err) } - _, err = f.UpdateSubaccountName("subzero", "bizzlebot") + _, err = f.UpdateSubaccountName(context.Background(), "subzero", "bizzlebot") if err != nil { t.Fatal(err) } - if err := f.DeleteSubaccount("bizzlebot"); err != nil { + if err := f.DeleteSubaccount(context.Background(), "bizzlebot"); err != nil { t.Error(err) } } func TestDeleteSubaccountName(t *testing.T) { t.Parallel() - if err := f.DeleteSubaccount(""); !errors.Is(err, errSubaccountNameMustBeSpecified) { + if err := f.DeleteSubaccount(context.Background(), ""); !errors.Is(err, errSubaccountNameMustBeSpecified) { t.Errorf("expected %v, but received: %s", errSubaccountNameMustBeSpecified, err) } if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test, either api keys or canManipulateRealOrders isn't set") } - _, err := f.CreateSubaccount("subzero") + _, err := f.CreateSubaccount(context.Background(), "subzero") if err != nil { t.Fatal(err) } - if err := f.DeleteSubaccount("subzero"); err != nil { + if err := f.DeleteSubaccount(context.Background(), "subzero"); err != nil { t.Error(err) } } func TestSubaccountBalances(t *testing.T) { t.Parallel() - _, err := f.SubaccountBalances("") + _, err := f.SubaccountBalances(context.Background(), "") if !errors.Is(err, errSubaccountNameMustBeSpecified) { t.Errorf("expected %s, but received: %s", errSubaccountNameMustBeSpecified, err) } if !areTestAPIKeysSet() { t.Skip("skipping test, api keys not set") } - _, err = f.SubaccountBalances("non-existent") + _, err = f.SubaccountBalances(context.Background(), "non-existent") if err == nil { t.Error("expecting non-existent subaccount to return an error") } - _, err = f.CreateSubaccount("subzero") + _, err = f.CreateSubaccount(context.Background(), "subzero") if err != nil { t.Fatal(err) } - _, err = f.SubaccountBalances("subzero") + _, err = f.SubaccountBalances(context.Background(), "subzero") if err != nil { t.Error(err) } - if err := f.DeleteSubaccount("subzero"); err != nil { + if err := f.DeleteSubaccount(context.Background(), "subzero"); err != nil { t.Error(err) } } @@ -1498,7 +1566,8 @@ func TestSubaccountTransfer(t *testing.T) { {Coin: currency.BTC, Size: 420, ErrExpected: errSubaccountTransferSourceDestinationMustNotBeEqual}, } for x := range tt { - _, err := f.SubaccountTransfer(tt[x].Coin, tt[x].Source, tt[x].Destination, tt[x].Size) + _, err := f.SubaccountTransfer(context.Background(), + tt[x].Coin, tt[x].Source, tt[x].Destination, tt[x].Size) if !errors.Is(err, tt[x].ErrExpected) { t.Errorf("expected %s, but received: %s", tt[x].ErrExpected, err) } @@ -1506,7 +1575,8 @@ func TestSubaccountTransfer(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test, either api keys or canManipulateRealOrders isn't set") } - _, err := f.SubaccountTransfer(currency.BTC, "", "test", 0.1) + _, err := f.SubaccountTransfer(context.Background(), + currency.BTC, "", "test", 0.1) if err != nil { t.Error(err) } @@ -1516,7 +1586,7 @@ func TestGetStakes(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("skipping test, api keys not set") } - _, err := f.GetStakes() + _, err := f.GetStakes(context.Background()) if err != nil { t.Error(err) } @@ -1526,7 +1596,7 @@ func TestGetUnstakeRequests(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("skipping test, api keys not set") } - _, err := f.GetUnstakeRequests() + _, err := f.GetUnstakeRequests(context.Background()) if err != nil { t.Error(err) } @@ -1536,7 +1606,7 @@ func TestGetStakeBalances(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("skipping test, api keys not set") } - _, err := f.GetStakeBalances() + _, err := f.GetStakeBalances(context.Background()) if err != nil { t.Error(err) } @@ -1546,12 +1616,12 @@ func TestUnstakeRequest(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test, either api keys or canManipulateRealOrders isn't set") } - r, err := f.UnstakeRequest(currency.FTT, 0.1) + r, err := f.UnstakeRequest(context.Background(), currency.FTT, 0.1) if err != nil { t.Fatal(err) } - success, err := f.CancelUnstakeRequest(r.ID) + success, err := f.CancelUnstakeRequest(context.Background(), r.ID) if err != nil || !success { t.Errorf("unable to cancel unstaking request: %s", err) } @@ -1561,7 +1631,7 @@ func TestCancelUnstakeRequest(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test, either api keys or canManipulateRealOrders isn't set") } - _, err := f.CancelUnstakeRequest(74351) + _, err := f.CancelUnstakeRequest(context.Background(), 74351) if err != nil { t.Error(err) } @@ -1571,7 +1641,7 @@ func TestGetStakingRewards(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("skipping test, api keys not set") } - _, err := f.GetStakingRewards() + _, err := f.GetStakingRewards(context.Background()) if err != nil { t.Error(err) } @@ -1583,14 +1653,14 @@ func TestStakeRequest(t *testing.T) { } // WARNING: This will lock up your funds for 14 days - _, err := f.StakeRequest(currency.FTT, 0.1) + _, err := f.StakeRequest(context.Background(), currency.FTT, 0.1) if err != nil { t.Error(err) } } func TestUpdateOrderExecutionLimits(t *testing.T) { - err := f.UpdateOrderExecutionLimits("") + err := f.UpdateOrderExecutionLimits(context.Background(), "") if err != nil { t.Fatal(err) } diff --git a/exchanges/ftx/ftx_websocket.go b/exchanges/ftx/ftx_websocket.go index 78c6a1ee..7a0da80c 100644 --- a/exchanges/ftx/ftx_websocket.go +++ b/exchanges/ftx/ftx_websocket.go @@ -1,6 +1,7 @@ package ftx import ( + "context" "encoding/json" "errors" "fmt" @@ -340,7 +341,7 @@ func (f *FTX) wsHandleData(respRaw []byte) error { return err } var orderVars OrderVars - orderVars, err = f.compatibleOrderVars( + orderVars, err = f.compatibleOrderVars(context.TODO(), resultData.OrderData.Side, resultData.OrderData.Status, resultData.OrderData.OrderType, diff --git a/exchanges/ftx/ftx_wrapper.go b/exchanges/ftx/ftx_wrapper.go index 2f7f1728..d3da4eec 100644 --- a/exchanges/ftx/ftx_wrapper.go +++ b/exchanges/ftx/ftx_wrapper.go @@ -1,6 +1,7 @@ package ftx import ( + "context" "errors" "fmt" "sort" @@ -41,7 +42,7 @@ func (f *FTX) GetDefaultConfig() (*config.ExchangeConfig, error) { } if f.Features.Supports.RESTCapabilities.AutoPairUpdates { - err = f.UpdateTradablePairs(true) + err = f.UpdateTradablePairs(context.TODO(), true) if err != nil { return nil, err } @@ -219,7 +220,7 @@ func (f *FTX) Run() { f.PrintEnabledPairs() } - err := f.UpdateOrderExecutionLimits("") + err := f.UpdateOrderExecutionLimits(context.TODO(), "") if err != nil { log.Errorf(log.ExchangeSys, "%s failed to set exchange order execution limits. Err: %v", @@ -231,7 +232,7 @@ func (f *FTX) Run() { return } - err = f.UpdateTradablePairs(false) + err = f.UpdateTradablePairs(context.TODO(), false) if err != nil { log.Errorf(log.ExchangeSys, "%s failed to update tradable pairs. Err: %s", @@ -241,11 +242,11 @@ func (f *FTX) Run() { } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (f *FTX) FetchTradablePairs(a asset.Item) ([]string, error) { +func (f *FTX) FetchTradablePairs(ctx context.Context, a asset.Item) ([]string, error) { if !f.SupportsAsset(a) { return nil, fmt.Errorf("asset type of %s is not supported by %s", a, f.Name) } - markets, err := f.GetMarkets() + markets, err := f.GetMarkets(ctx) if err != nil { return nil, err } @@ -281,10 +282,10 @@ func (f *FTX) FetchTradablePairs(a asset.Item) ([]string, error) { // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (f *FTX) UpdateTradablePairs(forceUpdate bool) error { +func (f *FTX) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { assets := f.GetAssetTypes(false) for x := range assets { - pairs, err := f.FetchTradablePairs(assets[x]) + pairs, err := f.FetchTradablePairs(ctx, assets[x]) if err != nil { return err } @@ -301,13 +302,13 @@ func (f *FTX) UpdateTradablePairs(forceUpdate bool) error { } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (f *FTX) UpdateTickers(a asset.Item) error { +func (f *FTX) UpdateTickers(ctx context.Context, a asset.Item) error { allPairs, err := f.GetEnabledPairs(a) if err != nil { return err } - markets, err := f.GetMarkets() + markets, err := f.GetMarkets(ctx) if err != nil { return err } @@ -342,13 +343,13 @@ func (f *FTX) UpdateTickers(a asset.Item) error { } // UpdateTicker updates and returns the ticker for a currency pair -func (f *FTX) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) { +func (f *FTX) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { formattedPair, err := f.FormatExchangeCurrency(p, a) if err != nil { return nil, err } - market, err := f.GetMarket(formattedPair.String()) + market, err := f.GetMarket(ctx, formattedPair.String()) if err != nil { return nil, err } @@ -373,25 +374,25 @@ func (f *FTX) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) } // FetchTicker returns the ticker for a currency pair -func (f *FTX) FetchTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) { +func (f *FTX) FetchTicker(ctx context.Context, p currency.Pair, assetType asset.Item) (*ticker.Price, error) { tickerNew, err := ticker.GetTicker(f.Name, p, assetType) if err != nil { - return f.UpdateTicker(p, assetType) + return f.UpdateTicker(ctx, p, assetType) } return tickerNew, nil } // FetchOrderbook returns orderbook base on the currency pair -func (f *FTX) FetchOrderbook(currency currency.Pair, assetType asset.Item) (*orderbook.Base, error) { - ob, err := orderbook.Get(f.Name, currency, assetType) +func (f *FTX) FetchOrderbook(ctx context.Context, c currency.Pair, assetType asset.Item) (*orderbook.Base, error) { + ob, err := orderbook.Get(f.Name, c, assetType) if err != nil { - return f.UpdateOrderbook(currency, assetType) + return f.UpdateOrderbook(ctx, c, assetType) } return ob, nil } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (f *FTX) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (f *FTX) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { book := &orderbook.Base{ Exchange: f.Name, Pair: p, @@ -402,7 +403,7 @@ func (f *FTX) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderbook if err != nil { return book, err } - tempResp, err := f.GetOrderbook(formattedPair.String(), 100) + tempResp, err := f.GetOrderbook(ctx, formattedPair.String(), 100) if err != nil { return book, err } @@ -424,11 +425,11 @@ func (f *FTX) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderbook } // UpdateAccountInfo retrieves balances for all enabled currencies -func (f *FTX) UpdateAccountInfo(a asset.Item) (account.Holdings, error) { +func (f *FTX) UpdateAccountInfo(ctx context.Context, a asset.Item) (account.Holdings, error) { var resp account.Holdings // Get all wallet balances used so we can transfer between accounts if // needed. - data, err := f.GetAllWalletBalances() + data, err := f.GetAllWalletBalances(ctx) if err != nil { return resp, err } @@ -457,10 +458,10 @@ func (f *FTX) UpdateAccountInfo(a asset.Item) (account.Holdings, error) { } // FetchAccountInfo retrieves balances for all enabled currencies -func (f *FTX) FetchAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (f *FTX) FetchAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { acc, err := account.GetHoldings(f.Name, assetType) if err != nil { - return f.UpdateAccountInfo(assetType) + return f.UpdateAccountInfo(ctx, assetType) } return acc, nil @@ -468,9 +469,9 @@ func (f *FTX) FetchAccountInfo(assetType asset.Item) (account.Holdings, error) { // GetFundingHistory returns funding history, deposits and // withdrawals -func (f *FTX) GetFundingHistory() ([]exchange.FundHistory, error) { +func (f *FTX) GetFundingHistory(ctx context.Context) ([]exchange.FundHistory, error) { var resp []exchange.FundHistory - depositData, err := f.FetchDepositHistory() + depositData, err := f.FetchDepositHistory(ctx) if err != nil { return resp, err } @@ -486,7 +487,7 @@ func (f *FTX) GetFundingHistory() ([]exchange.FundHistory, error) { tempData.TransferID = strconv.FormatInt(depositData[x].ID, 10) resp = append(resp, tempData) } - withdrawalData, err := f.FetchWithdrawalHistory() + withdrawalData, err := f.FetchWithdrawalHistory(ctx) if err != nil { return resp, err } @@ -506,18 +507,18 @@ func (f *FTX) GetFundingHistory() ([]exchange.FundHistory, error) { } // GetWithdrawalsHistory returns previous withdrawals data -func (f *FTX) GetWithdrawalsHistory(c currency.Code) (resp []exchange.WithdrawalHistory, err error) { +func (f *FTX) GetWithdrawalsHistory(ctx context.Context, c currency.Code) (resp []exchange.WithdrawalHistory, err error) { return nil, common.ErrNotYetImplemented } // GetRecentTrades returns the most recent trades for a currency and asset -func (f *FTX) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade.Data, error) { - return f.GetHistoricTrades(p, assetType, time.Now().Add(-time.Minute*15), time.Now()) +func (f *FTX) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { + return f.GetHistoricTrades(ctx, p, assetType, time.Now().Add(-time.Minute*15), time.Now()) } // GetHistoricTrades returns historic trade data within the timeframe provided // FTX returns trades from the end date and iterates towards the start date -func (f *FTX) GetHistoricTrades(p currency.Pair, assetType asset.Item, timestampStart, timestampEnd time.Time) ([]trade.Data, error) { +func (f *FTX) GetHistoricTrades(ctx context.Context, p currency.Pair, assetType asset.Item, timestampStart, timestampEnd time.Time) ([]trade.Data, error) { if err := common.StartEndTimeCheck(timestampStart, timestampEnd); err != nil { return nil, fmt.Errorf("invalid time range supplied. Start: %v End %v %w", timestampStart, timestampEnd, err) } @@ -532,7 +533,8 @@ func (f *FTX) GetHistoricTrades(p currency.Pair, assetType asset.Item, timestamp allTrades: for { var trades []TradeData - trades, err = f.GetTrades(p.String(), + trades, err = f.GetTrades(ctx, + p.String(), timestampStart.Unix(), ts.Unix(), 100) @@ -585,7 +587,7 @@ allTrades: } // SubmitOrder submits a new order -func (f *FTX) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { +func (f *FTX) SubmitOrder(ctx context.Context, s *order.Submit) (order.SubmitResponse, error) { var resp order.SubmitResponse if err := s.Validate(); err != nil { return resp, err @@ -603,7 +605,8 @@ func (f *FTX) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { return resp, err } - tempResp, err := f.Order(fPair.String(), + tempResp, err := f.Order(ctx, + fPair.String(), s.Side.Lower(), s.Type.Lower(), s.ReduceOnly, @@ -622,13 +625,14 @@ func (f *FTX) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (f *FTX) ModifyOrder(action *order.Modify) (order.Modify, error) { +func (f *FTX) ModifyOrder(ctx context.Context, action *order.Modify) (order.Modify, error) { if err := action.Validate(); err != nil { return order.Modify{}, err } if action.TriggerPrice != 0 { - a, err := f.ModifyTriggerOrder(action.ID, + a, err := f.ModifyTriggerOrder(ctx, + action.ID, action.Type.String(), action.Amount, action.TriggerPrice, @@ -652,12 +656,20 @@ func (f *FTX) ModifyOrder(action *order.Modify) (order.Modify, error) { var o OrderData var err error if action.ID == "" { - o, err = f.ModifyOrderByClientID(action.ClientOrderID, action.ClientOrderID, action.Price, action.Amount) + o, err = f.ModifyOrderByClientID(ctx, + action.ClientOrderID, + action.ClientOrderID, + action.Price, + action.Amount) if err != nil { return order.Modify{}, err } } else { - o, err = f.ModifyPlacedOrder(action.ID, action.ClientOrderID, action.Price, action.Amount) + o, err = f.ModifyPlacedOrder(ctx, + action.ID, + action.ClientOrderID, + action.Price, + action.Amount) if err != nil { return order.Modify{}, err } @@ -674,27 +686,27 @@ func (f *FTX) ModifyOrder(action *order.Modify) (order.Modify, error) { } // CancelOrder cancels an order by its corresponding ID number -func (f *FTX) CancelOrder(o *order.Cancel) error { +func (f *FTX) CancelOrder(ctx context.Context, o *order.Cancel) error { if err := o.Validate(o.StandardCancel()); err != nil { return err } if o.ClientOrderID != "" { - _, err := f.DeleteOrderByClientID(o.ClientOrderID) + _, err := f.DeleteOrderByClientID(ctx, o.ClientOrderID) return err } - _, err := f.DeleteOrder(o.ID) + _, err := f.DeleteOrder(ctx, o.ID) return err } // CancelBatchOrders cancels an orders by their corresponding ID numbers -func (f *FTX) CancelBatchOrders(o []order.Cancel) (order.CancelBatchResponse, error) { +func (f *FTX) CancelBatchOrders(ctx context.Context, o []order.Cancel) (order.CancelBatchResponse, error) { return order.CancelBatchResponse{}, common.ErrNotYetImplemented } // CancelAllOrders cancels all orders associated with a currency pair -func (f *FTX) CancelAllOrders(orderCancellation *order.Cancel) (order.CancelAllResponse, error) { +func (f *FTX) CancelAllOrders(ctx context.Context, orderCancellation *order.Cancel) (order.CancelAllResponse, error) { if err := orderCancellation.Validate(); err != nil { return order.CancelAllResponse{}, err } @@ -704,14 +716,14 @@ func (f *FTX) CancelAllOrders(orderCancellation *order.Cancel) (order.CancelAllR if err != nil { return resp, err } - orders, err := f.GetOpenOrders(formattedPair.String()) + orders, err := f.GetOpenOrders(ctx, formattedPair.String()) if err != nil { return resp, err } tempMap := make(map[string]string) for x := range orders { - _, err := f.DeleteOrder(strconv.FormatInt(orders[x].ID, 10)) + _, err := f.DeleteOrder(ctx, strconv.FormatInt(orders[x].ID, 10)) if err != nil { tempMap[strconv.FormatInt(orders[x].ID, 10)] = "Cancellation Failed" continue @@ -723,7 +735,7 @@ func (f *FTX) CancelAllOrders(orderCancellation *order.Cancel) (order.CancelAllR } // GetCompatible gets compatible variables for order vars -func (s *OrderData) GetCompatible(f *FTX) (OrderVars, error) { +func (s *OrderData) GetCompatible(ctx context.Context, f *FTX) (OrderVars, error) { var resp OrderVars switch s.Side { case order.Buy.Lower(): @@ -759,7 +771,7 @@ func (s *OrderData) GetCompatible(f *FTX) (OrderVars, error) { resp.OrderType = order.Limit feeBuilder.IsMaker = true } - fee, err := f.GetFee(&feeBuilder) + fee, err := f.GetFee(ctx, &feeBuilder) if err != nil { return resp, err } @@ -768,9 +780,9 @@ func (s *OrderData) GetCompatible(f *FTX) (OrderVars, error) { } // GetOrderInfo returns order information based on order ID -func (f *FTX) GetOrderInfo(orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { +func (f *FTX) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { var resp order.Detail - orderData, err := f.GetOrderStatus(orderID) + orderData, err := f.GetOrderStatus(ctx, orderID) if err != nil { return resp, err } @@ -792,7 +804,7 @@ func (f *FTX) GetOrderInfo(orderID string, pair currency.Pair, assetType asset.I resp.AssetType = orderAssetType resp.Price = orderData.Price resp.RemainingAmount = orderData.RemainingSize - orderVars, err := orderData.GetCompatible(f) + orderVars, err := orderData.GetCompatible(ctx, f) if err != nil { return resp, err } @@ -804,8 +816,8 @@ func (f *FTX) GetOrderInfo(orderID string, pair currency.Pair, assetType asset.I } // GetDepositAddress returns a deposit address for a specified currency -func (f *FTX) GetDepositAddress(cryptocurrency currency.Code, _ string) (string, error) { - a, err := f.FetchDepositAddress(cryptocurrency) +func (f *FTX) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _ string) (string, error) { + a, err := f.FetchDepositAddress(ctx, cryptocurrency) if err != nil { return "", err } @@ -814,11 +826,12 @@ func (f *FTX) GetDepositAddress(cryptocurrency currency.Code, _ string) (string, // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is // submitted -func (f *FTX) WithdrawCryptocurrencyFunds(withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (f *FTX) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } - resp, err := f.Withdraw(withdrawRequest.Currency, + resp, err := f.Withdraw(ctx, + withdrawRequest.Currency, withdrawRequest.Crypto.Address, withdrawRequest.Crypto.AddressTag, withdrawRequest.TradePassword, @@ -836,13 +849,13 @@ func (f *FTX) WithdrawCryptocurrencyFunds(withdrawRequest *withdraw.Request) (*w // WithdrawFiatFunds returns a withdrawal ID when a withdrawal is // submitted -func (f *FTX) WithdrawFiatFunds(_ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (f *FTX) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a // withdrawal is submitted -func (f *FTX) WithdrawFiatFundsToInternationalBank(_ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (f *FTX) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } @@ -852,7 +865,7 @@ func (f *FTX) GetWebsocket() (*stream.Websocket, error) { } // GetActiveOrders retrieves any orders that are active/open -func (f *FTX) GetActiveOrders(getOrdersRequest *order.GetOrdersRequest) ([]order.Detail, error) { +func (f *FTX) GetActiveOrders(ctx context.Context, getOrdersRequest *order.GetOrdersRequest) ([]order.Detail, error) { if err := getOrdersRequest.Validate(); err != nil { return nil, err } @@ -870,7 +883,7 @@ func (f *FTX) GetActiveOrders(getOrdersRequest *order.GetOrdersRequest) ([]order } var tempResp order.Detail - orderData, err := f.GetOpenOrders(formattedPair.String()) + orderData, err := f.GetOpenOrders(ctx, formattedPair.String()) if err != nil { return resp, err } @@ -892,7 +905,7 @@ func (f *FTX) GetActiveOrders(getOrdersRequest *order.GetOrdersRequest) ([]order tempResp.Price = orderData[y].Price tempResp.RemainingAmount = orderData[y].RemainingSize var orderVars OrderVars - orderVars, err = f.compatibleOrderVars( + orderVars, err = f.compatibleOrderVars(ctx, orderData[y].Side, orderData[y].Status, orderData[y].OrderType, @@ -909,7 +922,8 @@ func (f *FTX) GetActiveOrders(getOrdersRequest *order.GetOrdersRequest) ([]order resp = append(resp, tempResp) } - triggerOrderData, err := f.GetOpenTriggerOrders(formattedPair.String(), + triggerOrderData, err := f.GetOpenTriggerOrders(ctx, + formattedPair.String(), getOrdersRequest.Type.String()) if err != nil { return resp, err @@ -930,7 +944,7 @@ func (f *FTX) GetActiveOrders(getOrdersRequest *order.GetOrdersRequest) ([]order tempResp.Price = triggerOrderData[z].AvgFillPrice tempResp.RemainingAmount = triggerOrderData[z].Size - triggerOrderData[z].FilledSize tempResp.TriggerPrice = triggerOrderData[z].TriggerPrice - orderVars, err := f.compatibleOrderVars( + orderVars, err := f.compatibleOrderVars(ctx, triggerOrderData[z].Side, triggerOrderData[z].Status, triggerOrderData[z].OrderType, @@ -952,7 +966,7 @@ func (f *FTX) GetActiveOrders(getOrdersRequest *order.GetOrdersRequest) ([]order // GetOrderHistory retrieves account order information // Can Limit response to specific order status -func (f *FTX) GetOrderHistory(getOrdersRequest *order.GetOrdersRequest) ([]order.Detail, error) { +func (f *FTX) GetOrderHistory(ctx context.Context, getOrdersRequest *order.GetOrdersRequest) ([]order.Detail, error) { if err := getOrdersRequest.Validate(); err != nil { return nil, err } @@ -970,8 +984,11 @@ func (f *FTX) GetOrderHistory(getOrdersRequest *order.GetOrdersRequest) ([]order return nil, err } - orderData, err := f.FetchOrderHistory(formattedPair.String(), - getOrdersRequest.StartTime, getOrdersRequest.EndTime, "") + orderData, err := f.FetchOrderHistory(ctx, + formattedPair.String(), + getOrdersRequest.StartTime, + getOrdersRequest.EndTime, + "") if err != nil { return resp, err } @@ -992,7 +1009,7 @@ func (f *FTX) GetOrderHistory(getOrdersRequest *order.GetOrdersRequest) ([]order tempResp.Price = orderData[y].Price tempResp.RemainingAmount = orderData[y].RemainingSize var orderVars OrderVars - orderVars, err = f.compatibleOrderVars( + orderVars, err = f.compatibleOrderVars(ctx, orderData[y].Side, orderData[y].Status, orderData[y].OrderType, @@ -1008,7 +1025,8 @@ func (f *FTX) GetOrderHistory(getOrdersRequest *order.GetOrdersRequest) ([]order tempResp.Fee = orderVars.Fee resp = append(resp, tempResp) } - triggerOrderData, err := f.GetTriggerOrderHistory(formattedPair.String(), + triggerOrderData, err := f.GetTriggerOrderHistory(ctx, + formattedPair.String(), getOrdersRequest.StartTime, getOrdersRequest.EndTime, strings.ToLower(getOrdersRequest.Side.String()), @@ -1033,7 +1051,7 @@ func (f *FTX) GetOrderHistory(getOrdersRequest *order.GetOrdersRequest) ([]order tempResp.Price = triggerOrderData[z].AvgFillPrice tempResp.RemainingAmount = triggerOrderData[z].Size - triggerOrderData[z].FilledSize tempResp.TriggerPrice = triggerOrderData[z].TriggerPrice - orderVars, err := f.compatibleOrderVars( + orderVars, err := f.compatibleOrderVars(ctx, triggerOrderData[z].Side, triggerOrderData[z].Status, triggerOrderData[z].OrderType, @@ -1054,8 +1072,8 @@ func (f *FTX) GetOrderHistory(getOrdersRequest *order.GetOrdersRequest) ([]order } // GetFeeByType returns an estimate of fee based on the type of transaction -func (f *FTX) GetFeeByType(feeBuilder *exchange.FeeBuilder) (float64, error) { - return f.GetFee(feeBuilder) +func (f *FTX) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { + return f.GetFee(ctx, feeBuilder) } // SubscribeToWebsocketChannels appends to ChannelsToSubscribe @@ -1071,19 +1089,19 @@ func (f *FTX) UnsubscribeToWebsocketChannels(channels []stream.ChannelSubscripti } // AuthenticateWebsocket sends an authentication message to the websocket -func (f *FTX) AuthenticateWebsocket() error { +func (f *FTX) AuthenticateWebsocket(_ context.Context) error { return f.WsAuth() } // ValidateCredentials validates current credentials used for wrapper // functionality -func (f *FTX) ValidateCredentials(assetType asset.Item) error { - _, err := f.UpdateAccountInfo(assetType) +func (f *FTX) ValidateCredentials(ctx context.Context, assetType asset.Item) error { + _, err := f.UpdateAccountInfo(ctx, assetType) return f.CheckTransientError(err) } // GetHistoricCandles returns candles between a time period for a set time interval -func (f *FTX) GetHistoricCandles(p currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (f *FTX) GetHistoricCandles(ctx context.Context, p currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { if err := f.ValidateKline(p, a, interval); err != nil { return kline.Item{}, err } @@ -1093,10 +1111,12 @@ func (f *FTX) GetHistoricCandles(p currency.Pair, a asset.Item, start, end time. return kline.Item{}, err } - ohlcData, err := f.GetHistoricalData(formattedPair.String(), + ohlcData, err := f.GetHistoricalData(ctx, + formattedPair.String(), int64(interval.Duration().Seconds()), int64(f.Features.Enabled.Kline.ResultLimit), - start, end) + start, + end) if err != nil { return kline.Item{}, err } @@ -1122,7 +1142,7 @@ func (f *FTX) GetHistoricCandles(p currency.Pair, a asset.Item, start, end time. } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (f *FTX) GetHistoricCandlesExtended(p currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (f *FTX) GetHistoricCandlesExtended(ctx context.Context, p currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { if err := f.ValidateKline(p, a, interval); err != nil { return kline.Item{}, err } @@ -1146,10 +1166,12 @@ func (f *FTX) GetHistoricCandlesExtended(p currency.Pair, a asset.Item, start, e for x := range dates.Ranges { var ohlcData []OHLCVData - ohlcData, err = f.GetHistoricalData(formattedPair.String(), + ohlcData, err = f.GetHistoricalData(ctx, + formattedPair.String(), int64(interval.Duration().Seconds()), int64(f.Features.Enabled.Kline.ResultLimit), - dates.Ranges[x].Start.Time, dates.Ranges[x].End.Time) + dates.Ranges[x].Start.Time, + dates.Ranges[x].End.Time) if err != nil { return kline.Item{}, err } @@ -1177,8 +1199,8 @@ func (f *FTX) GetHistoricCandlesExtended(p currency.Pair, a asset.Item, start, e } // UpdateOrderExecutionLimits sets exchange executions for a required asset type -func (f *FTX) UpdateOrderExecutionLimits(_ asset.Item) error { - limits, err := f.FetchExchangeLimits() +func (f *FTX) UpdateOrderExecutionLimits(ctx context.Context, _ asset.Item) error { + limits, err := f.FetchExchangeLimits(ctx) if err != nil { return fmt.Errorf("cannot update exchange execution limits: %w", err) } diff --git a/exchanges/gateio/gateio.go b/exchanges/gateio/gateio.go index 19327fc1..8fb353ec 100644 --- a/exchanges/gateio/gateio.go +++ b/exchanges/gateio/gateio.go @@ -48,10 +48,10 @@ type Gateio struct { } // GetSymbols returns all supported symbols -func (g *Gateio) GetSymbols() ([]string, error) { +func (g *Gateio) GetSymbols(ctx context.Context) ([]string, error) { var result []string urlPath := fmt.Sprintf("/%s/%s", gateioAPIVersion, gateioSymbol) - err := g.SendHTTPRequest(exchange.RestSpotSupplementary, urlPath, &result) + err := g.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, urlPath, &result) if err != nil { return nil, nil } @@ -60,7 +60,7 @@ func (g *Gateio) GetSymbols() ([]string, error) { // GetMarketInfo returns information about all trading pairs, including // transaction fee, minimum order quantity, price accuracy and so on -func (g *Gateio) GetMarketInfo() (MarketInfoResponse, error) { +func (g *Gateio) GetMarketInfo(ctx context.Context) (MarketInfoResponse, error) { type response struct { Result string `json:"result"` Pairs []interface{} `json:"pairs"` @@ -69,7 +69,7 @@ func (g *Gateio) GetMarketInfo() (MarketInfoResponse, error) { urlPath := fmt.Sprintf("/%s/%s", gateioAPIVersion, gateioMarketInfo) var res response var result MarketInfoResponse - err := g.SendHTTPRequest(exchange.RestSpotSupplementary, urlPath, &res) + err := g.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, urlPath, &res) if err != nil { return result, err } @@ -94,8 +94,8 @@ func (g *Gateio) GetMarketInfo() (MarketInfoResponse, error) { // updated every 10 seconds // // symbol: string of currency pair -func (g *Gateio) GetLatestSpotPrice(symbol string) (float64, error) { - res, err := g.GetTicker(symbol) +func (g *Gateio) GetLatestSpotPrice(ctx context.Context, symbol string) (float64, error) { + res, err := g.GetTicker(ctx, symbol) if err != nil { return 0, err } @@ -105,17 +105,17 @@ func (g *Gateio) GetLatestSpotPrice(symbol string) (float64, error) { // GetTicker returns a ticker for the supplied symbol // updated every 10 seconds -func (g *Gateio) GetTicker(symbol string) (TickerResponse, error) { +func (g *Gateio) GetTicker(ctx context.Context, symbol string) (TickerResponse, error) { urlPath := fmt.Sprintf("/%s/%s/%s", gateioAPIVersion, gateioTicker, symbol) var res TickerResponse - return res, g.SendHTTPRequest(exchange.RestSpotSupplementary, urlPath, &res) + return res, g.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, urlPath, &res) } // GetTickers returns tickers for all symbols -func (g *Gateio) GetTickers() (map[string]TickerResponse, error) { +func (g *Gateio) GetTickers(ctx context.Context) (map[string]TickerResponse, error) { urlPath := fmt.Sprintf("/%s/%s", gateioAPIVersion, gateioTickers) resp := make(map[string]TickerResponse) - err := g.SendHTTPRequest(exchange.RestSpotSupplementary, urlPath, &resp) + err := g.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, urlPath, &resp) if err != nil { return nil, err } @@ -123,10 +123,10 @@ func (g *Gateio) GetTickers() (map[string]TickerResponse, error) { } // GetTrades returns trades for symbols -func (g *Gateio) GetTrades(symbol string) (TradeHistory, error) { +func (g *Gateio) GetTrades(ctx context.Context, symbol string) (TradeHistory, error) { urlPath := fmt.Sprintf("/%s/%s/%s", gateioAPIVersion, gateioTrades, symbol) var resp TradeHistory - err := g.SendHTTPRequest(exchange.RestSpotSupplementary, urlPath, &resp) + err := g.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, urlPath, &resp) if err != nil { return TradeHistory{}, err } @@ -134,10 +134,10 @@ func (g *Gateio) GetTrades(symbol string) (TradeHistory, error) { } // GetOrderbook returns the orderbook data for a suppled symbol -func (g *Gateio) GetOrderbook(symbol string) (Orderbook, error) { +func (g *Gateio) GetOrderbook(ctx context.Context, symbol string) (Orderbook, error) { urlPath := fmt.Sprintf("/%s/%s/%s", gateioAPIVersion, gateioOrderbook, symbol) var resp OrderbookResponse - err := g.SendHTTPRequest(exchange.RestSpotSupplementary, urlPath, &resp) + err := g.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, urlPath, &resp) if err != nil { return Orderbook{}, err } @@ -195,7 +195,7 @@ func (g *Gateio) GetOrderbook(symbol string) (Orderbook, error) { } // GetSpotKline returns kline data for the most recent time period -func (g *Gateio) GetSpotKline(arg KlinesRequestParams) (kline.Item, error) { +func (g *Gateio) GetSpotKline(ctx context.Context, arg KlinesRequestParams) (kline.Item, error) { urlPath := fmt.Sprintf("/%s/%s/%s?group_sec=%s&range_hour=%d", gateioAPIVersion, gateioKline, @@ -204,7 +204,7 @@ func (g *Gateio) GetSpotKline(arg KlinesRequestParams) (kline.Item, error) { arg.HourSize) var rawKlines map[string]interface{} - err := g.SendHTTPRequest(exchange.RestSpotSupplementary, urlPath, &rawKlines) + err := g.SendHTTPRequest(ctx, exchange.RestSpotSupplementary, urlPath, &rawKlines) if err != nil { return kline.Item{}, err } @@ -265,15 +265,14 @@ func (g *Gateio) GetSpotKline(arg KlinesRequestParams) (kline.Item, error) { } // GetBalances obtains the users account balance -func (g *Gateio) GetBalances() (BalancesResponse, error) { +func (g *Gateio) GetBalances(ctx context.Context) (BalancesResponse, error) { var result BalancesResponse - return result, - g.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, gateioBalances, "", &result) + g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, gateioBalances, "", &result) } // SpotNewOrder places a new order -func (g *Gateio) SpotNewOrder(arg SpotNewOrderRequestParams) (SpotNewOrderResponse, error) { +func (g *Gateio) SpotNewOrder(ctx context.Context, arg SpotNewOrderRequestParams) (SpotNewOrderResponse, error) { var result SpotNewOrderResponse // Be sure to use the correct price precision before calling this @@ -284,13 +283,13 @@ func (g *Gateio) SpotNewOrder(arg SpotNewOrderRequestParams) (SpotNewOrderRespon ) urlPath := fmt.Sprintf("%s/%s", gateioOrder, arg.Type) - return result, g.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, urlPath, params, &result) + return result, g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, urlPath, params, &result) } // CancelExistingOrder cancels an order given the supplied orderID and symbol // orderID order ID number // symbol trade pair (ltc_btc) -func (g *Gateio) CancelExistingOrder(orderID int64, symbol string) (bool, error) { +func (g *Gateio) CancelExistingOrder(ctx context.Context, orderID int64, symbol string) (bool, error) { type response struct { Result bool `json:"result"` Code int `json:"code"` @@ -303,7 +302,7 @@ func (g *Gateio) CancelExistingOrder(orderID int64, symbol string) (bool, error) orderID, symbol, ) - err := g.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, gateioCancelOrder, params, &result) + err := g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, gateioCancelOrder, params, &result) if err != nil { return false, err } @@ -315,7 +314,7 @@ func (g *Gateio) CancelExistingOrder(orderID int64, symbol string) (bool, error) } // SendHTTPRequest sends an unauthenticated HTTP request -func (g *Gateio) SendHTTPRequest(ep exchange.URL, path string, result interface{}) error { +func (g *Gateio) SendHTTPRequest(ctx context.Context, ep exchange.URL, path string, result interface{}) error { endpoint, err := g.API.Endpoints.GetURL(ep) if err != nil { return err @@ -328,14 +327,14 @@ func (g *Gateio) SendHTTPRequest(ep exchange.URL, path string, result interface{ HTTPDebugging: g.HTTPDebugging, HTTPRecording: g.HTTPRecording, } - return g.SendPayload(context.Background(), request.Unset, func() (*request.Item, error) { + return g.SendPayload(ctx, request.Unset, func() (*request.Item, error) { return item, nil }) } // CancelAllExistingOrders all orders for a given symbol and side // orderType (0: sell,1: buy,-1: unlimited) -func (g *Gateio) CancelAllExistingOrders(orderType int64, symbol string) error { +func (g *Gateio) CancelAllExistingOrders(ctx context.Context, orderType int64, symbol string) error { type response struct { Result bool `json:"result"` Code int `json:"code"` @@ -347,7 +346,7 @@ func (g *Gateio) CancelAllExistingOrders(orderType int64, symbol string) error { orderType, symbol, ) - err := g.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, gateioCancelAllOrders, params, &result) + err := g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, gateioCancelAllOrders, params, &result) if err != nil { return err } @@ -360,7 +359,7 @@ func (g *Gateio) CancelAllExistingOrders(orderType int64, symbol string) error { } // GetOpenOrders retrieves all open orders with an optional symbol filter -func (g *Gateio) GetOpenOrders(symbol string) (OpenOrdersResponse, error) { +func (g *Gateio) GetOpenOrders(ctx context.Context, symbol string) (OpenOrdersResponse, error) { var params string var result OpenOrdersResponse @@ -368,7 +367,7 @@ func (g *Gateio) GetOpenOrders(symbol string) (OpenOrdersResponse, error) { params = fmt.Sprintf("currencyPair=%s", symbol) } - err := g.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, gateioOpenOrders, params, &result) + err := g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, gateioOpenOrders, params, &result) if err != nil { return result, err } @@ -381,12 +380,12 @@ func (g *Gateio) GetOpenOrders(symbol string) (OpenOrdersResponse, error) { } // GetTradeHistory retrieves all orders with an optional symbol filter -func (g *Gateio) GetTradeHistory(symbol string) (TradHistoryResponse, error) { +func (g *Gateio) GetTradeHistory(ctx context.Context, symbol string) (TradHistoryResponse, error) { var params string var result TradHistoryResponse params = fmt.Sprintf("currencyPair=%s", symbol) - err := g.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, gateioTradeHistory, params, &result) + err := g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, gateioTradeHistory, params, &result) if err != nil { return result, err } @@ -406,7 +405,7 @@ func (g *Gateio) GenerateSignature(message string) ([]byte, error) { // SendAuthenticatedHTTPRequest sends authenticated requests to the Gateio API // To use this you must setup an APIKey and APISecret from the exchange -func (g *Gateio) SendAuthenticatedHTTPRequest(ep exchange.URL, method, endpoint, param string, result interface{}) error { +func (g *Gateio) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, method, endpoint, param string, result interface{}) error { if !g.AllowAuthenticatedRequest() { return fmt.Errorf("%s %w", g.Name, exchange.ErrAuthenticatedRequestWithoutCredentialsSet) } @@ -438,7 +437,7 @@ func (g *Gateio) SendAuthenticatedHTTPRequest(ep exchange.URL, method, endpoint, HTTPDebugging: g.HTTPDebugging, HTTPRecording: g.HTTPRecording, } - err = g.SendPayload(context.Background(), request.Unset, func() (*request.Item, error) { + err = g.SendPayload(ctx, request.Unset, func() (*request.Item, error) { item.Body = strings.NewReader(param) return item, nil }) @@ -465,10 +464,10 @@ func (g *Gateio) SendAuthenticatedHTTPRequest(ep exchange.URL, method, endpoint, } // GetFee returns an estimate of fee based on type of transaction -func (g *Gateio) GetFee(feeBuilder *exchange.FeeBuilder) (fee float64, err error) { +func (g *Gateio) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) (fee float64, err error) { switch feeBuilder.FeeType { case exchange.CryptocurrencyTradeFee: - feePairs, err := g.GetMarketInfo() + feePairs, err := g.GetMarketInfo(ctx) if err != nil { return 0, err } @@ -520,7 +519,7 @@ func getCryptocurrencyWithdrawalFee(c currency.Code) float64 { } // WithdrawCrypto withdraws cryptocurrency to your selected wallet -func (g *Gateio) WithdrawCrypto(currency, address string, amount float64) (*withdraw.ExchangeResponse, error) { +func (g *Gateio) WithdrawCrypto(ctx context.Context, currency, address string, amount float64) (*withdraw.ExchangeResponse, error) { type response struct { Result bool `json:"result"` Message string `json:"message"` @@ -533,7 +532,7 @@ func (g *Gateio) WithdrawCrypto(currency, address string, amount float64) (*with address, amount, ) - err := g.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, gateioWithdraw, params, &result) + err := g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, gateioWithdraw, params, &result) if err != nil { return nil, err } @@ -547,7 +546,7 @@ func (g *Gateio) WithdrawCrypto(currency, address string, amount float64) (*with } // GetCryptoDepositAddress returns a deposit address for a cryptocurrency -func (g *Gateio) GetCryptoDepositAddress(currency string) (string, error) { +func (g *Gateio) GetCryptoDepositAddress(ctx context.Context, currency string) (string, error) { type response struct { Result bool `json:"result,string"` Code int `json:"code"` @@ -559,7 +558,7 @@ func (g *Gateio) GetCryptoDepositAddress(currency string) (string, error) { params := fmt.Sprintf("currency=%s", currency) - err := g.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, gateioDepositAddress, params, &result) + err := g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, gateioDepositAddress, params, &result) if err != nil { return "", err } diff --git a/exchanges/gateio/gateio_test.go b/exchanges/gateio/gateio_test.go index 507d1467..4a1ef237 100644 --- a/exchanges/gateio/gateio_test.go +++ b/exchanges/gateio/gateio_test.go @@ -1,6 +1,7 @@ package gateio import ( + "context" "log" "net/http" "os" @@ -59,7 +60,7 @@ func TestMain(m *testing.M) { func TestGetSymbols(t *testing.T) { t.Parallel() - _, err := g.GetSymbols() + _, err := g.GetSymbols(context.Background()) if err != nil { t.Errorf("Gateio TestGetSymbols: %s", err) } @@ -67,7 +68,7 @@ func TestGetSymbols(t *testing.T) { func TestGetMarketInfo(t *testing.T) { t.Parallel() - _, err := g.GetMarketInfo() + _, err := g.GetMarketInfo(context.Background()) if err != nil { t.Errorf("Gateio GetMarketInfo: %s", err) } @@ -80,12 +81,13 @@ func TestSpotNewOrder(t *testing.T) { t.Skip() } - _, err := g.SpotNewOrder(SpotNewOrderRequestParams{ - Symbol: "btc_usdt", - Amount: -1, - Price: 100000, - Type: order.Sell.Lower(), - }) + _, err := g.SpotNewOrder(context.Background(), + SpotNewOrderRequestParams{ + Symbol: "btc_usdt", + Amount: -1, + Price: 100000, + Type: order.Sell.Lower(), + }) if err != nil { t.Errorf("Gateio SpotNewOrder: %s", err) } @@ -98,7 +100,7 @@ func TestCancelExistingOrder(t *testing.T) { t.Skip() } - _, err := g.CancelExistingOrder(917591554, "btc_usdt") + _, err := g.CancelExistingOrder(context.Background(), 917591554, "btc_usdt") if err != nil { t.Errorf("Gateio CancelExistingOrder: %s", err) } @@ -111,7 +113,7 @@ func TestGetBalances(t *testing.T) { t.Skip() } - _, err := g.GetBalances() + _, err := g.GetBalances(context.Background()) if err != nil { t.Errorf("Gateio GetBalances: %s", err) } @@ -119,7 +121,7 @@ func TestGetBalances(t *testing.T) { func TestGetLatestSpotPrice(t *testing.T) { t.Parallel() - _, err := g.GetLatestSpotPrice("btc_usdt") + _, err := g.GetLatestSpotPrice(context.Background(), "btc_usdt") if err != nil { t.Errorf("Gateio GetLatestSpotPrice: %s", err) } @@ -127,7 +129,7 @@ func TestGetLatestSpotPrice(t *testing.T) { func TestGetTicker(t *testing.T) { t.Parallel() - _, err := g.GetTicker("btc_usdt") + _, err := g.GetTicker(context.Background(), "btc_usdt") if err != nil { t.Errorf("Gateio GetTicker: %s", err) } @@ -135,7 +137,7 @@ func TestGetTicker(t *testing.T) { func TestGetTickers(t *testing.T) { t.Parallel() - _, err := g.GetTickers() + _, err := g.GetTickers(context.Background()) if err != nil { t.Errorf("Gateio GetTicker: %s", err) } @@ -143,7 +145,7 @@ func TestGetTickers(t *testing.T) { func TestGetOrderbook(t *testing.T) { t.Parallel() - _, err := g.GetOrderbook("btc_usdt") + _, err := g.GetOrderbook(context.Background(), "btc_usdt") if err != nil { t.Errorf("Gateio GetTicker: %s", err) } @@ -151,11 +153,12 @@ func TestGetOrderbook(t *testing.T) { func TestGetSpotKline(t *testing.T) { t.Parallel() - _, err := g.GetSpotKline(KlinesRequestParams{ - Symbol: "btc_usdt", - GroupSec: "5", // 5 minutes or less - HourSize: 1, // 1 hour data - }) + _, err := g.GetSpotKline(context.Background(), + KlinesRequestParams{ + Symbol: "btc_usdt", + GroupSec: "5", // 5 minutes or less + HourSize: 1, // 1 hour data + }) if err != nil { t.Errorf("Gateio GetSpotKline: %s", err) @@ -176,8 +179,9 @@ func setFeeBuilder() *exchange.FeeBuilder { } func TestGetTradeHistory(t *testing.T) { - _, err := g.GetTrades(currency.NewPairWithDelimiter(currency.BTC.String(), - currency.USDT.String(), "_").String()) + _, err := g.GetTrades(context.Background(), + currency.NewPairWithDelimiter(currency.BTC.String(), + currency.USDT.String(), "_").String()) if err != nil { t.Error(err) } @@ -186,7 +190,7 @@ func TestGetTradeHistory(t *testing.T) { // TestGetFeeByTypeOfflineTradeFee logic test func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { var feeBuilder = setFeeBuilder() - _, err := g.GetFeeByType(feeBuilder) + _, err := g.GetFeeByType(context.Background(), feeBuilder) if err != nil { t.Fatal(err) } @@ -205,7 +209,7 @@ func TestGetFee(t *testing.T) { var feeBuilder = setFeeBuilder() if areTestAPIKeysSet() { // CryptocurrencyTradeFee Basic - if _, err := g.GetFee(feeBuilder); err != nil { + if _, err := g.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } @@ -213,28 +217,28 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.Amount = 1000 feeBuilder.PurchasePrice = 1000 - if _, err := g.GetFee(feeBuilder); err != nil { + if _, err := g.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyTradeFee IsMaker feeBuilder = setFeeBuilder() feeBuilder.IsMaker = true - if _, err := g.GetFee(feeBuilder); err != nil { + if _, err := g.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyTradeFee Negative purchase price feeBuilder = setFeeBuilder() feeBuilder.PurchasePrice = -1000 - if _, err := g.GetFee(feeBuilder); err != nil { + if _, err := g.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } } // CryptocurrencyWithdrawalFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee - if _, err := g.GetFee(feeBuilder); err != nil { + if _, err := g.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } @@ -242,21 +246,21 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.Pair.Base = currency.NewCode("hello") feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee - if _, err := g.GetFee(feeBuilder); err != nil { + if _, err := g.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyDepositFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.CryptocurrencyDepositFee - if _, err := g.GetFee(feeBuilder); err != nil { + if _, err := g.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } // InternationalBankDepositFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankDepositFee - if _, err := g.GetFee(feeBuilder); err != nil { + if _, err := g.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } @@ -264,7 +268,7 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee feeBuilder.FiatCurrency = currency.USD - if _, err := g.GetFee(feeBuilder); err != nil { + if _, err := g.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } } @@ -283,7 +287,7 @@ func TestGetActiveOrders(t *testing.T) { AssetType: asset.Spot, } - _, err := g.GetActiveOrders(&getOrdersRequest) + _, err := g.GetActiveOrders(context.Background(), &getOrdersRequest) if areTestAPIKeysSet() && err != nil { t.Errorf("Could not get open orders: %s", err) } else if !areTestAPIKeysSet() && err == nil { @@ -301,7 +305,7 @@ func TestGetOrderHistory(t *testing.T) { currPair.Delimiter = "_" getOrdersRequest.Pairs = []currency.Pair{currPair} - _, err := g.GetOrderHistory(&getOrdersRequest) + _, err := g.GetOrderHistory(context.Background(), &getOrdersRequest) if areTestAPIKeysSet() && err != nil { t.Errorf("Could not get order history: %s", err) } else if !areTestAPIKeysSet() && err == nil { @@ -333,7 +337,7 @@ func TestSubmitOrder(t *testing.T) { ClientID: "meowOrder", AssetType: asset.Spot, } - response, err := g.SubmitOrder(orderSubmission) + response, err := g.SubmitOrder(context.Background(), orderSubmission) if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) { t.Errorf("Order failed to be placed: %v", err) } else if !areTestAPIKeysSet() && err == nil { @@ -355,7 +359,7 @@ func TestCancelExchangeOrder(t *testing.T) { AssetType: asset.Spot, } - err := g.CancelOrder(orderCancellation) + err := g.CancelOrder(context.Background(), orderCancellation) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") } @@ -378,7 +382,7 @@ func TestCancelAllExchangeOrders(t *testing.T) { AssetType: asset.Spot, } - resp, err := g.CancelAllOrders(orderCancellation) + resp, err := g.CancelAllOrders(context.Background(), orderCancellation) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") @@ -394,12 +398,12 @@ func TestCancelAllExchangeOrders(t *testing.T) { func TestGetAccountInfo(t *testing.T) { if apiSecret == "" || apiKey == "" { - _, err := g.UpdateAccountInfo(asset.Spot) + _, err := g.UpdateAccountInfo(context.Background(), asset.Spot) if err == nil { t.Error("GetAccountInfo() Expected error") } } else { - _, err := g.UpdateAccountInfo(asset.Spot) + _, err := g.UpdateAccountInfo(context.Background(), asset.Spot) if err != nil { t.Error("GetAccountInfo() error", err) } @@ -410,7 +414,8 @@ func TestModifyOrder(t *testing.T) { if areTestAPIKeysSet() && !canManipulateRealOrders { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - _, err := g.ModifyOrder(&order.Modify{AssetType: asset.Spot}) + _, err := g.ModifyOrder(context.Background(), + &order.Modify{AssetType: asset.Spot}) if err == nil { t.Error("ModifyOrder() Expected error") } @@ -430,7 +435,8 @@ func TestWithdraw(t *testing.T) { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - _, err := g.WithdrawCryptocurrencyFunds(&withdrawCryptoRequest) + _, err := g.WithdrawCryptocurrencyFunds(context.Background(), + &withdrawCryptoRequest) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") } @@ -445,7 +451,7 @@ func TestWithdrawFiat(t *testing.T) { } var withdrawFiatRequest = withdraw.Request{} - _, err := g.WithdrawFiatFunds(&withdrawFiatRequest) + _, err := g.WithdrawFiatFunds(context.Background(), &withdrawFiatRequest) if err != common.ErrFunctionNotSupported { t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err) } @@ -457,7 +463,8 @@ func TestWithdrawInternationalBank(t *testing.T) { } var withdrawFiatRequest = withdraw.Request{} - _, err := g.WithdrawFiatFundsToInternationalBank(&withdrawFiatRequest) + _, err := g.WithdrawFiatFundsToInternationalBank(context.Background(), + &withdrawFiatRequest) if err != common.ErrFunctionNotSupported { t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err) } @@ -465,12 +472,12 @@ func TestWithdrawInternationalBank(t *testing.T) { func TestGetDepositAddress(t *testing.T) { if areTestAPIKeysSet() { - _, err := g.GetDepositAddress(currency.ETC, "") + _, err := g.GetDepositAddress(context.Background(), currency.ETC, "") if err != nil { t.Error("Test Fail - GetDepositAddress error", err) } } else { - _, err := g.GetDepositAddress(currency.ETC, "") + _, err := g.GetDepositAddress(context.Background(), currency.ETC, "") if err == nil { t.Error("Test Fail - GetDepositAddress error cannot be nil") } @@ -481,7 +488,8 @@ func TestGetOrderInfo(t *testing.T) { t.Skip("no API keys set skipping test") } - _, err := g.GetOrderInfo("917591554", currency.Pair{}, asset.Spot) + _, err := g.GetOrderInfo(context.Background(), + "917591554", currency.Pair{}, asset.Spot) if err != nil { if err.Error() != "no order found with id 917591554" && err.Error() != "failed to get open orders" { t.Fatalf("GetOrderInfo() returned an error skipping test: %v", err) @@ -742,7 +750,8 @@ func TestGetHistoricCandles(t *testing.T) { t.Fatal(err) } startTime := time.Now().Add(-time.Hour * 6) - _, err = g.GetHistoricCandles(currencyPair, asset.Spot, startTime, time.Now(), kline.OneMin) + _, err = g.GetHistoricCandles(context.Background(), + currencyPair, asset.Spot, startTime, time.Now(), kline.OneMin) if err != nil { t.Fatal(err) } @@ -754,7 +763,8 @@ func TestGetHistoricCandlesExtended(t *testing.T) { t.Fatal(err) } startTime := time.Now().Add(-time.Minute * 2) - _, err = g.GetHistoricCandlesExtended(currencyPair, asset.Spot, startTime, time.Now(), kline.OneMin) + _, err = g.GetHistoricCandlesExtended(context.Background(), + currencyPair, asset.Spot, startTime, time.Now(), kline.OneMin) if err != nil { t.Fatal(err) } @@ -820,7 +830,7 @@ func TestGetRecentTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = g.GetRecentTrades(currencyPair, asset.Spot) + _, err = g.GetRecentTrades(context.Background(), currencyPair, asset.Spot) if err != nil { t.Error(err) } @@ -832,7 +842,8 @@ func TestGetHistoricTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = g.GetHistoricTrades(currencyPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) + _, err = g.GetHistoricTrades(context.Background(), + currencyPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) if err != nil && err != common.ErrFunctionNotSupported { t.Error(err) } @@ -844,14 +855,14 @@ func TestUpdateTicker(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = g.UpdateTicker(cp, asset.Spot) + _, err = g.UpdateTicker(context.Background(), cp, asset.Spot) if err != nil { t.Error(err) } } func TestUpdateTickers(t *testing.T) { - err := g.UpdateTickers(asset.Spot) + err := g.UpdateTickers(context.Background(), asset.Spot) if err != nil { t.Error(err) } diff --git a/exchanges/gateio/gateio_wrapper.go b/exchanges/gateio/gateio_wrapper.go index c72b7464..3f1a9b1e 100644 --- a/exchanges/gateio/gateio_wrapper.go +++ b/exchanges/gateio/gateio_wrapper.go @@ -1,6 +1,7 @@ package gateio import ( + "context" "errors" "fmt" "sort" @@ -42,7 +43,7 @@ func (g *Gateio) GetDefaultConfig() (*config.ExchangeConfig, error) { } if g.Features.Supports.RESTCapabilities.AutoPairUpdates { - err = g.UpdateTradablePairs(true) + err = g.UpdateTradablePairs(context.TODO(), true) if err != nil { return nil, err } @@ -205,21 +206,21 @@ func (g *Gateio) Run() { return } - err := g.UpdateTradablePairs(false) + err := g.UpdateTradablePairs(context.TODO(), false) if err != nil { log.Errorf(log.ExchangeSys, "%s failed to update tradable pairs. Err: %s", g.Name, err) } } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (g *Gateio) FetchTradablePairs(asset asset.Item) ([]string, error) { - return g.GetSymbols() +func (g *Gateio) FetchTradablePairs(ctx context.Context, asset asset.Item) ([]string, error) { + return g.GetSymbols(ctx) } // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (g *Gateio) UpdateTradablePairs(forceUpdate bool) error { - pairs, err := g.FetchTradablePairs(asset.Spot) +func (g *Gateio) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { + pairs, err := g.FetchTradablePairs(ctx, asset.Spot) if err != nil { return err } @@ -232,8 +233,8 @@ func (g *Gateio) UpdateTradablePairs(forceUpdate bool) error { } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (g *Gateio) UpdateTickers(a asset.Item) error { - result, err := g.GetTickers() +func (g *Gateio) UpdateTickers(ctx context.Context, a asset.Item) error { + result, err := g.GetTickers(ctx) if err != nil { return err } @@ -268,8 +269,8 @@ func (g *Gateio) UpdateTickers(a asset.Item) error { } // UpdateTicker updates and returns the ticker for a currency pair -func (g *Gateio) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) { - err := g.UpdateTickers(a) +func (g *Gateio) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { + err := g.UpdateTickers(ctx, a) if err != nil { return nil, err } @@ -277,25 +278,25 @@ func (g *Gateio) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, err } // FetchTicker returns the ticker for a currency pair -func (g *Gateio) FetchTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) { +func (g *Gateio) FetchTicker(ctx context.Context, p currency.Pair, assetType asset.Item) (*ticker.Price, error) { tickerNew, err := ticker.GetTicker(g.Name, p, assetType) if err != nil { - return g.UpdateTicker(p, assetType) + return g.UpdateTicker(ctx, p, assetType) } return tickerNew, nil } // FetchOrderbook returns orderbook base on the currency pair -func (g *Gateio) FetchOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (g *Gateio) FetchOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { ob, err := orderbook.Get(g.Name, p, assetType) if err != nil { - return g.UpdateOrderbook(p, assetType) + return g.UpdateOrderbook(ctx, p, assetType) } return ob, nil } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (g *Gateio) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (g *Gateio) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { book := &orderbook.Base{ Exchange: g.Name, Pair: p, @@ -307,7 +308,7 @@ func (g *Gateio) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderb return book, err } - orderbookNew, err := g.GetOrderbook(curr.String()) + orderbookNew, err := g.GetOrderbook(ctx, curr.String()) if err != nil { return book, err } @@ -334,7 +335,7 @@ func (g *Gateio) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderb // UpdateAccountInfo retrieves balances for all enabled currencies for the // ZB exchange -func (g *Gateio) UpdateAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (g *Gateio) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { var info account.Holdings var balances []account.Balance @@ -355,7 +356,7 @@ func (g *Gateio) UpdateAccountInfo(assetType asset.Item) (account.Holdings, erro Currencies: currData, }) } else { - balance, err := g.GetBalances() + balance, err := g.GetBalances(ctx) if err != nil { return info, err } @@ -419,10 +420,10 @@ func (g *Gateio) UpdateAccountInfo(assetType asset.Item) (account.Holdings, erro } // FetchAccountInfo retrieves balances for all enabled currencies -func (g *Gateio) FetchAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (g *Gateio) FetchAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { acc, err := account.GetHoldings(g.Name, assetType) if err != nil { - return g.UpdateAccountInfo(assetType) + return g.UpdateAccountInfo(ctx, assetType) } return acc, nil @@ -430,24 +431,24 @@ func (g *Gateio) FetchAccountInfo(assetType asset.Item) (account.Holdings, error // GetFundingHistory returns funding history, deposits and // withdrawals -func (g *Gateio) GetFundingHistory() ([]exchange.FundHistory, error) { +func (g *Gateio) GetFundingHistory(ctx context.Context) ([]exchange.FundHistory, error) { return nil, common.ErrFunctionNotSupported } // GetWithdrawalsHistory returns previous withdrawals data -func (g *Gateio) GetWithdrawalsHistory(c currency.Code) (resp []exchange.WithdrawalHistory, err error) { +func (g *Gateio) GetWithdrawalsHistory(ctx context.Context, c currency.Code) (resp []exchange.WithdrawalHistory, err error) { return nil, common.ErrNotYetImplemented } // GetRecentTrades returns the most recent trades for a currency and asset -func (g *Gateio) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade.Data, error) { +func (g *Gateio) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { var err error p, err = g.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err } var tradeData TradeHistory - tradeData, err = g.GetTrades(p.String()) + tradeData, err = g.GetTrades(ctx, p.String()) if err != nil { return nil, err } @@ -480,13 +481,13 @@ func (g *Gateio) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade } // GetHistoricTrades returns historic trade data within the timeframe provided -func (g *Gateio) GetHistoricTrades(_ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { +func (g *Gateio) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { return nil, common.ErrFunctionNotSupported } // SubmitOrder submits a new order // TODO: support multiple order types (IOC) -func (g *Gateio) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { +func (g *Gateio) SubmitOrder(ctx context.Context, s *order.Submit) (order.SubmitResponse, error) { var submitOrderResponse order.SubmitResponse if err := s.Validate(); err != nil { return submitOrderResponse, err @@ -511,7 +512,7 @@ func (g *Gateio) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { Type: orderTypeFormat, } - response, err := g.SpotNewOrder(spotNewOrderRequestParams) + response, err := g.SpotNewOrder(ctx, spotNewOrderRequestParams) if err != nil { return submitOrderResponse, err } @@ -528,12 +529,12 @@ func (g *Gateio) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (g *Gateio) ModifyOrder(action *order.Modify) (order.Modify, error) { +func (g *Gateio) ModifyOrder(ctx context.Context, action *order.Modify) (order.Modify, error) { return order.Modify{}, common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number -func (g *Gateio) CancelOrder(o *order.Cancel) error { +func (g *Gateio) CancelOrder(ctx context.Context, o *order.Cancel) error { if err := o.Validate(o.StandardCancel()); err != nil { return err } @@ -548,21 +549,21 @@ func (g *Gateio) CancelOrder(o *order.Cancel) error { return err } - _, err = g.CancelExistingOrder(orderIDInt, fpair.String()) + _, err = g.CancelExistingOrder(ctx, orderIDInt, fpair.String()) return err } // CancelBatchOrders cancels an orders by their corresponding ID numbers -func (g *Gateio) CancelBatchOrders(o []order.Cancel) (order.CancelBatchResponse, error) { +func (g *Gateio) CancelBatchOrders(ctx context.Context, o []order.Cancel) (order.CancelBatchResponse, error) { return order.CancelBatchResponse{}, common.ErrNotYetImplemented } // CancelAllOrders cancels all orders associated with a currency pair -func (g *Gateio) CancelAllOrders(_ *order.Cancel) (order.CancelAllResponse, error) { +func (g *Gateio) CancelAllOrders(ctx context.Context, _ *order.Cancel) (order.CancelAllResponse, error) { cancelAllOrdersResponse := order.CancelAllResponse{ Status: make(map[string]string), } - openOrders, err := g.GetOpenOrders("") + openOrders, err := g.GetOpenOrders(ctx, "") if err != nil { return cancelAllOrdersResponse, err } @@ -573,7 +574,7 @@ func (g *Gateio) CancelAllOrders(_ *order.Cancel) (order.CancelAllResponse, erro } for unique := range uniqueSymbols { - err = g.CancelAllExistingOrders(-1, unique) + err = g.CancelAllExistingOrders(ctx, -1, unique) if err != nil { cancelAllOrdersResponse.Status[unique] = err.Error() } @@ -583,9 +584,9 @@ func (g *Gateio) CancelAllOrders(_ *order.Cancel) (order.CancelAllResponse, erro } // GetOrderInfo returns order information based on order ID -func (g *Gateio) GetOrderInfo(orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { +func (g *Gateio) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { var orderDetail order.Detail - orders, err := g.GetOpenOrders("") + orders, err := g.GetOpenOrders(ctx, "") if err != nil { return orderDetail, errors.New("failed to get open orders") } @@ -627,8 +628,8 @@ func (g *Gateio) GetOrderInfo(orderID string, pair currency.Pair, assetType asse } // GetDepositAddress returns a deposit address for a specified currency -func (g *Gateio) GetDepositAddress(cryptocurrency currency.Code, _ string) (string, error) { - addr, err := g.GetCryptoDepositAddress(cryptocurrency.String()) +func (g *Gateio) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _ string) (string, error) { + addr, err := g.GetCryptoDepositAddress(ctx, cryptocurrency.String()) if err != nil { return "", err } @@ -642,38 +643,39 @@ func (g *Gateio) GetDepositAddress(cryptocurrency currency.Code, _ string) (stri // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is // submitted -func (g *Gateio) WithdrawCryptocurrencyFunds(withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (g *Gateio) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } - return g.WithdrawCrypto(withdrawRequest.Currency.String(), + return g.WithdrawCrypto(ctx, + withdrawRequest.Currency.String(), withdrawRequest.Crypto.Address, withdrawRequest.Amount) } // WithdrawFiatFunds returns a withdrawal ID when a // withdrawal is submitted -func (g *Gateio) WithdrawFiatFunds(_ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (g *Gateio) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a // withdrawal is submitted -func (g *Gateio) WithdrawFiatFundsToInternationalBank(_ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (g *Gateio) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // GetFeeByType returns an estimate of fee based on type of transaction -func (g *Gateio) GetFeeByType(feeBuilder *exchange.FeeBuilder) (float64, error) { +func (g *Gateio) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { if !g.AllowAuthenticatedRequest() && // Todo check connection status feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { feeBuilder.FeeType = exchange.OfflineTradeFee } - return g.GetFee(feeBuilder) + return g.GetFee(ctx, feeBuilder) } // GetActiveOrders retrieves any orders that are active/open -func (g *Gateio) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, error) { +func (g *Gateio) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) { if err := req.Validate(); err != nil { return nil, err } @@ -727,7 +729,7 @@ func (g *Gateio) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, e } } } else { - resp, err := g.GetOpenOrders(currPair) + resp, err := g.GetOpenOrders(ctx, currPair) if err != nil { return nil, err } @@ -769,14 +771,14 @@ func (g *Gateio) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, e // GetOrderHistory retrieves account order information // Can Limit response to specific order status -func (g *Gateio) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, error) { +func (g *Gateio) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) { if err := req.Validate(); err != nil { return nil, err } var trades []TradesResponse for i := range req.Pairs { - resp, err := g.GetTradeHistory(req.Pairs[i].String()) + resp, err := g.GetTradeHistory(ctx, req.Pairs[i].String()) if err != nil { return nil, err } @@ -814,14 +816,14 @@ func (g *Gateio) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, e } // AuthenticateWebsocket sends an authentication message to the websocket -func (g *Gateio) AuthenticateWebsocket() error { +func (g *Gateio) AuthenticateWebsocket(_ context.Context) error { return g.wsServerSignIn() } // ValidateCredentials validates current credentials used for wrapper // functionality -func (g *Gateio) ValidateCredentials(assetType asset.Item) error { - _, err := g.UpdateAccountInfo(assetType) +func (g *Gateio) ValidateCredentials(ctx context.Context, assetType asset.Item) error { + _, err := g.UpdateAccountInfo(ctx, assetType) return g.CheckTransientError(err) } @@ -831,7 +833,7 @@ func (g *Gateio) FormatExchangeKlineInterval(in kline.Interval) string { } // GetHistoricCandles returns candles between a time period for a set time interval -func (g *Gateio) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (g *Gateio) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { if err := g.ValidateKline(pair, a, interval); err != nil { return kline.Item{}, err } @@ -848,7 +850,7 @@ func (g *Gateio) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end HourSize: int(hours), } - klineData, err := g.GetSpotKline(params) + klineData, err := g.GetSpotKline(ctx, params) if err != nil { return kline.Item{}, err } @@ -862,6 +864,6 @@ func (g *Gateio) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (g *Gateio) GetHistoricCandlesExtended(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { - return g.GetHistoricCandles(pair, a, start, end, interval) +func (g *Gateio) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { + return g.GetHistoricCandles(ctx, pair, a, start, end, interval) } diff --git a/exchanges/gemini/gemini.go b/exchanges/gemini/gemini.go index 677e94f3..51875557 100644 --- a/exchanges/gemini/gemini.go +++ b/exchanges/gemini/gemini.go @@ -53,17 +53,17 @@ type Gemini struct { } // GetSymbols returns all available symbols for trading -func (g *Gemini) GetSymbols() ([]string, error) { +func (g *Gemini) GetSymbols(ctx context.Context) ([]string, error) { var symbols []string path := fmt.Sprintf("/v%s/%s", geminiAPIVersion, geminiSymbols) - return symbols, g.SendHTTPRequest(exchange.RestSpot, path, &symbols) + return symbols, g.SendHTTPRequest(ctx, exchange.RestSpot, path, &symbols) } // GetTicker returns information about recent trading activity for the symbol -func (g *Gemini) GetTicker(currencyPair string) (TickerV2, error) { +func (g *Gemini) GetTicker(ctx context.Context, currencyPair string) (TickerV2, error) { ticker := TickerV2{} path := fmt.Sprintf("/v2/ticker/%s", currencyPair) - err := g.SendHTTPRequest(exchange.RestSpot, path, &ticker) + err := g.SendHTTPRequest(ctx, exchange.RestSpot, path, &ticker) if err != nil { return ticker, err } @@ -82,7 +82,7 @@ func (g *Gemini) GetTicker(currencyPair string) (TickerV2, error) { // // params - limit_bids or limit_asks [OPTIONAL] default 50, 0 returns all Values // Type is an integer ie "params.Set("limit_asks", 30)" -func (g *Gemini) GetOrderbook(currencyPair string, params url.Values) (Orderbook, error) { +func (g *Gemini) GetOrderbook(ctx context.Context, currencyPair string, params url.Values) (Orderbook, error) { path := common.EncodeURLValues( fmt.Sprintf("/v%s/%s/%s", geminiAPIVersion, @@ -91,7 +91,7 @@ func (g *Gemini) GetOrderbook(currencyPair string, params url.Values) (Orderbook params) var orderbook Orderbook - return orderbook, g.SendHTTPRequest(exchange.RestSpot, path, &orderbook) + return orderbook, g.SendHTTPRequest(ctx, exchange.RestSpot, path, &orderbook) } // GetTrades return the trades that have executed since the specified timestamp. @@ -103,7 +103,7 @@ func (g *Gemini) GetOrderbook(currencyPair string, params url.Values) (Orderbook // limit_trades integer Optional. The maximum number of trades to return. // include_breaks boolean Optional. Whether to display broken trades. False by // default. Can be '1' or 'true' to activate -func (g *Gemini) GetTrades(currencyPair string, since, limit int64, includeBreaks bool) ([]Trade, error) { +func (g *Gemini) GetTrades(ctx context.Context, currencyPair string, since, limit int64, includeBreaks bool) ([]Trade, error) { params := url.Values{} if since > 0 { params.Add("since", strconv.FormatInt(since, 10)) @@ -117,15 +117,15 @@ func (g *Gemini) GetTrades(currencyPair string, since, limit int64, includeBreak path := common.EncodeURLValues(fmt.Sprintf("/v%s/%s/%s", geminiAPIVersion, geminiTrades, currencyPair), params) var trades []Trade - return trades, g.SendHTTPRequest(exchange.RestSpot, path, &trades) + return trades, g.SendHTTPRequest(ctx, exchange.RestSpot, path, &trades) } // GetAuction returns auction information -func (g *Gemini) GetAuction(currencyPair string) (Auction, error) { +func (g *Gemini) GetAuction(ctx context.Context, currencyPair string) (Auction, error) { path := fmt.Sprintf("/v%s/%s/%s", geminiAPIVersion, geminiAuction, currencyPair) auction := Auction{} - return auction, g.SendHTTPRequest(exchange.RestSpot, path, &auction) + return auction, g.SendHTTPRequest(ctx, exchange.RestSpot, path, &auction) } // GetAuctionHistory returns the auction events, optionally including @@ -139,15 +139,15 @@ func (g *Gemini) GetAuction(currencyPair string) (Auction, error) { // events to return. // include_indicative - [bool] Whether to include publication of // indicative prices and quantities. -func (g *Gemini) GetAuctionHistory(currencyPair string, params url.Values) ([]AuctionHistory, error) { +func (g *Gemini) GetAuctionHistory(ctx context.Context, currencyPair string, params url.Values) ([]AuctionHistory, error) { path := common.EncodeURLValues(fmt.Sprintf("/v%s/%s/%s/%s", geminiAPIVersion, geminiAuction, currencyPair, geminiAuctionHistory), params) var auctionHist []AuctionHistory - return auctionHist, g.SendHTTPRequest(exchange.RestSpot, path, &auctionHist) + return auctionHist, g.SendHTTPRequest(ctx, exchange.RestSpot, path, &auctionHist) } // NewOrder Only limit orders are supported through the API at present. // returns order ID if successful -func (g *Gemini) NewOrder(symbol string, amount, price float64, side, orderType string) (int64, error) { +func (g *Gemini) NewOrder(ctx context.Context, symbol string, amount, price float64, side, orderType string) (int64, error) { req := make(map[string]interface{}) req["symbol"] = symbol req["amount"] = strconv.FormatFloat(amount, 'f', -1, 64) @@ -156,7 +156,7 @@ func (g *Gemini) NewOrder(symbol string, amount, price float64, side, orderType req["type"] = orderType response := Order{} - err := g.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, geminiOrderNew, req, &response) + err := g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, geminiOrderNew, req, &response) if err != nil { return 0, err } @@ -165,12 +165,12 @@ func (g *Gemini) NewOrder(symbol string, amount, price float64, side, orderType // CancelExistingOrder will cancel an order. If the order is already canceled, the // message will succeed but have no effect. -func (g *Gemini) CancelExistingOrder(orderID int64) (Order, error) { +func (g *Gemini) CancelExistingOrder(ctx context.Context, orderID int64) (Order, error) { req := make(map[string]interface{}) req["order_id"] = orderID response := Order{} - err := g.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, geminiOrderCancel, req, &response) + err := g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, geminiOrderCancel, req, &response) if err != nil { return Order{}, err } @@ -185,14 +185,14 @@ func (g *Gemini) CancelExistingOrder(orderID int64) (Order, error) { // sessions owned by this account, including interactive orders placed through // the UI. If sessions = true will only cancel the order that is called on this // session asssociated with the APIKEY -func (g *Gemini) CancelExistingOrders(cancelBySession bool) (OrderResult, error) { +func (g *Gemini) CancelExistingOrders(ctx context.Context, cancelBySession bool) (OrderResult, error) { path := geminiOrderCancelAll if cancelBySession { path = geminiOrderCancelSession } var response OrderResult - err := g.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, path, nil, &response) + err := g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, path, nil, &response) if err != nil { return response, err } @@ -203,13 +203,13 @@ func (g *Gemini) CancelExistingOrders(cancelBySession bool) (OrderResult, error) } // GetOrderStatus returns the status for an order -func (g *Gemini) GetOrderStatus(orderID int64) (Order, error) { +func (g *Gemini) GetOrderStatus(ctx context.Context, orderID int64) (Order, error) { req := make(map[string]interface{}) req["order_id"] = orderID response := Order{} - err := g.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, geminiOrderStatus, req, &response) + err := g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, geminiOrderStatus, req, &response) if err != nil { return response, err } @@ -221,14 +221,14 @@ func (g *Gemini) GetOrderStatus(orderID int64) (Order, error) { } // GetOrders returns active orders in the market -func (g *Gemini) GetOrders() ([]Order, error) { +func (g *Gemini) GetOrders(ctx context.Context) ([]Order, error) { var response interface{} type orders struct { orders []Order } - err := g.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, geminiOrders, nil, &response) + err := g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, geminiOrders, nil, &response) if err != nil { return nil, err } @@ -245,7 +245,7 @@ func (g *Gemini) GetOrders() ([]Order, error) { // // currencyPair - example "btcusd" // timestamp - [optional] Only return trades on or after this timestamp. -func (g *Gemini) GetTradeHistory(currencyPair string, timestamp int64) ([]TradeHistory, error) { +func (g *Gemini) GetTradeHistory(ctx context.Context, currencyPair string, timestamp int64) ([]TradeHistory, error) { var response []TradeHistory req := make(map[string]interface{}) req["symbol"] = currencyPair @@ -255,35 +255,35 @@ func (g *Gemini) GetTradeHistory(currencyPair string, timestamp int64) ([]TradeH } return response, - g.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, geminiMyTrades, req, &response) + g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, geminiMyTrades, req, &response) } // GetNotionalVolume returns the volume in price currency that has been traded across all pairs over a period of 30 days -func (g *Gemini) GetNotionalVolume() (NotionalVolume, error) { +func (g *Gemini) GetNotionalVolume(ctx context.Context) (NotionalVolume, error) { response := NotionalVolume{} return response, - g.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, geminiVolume, nil, &response) + g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, geminiVolume, nil, &response) } // GetTradeVolume returns a multi-arrayed volume response -func (g *Gemini) GetTradeVolume() ([][]TradeVolume, error) { +func (g *Gemini) GetTradeVolume(ctx context.Context) ([][]TradeVolume, error) { var response [][]TradeVolume return response, - g.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, geminiTradeVolume, nil, &response) + g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, geminiTradeVolume, nil, &response) } // GetBalances returns available balances in the supported currencies -func (g *Gemini) GetBalances() ([]Balance, error) { +func (g *Gemini) GetBalances(ctx context.Context) ([]Balance, error) { var response []Balance return response, - g.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, geminiBalances, nil, &response) + g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, geminiBalances, nil, &response) } // GetCryptoDepositAddress returns a deposit address -func (g *Gemini) GetCryptoDepositAddress(depositAddlabel, currency string) (DepositAddress, error) { +func (g *Gemini) GetCryptoDepositAddress(ctx context.Context, depositAddlabel, currency string) (DepositAddress, error) { response := DepositAddress{} req := make(map[string]interface{}) @@ -291,7 +291,7 @@ func (g *Gemini) GetCryptoDepositAddress(depositAddlabel, currency string) (Depo req["label"] = depositAddlabel } - err := g.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, geminiDeposit+"/"+currency+"/"+geminiNewAddress, req, &response) + err := g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, geminiDeposit+"/"+currency+"/"+geminiNewAddress, req, &response) if err != nil { return response, err } @@ -302,13 +302,13 @@ func (g *Gemini) GetCryptoDepositAddress(depositAddlabel, currency string) (Depo } // WithdrawCrypto withdraws crypto currency to a whitelisted address -func (g *Gemini) WithdrawCrypto(address, currency string, amount float64) (WithdrawalAddress, error) { +func (g *Gemini) WithdrawCrypto(ctx context.Context, address, currency string, amount float64) (WithdrawalAddress, error) { response := WithdrawalAddress{} req := make(map[string]interface{}) req["address"] = address req["amount"] = strconv.FormatFloat(amount, 'f', -1, 64) - err := g.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, geminiWithdraw+strings.ToLower(currency), req, &response) + err := g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, geminiWithdraw+strings.ToLower(currency), req, &response) if err != nil { return response, err } @@ -320,14 +320,14 @@ func (g *Gemini) WithdrawCrypto(address, currency string, amount float64) (Withd // PostHeartbeat sends a maintenance heartbeat to the exchange for all heartbeat // maintaned sessions -func (g *Gemini) PostHeartbeat() (string, error) { +func (g *Gemini) PostHeartbeat(ctx context.Context) (string, error) { type Response struct { Result string `json:"result"` Message string `json:"message"` } response := Response{} - err := g.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, geminiHeartbeat, nil, &response) + err := g.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, geminiHeartbeat, nil, &response) if err != nil { return response.Result, err } @@ -338,7 +338,7 @@ func (g *Gemini) PostHeartbeat() (string, error) { } // SendHTTPRequest sends an unauthenticated request -func (g *Gemini) SendHTTPRequest(ep exchange.URL, path string, result interface{}) error { +func (g *Gemini) SendHTTPRequest(ctx context.Context, ep exchange.URL, path string, result interface{}) error { endpoint, err := g.API.Endpoints.GetURL(ep) if err != nil { return err @@ -353,14 +353,14 @@ func (g *Gemini) SendHTTPRequest(ep exchange.URL, path string, result interface{ HTTPRecording: g.HTTPRecording, } - return g.SendPayload(context.Background(), request.Unset, func() (*request.Item, error) { + return g.SendPayload(ctx, request.Unset, func() (*request.Item, error) { return item, nil }) } // SendAuthenticatedHTTPRequest sends an authenticated HTTP request to the // exchange and returns an error -func (g *Gemini) SendAuthenticatedHTTPRequest(ep exchange.URL, method, path string, params map[string]interface{}, result interface{}) (err error) { +func (g *Gemini) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, method, path string, params map[string]interface{}, result interface{}) (err error) { if !g.AllowAuthenticatedRequest() { return fmt.Errorf("%s %w", g.Name, exchange.ErrAuthenticatedRequestWithoutCredentialsSet) } @@ -370,7 +370,7 @@ func (g *Gemini) SendAuthenticatedHTTPRequest(ep exchange.URL, method, path stri return err } - return g.SendPayload(context.Background(), request.Auth, func() (*request.Item, error) { + return g.SendPayload(ctx, request.Auth, func() (*request.Item, error) { req := make(map[string]interface{}) req["request"] = fmt.Sprintf("/v%s/%s", geminiAPIVersion, path) req["nonce"] = g.Requester.GetNonce(true).String() @@ -415,11 +415,11 @@ func (g *Gemini) SendAuthenticatedHTTPRequest(ep exchange.URL, method, path stri } // GetFee returns an estimate of fee based on type of transaction -func (g *Gemini) GetFee(feeBuilder *exchange.FeeBuilder) (float64, error) { +func (g *Gemini) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { var fee float64 switch feeBuilder.FeeType { case exchange.CryptocurrencyTradeFee: - notionVolume, err := g.GetNotionalVolume() + notionVolume, err := g.GetNotionalVolume(ctx) if err != nil { return 0, err } diff --git a/exchanges/gemini/gemini_test.go b/exchanges/gemini/gemini_test.go index ee89ea98..ea464449 100644 --- a/exchanges/gemini/gemini_test.go +++ b/exchanges/gemini/gemini_test.go @@ -1,6 +1,7 @@ package gemini import ( + "context" "net/url" "strings" "testing" @@ -33,7 +34,7 @@ var g Gemini func TestGetSymbols(t *testing.T) { t.Parallel() - _, err := g.GetSymbols() + _, err := g.GetSymbols(context.Background()) if err != nil { t.Error("GetSymbols() error", err) } @@ -41,7 +42,7 @@ func TestGetSymbols(t *testing.T) { func TestFetchTradablePairs(t *testing.T) { t.Parallel() - r, err := g.FetchTradablePairs(asset.Spot) + r, err := g.FetchTradablePairs(context.Background(), asset.Spot) if err != nil { t.Fatal(err) } @@ -62,11 +63,11 @@ func TestFetchTradablePairs(t *testing.T) { func TestGetTicker(t *testing.T) { t.Parallel() - _, err := g.GetTicker("BTCUSD") + _, err := g.GetTicker(context.Background(), "BTCUSD") if err != nil { t.Error("GetTicker() error", err) } - _, err = g.GetTicker("bla") + _, err = g.GetTicker(context.Background(), "bla") if err == nil { t.Error("GetTicker() Expected error") } @@ -74,7 +75,7 @@ func TestGetTicker(t *testing.T) { func TestGetOrderbook(t *testing.T) { t.Parallel() - _, err := g.GetOrderbook(testCurrency, url.Values{}) + _, err := g.GetOrderbook(context.Background(), testCurrency, url.Values{}) if err != nil { t.Error("GetOrderbook() error", err) } @@ -82,7 +83,7 @@ func TestGetOrderbook(t *testing.T) { func TestGetTrades(t *testing.T) { t.Parallel() - _, err := g.GetTrades(testCurrency, 0, 0, false) + _, err := g.GetTrades(context.Background(), testCurrency, 0, 0, false) if err != nil { t.Error("GetTrades() error", err) } @@ -90,7 +91,7 @@ func TestGetTrades(t *testing.T) { func TestGetNotionalVolume(t *testing.T) { t.Parallel() - _, err := g.GetNotionalVolume() + _, err := g.GetNotionalVolume(context.Background()) if err != nil && mockTests { t.Error("GetNotionalVolume() error", err) } else if err == nil && !mockTests { @@ -100,7 +101,7 @@ func TestGetNotionalVolume(t *testing.T) { func TestGetAuction(t *testing.T) { t.Parallel() - _, err := g.GetAuction(testCurrency) + _, err := g.GetAuction(context.Background(), testCurrency) if err != nil { t.Error("GetAuction() error", err) } @@ -108,7 +109,7 @@ func TestGetAuction(t *testing.T) { func TestGetAuctionHistory(t *testing.T) { t.Parallel() - _, err := g.GetAuctionHistory(testCurrency, url.Values{}) + _, err := g.GetAuctionHistory(context.Background(), testCurrency, url.Values{}) if err != nil { t.Error("GetAuctionHistory() error", err) } @@ -116,7 +117,8 @@ func TestGetAuctionHistory(t *testing.T) { func TestNewOrder(t *testing.T) { t.Parallel() - _, err := g.NewOrder(testCurrency, + _, err := g.NewOrder(context.Background(), + testCurrency, 1, 9000000, order.Sell.Lower(), @@ -130,7 +132,7 @@ func TestNewOrder(t *testing.T) { func TestCancelExistingOrder(t *testing.T) { t.Parallel() - _, err := g.CancelExistingOrder(265555413) + _, err := g.CancelExistingOrder(context.Background(), 265555413) if err != nil && mockTests { t.Error("CancelExistingOrder() error", err) } else if err == nil && !mockTests { @@ -140,7 +142,7 @@ func TestCancelExistingOrder(t *testing.T) { func TestCancelExistingOrders(t *testing.T) { t.Parallel() - _, err := g.CancelExistingOrders(false) + _, err := g.CancelExistingOrders(context.Background(), false) if err != nil && mockTests { t.Error("CancelExistingOrders() error", err) } else if err == nil && !mockTests { @@ -150,7 +152,7 @@ func TestCancelExistingOrders(t *testing.T) { func TestGetOrderStatus(t *testing.T) { t.Parallel() - _, err := g.GetOrderStatus(265563260) + _, err := g.GetOrderStatus(context.Background(), 265563260) if err != nil && mockTests { t.Error("GetOrderStatus() error", err) } else if err == nil && !mockTests { @@ -160,7 +162,7 @@ func TestGetOrderStatus(t *testing.T) { func TestGetOrders(t *testing.T) { t.Parallel() - _, err := g.GetOrders() + _, err := g.GetOrders(context.Background()) if err != nil && mockTests { t.Error("GetOrders() error", err) } else if err == nil && !mockTests { @@ -170,7 +172,7 @@ func TestGetOrders(t *testing.T) { func TestGetTradeHistory(t *testing.T) { t.Parallel() - _, err := g.GetTradeHistory(testCurrency, 0) + _, err := g.GetTradeHistory(context.Background(), testCurrency, 0) if err != nil && mockTests { t.Error("GetTradeHistory() error", err) } else if err == nil && !mockTests { @@ -180,7 +182,7 @@ func TestGetTradeHistory(t *testing.T) { func TestGetTradeVolume(t *testing.T) { t.Parallel() - _, err := g.GetTradeVolume() + _, err := g.GetTradeVolume(context.Background()) if err != nil && mockTests { t.Error("GetTradeVolume() error", err) } else if err == nil && !mockTests { @@ -190,7 +192,7 @@ func TestGetTradeVolume(t *testing.T) { func TestGetBalances(t *testing.T) { t.Parallel() - _, err := g.GetBalances() + _, err := g.GetBalances(context.Background()) if err != nil && mockTests { t.Error("GetBalances() error", err) } else if err == nil && !mockTests { @@ -200,7 +202,7 @@ func TestGetBalances(t *testing.T) { func TestGetCryptoDepositAddress(t *testing.T) { t.Parallel() - _, err := g.GetCryptoDepositAddress("LOL123", "btc") + _, err := g.GetCryptoDepositAddress(context.Background(), "LOL123", "btc") if err == nil { t.Error("GetCryptoDepositAddress() Expected error") } @@ -208,7 +210,7 @@ func TestGetCryptoDepositAddress(t *testing.T) { func TestWithdrawCrypto(t *testing.T) { t.Parallel() - _, err := g.WithdrawCrypto("LOL123", "btc", 1) + _, err := g.WithdrawCrypto(context.Background(), "LOL123", "btc", 1) if err == nil { t.Error("WithdrawCrypto() Expected error") } @@ -216,7 +218,7 @@ func TestWithdrawCrypto(t *testing.T) { func TestPostHeartbeat(t *testing.T) { t.Parallel() - _, err := g.PostHeartbeat() + _, err := g.PostHeartbeat(context.Background()) if err != nil && mockTests { t.Error("PostHeartbeat() error", err) } else if err == nil && !mockTests { @@ -241,7 +243,7 @@ func setFeeBuilder() *exchange.FeeBuilder { func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { t.Parallel() var feeBuilder = setFeeBuilder() - _, err := g.GetFeeByType(feeBuilder) + _, err := g.GetFeeByType(context.Background(), feeBuilder) if err != nil { t.Fatal(err) } @@ -265,7 +267,7 @@ func TestGetFee(t *testing.T) { var feeBuilder = setFeeBuilder() if areTestAPIKeysSet() || mockTests { // CryptocurrencyTradeFee Basic - if _, err := g.GetFee(feeBuilder); err != nil { + if _, err := g.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } @@ -273,28 +275,28 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.Amount = 1000 feeBuilder.PurchasePrice = 1000 - if _, err := g.GetFee(feeBuilder); err != nil { + if _, err := g.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyTradeFee IsMaker feeBuilder = setFeeBuilder() feeBuilder.IsMaker = true - if _, err := g.GetFee(feeBuilder); err != nil { + if _, err := g.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyTradeFee Negative purchase price feeBuilder = setFeeBuilder() feeBuilder.PurchasePrice = -1000 - if _, err := g.GetFee(feeBuilder); err != nil { + if _, err := g.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } } // CryptocurrencyWithdrawalFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee - if _, err := g.GetFee(feeBuilder); err != nil { + if _, err := g.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } @@ -302,21 +304,21 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.Pair.Base = currency.NewCode("hello") feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee - if _, err := g.GetFee(feeBuilder); err != nil { + if _, err := g.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyDepositFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.CryptocurrencyDepositFee - if _, err := g.GetFee(feeBuilder); err != nil { + if _, err := g.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } // InternationalBankDepositFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankDepositFee - if _, err := g.GetFee(feeBuilder); err != nil { + if _, err := g.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } @@ -324,7 +326,7 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee feeBuilder.FiatCurrency = currency.USD - if _, err := g.GetFee(feeBuilder); err != nil { + if _, err := g.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } } @@ -354,7 +356,7 @@ func TestGetActiveOrders(t *testing.T) { AssetType: asset.Spot, } - _, err := g.GetActiveOrders(&getOrdersRequest) + _, err := g.GetActiveOrders(context.Background(), &getOrdersRequest) switch { case areTestAPIKeysSet() && err != nil && !mockTests: t.Errorf("Could not get open orders: %s", err) @@ -373,7 +375,7 @@ func TestGetOrderHistory(t *testing.T) { AssetType: asset.Spot, } - _, err := g.GetOrderHistory(&getOrdersRequest) + _, err := g.GetOrderHistory(context.Background(), &getOrdersRequest) switch { case areTestAPIKeysSet() && err != nil: t.Errorf("Could not get order history: %s", err) @@ -410,7 +412,7 @@ func TestSubmitOrder(t *testing.T) { AssetType: asset.Spot, } - response, err := g.SubmitOrder(orderSubmission) + response, err := g.SubmitOrder(context.Background(), orderSubmission) switch { case areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced): t.Errorf("Order failed to be placed: %v", err) @@ -432,7 +434,7 @@ func TestCancelExchangeOrder(t *testing.T) { Pair: currency.NewPair(currency.BTC, currency.USDT), } - err := g.CancelOrder(orderCancellation) + err := g.CancelOrder(context.Background(), orderCancellation) switch { case !areTestAPIKeysSet() && err == nil && !mockTests: t.Error("Expecting an error when no keys are set") @@ -458,7 +460,7 @@ func TestCancelAllExchangeOrders(t *testing.T) { AssetType: asset.Spot, } - resp, err := g.CancelAllOrders(orderCancellation) + resp, err := g.CancelAllOrders(context.Background(), orderCancellation) switch { case !areTestAPIKeysSet() && err == nil && !mockTests: t.Error("Expecting an error when no keys are set") @@ -475,7 +477,8 @@ func TestCancelAllExchangeOrders(t *testing.T) { func TestModifyOrder(t *testing.T) { t.Parallel() - _, err := g.ModifyOrder(&order.Modify{AssetType: asset.Spot}) + _, err := g.ModifyOrder(context.Background(), + &order.Modify{AssetType: asset.Spot}) if err == nil { t.Error("ModifyOrder() Expected error") } @@ -496,7 +499,8 @@ func TestWithdraw(t *testing.T) { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - _, err := g.WithdrawCryptocurrencyFunds(&withdrawCryptoRequest) + _, err := g.WithdrawCryptocurrencyFunds(context.Background(), + &withdrawCryptoRequest) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") } @@ -515,7 +519,7 @@ func TestWithdrawFiat(t *testing.T) { } var withdrawFiatRequest = withdraw.Request{} - _, err := g.WithdrawFiatFunds(&withdrawFiatRequest) + _, err := g.WithdrawFiatFunds(context.Background(), &withdrawFiatRequest) if err != common.ErrFunctionNotSupported { t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, @@ -530,7 +534,8 @@ func TestWithdrawInternationalBank(t *testing.T) { } var withdrawFiatRequest = withdraw.Request{} - _, err := g.WithdrawFiatFundsToInternationalBank(&withdrawFiatRequest) + _, err := g.WithdrawFiatFundsToInternationalBank(context.Background(), + &withdrawFiatRequest) if err != common.ErrFunctionNotSupported { t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, @@ -540,7 +545,7 @@ func TestWithdrawInternationalBank(t *testing.T) { func TestGetDepositAddress(t *testing.T) { t.Parallel() - _, err := g.GetDepositAddress(currency.BTC, "") + _, err := g.GetDepositAddress(context.Background(), currency.BTC, "") if err == nil { t.Error("GetDepositAddress error cannot be nil") } @@ -1176,7 +1181,7 @@ func TestGetRecentTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = g.GetRecentTrades(currencyPair, asset.Spot) + _, err = g.GetRecentTrades(context.Background(), currencyPair, asset.Spot) if err != nil { t.Error(err) } @@ -1194,7 +1199,8 @@ func TestGetHistoricTrades(t *testing.T) { tStart = time.Date(time.Now().Year(), time.Now().Month(), 1, 0, 0, 0, 0, time.UTC) tEnd = time.Date(time.Now().Year(), time.Now().Month(), 1, 0, 15, 0, 0, time.UTC) } - _, err = g.GetHistoricTrades(currencyPair, asset.Spot, tStart, tEnd) + _, err = g.GetHistoricTrades(context.Background(), + currencyPair, asset.Spot, tStart, tEnd) if err != nil { t.Error(err) } diff --git a/exchanges/gemini/gemini_wrapper.go b/exchanges/gemini/gemini_wrapper.go index cb6dc116..7bd4ffbb 100644 --- a/exchanges/gemini/gemini_wrapper.go +++ b/exchanges/gemini/gemini_wrapper.go @@ -1,6 +1,7 @@ package gemini import ( + "context" "errors" "fmt" "net/url" @@ -42,7 +43,7 @@ func (g *Gemini) GetDefaultConfig() (*config.ExchangeConfig, error) { } if g.Features.Supports.RESTCapabilities.AutoPairUpdates { - err := g.UpdateTradablePairs(true) + err := g.UpdateTradablePairs(context.TODO(), true) if err != nil { return nil, err } @@ -256,7 +257,7 @@ func (g *Gemini) Run() { if !g.GetEnabledFeatures().AutoPairUpdates && !forceUpdate { return } - err = g.UpdateTradablePairs(forceUpdate) + err = g.UpdateTradablePairs(context.TODO(), forceUpdate) if err != nil { log.Errorf(log.ExchangeSys, "%s failed to update tradable pairs. Err: %s", @@ -266,8 +267,8 @@ func (g *Gemini) Run() { } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (g *Gemini) FetchTradablePairs(asset asset.Item) ([]string, error) { - pairs, err := g.GetSymbols() +func (g *Gemini) FetchTradablePairs(ctx context.Context, asset asset.Item) ([]string, error) { + pairs, err := g.GetSymbols(ctx) if err != nil { return nil, err } @@ -288,8 +289,8 @@ func (g *Gemini) FetchTradablePairs(asset asset.Item) ([]string, error) { // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (g *Gemini) UpdateTradablePairs(forceUpdate bool) error { - pairs, err := g.FetchTradablePairs(asset.Spot) +func (g *Gemini) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { + pairs, err := g.FetchTradablePairs(ctx, asset.Spot) if err != nil { return err } @@ -304,10 +305,10 @@ func (g *Gemini) UpdateTradablePairs(forceUpdate bool) error { // UpdateAccountInfo Retrieves balances for all enabled currencies for the // Gemini exchange -func (g *Gemini) UpdateAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (g *Gemini) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { var response account.Holdings response.Exchange = g.Name - accountBalance, err := g.GetBalances() + accountBalance, err := g.GetBalances(ctx) if err != nil { return response, err } @@ -334,28 +335,28 @@ func (g *Gemini) UpdateAccountInfo(assetType asset.Item) (account.Holdings, erro } // FetchAccountInfo retrieves balances for all enabled currencies -func (g *Gemini) FetchAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (g *Gemini) FetchAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { acc, err := account.GetHoldings(g.Name, assetType) if err != nil { - return g.UpdateAccountInfo(assetType) + return g.UpdateAccountInfo(ctx, assetType) } return acc, nil } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (g *Gemini) UpdateTickers(a asset.Item) error { +func (g *Gemini) UpdateTickers(ctx context.Context, a asset.Item) error { return common.ErrFunctionNotSupported } // UpdateTicker updates and returns the ticker for a currency pair -func (g *Gemini) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) { +func (g *Gemini) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { fPair, err := g.FormatExchangeCurrency(p, a) if err != nil { return nil, err } - tick, err := g.GetTicker(fPair.String()) + tick, err := g.GetTicker(ctx, fPair.String()) if err != nil { return nil, err } @@ -378,7 +379,7 @@ func (g *Gemini) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, err } // FetchTicker returns the ticker for a currency pair -func (g *Gemini) FetchTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) { +func (g *Gemini) FetchTicker(ctx context.Context, p currency.Pair, assetType asset.Item) (*ticker.Price, error) { fPair, err := g.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err @@ -386,13 +387,13 @@ func (g *Gemini) FetchTicker(p currency.Pair, assetType asset.Item) (*ticker.Pri tickerNew, err := ticker.GetTicker(g.Name, fPair, assetType) if err != nil { - return g.UpdateTicker(fPair, assetType) + return g.UpdateTicker(ctx, fPair, assetType) } return tickerNew, nil } // FetchOrderbook returns orderbook base on the currency pair -func (g *Gemini) FetchOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (g *Gemini) FetchOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { fPair, err := g.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err @@ -400,13 +401,13 @@ func (g *Gemini) FetchOrderbook(p currency.Pair, assetType asset.Item) (*orderbo ob, err := orderbook.Get(g.Name, fPair, assetType) if err != nil { - return g.UpdateOrderbook(fPair, assetType) + return g.UpdateOrderbook(ctx, fPair, assetType) } return ob, nil } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (g *Gemini) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (g *Gemini) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { book := &orderbook.Base{ Exchange: g.Name, Pair: p, @@ -418,7 +419,7 @@ func (g *Gemini) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderb return book, err } - orderbookNew, err := g.GetOrderbook(fPair.String(), url.Values{}) + orderbookNew, err := g.GetOrderbook(ctx, fPair.String(), url.Values{}) if err != nil { return book, err } @@ -443,22 +444,22 @@ func (g *Gemini) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderb // GetFundingHistory returns funding history, deposits and // withdrawals -func (g *Gemini) GetFundingHistory() ([]exchange.FundHistory, error) { +func (g *Gemini) GetFundingHistory(ctx context.Context) ([]exchange.FundHistory, error) { return nil, common.ErrFunctionNotSupported } // GetWithdrawalsHistory returns previous withdrawals data -func (g *Gemini) GetWithdrawalsHistory(c currency.Code) (resp []exchange.WithdrawalHistory, err error) { +func (g *Gemini) GetWithdrawalsHistory(ctx context.Context, c currency.Code) (resp []exchange.WithdrawalHistory, err error) { return nil, common.ErrNotYetImplemented } // GetRecentTrades returns the most recent trades for a currency and asset -func (g *Gemini) GetRecentTrades(currencyPair currency.Pair, assetType asset.Item) ([]trade.Data, error) { - return g.GetHistoricTrades(currencyPair, assetType, time.Time{}, time.Time{}) +func (g *Gemini) GetRecentTrades(ctx context.Context, pair currency.Pair, assetType asset.Item) ([]trade.Data, error) { + return g.GetHistoricTrades(ctx, pair, assetType, time.Time{}, time.Time{}) } // GetHistoricTrades returns historic trade data within the timeframe provided -func (g *Gemini) GetHistoricTrades(p currency.Pair, assetType asset.Item, timestampStart, timestampEnd time.Time) ([]trade.Data, error) { +func (g *Gemini) GetHistoricTrades(ctx context.Context, p currency.Pair, assetType asset.Item, timestampStart, timestampEnd time.Time) ([]trade.Data, error) { if err := common.StartEndTimeCheck(timestampStart, timestampEnd); err != nil && !errors.Is(err, common.ErrDateUnset) { return nil, fmt.Errorf("invalid time range supplied. Start: %v End %v %w", timestampStart, timestampEnd, err) } @@ -473,7 +474,11 @@ func (g *Gemini) GetHistoricTrades(p currency.Pair, assetType asset.Item, timest allTrades: for { var tradeData []Trade - tradeData, err = g.GetTrades(p.String(), ts.Unix(), int64(limit), false) + tradeData, err = g.GetTrades(ctx, + p.String(), + ts.Unix(), + int64(limit), + false) if err != nil { return nil, err } @@ -521,7 +526,7 @@ allTrades: } // SubmitOrder submits a new order -func (g *Gemini) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { +func (g *Gemini) SubmitOrder(ctx context.Context, s *order.Submit) (order.SubmitResponse, error) { var submitOrderResponse order.SubmitResponse if err := s.Validate(); err != nil { return submitOrderResponse, err @@ -537,7 +542,8 @@ func (g *Gemini) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { return submitOrderResponse, err } - response, err := g.NewOrder(fpair.String(), + response, err := g.NewOrder(ctx, + fpair.String(), s.Amount, s.Price, s.Side.String(), @@ -556,12 +562,12 @@ func (g *Gemini) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (g *Gemini) ModifyOrder(action *order.Modify) (order.Modify, error) { +func (g *Gemini) ModifyOrder(ctx context.Context, action *order.Modify) (order.Modify, error) { return order.Modify{}, common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number -func (g *Gemini) CancelOrder(o *order.Cancel) error { +func (g *Gemini) CancelOrder(ctx context.Context, o *order.Cancel) error { if err := o.Validate(o.StandardCancel()); err != nil { return err } @@ -571,21 +577,21 @@ func (g *Gemini) CancelOrder(o *order.Cancel) error { return err } - _, err = g.CancelExistingOrder(orderIDInt) + _, err = g.CancelExistingOrder(ctx, orderIDInt) return err } // CancelBatchOrders cancels an orders by their corresponding ID numbers -func (g *Gemini) CancelBatchOrders(o []order.Cancel) (order.CancelBatchResponse, error) { +func (g *Gemini) CancelBatchOrders(ctx context.Context, o []order.Cancel) (order.CancelBatchResponse, error) { return order.CancelBatchResponse{}, common.ErrNotYetImplemented } // CancelAllOrders cancels all orders associated with a currency pair -func (g *Gemini) CancelAllOrders(_ *order.Cancel) (order.CancelAllResponse, error) { +func (g *Gemini) CancelAllOrders(ctx context.Context, _ *order.Cancel) (order.CancelAllResponse, error) { cancelAllOrdersResponse := order.CancelAllResponse{ Status: make(map[string]string), } - resp, err := g.CancelExistingOrders(false) + resp, err := g.CancelExistingOrders(ctx, false) if err != nil { return cancelAllOrdersResponse, err } @@ -598,14 +604,14 @@ func (g *Gemini) CancelAllOrders(_ *order.Cancel) (order.CancelAllResponse, erro } // GetOrderInfo returns order information based on order ID -func (g *Gemini) GetOrderInfo(orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { +func (g *Gemini) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { var orderDetail order.Detail return orderDetail, common.ErrNotYetImplemented } // GetDepositAddress returns a deposit address for a specified currency -func (g *Gemini) GetDepositAddress(cryptocurrency currency.Code, _ string) (string, error) { - addr, err := g.GetCryptoDepositAddress("", cryptocurrency.String()) +func (g *Gemini) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _ string) (string, error) { + addr, err := g.GetCryptoDepositAddress(ctx, "", cryptocurrency.String()) if err != nil { return "", err } @@ -614,11 +620,14 @@ func (g *Gemini) GetDepositAddress(cryptocurrency currency.Code, _ string) (stri // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is // submitted -func (g *Gemini) WithdrawCryptocurrencyFunds(withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (g *Gemini) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } - resp, err := g.WithdrawCrypto(withdrawRequest.Crypto.Address, withdrawRequest.Currency.String(), withdrawRequest.Amount) + resp, err := g.WithdrawCrypto(ctx, + withdrawRequest.Crypto.Address, + withdrawRequest.Currency.String(), + withdrawRequest.Amount) if err != nil { return nil, err } @@ -633,32 +642,32 @@ func (g *Gemini) WithdrawCryptocurrencyFunds(withdrawRequest *withdraw.Request) // WithdrawFiatFunds returns a withdrawal ID when a // withdrawal is submitted -func (g *Gemini) WithdrawFiatFunds(_ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (g *Gemini) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a // withdrawal is submitted -func (g *Gemini) WithdrawFiatFundsToInternationalBank(_ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (g *Gemini) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // GetFeeByType returns an estimate of fee based on type of transaction -func (g *Gemini) GetFeeByType(feeBuilder *exchange.FeeBuilder) (float64, error) { +func (g *Gemini) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { if (!g.AllowAuthenticatedRequest() || g.SkipAuthCheck) && // Todo check connection status feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { feeBuilder.FeeType = exchange.OfflineTradeFee } - return g.GetFee(feeBuilder) + return g.GetFee(ctx, feeBuilder) } // GetActiveOrders retrieves any orders that are active/open -func (g *Gemini) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, error) { +func (g *Gemini) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) { if err := req.Validate(); err != nil { return nil, err } - resp, err := g.GetOrders() + resp, err := g.GetOrders(ctx) if err != nil { return nil, err } @@ -713,7 +722,7 @@ func (g *Gemini) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, e // GetOrderHistory retrieves account order information // Can Limit response to specific order status -func (g *Gemini) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, error) { +func (g *Gemini) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) { if err := req.Validate(); err != nil { return nil, err } @@ -729,7 +738,9 @@ func (g *Gemini) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, e return nil, err } - resp, err := g.GetTradeHistory(fpair.String(), req.StartTime.Unix()) + resp, err := g.GetTradeHistory(ctx, + fpair.String(), + req.StartTime.Unix()) if err != nil { return nil, err } @@ -772,17 +783,17 @@ func (g *Gemini) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, e // ValidateCredentials validates current credentials used for wrapper // functionality -func (g *Gemini) ValidateCredentials(assetType asset.Item) error { - _, err := g.UpdateAccountInfo(assetType) +func (g *Gemini) ValidateCredentials(ctx context.Context, assetType asset.Item) error { + _, err := g.UpdateAccountInfo(ctx, assetType) return g.CheckTransientError(err) } // GetHistoricCandles returns candles between a time period for a set time interval -func (g *Gemini) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (g *Gemini) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { return kline.Item{}, common.ErrFunctionNotSupported } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (g *Gemini) GetHistoricCandlesExtended(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (g *Gemini) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { return kline.Item{}, common.ErrFunctionNotSupported } diff --git a/exchanges/hitbtc/hitbtc.go b/exchanges/hitbtc/hitbtc.go index 8f8780ed..2e25efbf 100644 --- a/exchanges/hitbtc/hitbtc.go +++ b/exchanges/hitbtc/hitbtc.go @@ -53,7 +53,7 @@ type HitBTC struct { // GetCurrencies returns the actual list of available currencies, tokens, ICO // etc. -func (h *HitBTC) GetCurrencies() (map[string]Currencies, error) { +func (h *HitBTC) GetCurrencies(ctx context.Context) (map[string]Currencies, error) { type Response struct { Data []Currencies } @@ -61,7 +61,7 @@ func (h *HitBTC) GetCurrencies() (map[string]Currencies, error) { path := fmt.Sprintf("/%s", apiV2Currency) ret := make(map[string]Currencies) - err := h.SendHTTPRequest(exchange.RestSpot, path, &resp.Data) + err := h.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp.Data) if err != nil { return ret, err } @@ -74,14 +74,14 @@ func (h *HitBTC) GetCurrencies() (map[string]Currencies, error) { // GetCurrency returns the actual list of available currencies, tokens, ICO // etc. -func (h *HitBTC) GetCurrency(currency string) (Currencies, error) { +func (h *HitBTC) GetCurrency(ctx context.Context, currency string) (Currencies, error) { type Response struct { Data Currencies } resp := Response{} path := fmt.Sprintf("/%s/%s", apiV2Currency, currency) - return resp.Data, h.SendHTTPRequest(exchange.RestSpot, path, &resp.Data) + return resp.Data, h.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp.Data) } // GetSymbols Return the actual list of currency symbols (currency pairs) traded @@ -89,12 +89,12 @@ func (h *HitBTC) GetCurrency(currency string) (Currencies, error) { // currency, and the second currency is called the quote currency. The currency // pair indicates how much of the quote currency is needed to purchase one unit // of the base currency. -func (h *HitBTC) GetSymbols(symbol string) ([]string, error) { +func (h *HitBTC) GetSymbols(ctx context.Context, symbol string) ([]string, error) { var resp []Symbol path := fmt.Sprintf("/%s/%s", apiV2Symbol, symbol) ret := make([]string, 0, len(resp)) - err := h.SendHTTPRequest(exchange.RestSpot, path, &resp) + err := h.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) if err != nil { return ret, err } @@ -107,28 +107,28 @@ func (h *HitBTC) GetSymbols(symbol string) ([]string, error) { // GetSymbolsDetailed is the same as above but returns an array of symbols with // all their details. -func (h *HitBTC) GetSymbolsDetailed() ([]Symbol, error) { +func (h *HitBTC) GetSymbolsDetailed(ctx context.Context) ([]Symbol, error) { var resp []Symbol path := fmt.Sprintf("/%s", apiV2Symbol) - return resp, h.SendHTTPRequest(exchange.RestSpot, path, &resp) + return resp, h.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) } // GetTicker returns ticker information -func (h *HitBTC) GetTicker(symbol string) (TickerResponse, error) { +func (h *HitBTC) GetTicker(ctx context.Context, symbol string) (TickerResponse, error) { var resp TickerResponse path := fmt.Sprintf("/%s/%s", apiV2Ticker, symbol) - return resp, h.SendHTTPRequest(exchange.RestSpot, path, &resp) + return resp, h.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) } // GetTickers returns ticker information -func (h *HitBTC) GetTickers() ([]TickerResponse, error) { +func (h *HitBTC) GetTickers(ctx context.Context) ([]TickerResponse, error) { var resp []TickerResponse path := fmt.Sprintf("/%s/", apiV2Ticker) - return resp, h.SendHTTPRequest(exchange.RestSpot, path, &resp) + return resp, h.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) } // GetTrades returns trades from hitbtc -func (h *HitBTC) GetTrades(currencyPair, by, sort string, from, till, limit, offset int64) ([]TradeHistory, error) { +func (h *HitBTC) GetTrades(ctx context.Context, currencyPair, by, sort string, from, till, limit, offset int64) ([]TradeHistory, error) { urlValues := url.Values{} if from > 0 { urlValues.Set("from", strconv.FormatInt(from, 10)) @@ -154,12 +154,12 @@ func (h *HitBTC) GetTrades(currencyPair, by, sort string, from, till, limit, off apiV2Trades, currencyPair, urlValues.Encode()) - return resp, h.SendHTTPRequest(exchange.RestSpot, path, &resp) + return resp, h.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) } // GetOrderbook an order book is an electronic list of buy and sell orders for a // specific symbol, organized by price level. -func (h *HitBTC) GetOrderbook(currencyPair string, limit int) (Orderbook, error) { +func (h *HitBTC) GetOrderbook(ctx context.Context, currencyPair string, limit int) (Orderbook, error) { // limit Limit of orderbook levels, default 100. Set 0 to view full orderbook levels vals := url.Values{} @@ -173,7 +173,7 @@ func (h *HitBTC) GetOrderbook(currencyPair string, limit int) (Orderbook, error) currencyPair, vals.Encode()) - err := h.SendHTTPRequest(exchange.RestSpot, path, &resp) + err := h.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) if err != nil { return Orderbook{}, err } @@ -186,7 +186,7 @@ func (h *HitBTC) GetOrderbook(currencyPair string, limit int) (Orderbook, error) // GetCandles returns candles which is used for OHLC a specific currency. // Note: Result contain candles only with non zero volume. -func (h *HitBTC) GetCandles(currencyPair, limit, period string, start, end time.Time) ([]ChartData, error) { +func (h *HitBTC) GetCandles(ctx context.Context, currencyPair, limit, period string, start, end time.Time) ([]ChartData, error) { // limit Limit of candles, default 100. // period One of: M1 (one minute), M3, M5, M15, M30, H1, H4, D1, D7, 1M (one month). Default is M30 (30 minutes). vals := url.Values{} @@ -212,16 +212,18 @@ func (h *HitBTC) GetCandles(currencyPair, limit, period string, start, end time. var resp []ChartData path := fmt.Sprintf("/%s/%s?%s", apiV2Candles, currencyPair, vals.Encode()) - return resp, h.SendHTTPRequest(exchange.RestSpot, path, &resp) + return resp, h.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) } // Authenticated Market Data // https://api.hitbtc.com/?python#market-data // GetBalances returns full balance for your account -func (h *HitBTC) GetBalances() (map[string]Balance, error) { +func (h *HitBTC) GetBalances(ctx context.Context) (map[string]Balance, error) { var result []Balance - err := h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, + err := h.SendAuthenticatedHTTPRequest(ctx, + exchange.RestSpot, + http.MethodGet, apiV2Balance, url.Values{}, otherRequests, @@ -240,11 +242,11 @@ func (h *HitBTC) GetBalances() (map[string]Balance, error) { } // GetDepositAddresses returns a deposit address for a specific currency -func (h *HitBTC) GetDepositAddresses(currency string) (DepositCryptoAddresses, error) { +func (h *HitBTC) GetDepositAddresses(ctx context.Context, currency string) (DepositCryptoAddresses, error) { var resp DepositCryptoAddresses return resp, - h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, + h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, apiV2CryptoAddress+"/"+currency, url.Values{}, otherRequests, @@ -252,9 +254,9 @@ func (h *HitBTC) GetDepositAddresses(currency string) (DepositCryptoAddresses, e } // GenerateNewAddress generates a new deposit address for a currency -func (h *HitBTC) GenerateNewAddress(currency string) (DepositCryptoAddresses, error) { +func (h *HitBTC) GenerateNewAddress(ctx context.Context, currency string) (DepositCryptoAddresses, error) { resp := DepositCryptoAddresses{} - err := h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + err := h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, apiV2CryptoAddress+"/"+currency, url.Values{}, otherRequests, @@ -264,9 +266,9 @@ func (h *HitBTC) GenerateNewAddress(currency string) (DepositCryptoAddresses, er } // GetActiveorders returns all your active orders -func (h *HitBTC) GetActiveorders(currency string) ([]Order, error) { +func (h *HitBTC) GetActiveorders(ctx context.Context, currency string) ([]Order, error) { var resp []Order - err := h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, + err := h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, orders+"?symbol="+currency, url.Values{}, tradingRequests, @@ -276,7 +278,7 @@ func (h *HitBTC) GetActiveorders(currency string) ([]Order, error) { } // GetTradeHistoryForCurrency returns your trade history -func (h *HitBTC) GetTradeHistoryForCurrency(currency, start, end string) (AuthenticatedTradeHistoryResponse, error) { +func (h *HitBTC) GetTradeHistoryForCurrency(ctx context.Context, currency, start, end string) (AuthenticatedTradeHistoryResponse, error) { values := url.Values{} if start != "" { @@ -290,7 +292,7 @@ func (h *HitBTC) GetTradeHistoryForCurrency(currency, start, end string) (Authen values.Set("currencyPair", currency) result := AuthenticatedTradeHistoryResponse{} - return result, h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return result, h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, apiV2TradeHistory, values, otherRequests, @@ -298,7 +300,7 @@ func (h *HitBTC) GetTradeHistoryForCurrency(currency, start, end string) (Authen } // GetTradeHistoryForAllCurrencies returns your trade history -func (h *HitBTC) GetTradeHistoryForAllCurrencies(start, end string) (AuthenticatedTradeHistoryAll, error) { +func (h *HitBTC) GetTradeHistoryForAllCurrencies(ctx context.Context, start, end string) (AuthenticatedTradeHistoryAll, error) { values := url.Values{} if start != "" { @@ -312,7 +314,7 @@ func (h *HitBTC) GetTradeHistoryForAllCurrencies(start, end string) (Authenticat values.Set("currencyPair", "all") result := AuthenticatedTradeHistoryAll{} - return result, h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return result, h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, apiV2TradeHistory, values, otherRequests, @@ -320,12 +322,12 @@ func (h *HitBTC) GetTradeHistoryForAllCurrencies(start, end string) (Authenticat } // GetOrders List of your order history. -func (h *HitBTC) GetOrders(currency string) ([]OrderHistoryResponse, error) { +func (h *HitBTC) GetOrders(ctx context.Context, currency string) ([]OrderHistoryResponse, error) { values := url.Values{} values.Set("symbol", currency) var result []OrderHistoryResponse - return result, h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, + return result, h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, apiV2OrderHistory, values, tradingRequests, @@ -333,12 +335,12 @@ func (h *HitBTC) GetOrders(currency string) ([]OrderHistoryResponse, error) { } // GetOpenOrders List of your currently open orders. -func (h *HitBTC) GetOpenOrders(currency string) ([]OrderHistoryResponse, error) { +func (h *HitBTC) GetOpenOrders(ctx context.Context, currency string) ([]OrderHistoryResponse, error) { values := url.Values{} values.Set("symbol", currency) var result []OrderHistoryResponse - return result, h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, + return result, h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, apiv2OpenOrders, values, tradingRequests, @@ -346,7 +348,7 @@ func (h *HitBTC) GetOpenOrders(currency string) ([]OrderHistoryResponse, error) } // PlaceOrder places an order on the exchange -func (h *HitBTC) PlaceOrder(currency string, rate, amount float64, orderType, side string) (OrderResponse, error) { +func (h *HitBTC) PlaceOrder(ctx context.Context, currency string, rate, amount float64, orderType, side string) (OrderResponse, error) { var result OrderResponse values := url.Values{} @@ -357,7 +359,7 @@ func (h *HitBTC) PlaceOrder(currency string, rate, amount float64, orderType, si values.Set("price", strconv.FormatFloat(rate, 'f', -1, 64)) values.Set("type", orderType) - return result, h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return result, h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, apiOrder, values, tradingRequests, @@ -365,11 +367,11 @@ func (h *HitBTC) PlaceOrder(currency string, rate, amount float64, orderType, si } // CancelExistingOrder cancels a specific order by OrderID -func (h *HitBTC) CancelExistingOrder(orderID int64) (bool, error) { +func (h *HitBTC) CancelExistingOrder(ctx context.Context, orderID int64) (bool, error) { result := GenericResponse{} values := url.Values{} - err := h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodDelete, + err := h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodDelete, apiOrder+"/"+strconv.FormatInt(orderID, 10), values, tradingRequests, @@ -387,10 +389,10 @@ func (h *HitBTC) CancelExistingOrder(orderID int64) (bool, error) { } // CancelAllExistingOrders cancels all open orders -func (h *HitBTC) CancelAllExistingOrders() ([]Order, error) { +func (h *HitBTC) CancelAllExistingOrders(ctx context.Context) ([]Order, error) { var result []Order values := url.Values{} - return result, h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodDelete, + return result, h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodDelete, apiOrder, values, tradingRequests, @@ -398,7 +400,7 @@ func (h *HitBTC) CancelAllExistingOrders() ([]Order, error) { } // MoveOrder generates a new move order -func (h *HitBTC) MoveOrder(orderID int64, rate, amount float64) (MoveOrderResponse, error) { +func (h *HitBTC) MoveOrder(ctx context.Context, orderID int64, rate, amount float64) (MoveOrderResponse, error) { result := MoveOrderResponse{} values := url.Values{} values.Set("orderNumber", strconv.FormatInt(orderID, 10)) @@ -408,7 +410,7 @@ func (h *HitBTC) MoveOrder(orderID int64, rate, amount float64) (MoveOrderRespon values.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) } - err := h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + err := h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, orderMove, values, tradingRequests, @@ -426,7 +428,7 @@ func (h *HitBTC) MoveOrder(orderID int64, rate, amount float64) (MoveOrderRespon } // Withdraw allows for the withdrawal to a specific address -func (h *HitBTC) Withdraw(currency, address string, amount float64) (bool, error) { +func (h *HitBTC) Withdraw(ctx context.Context, currency, address string, amount float64) (bool, error) { result := Withdraw{} values := url.Values{} @@ -434,7 +436,7 @@ func (h *HitBTC) Withdraw(currency, address string, amount float64) (bool, error values.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) values.Set("address", address) - err := h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + err := h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, apiV2CryptoWithdraw, values, otherRequests, @@ -452,9 +454,9 @@ func (h *HitBTC) Withdraw(currency, address string, amount float64) (bool, error } // GetFeeInfo returns current fee information -func (h *HitBTC) GetFeeInfo(currencyPair string) (Fee, error) { +func (h *HitBTC) GetFeeInfo(ctx context.Context, currencyPair string) (Fee, error) { result := Fee{} - err := h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, + err := h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, apiV2FeeInfo+"/"+currencyPair, url.Values{}, tradingRequests, @@ -464,13 +466,13 @@ func (h *HitBTC) GetFeeInfo(currencyPair string) (Fee, error) { } // GetTradableBalances returns current tradable balances -func (h *HitBTC) GetTradableBalances() (map[string]map[string]float64, error) { +func (h *HitBTC) GetTradableBalances(ctx context.Context) (map[string]map[string]float64, error) { type Response struct { Data map[string]map[string]interface{} } result := Response{} - err := h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + err := h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, tradableBalances, url.Values{}, tradingRequests, @@ -493,7 +495,7 @@ func (h *HitBTC) GetTradableBalances() (map[string]map[string]float64, error) { } // TransferBalance transfers a balance -func (h *HitBTC) TransferBalance(currency, from, to string, amount float64) (bool, error) { +func (h *HitBTC) TransferBalance(ctx context.Context, currency, from, to string, amount float64) (bool, error) { values := url.Values{} result := GenericResponse{} @@ -502,7 +504,7 @@ func (h *HitBTC) TransferBalance(currency, from, to string, amount float64) (boo values.Set("fromAccount", from) values.Set("toAccount", to) - err := h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + err := h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, transferBalance, values, otherRequests, @@ -520,7 +522,7 @@ func (h *HitBTC) TransferBalance(currency, from, to string, amount float64) (boo } // SendHTTPRequest sends an unauthenticated HTTP request -func (h *HitBTC) SendHTTPRequest(ep exchange.URL, path string, result interface{}) error { +func (h *HitBTC) SendHTTPRequest(ctx context.Context, ep exchange.URL, path string, result interface{}) error { endpoint, err := h.API.Endpoints.GetURL(ep) if err != nil { return err @@ -535,13 +537,13 @@ func (h *HitBTC) SendHTTPRequest(ep exchange.URL, path string, result interface{ HTTPRecording: h.HTTPRecording, } - return h.SendPayload(context.Background(), marketRequests, func() (*request.Item, error) { + return h.SendPayload(ctx, marketRequests, func() (*request.Item, error) { return item, nil }) } // SendAuthenticatedHTTPRequest sends an authenticated http request -func (h *HitBTC) SendAuthenticatedHTTPRequest(ep exchange.URL, method, endpoint string, values url.Values, f request.EndpointLimit, result interface{}) error { +func (h *HitBTC) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, method, endpoint string, values url.Values, f request.EndpointLimit, result interface{}) error { if !h.AllowAuthenticatedRequest() { return fmt.Errorf("%s %w", h.Name, exchange.ErrAuthenticatedRequestWithoutCredentialsSet) } @@ -565,20 +567,21 @@ func (h *HitBTC) SendAuthenticatedHTTPRequest(ep exchange.URL, method, endpoint HTTPRecording: h.HTTPRecording, } - return h.SendPayload(context.Background(), f, func() (*request.Item, error) { + return h.SendPayload(ctx, f, func() (*request.Item, error) { item.Body = bytes.NewBufferString(values.Encode()) return item, nil }) } // GetFee returns an estimate of fee based on type of transaction -func (h *HitBTC) GetFee(feeBuilder *exchange.FeeBuilder) (float64, error) { +func (h *HitBTC) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { var fee float64 switch feeBuilder.FeeType { case exchange.CryptocurrencyTradeFee: - feeInfo, err := h.GetFeeInfo(feeBuilder.Pair.Base.String() + - feeBuilder.Pair.Delimiter + - feeBuilder.Pair.Quote.String()) + feeInfo, err := h.GetFeeInfo(ctx, + feeBuilder.Pair.Base.String()+ + feeBuilder.Pair.Delimiter+ + feeBuilder.Pair.Quote.String()) if err != nil { return 0, err @@ -587,7 +590,7 @@ func (h *HitBTC) GetFee(feeBuilder *exchange.FeeBuilder) (float64, error) { feeBuilder.Amount, feeBuilder.IsMaker) case exchange.CryptocurrencyWithdrawalFee: - currencyInfo, err := h.GetCurrency(feeBuilder.Pair.Base.String()) + currencyInfo, err := h.GetCurrency(ctx, feeBuilder.Pair.Base.String()) if err != nil { return 0, err } diff --git a/exchanges/hitbtc/hitbtc_test.go b/exchanges/hitbtc/hitbtc_test.go index 2b0e9d62..7ba75bcf 100644 --- a/exchanges/hitbtc/hitbtc_test.go +++ b/exchanges/hitbtc/hitbtc_test.go @@ -1,6 +1,7 @@ package hitbtc import ( + "context" "log" "net/http" "os" @@ -55,21 +56,22 @@ func TestMain(m *testing.M) { } func TestGetOrderbook(t *testing.T) { - _, err := h.GetOrderbook("BTCUSD", 50) + _, err := h.GetOrderbook(context.Background(), "BTCUSD", 50) if err != nil { t.Error("Test faild - HitBTC GetOrderbook() error", err) } } func TestGetTrades(t *testing.T) { - _, err := h.GetTrades("BTCUSD", "", "", 0, 0, 0, 0) + _, err := h.GetTrades(context.Background(), "BTCUSD", "", "", 0, 0, 0, 0) if err != nil { t.Error("Test faild - HitBTC GetTradeHistory() error", err) } } func TestGetChartCandles(t *testing.T) { - _, err := h.GetCandles("BTCUSD", "", "D1", time.Now().Add(-24*time.Hour), time.Now()) + _, err := h.GetCandles(context.Background(), + "BTCUSD", "", "D1", time.Now().Add(-24*time.Hour), time.Now()) if err != nil { t.Error("Test faild - HitBTC GetChartData() error", err) } @@ -82,12 +84,14 @@ func TestGetHistoricCandles(t *testing.T) { } startTime := time.Now().Add(-time.Hour * 24) end := time.Now() - _, err = h.GetHistoricCandles(currencyPair, asset.Spot, startTime, end, kline.OneMin) + _, err = h.GetHistoricCandles(context.Background(), + currencyPair, asset.Spot, startTime, end, kline.OneMin) if err != nil { t.Fatal(err) } - _, err = h.GetHistoricCandles(currencyPair, asset.Spot, startTime, end, kline.Interval(time.Hour*7)) + _, err = h.GetHistoricCandles(context.Background(), + currencyPair, asset.Spot, startTime, end, kline.Interval(time.Hour*7)) if err == nil { t.Fatal("unexpected result") } @@ -100,19 +104,21 @@ func TestGetHistoricCandlesExtended(t *testing.T) { } startTime := time.Unix(1546300800, 0) end := time.Unix(1577836799, 0) - _, err = h.GetHistoricCandlesExtended(currencyPair, asset.Spot, startTime, end, kline.OneHour) + _, err = h.GetHistoricCandlesExtended(context.Background(), + currencyPair, asset.Spot, startTime, end, kline.OneHour) if err != nil { t.Fatal(err) } - _, err = h.GetHistoricCandlesExtended(currencyPair, asset.Spot, startTime, end, kline.Interval(time.Hour*7)) + _, err = h.GetHistoricCandlesExtended(context.Background(), + currencyPair, asset.Spot, startTime, end, kline.Interval(time.Hour*7)) if err == nil { t.Fatal("unexpected result") } } func TestGetCurrencies(t *testing.T) { - _, err := h.GetCurrencies() + _, err := h.GetCurrencies(context.Background()) if err != nil { t.Error("Test faild - HitBTC GetCurrencies() error", err) } @@ -132,7 +138,7 @@ func setFeeBuilder() *exchange.FeeBuilder { // TestGetFeeByTypeOfflineTradeFee logic test func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { var feeBuilder = setFeeBuilder() - _, err := h.GetFeeByType(feeBuilder) + _, err := h.GetFeeByType(context.Background(), feeBuilder) if err != nil { t.Fatal(err) } @@ -153,33 +159,36 @@ func TestUpdateTicker(t *testing.T) { t.Fatal(err) } h.CurrencyPairs.StorePairs(asset.Spot, pairs, true) - _, err = h.UpdateTicker(currency.NewPair(currency.BTC, currency.USD), asset.Spot) + _, err = h.UpdateTicker(context.Background(), + currency.NewPair(currency.BTC, currency.USD), + asset.Spot) if err != nil { t.Error(err) } - _, err = h.FetchTicker(currency.NewPair(currency.XRP, currency.USD), asset.Spot) + _, err = h.FetchTicker(context.Background(), + currency.NewPair(currency.XRP, currency.USD), asset.Spot) if err != nil { t.Error(err) } } func TestUpdateTickers(t *testing.T) { - err := h.UpdateTickers(asset.Spot) + err := h.UpdateTickers(context.Background(), asset.Spot) if err != nil { t.Error(err) } } func TestGetAllTickers(t *testing.T) { - _, err := h.GetTickers() + _, err := h.GetTickers(context.Background()) if err != nil { t.Error(err) } } func TestGetSingularTicker(t *testing.T) { - _, err := h.GetTicker("BTCUSD") + _, err := h.GetTicker(context.Background(), "BTCUSD") if err != nil { t.Error(err) } @@ -189,7 +198,7 @@ func TestGetFee(t *testing.T) { var feeBuilder = setFeeBuilder() if areTestAPIKeysSet() { // CryptocurrencyTradeFee Basic - if _, err := h.GetFee(feeBuilder); err != nil { + if _, err := h.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } @@ -197,32 +206,32 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.Amount = 1000 feeBuilder.PurchasePrice = 1000 - if _, err := h.GetFee(feeBuilder); err != nil { + if _, err := h.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyTradeFee IsMaker feeBuilder = setFeeBuilder() feeBuilder.IsMaker = true - if _, err := h.GetFee(feeBuilder); err != nil { + if _, err := h.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyTradeFee Negative purchase price feeBuilder = setFeeBuilder() feeBuilder.PurchasePrice = -1000 - if _, err := h.GetFee(feeBuilder); err != nil { + if _, err := h.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyWithdrawalFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee - if _, err := h.GetFee(feeBuilder); err != nil { + if _, err := h.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyWithdrawalFee Invalid currency feeBuilder = setFeeBuilder() feeBuilder.Pair.Base = currency.NewCode("hello") feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee - if _, err := h.GetFee(feeBuilder); err != nil { + if _, err := h.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } } @@ -232,14 +241,14 @@ func TestGetFee(t *testing.T) { feeBuilder.FeeType = exchange.CryptocurrencyDepositFee feeBuilder.Pair.Base = currency.BTC feeBuilder.Pair.Quote = currency.LTC - if _, err := h.GetFee(feeBuilder); err != nil { + if _, err := h.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } // InternationalBankDepositFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankDepositFee - if _, err := h.GetFee(feeBuilder); err != nil { + if _, err := h.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } @@ -247,7 +256,7 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee feeBuilder.FiatCurrency = currency.USD - if _, err := h.GetFee(feeBuilder); err != nil { + if _, err := h.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } } @@ -267,7 +276,7 @@ func TestGetActiveOrders(t *testing.T) { AssetType: asset.Spot, } - _, err := h.GetActiveOrders(&getOrdersRequest) + _, err := h.GetActiveOrders(context.Background(), &getOrdersRequest) if areTestAPIKeysSet() && err != nil { t.Errorf("Could not get open orders: %s", err) } else if !areTestAPIKeysSet() && err == nil { @@ -282,7 +291,7 @@ func TestGetOrderHistory(t *testing.T) { Pairs: []currency.Pair{currency.NewPair(currency.ETH, currency.BTC)}, } - _, err := h.GetOrderHistory(&getOrdersRequest) + _, err := h.GetOrderHistory(context.Background(), &getOrdersRequest) if areTestAPIKeysSet() && err != nil { t.Errorf("Could not get order history: %s", err) } else if !areTestAPIKeysSet() && err == nil { @@ -313,7 +322,7 @@ func TestSubmitOrder(t *testing.T) { ClientID: "meowOrder", AssetType: asset.Spot, } - response, err := h.SubmitOrder(orderSubmission) + response, err := h.SubmitOrder(context.Background(), orderSubmission) if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) { t.Errorf("Order failed to be placed: %v", err) } else if !areTestAPIKeysSet() && err == nil { @@ -335,7 +344,7 @@ func TestCancelExchangeOrder(t *testing.T) { AssetType: asset.Spot, } - err := h.CancelOrder(orderCancellation) + err := h.CancelOrder(context.Background(), orderCancellation) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") } @@ -358,7 +367,7 @@ func TestCancelAllExchangeOrders(t *testing.T) { AssetType: asset.Spot, } - resp, err := h.CancelAllOrders(orderCancellation) + resp, err := h.CancelAllOrders(context.Background(), orderCancellation) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") @@ -376,7 +385,8 @@ func TestModifyOrder(t *testing.T) { if areTestAPIKeysSet() && !canManipulateRealOrders { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - _, err := h.ModifyOrder(&order.Modify{AssetType: asset.Spot}) + _, err := h.ModifyOrder(context.Background(), + &order.Modify{AssetType: asset.Spot}) if err == nil { t.Error("ModifyOrder() Expected error") } @@ -396,7 +406,8 @@ func TestWithdraw(t *testing.T) { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - _, err := h.WithdrawCryptocurrencyFunds(&withdrawCryptoRequest) + _, err := h.WithdrawCryptocurrencyFunds(context.Background(), + &withdrawCryptoRequest) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") } @@ -411,7 +422,7 @@ func TestWithdrawFiat(t *testing.T) { } var withdrawFiatRequest = withdraw.Request{} - _, err := h.WithdrawFiatFunds(&withdrawFiatRequest) + _, err := h.WithdrawFiatFunds(context.Background(), &withdrawFiatRequest) if err != common.ErrFunctionNotSupported { t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err) } @@ -423,7 +434,8 @@ func TestWithdrawInternationalBank(t *testing.T) { } var withdrawFiatRequest = withdraw.Request{} - _, err := h.WithdrawFiatFundsToInternationalBank(&withdrawFiatRequest) + _, err := h.WithdrawFiatFundsToInternationalBank(context.Background(), + &withdrawFiatRequest) if err != common.ErrFunctionNotSupported { t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err) } @@ -431,12 +443,12 @@ func TestWithdrawInternationalBank(t *testing.T) { func TestGetDepositAddress(t *testing.T) { if areTestAPIKeysSet() { - _, err := h.GetDepositAddress(currency.BTC, "") + _, err := h.GetDepositAddress(context.Background(), currency.BTC, "") if err != nil { t.Error("GetDepositAddress() error", err) } } else { - _, err := h.GetDepositAddress(currency.BTC, "") + _, err := h.GetDepositAddress(context.Background(), currency.BTC, "") if err == nil { t.Error("GetDepositAddress() error cannot be nil") } @@ -1001,7 +1013,7 @@ func TestGetRecentTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = h.GetRecentTrades(currencyPair, asset.Spot) + _, err = h.GetRecentTrades(context.Background(), currencyPair, asset.Spot) if err != nil { t.Error(err) } @@ -1013,12 +1025,16 @@ func TestGetHistoricTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = h.GetHistoricTrades(currencyPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) + _, err = h.GetHistoricTrades(context.Background(), + currencyPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) if err != nil && err != common.ErrFunctionNotSupported { t.Error(err) } // longer term - _, err = h.GetHistoricTrades(currencyPair, asset.Spot, time.Now().Add(-time.Minute*60*200), time.Now().Add(-time.Minute*60*199)) + _, err = h.GetHistoricTrades(context.Background(), + currencyPair, asset.Spot, + time.Now().Add(-time.Minute*60*200), + time.Now().Add(-time.Minute*60*199)) if err != nil { t.Error(err) } diff --git a/exchanges/hitbtc/hitbtc_wrapper.go b/exchanges/hitbtc/hitbtc_wrapper.go index babfc1fc..b7974a74 100644 --- a/exchanges/hitbtc/hitbtc_wrapper.go +++ b/exchanges/hitbtc/hitbtc_wrapper.go @@ -1,6 +1,7 @@ package hitbtc import ( + "context" "errors" "fmt" "sort" @@ -41,7 +42,7 @@ func (h *HitBTC) GetDefaultConfig() (*config.ExchangeConfig, error) { } if h.Features.Supports.RESTCapabilities.AutoPairUpdates { - err = h.UpdateTradablePairs(true) + err = h.UpdateTradablePairs(context.TODO(), true) if err != nil { return nil, err } @@ -260,7 +261,7 @@ func (h *HitBTC) Run() { return } - err = h.UpdateTradablePairs(forceUpdate) + err = h.UpdateTradablePairs(context.TODO(), forceUpdate) if err != nil { log.Errorf(log.ExchangeSys, "%s failed to update tradable pairs. Err: %s", @@ -270,8 +271,8 @@ func (h *HitBTC) Run() { } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (h *HitBTC) FetchTradablePairs(asset asset.Item) ([]string, error) { - symbols, err := h.GetSymbolsDetailed() +func (h *HitBTC) FetchTradablePairs(ctx context.Context, asset asset.Item) ([]string, error) { + symbols, err := h.GetSymbolsDetailed(ctx) if err != nil { return nil, err } @@ -292,8 +293,8 @@ func (h *HitBTC) FetchTradablePairs(asset asset.Item) ([]string, error) { // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (h *HitBTC) UpdateTradablePairs(forceUpdate bool) error { - pairs, err := h.FetchTradablePairs(asset.Spot) +func (h *HitBTC) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { + pairs, err := h.FetchTradablePairs(ctx, asset.Spot) if err != nil { return err } @@ -306,8 +307,8 @@ func (h *HitBTC) UpdateTradablePairs(forceUpdate bool) error { } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (h *HitBTC) UpdateTickers(a asset.Item) error { - tick, err := h.GetTickers() +func (h *HitBTC) UpdateTickers(ctx context.Context, a asset.Item) error { + tick, err := h.GetTickers(ctx) if err != nil { return err } @@ -356,8 +357,8 @@ func (h *HitBTC) UpdateTickers(a asset.Item) error { } // UpdateTicker updates and returns the ticker for a currency pair -func (h *HitBTC) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) { - err := h.UpdateTickers(a) +func (h *HitBTC) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { + err := h.UpdateTickers(ctx, a) if err != nil { return nil, err } @@ -365,25 +366,25 @@ func (h *HitBTC) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, err } // FetchTicker returns the ticker for a currency pair -func (h *HitBTC) FetchTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) { +func (h *HitBTC) FetchTicker(ctx context.Context, p currency.Pair, assetType asset.Item) (*ticker.Price, error) { tickerNew, err := ticker.GetTicker(h.Name, p, assetType) if err != nil { - return h.UpdateTicker(p, assetType) + return h.UpdateTicker(ctx, p, assetType) } return tickerNew, nil } // FetchOrderbook returns orderbook base on the currency pair -func (h *HitBTC) FetchOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (h *HitBTC) FetchOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { ob, err := orderbook.Get(h.Name, p, assetType) if err != nil { - return h.UpdateOrderbook(p, assetType) + return h.UpdateOrderbook(ctx, p, assetType) } return ob, nil } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (h *HitBTC) UpdateOrderbook(c currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (h *HitBTC) UpdateOrderbook(ctx context.Context, c currency.Pair, assetType asset.Item) (*orderbook.Base, error) { book := &orderbook.Base{ Exchange: h.Name, Pair: c, @@ -395,7 +396,7 @@ func (h *HitBTC) UpdateOrderbook(c currency.Pair, assetType asset.Item) (*orderb return book, err } - orderbookNew, err := h.GetOrderbook(fpair.String(), 1000) + orderbookNew, err := h.GetOrderbook(ctx, fpair.String(), 1000) if err != nil { return book, err } @@ -422,10 +423,10 @@ func (h *HitBTC) UpdateOrderbook(c currency.Pair, assetType asset.Item) (*orderb // UpdateAccountInfo retrieves balances for all enabled currencies for the // HitBTC exchange -func (h *HitBTC) UpdateAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (h *HitBTC) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { var response account.Holdings response.Exchange = h.Name - accountBalance, err := h.GetBalances() + accountBalance, err := h.GetBalances(ctx) if err != nil { return response, err } @@ -452,10 +453,10 @@ func (h *HitBTC) UpdateAccountInfo(assetType asset.Item) (account.Holdings, erro } // FetchAccountInfo retrieves balances for all enabled currencies -func (h *HitBTC) FetchAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (h *HitBTC) FetchAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { acc, err := account.GetHoldings(h.Name, assetType) if err != nil { - return h.UpdateAccountInfo(assetType) + return h.UpdateAccountInfo(ctx, assetType) } return acc, nil @@ -463,22 +464,22 @@ func (h *HitBTC) FetchAccountInfo(assetType asset.Item) (account.Holdings, error // GetFundingHistory returns funding history, deposits and // withdrawals -func (h *HitBTC) GetFundingHistory() ([]exchange.FundHistory, error) { +func (h *HitBTC) GetFundingHistory(ctx context.Context) ([]exchange.FundHistory, error) { return nil, common.ErrFunctionNotSupported } // GetWithdrawalsHistory returns previous withdrawals data -func (h *HitBTC) GetWithdrawalsHistory(c currency.Code) (resp []exchange.WithdrawalHistory, err error) { +func (h *HitBTC) GetWithdrawalsHistory(ctx context.Context, c currency.Code) (resp []exchange.WithdrawalHistory, err error) { return nil, common.ErrNotYetImplemented } // GetRecentTrades returns the most recent trades for a currency and asset -func (h *HitBTC) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade.Data, error) { - return h.GetHistoricTrades(p, assetType, time.Now().Add(-time.Minute*15), time.Now()) +func (h *HitBTC) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { + return h.GetHistoricTrades(ctx, p, assetType, time.Now().Add(-time.Minute*15), time.Now()) } // GetHistoricTrades returns historic trade data within the timeframe provided -func (h *HitBTC) GetHistoricTrades(p currency.Pair, assetType asset.Item, timestampStart, timestampEnd time.Time) ([]trade.Data, error) { +func (h *HitBTC) GetHistoricTrades(ctx context.Context, p currency.Pair, assetType asset.Item, timestampStart, timestampEnd time.Time) ([]trade.Data, error) { if err := common.StartEndTimeCheck(timestampStart, timestampEnd); err != nil { return nil, fmt.Errorf("invalid time range supplied. Start: %v End %v %w", timestampStart, timestampEnd, err) } @@ -493,7 +494,14 @@ func (h *HitBTC) GetHistoricTrades(p currency.Pair, assetType asset.Item, timest allTrades: for { var tradeData []TradeHistory - tradeData, err = h.GetTrades(p.String(), "", "", ts.UnixNano()/int64(time.Millisecond), timestampEnd.UnixNano()/int64(time.Millisecond), int64(limit), 0) + tradeData, err = h.GetTrades(ctx, + p.String(), + "", + "", + ts.UnixNano()/int64(time.Millisecond), + timestampEnd.UnixNano()/int64(time.Millisecond), + int64(limit), + 0) if err != nil { return nil, err } @@ -539,7 +547,7 @@ allTrades: } // SubmitOrder submits a new order -func (h *HitBTC) SubmitOrder(o *order.Submit) (order.SubmitResponse, error) { +func (h *HitBTC) SubmitOrder(ctx context.Context, o *order.Submit) (order.SubmitResponse, error) { var submitOrderResponse order.SubmitResponse err := o.Validate() if err != nil { @@ -562,7 +570,8 @@ func (h *HitBTC) SubmitOrder(o *order.Submit) (order.SubmitResponse, error) { } var response OrderResponse - response, err = h.PlaceOrder(fPair.String(), + response, err = h.PlaceOrder(ctx, + fPair.String(), o.Price, o.Amount, strings.ToLower(o.Type.String()), @@ -584,12 +593,12 @@ func (h *HitBTC) SubmitOrder(o *order.Submit) (order.SubmitResponse, error) { // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (h *HitBTC) ModifyOrder(action *order.Modify) (order.Modify, error) { +func (h *HitBTC) ModifyOrder(ctx context.Context, action *order.Modify) (order.Modify, error) { return order.Modify{}, common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number -func (h *HitBTC) CancelOrder(o *order.Cancel) error { +func (h *HitBTC) CancelOrder(ctx context.Context, o *order.Cancel) error { if err := o.Validate(o.StandardCancel()); err != nil { return err } @@ -599,22 +608,22 @@ func (h *HitBTC) CancelOrder(o *order.Cancel) error { return err } - _, err = h.CancelExistingOrder(orderIDInt) + _, err = h.CancelExistingOrder(ctx, orderIDInt) return err } // CancelBatchOrders cancels an orders by their corresponding ID numbers -func (h *HitBTC) CancelBatchOrders(o []order.Cancel) (order.CancelBatchResponse, error) { +func (h *HitBTC) CancelBatchOrders(ctx context.Context, o []order.Cancel) (order.CancelBatchResponse, error) { return order.CancelBatchResponse{}, common.ErrNotYetImplemented } // CancelAllOrders cancels all orders associated with a currency pair -func (h *HitBTC) CancelAllOrders(_ *order.Cancel) (order.CancelAllResponse, error) { +func (h *HitBTC) CancelAllOrders(ctx context.Context, _ *order.Cancel) (order.CancelAllResponse, error) { cancelAllOrdersResponse := order.CancelAllResponse{ Status: make(map[string]string), } - resp, err := h.CancelAllExistingOrders() + resp, err := h.CancelAllExistingOrders(ctx) if err != nil { return cancelAllOrdersResponse, err } @@ -632,14 +641,14 @@ func (h *HitBTC) CancelAllOrders(_ *order.Cancel) (order.CancelAllResponse, erro } // GetOrderInfo returns order information based on order ID -func (h *HitBTC) GetOrderInfo(orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { +func (h *HitBTC) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { var orderDetail order.Detail return orderDetail, common.ErrNotYetImplemented } // GetDepositAddress returns a deposit address for a specified currency -func (h *HitBTC) GetDepositAddress(currency currency.Code, _ string) (string, error) { - resp, err := h.GetDepositAddresses(currency.String()) +func (h *HitBTC) GetDepositAddress(ctx context.Context, c currency.Code, _ string) (string, error) { + resp, err := h.GetDepositAddresses(ctx, c.String()) if err != nil { return "", err } @@ -649,11 +658,14 @@ func (h *HitBTC) GetDepositAddress(currency currency.Code, _ string) (string, er // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is // submitted -func (h *HitBTC) WithdrawCryptocurrencyFunds(withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (h *HitBTC) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } - v, err := h.Withdraw(withdrawRequest.Currency.String(), withdrawRequest.Crypto.Address, withdrawRequest.Amount) + v, err := h.Withdraw(ctx, + withdrawRequest.Currency.String(), + withdrawRequest.Crypto.Address, + withdrawRequest.Amount) if err != nil { return nil, err } @@ -664,27 +676,27 @@ func (h *HitBTC) WithdrawCryptocurrencyFunds(withdrawRequest *withdraw.Request) // WithdrawFiatFunds returns a withdrawal ID when a // withdrawal is submitted -func (h *HitBTC) WithdrawFiatFunds(_ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (h *HitBTC) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a // withdrawal is submitted -func (h *HitBTC) WithdrawFiatFundsToInternationalBank(_ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (h *HitBTC) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // GetFeeByType returns an estimate of fee based on type of transaction -func (h *HitBTC) GetFeeByType(feeBuilder *exchange.FeeBuilder) (float64, error) { +func (h *HitBTC) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { if !h.AllowAuthenticatedRequest() && // Todo check connection status feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { feeBuilder.FeeType = exchange.OfflineTradeFee } - return h.GetFee(feeBuilder) + return h.GetFee(ctx, feeBuilder) } // GetActiveOrders retrieves any orders that are active/open -func (h *HitBTC) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, error) { +func (h *HitBTC) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) { if err := req.Validate(); err != nil { return nil, err } @@ -695,7 +707,7 @@ func (h *HitBTC) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, e var allOrders []OrderHistoryResponse for i := range req.Pairs { - resp, err := h.GetOpenOrders(req.Pairs[i].String()) + resp, err := h.GetOpenOrders(ctx, req.Pairs[i].String()) if err != nil { return nil, err } @@ -734,7 +746,7 @@ func (h *HitBTC) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, e // GetOrderHistory retrieves account order information // Can Limit response to specific order status -func (h *HitBTC) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, error) { +func (h *HitBTC) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) { if err := req.Validate(); err != nil { return nil, err } @@ -745,7 +757,7 @@ func (h *HitBTC) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, e var allOrders []OrderHistoryResponse for i := range req.Pairs { - resp, err := h.GetOrders(req.Pairs[i].String()) + resp, err := h.GetOrders(ctx, req.Pairs[i].String()) if err != nil { return nil, err } @@ -783,14 +795,14 @@ func (h *HitBTC) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, e } // AuthenticateWebsocket sends an authentication message to the websocket -func (h *HitBTC) AuthenticateWebsocket() error { +func (h *HitBTC) AuthenticateWebsocket(_ context.Context) error { return h.wsLogin() } // ValidateCredentials validates current credentials used for wrapper // functionality -func (h *HitBTC) ValidateCredentials(assetType asset.Item) error { - _, err := h.UpdateAccountInfo(assetType) +func (h *HitBTC) ValidateCredentials(ctx context.Context, assetType asset.Item) error { + _, err := h.UpdateAccountInfo(ctx, assetType) return h.CheckTransientError(err) } @@ -809,7 +821,7 @@ func (h *HitBTC) FormatExchangeKlineInterval(in kline.Interval) string { } // GetHistoricCandles returns candles between a time period for a set time interval -func (h *HitBTC) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (h *HitBTC) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { if err := h.ValidateKline(pair, a, interval); err != nil { return kline.Item{}, err } @@ -819,10 +831,12 @@ func (h *HitBTC) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end return kline.Item{}, err } - data, err := h.GetCandles(formattedPair.String(), + data, err := h.GetCandles(ctx, + formattedPair.String(), strconv.FormatInt(int64(h.Features.Enabled.Kline.ResultLimit), 10), h.FormatExchangeKlineInterval(interval), - start, end) + start, + end) if err != nil { return kline.Item{}, err } @@ -849,7 +863,7 @@ func (h *HitBTC) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (h *HitBTC) GetHistoricCandlesExtended(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (h *HitBTC) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { if err := h.ValidateKline(pair, a, interval); err != nil { return kline.Item{}, err } @@ -871,10 +885,12 @@ func (h *HitBTC) GetHistoricCandlesExtended(pair currency.Pair, a asset.Item, st for y := range dates.Ranges { var data []ChartData - data, err = h.GetCandles(formattedPair.String(), + data, err = h.GetCandles(ctx, + formattedPair.String(), strconv.FormatInt(int64(h.Features.Enabled.Kline.ResultLimit), 10), h.FormatExchangeKlineInterval(interval), - dates.Ranges[y].Start.Time, dates.Ranges[y].End.Time) + dates.Ranges[y].Start.Time, + dates.Ranges[y].End.Time) if err != nil { return kline.Item{}, err } diff --git a/exchanges/huobi/huobi.go b/exchanges/huobi/huobi.go index 90195b5d..1ce4b7d2 100644 --- a/exchanges/huobi/huobi.go +++ b/exchanges/huobi/huobi.go @@ -71,7 +71,7 @@ type HUOBI struct { } // GetMarginRates gets margin rates -func (h *HUOBI) GetMarginRates(symbol currency.Pair) (MarginRatesData, error) { +func (h *HUOBI) GetMarginRates(ctx context.Context, symbol currency.Pair) (MarginRatesData, error) { var resp MarginRatesData vals := url.Values{} if !symbol.IsEmpty() { @@ -81,12 +81,12 @@ func (h *HUOBI) GetMarginRates(symbol currency.Pair) (MarginRatesData, error) { } vals.Set("symbol", symbolValue) } - return resp, h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, huobiMarginRates, vals, nil, &resp, false) + return resp, h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, huobiMarginRates, vals, nil, &resp, false) } // GetSpotKline returns kline data // KlinesRequestParams contains symbol currency.Pair, period and size -func (h *HUOBI) GetSpotKline(arg KlinesRequestParams) ([]KlineItem, error) { +func (h *HUOBI) GetSpotKline(ctx context.Context, arg KlinesRequestParams) ([]KlineItem, error) { vals := url.Values{} symbolValue, err := h.FormatSymbol(arg.Symbol, asset.Spot) if err != nil { @@ -106,7 +106,7 @@ func (h *HUOBI) GetSpotKline(arg KlinesRequestParams) ([]KlineItem, error) { var result response - err = h.SendHTTPRequest(exchange.RestSpot, common.EncodeURLValues("/"+huobiMarketHistoryKline, vals), &result) + err = h.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues("/"+huobiMarketHistoryKline, vals), &result) if result.ErrorMessage != "" { return nil, errors.New(result.ErrorMessage) } @@ -114,7 +114,7 @@ func (h *HUOBI) GetSpotKline(arg KlinesRequestParams) ([]KlineItem, error) { } // Get24HrMarketSummary returns 24hr market summary for a given market symbol -func (h *HUOBI) Get24HrMarketSummary(symbol currency.Pair) (MarketSummary24Hr, error) { +func (h *HUOBI) Get24HrMarketSummary(ctx context.Context, symbol currency.Pair) (MarketSummary24Hr, error) { var result MarketSummary24Hr params := url.Values{} symbolValue, err := h.FormatSymbol(symbol, asset.Spot) @@ -122,17 +122,17 @@ func (h *HUOBI) Get24HrMarketSummary(symbol currency.Pair) (MarketSummary24Hr, e return result, err } params.Set("symbol", symbolValue) - return result, h.SendHTTPRequest(exchange.RestSpot, huobi24HrMarketSummary+params.Encode(), &result) + return result, h.SendHTTPRequest(ctx, exchange.RestSpot, huobi24HrMarketSummary+params.Encode(), &result) } // GetTickers returns the ticker for the specified symbol -func (h *HUOBI) GetTickers() (Tickers, error) { +func (h *HUOBI) GetTickers(ctx context.Context) (Tickers, error) { var result Tickers - return result, h.SendHTTPRequest(exchange.RestSpot, "/"+huobiMarketTickers, &result) + return result, h.SendHTTPRequest(ctx, exchange.RestSpot, "/"+huobiMarketTickers, &result) } // GetMarketDetailMerged returns the ticker for the specified symbol -func (h *HUOBI) GetMarketDetailMerged(symbol currency.Pair) (DetailMerged, error) { +func (h *HUOBI) GetMarketDetailMerged(ctx context.Context, symbol currency.Pair) (DetailMerged, error) { vals := url.Values{} symbolValue, err := h.FormatSymbol(symbol, asset.Spot) if err != nil { @@ -147,7 +147,7 @@ func (h *HUOBI) GetMarketDetailMerged(symbol currency.Pair) (DetailMerged, error var result response - err = h.SendHTTPRequest(exchange.RestSpot, common.EncodeURLValues("/"+huobiMarketDetailMerged, vals), &result) + err = h.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues("/"+huobiMarketDetailMerged, vals), &result) if result.ErrorMessage != "" { return result.Tick, errors.New(result.ErrorMessage) } @@ -155,7 +155,7 @@ func (h *HUOBI) GetMarketDetailMerged(symbol currency.Pair) (DetailMerged, error } // GetDepth returns the depth for the specified symbol -func (h *HUOBI) GetDepth(obd OrderBookDataRequestParams) (Orderbook, error) { +func (h *HUOBI) GetDepth(ctx context.Context, obd OrderBookDataRequestParams) (Orderbook, error) { vals := url.Values{} symbolValue, err := h.FormatSymbol(obd.Symbol, asset.Spot) if err != nil { @@ -174,7 +174,7 @@ func (h *HUOBI) GetDepth(obd OrderBookDataRequestParams) (Orderbook, error) { var result response - err = h.SendHTTPRequest(exchange.RestSpot, common.EncodeURLValues("/"+huobiMarketDepth, vals), &result) + err = h.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues("/"+huobiMarketDepth, vals), &result) if result.ErrorMessage != "" { return result.Depth, errors.New(result.ErrorMessage) } @@ -182,7 +182,7 @@ func (h *HUOBI) GetDepth(obd OrderBookDataRequestParams) (Orderbook, error) { } // GetTrades returns the trades for the specified symbol -func (h *HUOBI) GetTrades(symbol currency.Pair) ([]Trade, error) { +func (h *HUOBI) GetTrades(ctx context.Context, symbol currency.Pair) ([]Trade, error) { vals := url.Values{} symbolValue, err := h.FormatSymbol(symbol, asset.Spot) if err != nil { @@ -199,7 +199,7 @@ func (h *HUOBI) GetTrades(symbol currency.Pair) ([]Trade, error) { var result response - err = h.SendHTTPRequest(exchange.RestSpot, common.EncodeURLValues("/"+huobiMarketTrade, vals), &result) + err = h.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues("/"+huobiMarketTrade, vals), &result) if result.ErrorMessage != "" { return nil, errors.New(result.ErrorMessage) } @@ -209,8 +209,8 @@ func (h *HUOBI) GetTrades(symbol currency.Pair) ([]Trade, error) { // GetLatestSpotPrice returns latest spot price of symbol // // symbol: string of currency pair -func (h *HUOBI) GetLatestSpotPrice(symbol currency.Pair) (float64, error) { - list, err := h.GetTradeHistory(symbol, 1) +func (h *HUOBI) GetLatestSpotPrice(ctx context.Context, symbol currency.Pair) (float64, error) { + list, err := h.GetTradeHistory(ctx, symbol, 1) if err != nil { return 0, err @@ -223,7 +223,7 @@ func (h *HUOBI) GetLatestSpotPrice(symbol currency.Pair) (float64, error) { } // GetTradeHistory returns the trades for the specified symbol -func (h *HUOBI) GetTradeHistory(symbol currency.Pair, size int64) ([]TradeHistory, error) { +func (h *HUOBI) GetTradeHistory(ctx context.Context, symbol currency.Pair, size int64) ([]TradeHistory, error) { vals := url.Values{} symbolValue, err := h.FormatSymbol(symbol, asset.Spot) if err != nil { @@ -242,7 +242,7 @@ func (h *HUOBI) GetTradeHistory(symbol currency.Pair, size int64) ([]TradeHistor var result response - err = h.SendHTTPRequest(exchange.RestSpot, common.EncodeURLValues("/"+huobiMarketTradeHistory, vals), &result) + err = h.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues("/"+huobiMarketTradeHistory, vals), &result) if result.ErrorMessage != "" { return nil, errors.New(result.ErrorMessage) } @@ -250,7 +250,7 @@ func (h *HUOBI) GetTradeHistory(symbol currency.Pair, size int64) ([]TradeHistor } // GetMarketDetail returns the ticker for the specified symbol -func (h *HUOBI) GetMarketDetail(symbol currency.Pair) (Detail, error) { +func (h *HUOBI) GetMarketDetail(ctx context.Context, symbol currency.Pair) (Detail, error) { vals := url.Values{} symbolValue, err := h.FormatSymbol(symbol, asset.Spot) if err != nil { @@ -265,7 +265,7 @@ func (h *HUOBI) GetMarketDetail(symbol currency.Pair) (Detail, error) { var result response - err = h.SendHTTPRequest(exchange.RestSpot, common.EncodeURLValues("/"+huobiMarketDetail, vals), &result) + err = h.SendHTTPRequest(ctx, exchange.RestSpot, common.EncodeURLValues("/"+huobiMarketDetail, vals), &result) if result.ErrorMessage != "" { return result.Tick, errors.New(result.ErrorMessage) } @@ -273,7 +273,7 @@ func (h *HUOBI) GetMarketDetail(symbol currency.Pair) (Detail, error) { } // GetSymbols returns an array of symbols supported by Huobi -func (h *HUOBI) GetSymbols() ([]Symbol, error) { +func (h *HUOBI) GetSymbols(ctx context.Context) ([]Symbol, error) { type response struct { Response Symbols []Symbol `json:"data"` @@ -281,7 +281,7 @@ func (h *HUOBI) GetSymbols() ([]Symbol, error) { var result response - err := h.SendHTTPRequest(exchange.RestSpot, "/v"+huobiAPIVersion+"/"+huobiSymbols, &result) + err := h.SendHTTPRequest(ctx, exchange.RestSpot, "/v"+huobiAPIVersion+"/"+huobiSymbols, &result) if result.ErrorMessage != "" { return nil, errors.New(result.ErrorMessage) } @@ -289,15 +289,17 @@ func (h *HUOBI) GetSymbols() ([]Symbol, error) { } // GetCurrencies returns a list of currencies supported by Huobi -func (h *HUOBI) GetCurrencies() ([]string, error) { +func (h *HUOBI) GetCurrencies(ctx context.Context) ([]string, error) { type response struct { Response Currencies []string `json:"data"` } var result response - - err := h.SendHTTPRequest(exchange.RestSpot, "/v"+huobiAPIVersion+"/"+huobiCurrencies, &result) + err := h.SendHTTPRequest(ctx, + exchange.RestSpot, + "/v"+huobiAPIVersion+"/"+huobiCurrencies, + &result) if result.ErrorMessage != "" { return nil, errors.New(result.ErrorMessage) } @@ -305,7 +307,7 @@ func (h *HUOBI) GetCurrencies() ([]string, error) { } // GetTimestamp returns the Huobi server time -func (h *HUOBI) GetTimestamp() (int64, error) { +func (h *HUOBI) GetTimestamp(ctx context.Context) (int64, error) { type response struct { Response Timestamp int64 `json:"data"` @@ -313,7 +315,7 @@ func (h *HUOBI) GetTimestamp() (int64, error) { var result response - err := h.SendHTTPRequest(exchange.RestSpot, "/v"+huobiAPIVersion+"/"+huobiTimestamp, &result) + err := h.SendHTTPRequest(ctx, exchange.RestSpot, "/v"+huobiAPIVersion+"/"+huobiTimestamp, &result) if result.ErrorMessage != "" { return 0, errors.New(result.ErrorMessage) } @@ -321,32 +323,32 @@ func (h *HUOBI) GetTimestamp() (int64, error) { } // GetAccounts returns the Huobi user accounts -func (h *HUOBI) GetAccounts() ([]Account, error) { +func (h *HUOBI) GetAccounts(ctx context.Context) ([]Account, error) { result := struct { Accounts []Account `json:"data"` }{} - err := h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, huobiAccounts, url.Values{}, nil, &result, false) + err := h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, huobiAccounts, url.Values{}, nil, &result, false) return result.Accounts, err } // GetAccountBalance returns the users Huobi account balance -func (h *HUOBI) GetAccountBalance(accountID string) ([]AccountBalanceDetail, error) { +func (h *HUOBI) GetAccountBalance(ctx context.Context, accountID string) ([]AccountBalanceDetail, error) { result := struct { AccountBalanceData AccountBalance `json:"data"` }{} endpoint := fmt.Sprintf(huobiAccountBalance, accountID) v := url.Values{} v.Set("account-id", accountID) - err := h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, endpoint, v, nil, &result, false) + err := h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, endpoint, v, nil, &result, false) return result.AccountBalanceData.AccountBalanceDetails, err } // GetAggregatedBalance returns the balances of all the sub-account aggregated. -func (h *HUOBI) GetAggregatedBalance() ([]AggregatedBalance, error) { +func (h *HUOBI) GetAggregatedBalance(ctx context.Context) ([]AggregatedBalance, error) { result := struct { AggregatedBalances []AggregatedBalance `json:"data"` }{} - err := h.SendAuthenticatedHTTPRequest(exchange.RestSpot, + err := h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, huobiAggregatedBalance, nil, @@ -358,7 +360,7 @@ func (h *HUOBI) GetAggregatedBalance() ([]AggregatedBalance, error) { } // SpotNewOrder submits an order to Huobi -func (h *HUOBI) SpotNewOrder(arg *SpotNewOrderRequestParams) (int64, error) { +func (h *HUOBI) SpotNewOrder(ctx context.Context, arg *SpotNewOrderRequestParams) (int64, error) { symbolValue, err := h.FormatSymbol(arg.Symbol, asset.Spot) if err != nil { return 0, err @@ -390,7 +392,8 @@ func (h *HUOBI) SpotNewOrder(arg *SpotNewOrderRequestParams) (int64, error) { result := struct { OrderID int64 `json:"data,string"` }{} - err = h.SendAuthenticatedHTTPRequest(exchange.RestSpot, + err = h.SendAuthenticatedHTTPRequest(ctx, + exchange.RestSpot, http.MethodPost, huobiOrderPlace, nil, @@ -402,24 +405,24 @@ func (h *HUOBI) SpotNewOrder(arg *SpotNewOrderRequestParams) (int64, error) { } // CancelExistingOrder cancels an order on Huobi -func (h *HUOBI) CancelExistingOrder(orderID int64) (int64, error) { +func (h *HUOBI) CancelExistingOrder(ctx context.Context, orderID int64) (int64, error) { resp := struct { OrderID int64 `json:"data,string"` }{} endpoint := fmt.Sprintf(huobiOrderCancel, strconv.FormatInt(orderID, 10)) - err := h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, endpoint, url.Values{}, nil, &resp, false) + err := h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, endpoint, url.Values{}, nil, &resp, false) return resp.OrderID, err } // CancelOrderBatch cancels a batch of orders -- to-do -func (h *HUOBI) CancelOrderBatch(_ []int64) ([]CancelOrderBatch, error) { +func (h *HUOBI) CancelOrderBatch(ctx context.Context, _ []int64) ([]CancelOrderBatch, error) { type response struct { Response Data []CancelOrderBatch `json:"data"` } var result response - err := h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, huobiOrderCancelBatch, url.Values{}, nil, &result, false) + err := h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, huobiOrderCancelBatch, url.Values{}, nil, &result, false) if result.ErrorMessage != "" { return nil, errors.New(result.ErrorMessage) @@ -428,7 +431,7 @@ func (h *HUOBI) CancelOrderBatch(_ []int64) ([]CancelOrderBatch, error) { } // CancelOpenOrdersBatch cancels a batch of orders -- to-do -func (h *HUOBI) CancelOpenOrdersBatch(accountID string, symbol currency.Pair) (CancelOpenOrdersBatch, error) { +func (h *HUOBI) CancelOpenOrdersBatch(ctx context.Context, accountID string, symbol currency.Pair) (CancelOpenOrdersBatch, error) { params := url.Values{} symbolValue, err := h.FormatSymbol(symbol, asset.Spot) if err != nil { @@ -445,7 +448,7 @@ func (h *HUOBI) CancelOpenOrdersBatch(accountID string, symbol currency.Pair) (C Symbol: symbolValue, } - err = h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, huobiBatchCancelOpenOrders, url.Values{}, data, &result, false) + err = h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, huobiBatchCancelOpenOrders, url.Values{}, data, &result, false) if result.Data.FailedCount > 0 { return result, fmt.Errorf("there were %v failed order cancellations", result.Data.FailedCount) } @@ -454,13 +457,13 @@ func (h *HUOBI) CancelOpenOrdersBatch(accountID string, symbol currency.Pair) (C } // GetOrder returns order information for the specified order -func (h *HUOBI) GetOrder(orderID int64) (OrderInfo, error) { +func (h *HUOBI) GetOrder(ctx context.Context, orderID int64) (OrderInfo, error) { resp := struct { Order OrderInfo `json:"data"` }{} urlVal := url.Values{} urlVal.Set("clientOrderId", strconv.FormatInt(orderID, 10)) - err := h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, + err := h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, huobiGetOrder, urlVal, nil, @@ -470,17 +473,17 @@ func (h *HUOBI) GetOrder(orderID int64) (OrderInfo, error) { } // GetOrderMatchResults returns matched order info for the specified order -func (h *HUOBI) GetOrderMatchResults(orderID int64) ([]OrderMatchInfo, error) { +func (h *HUOBI) GetOrderMatchResults(ctx context.Context, orderID int64) ([]OrderMatchInfo, error) { resp := struct { Orders []OrderMatchInfo `json:"data"` }{} endpoint := fmt.Sprintf(huobiGetOrderMatch, strconv.FormatInt(orderID, 10)) - err := h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, endpoint, url.Values{}, nil, &resp, false) + err := h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, endpoint, url.Values{}, nil, &resp, false) return resp.Orders, err } // GetOrders returns a list of orders -func (h *HUOBI) GetOrders(symbol currency.Pair, types, start, end, states, from, direct, size string) ([]OrderInfo, error) { +func (h *HUOBI) GetOrders(ctx context.Context, symbol currency.Pair, types, start, end, states, from, direct, size string) ([]OrderInfo, error) { resp := struct { Orders []OrderInfo `json:"data"` }{} @@ -517,12 +520,12 @@ func (h *HUOBI) GetOrders(symbol currency.Pair, types, start, end, states, from, vals.Set("size", size) } - err = h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, huobiGetOrders, vals, nil, &resp, false) + err = h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, huobiGetOrders, vals, nil, &resp, false) return resp.Orders, err } // GetOpenOrders returns a list of orders -func (h *HUOBI) GetOpenOrders(symbol currency.Pair, accountID, side string, size int64) ([]OrderInfo, error) { +func (h *HUOBI) GetOpenOrders(ctx context.Context, symbol currency.Pair, accountID, side string, size int64) ([]OrderInfo, error) { resp := struct { Orders []OrderInfo `json:"data"` }{} @@ -539,12 +542,12 @@ func (h *HUOBI) GetOpenOrders(symbol currency.Pair, accountID, side string, size } vals.Set("size", strconv.FormatInt(size, 10)) - err = h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, huobiGetOpenOrders, vals, nil, &resp, false) + err = h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, huobiGetOpenOrders, vals, nil, &resp, false) return resp.Orders, err } // GetOrdersMatch returns a list of matched orders -func (h *HUOBI) GetOrdersMatch(symbol currency.Pair, types, start, end, from, direct, size string) ([]OrderMatchInfo, error) { +func (h *HUOBI) GetOrdersMatch(ctx context.Context, symbol currency.Pair, types, start, end, from, direct, size string) ([]OrderMatchInfo, error) { resp := struct { Orders []OrderMatchInfo `json:"data"` }{} @@ -580,12 +583,12 @@ func (h *HUOBI) GetOrdersMatch(symbol currency.Pair, types, start, end, from, di vals.Set("size", size) } - err = h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, huobiGetOrdersMatch, vals, nil, &resp, false) + err = h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, huobiGetOrdersMatch, vals, nil, &resp, false) return resp.Orders, err } // MarginTransfer transfers assets into or out of the margin account -func (h *HUOBI) MarginTransfer(symbol currency.Pair, currency string, amount float64, in bool) (int64, error) { +func (h *HUOBI) MarginTransfer(ctx context.Context, symbol currency.Pair, currency string, amount float64, in bool) (int64, error) { symbolValue, err := h.FormatSymbol(symbol, asset.Spot) if err != nil { return 0, err @@ -608,12 +611,12 @@ func (h *HUOBI) MarginTransfer(symbol currency.Pair, currency string, amount flo resp := struct { TransferID int64 `json:"data"` }{} - err = h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, path, nil, data, &resp, false) + err = h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, path, nil, data, &resp, false) return resp.TransferID, err } // MarginOrder submits a margin order application -func (h *HUOBI) MarginOrder(symbol currency.Pair, currency string, amount float64) (int64, error) { +func (h *HUOBI) MarginOrder(ctx context.Context, symbol currency.Pair, currency string, amount float64) (int64, error) { symbolValue, err := h.FormatSymbol(symbol, asset.Spot) if err != nil { return 0, err @@ -631,12 +634,12 @@ func (h *HUOBI) MarginOrder(symbol currency.Pair, currency string, amount float6 resp := struct { MarginOrderID int64 `json:"data"` }{} - err = h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, huobiMarginOrders, nil, data, &resp, false) + err = h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, huobiMarginOrders, nil, data, &resp, false) return resp.MarginOrderID, err } // MarginRepayment repays a margin amount for a margin ID -func (h *HUOBI) MarginRepayment(orderID int64, amount float64) (int64, error) { +func (h *HUOBI) MarginRepayment(ctx context.Context, orderID int64, amount float64) (int64, error) { data := struct { Amount string `json:"amount"` }{ @@ -648,12 +651,12 @@ func (h *HUOBI) MarginRepayment(orderID int64, amount float64) (int64, error) { }{} endpoint := fmt.Sprintf(huobiMarginRepay, strconv.FormatInt(orderID, 10)) - err := h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, endpoint, nil, data, &resp, false) + err := h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, endpoint, nil, data, &resp, false) return resp.MarginOrderID, err } // GetMarginLoanOrders returns the margin loan orders -func (h *HUOBI) GetMarginLoanOrders(symbol currency.Pair, currency, start, end, states, from, direct, size string) ([]MarginOrder, error) { +func (h *HUOBI) GetMarginLoanOrders(ctx context.Context, symbol currency.Pair, currency, start, end, states, from, direct, size string) ([]MarginOrder, error) { vals := url.Values{} symbolValue, err := h.FormatSymbol(symbol, asset.Spot) if err != nil { @@ -689,12 +692,12 @@ func (h *HUOBI) GetMarginLoanOrders(symbol currency.Pair, currency, start, end, resp := struct { MarginLoanOrders []MarginOrder `json:"data"` }{} - err = h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, huobiMarginLoanOrders, vals, nil, &resp, false) + err = h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, huobiMarginLoanOrders, vals, nil, &resp, false) return resp.MarginLoanOrders, err } // GetMarginAccountBalance returns the margin account balances -func (h *HUOBI) GetMarginAccountBalance(symbol currency.Pair) ([]MarginAccountBalance, error) { +func (h *HUOBI) GetMarginAccountBalance(ctx context.Context, symbol currency.Pair) ([]MarginAccountBalance, error) { resp := struct { Balances []MarginAccountBalance `json:"data"` }{} @@ -706,12 +709,12 @@ func (h *HUOBI) GetMarginAccountBalance(symbol currency.Pair) ([]MarginAccountBa } vals.Set("symbol", symbolValue) } - err := h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, huobiMarginAccountBalance, vals, nil, &resp, false) + err := h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, huobiMarginAccountBalance, vals, nil, &resp, false) return resp.Balances, err } // Withdraw withdraws the desired amount and currency -func (h *HUOBI) Withdraw(c currency.Code, address, addrTag string, amount, fee float64) (int64, error) { +func (h *HUOBI) Withdraw(ctx context.Context, c currency.Code, address, addrTag string, amount, fee float64) (int64, error) { resp := struct { WithdrawID int64 `json:"data"` }{} @@ -736,12 +739,12 @@ func (h *HUOBI) Withdraw(c currency.Code, address, addrTag string, amount, fee f data.AddrTag = addrTag } - err := h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, huobiWithdrawCreate, nil, data, &resp.WithdrawID, false) + err := h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, huobiWithdrawCreate, nil, data, &resp.WithdrawID, false) return resp.WithdrawID, err } // CancelWithdraw cancels a withdraw request -func (h *HUOBI) CancelWithdraw(withdrawID int64) (int64, error) { +func (h *HUOBI) CancelWithdraw(ctx context.Context, withdrawID int64) (int64, error) { resp := struct { WithdrawID int64 `json:"data"` }{} @@ -749,12 +752,12 @@ func (h *HUOBI) CancelWithdraw(withdrawID int64) (int64, error) { vals.Set("withdraw-id", strconv.FormatInt(withdrawID, 10)) endpoint := fmt.Sprintf(huobiWithdrawCancel, strconv.FormatInt(withdrawID, 10)) - err := h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, endpoint, vals, nil, &resp, false) + err := h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, endpoint, vals, nil, &resp, false) return resp.WithdrawID, err } // QueryDepositAddress returns the deposit address for a specified currency -func (h *HUOBI) QueryDepositAddress(cryptocurrency string) (DepositAddress, error) { +func (h *HUOBI) QueryDepositAddress(ctx context.Context, cryptocurrency string) (DepositAddress, error) { resp := struct { DepositAddress []DepositAddress `json:"data"` }{} @@ -762,7 +765,7 @@ func (h *HUOBI) QueryDepositAddress(cryptocurrency string) (DepositAddress, erro vals := url.Values{} vals.Set("currency", cryptocurrency) - err := h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, huobiAccountDepositAddress, vals, nil, &resp, true) + err := h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, huobiAccountDepositAddress, vals, nil, &resp, true) if err != nil { return DepositAddress{}, err } @@ -773,7 +776,7 @@ func (h *HUOBI) QueryDepositAddress(cryptocurrency string) (DepositAddress, erro } // QueryWithdrawQuotas returns the users cryptocurrency withdraw quotas -func (h *HUOBI) QueryWithdrawQuotas(cryptocurrency string) (WithdrawQuota, error) { +func (h *HUOBI) QueryWithdrawQuotas(ctx context.Context, cryptocurrency string) (WithdrawQuota, error) { resp := struct { WithdrawQuota WithdrawQuota `json:"data"` }{} @@ -781,7 +784,7 @@ func (h *HUOBI) QueryWithdrawQuotas(cryptocurrency string) (WithdrawQuota, error vals := url.Values{} vals.Set("currency", cryptocurrency) - err := h.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, huobiAccountWithdrawQuota, vals, nil, &resp, true) + err := h.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, huobiAccountWithdrawQuota, vals, nil, &resp, true) if err != nil { return WithdrawQuota{}, err } @@ -789,7 +792,7 @@ func (h *HUOBI) QueryWithdrawQuotas(cryptocurrency string) (WithdrawQuota, error } // SendHTTPRequest sends an unauthenticated HTTP request -func (h *HUOBI) SendHTTPRequest(ep exchange.URL, path string, result interface{}) error { +func (h *HUOBI) SendHTTPRequest(ctx context.Context, ep exchange.URL, path string, result interface{}) error { endpoint, err := h.API.Endpoints.GetURL(ep) if err != nil { return err @@ -805,7 +808,7 @@ func (h *HUOBI) SendHTTPRequest(ep exchange.URL, path string, result interface{} HTTPRecording: h.HTTPRecording, } - err = h.SendPayload(context.Background(), request.Unset, func() (*request.Item, error) { + err = h.SendPayload(ctx, request.Unset, func() (*request.Item, error) { return item, nil }) if err != nil { @@ -822,7 +825,7 @@ func (h *HUOBI) SendHTTPRequest(ep exchange.URL, path string, result interface{} } // SendAuthenticatedHTTPRequest sends authenticated requests to the HUOBI API -func (h *HUOBI) SendAuthenticatedHTTPRequest(ep exchange.URL, method, endpoint string, values url.Values, data, result interface{}, isVersion2API bool) error { +func (h *HUOBI) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, method, endpoint string, values url.Values, data, result interface{}, isVersion2API bool) error { if !h.AllowAuthenticatedRequest() { return fmt.Errorf("%s %w", h.Name, exchange.ErrAuthenticatedRequestWithoutCredentialsSet) } @@ -891,7 +894,7 @@ func (h *HUOBI) SendAuthenticatedHTTPRequest(ep exchange.URL, method, endpoint s }, nil } - err = h.SendPayload(context.Background(), request.Unset, newRequest) + err = h.SendPayload(ctx, request.Unset, newRequest) if err != nil { return err } diff --git a/exchanges/huobi/huobi_cfutures.go b/exchanges/huobi/huobi_cfutures.go index 7a458779..73f2fbba 100644 --- a/exchanges/huobi/huobi_cfutures.go +++ b/exchanges/huobi/huobi_cfutures.go @@ -1,6 +1,7 @@ package huobi import ( + "context" "errors" "fmt" "net/http" @@ -71,7 +72,7 @@ const ( ) // QuerySwapIndexPriceInfo gets perpetual swap index's price info -func (h *HUOBI) QuerySwapIndexPriceInfo(code currency.Pair) (SwapIndexPriceData, error) { +func (h *HUOBI) QuerySwapIndexPriceInfo(ctx context.Context, code currency.Pair) (SwapIndexPriceData, error) { var resp SwapIndexPriceData path := huobiSwapIndexPriceInfo if code != (currency.Pair{}) { @@ -83,11 +84,11 @@ func (h *HUOBI) QuerySwapIndexPriceInfo(code currency.Pair) (SwapIndexPriceData, params.Set("contract_code", codeValue) path = huobiSwapIndexPriceInfo + params.Encode() } - return resp, h.SendHTTPRequest(exchange.RestFutures, path, &resp) + return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // GetSwapPriceLimits gets price caps for perpetual futures -func (h *HUOBI) GetSwapPriceLimits(code currency.Pair) (SwapPriceLimitsData, error) { +func (h *HUOBI) GetSwapPriceLimits(ctx context.Context, code currency.Pair) (SwapPriceLimitsData, error) { var resp SwapPriceLimitsData params := url.Values{} codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) @@ -95,12 +96,12 @@ func (h *HUOBI) GetSwapPriceLimits(code currency.Pair) (SwapPriceLimitsData, err return resp, err } params.Set("contract_code", codeValue) - return resp, h.SendHTTPRequest(exchange.RestFutures, huobiSwapPriceLimitation+params.Encode(), + return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, huobiSwapPriceLimitation+params.Encode(), &resp) } // SwapOpenInterestInformation gets open interest data for perpetual futures -func (h *HUOBI) SwapOpenInterestInformation(code currency.Pair) (SwapOpenInterestData, error) { +func (h *HUOBI) SwapOpenInterestInformation(ctx context.Context, code currency.Pair) (SwapOpenInterestData, error) { var resp SwapOpenInterestData params := url.Values{} codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) @@ -108,11 +109,11 @@ func (h *HUOBI) SwapOpenInterestInformation(code currency.Pair) (SwapOpenInteres return resp, err } params.Set("contract_code", codeValue) - return resp, h.SendHTTPRequest(exchange.RestFutures, huobiSwapOpenInterestInfo+params.Encode(), &resp) + return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, huobiSwapOpenInterestInfo+params.Encode(), &resp) } // GetSwapMarketDepth gets market depth for perpetual futures -func (h *HUOBI) GetSwapMarketDepth(code currency.Pair, dataType string) (SwapMarketDepthData, error) { +func (h *HUOBI) GetSwapMarketDepth(ctx context.Context, code currency.Pair, dataType string) (SwapMarketDepthData, error) { var resp SwapMarketDepthData params := url.Values{} codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) @@ -121,11 +122,11 @@ func (h *HUOBI) GetSwapMarketDepth(code currency.Pair, dataType string) (SwapMar } params.Set("contract_code", codeValue) params.Set("type", dataType) - return resp, h.SendHTTPRequest(exchange.RestFutures, huobiSwapMarketDepth+params.Encode(), &resp) + return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, huobiSwapMarketDepth+params.Encode(), &resp) } // GetSwapKlineData gets kline data for perpetual futures -func (h *HUOBI) GetSwapKlineData(code currency.Pair, period string, size int64, startTime, endTime time.Time) (SwapKlineData, error) { +func (h *HUOBI) GetSwapKlineData(ctx context.Context, code currency.Pair, period string, size int64, startTime, endTime time.Time) (SwapKlineData, error) { var resp SwapKlineData params := url.Values{} codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) @@ -148,11 +149,11 @@ func (h *HUOBI) GetSwapKlineData(code currency.Pair, period string, size int64, params.Set("start_time", strconv.FormatInt(startTime.Unix(), 10)) params.Set("end_time", strconv.FormatInt(endTime.Unix(), 10)) } - return resp, h.SendHTTPRequest(exchange.RestFutures, huobiKLineData+params.Encode(), &resp) + return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, huobiKLineData+params.Encode(), &resp) } // GetSwapMarketOverview gets market data overview for perpetual futures -func (h *HUOBI) GetSwapMarketOverview(code currency.Pair) (MarketOverviewData, error) { +func (h *HUOBI) GetSwapMarketOverview(ctx context.Context, code currency.Pair) (MarketOverviewData, error) { var resp MarketOverviewData params := url.Values{} codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) @@ -160,11 +161,11 @@ func (h *HUOBI) GetSwapMarketOverview(code currency.Pair) (MarketOverviewData, e return resp, err } params.Set("contract_code", codeValue) - return resp, h.SendHTTPRequest(exchange.RestFutures, huobiMarketDataOverview+params.Encode(), &resp) + return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, huobiMarketDataOverview+params.Encode(), &resp) } // GetLastTrade gets the last trade for a given perpetual contract -func (h *HUOBI) GetLastTrade(code currency.Pair) (LastTradeData, error) { +func (h *HUOBI) GetLastTrade(ctx context.Context, code currency.Pair) (LastTradeData, error) { var resp LastTradeData params := url.Values{} codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) @@ -172,11 +173,11 @@ func (h *HUOBI) GetLastTrade(code currency.Pair) (LastTradeData, error) { return resp, err } params.Set("contract_code", codeValue) - return resp, h.SendHTTPRequest(exchange.RestFutures, huobiLastTradeContract+params.Encode(), &resp) + return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, huobiLastTradeContract+params.Encode(), &resp) } // GetBatchTrades gets batch trades for a specified contract (fetching size cannot be bigger than 2000) -func (h *HUOBI) GetBatchTrades(code currency.Pair, size int64) (BatchTradesData, error) { +func (h *HUOBI) GetBatchTrades(ctx context.Context, code currency.Pair, size int64) (BatchTradesData, error) { var resp BatchTradesData params := url.Values{} codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) @@ -188,11 +189,11 @@ func (h *HUOBI) GetBatchTrades(code currency.Pair, size int64) (BatchTradesData, return resp, fmt.Errorf("invalid size provided values from 1-1200 supported") } params.Set("size", strconv.FormatInt(size, 10)) - return resp, h.SendHTTPRequest(exchange.RestFutures, huobiRequestBatchOfTradingRecords+params.Encode(), &resp) + return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, huobiRequestBatchOfTradingRecords+params.Encode(), &resp) } // GetInsuranceData gets insurance fund data and clawback rates -func (h *HUOBI) GetInsuranceData(code currency.Pair) (InsuranceAndClawbackData, error) { +func (h *HUOBI) GetInsuranceData(ctx context.Context, code currency.Pair) (InsuranceAndClawbackData, error) { var resp InsuranceAndClawbackData params := url.Values{} codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) @@ -200,11 +201,11 @@ func (h *HUOBI) GetInsuranceData(code currency.Pair) (InsuranceAndClawbackData, return resp, err } params.Set("contract_code", codeValue) - return resp, h.SendHTTPRequest(exchange.RestFutures, huobiInsuranceBalanceAndClawbackRate+params.Encode(), &resp) + return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, huobiInsuranceBalanceAndClawbackRate+params.Encode(), &resp) } // GetHistoricalInsuranceData gets historical insurance fund data and clawback rates -func (h *HUOBI) GetHistoricalInsuranceData(code currency.Pair, pageIndex, pageSize int64) (HistoricalInsuranceFundBalance, error) { +func (h *HUOBI) GetHistoricalInsuranceData(ctx context.Context, code currency.Pair, pageIndex, pageSize int64) (HistoricalInsuranceFundBalance, error) { var resp HistoricalInsuranceFundBalance params := url.Values{} codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) @@ -218,11 +219,11 @@ func (h *HUOBI) GetHistoricalInsuranceData(code currency.Pair, pageIndex, pageSi if pageSize != 0 { params.Set("page_size", strconv.FormatInt(pageIndex, 10)) } - return resp, h.SendHTTPRequest(exchange.RestFutures, huobiInsuranceBalanceHistory+params.Encode(), &resp) + return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, huobiInsuranceBalanceHistory+params.Encode(), &resp) } // GetTieredAjustmentFactorInfo gets tiered adjustment factor data -func (h *HUOBI) GetTieredAjustmentFactorInfo(code currency.Pair) (TieredAdjustmentFactorData, error) { +func (h *HUOBI) GetTieredAjustmentFactorInfo(ctx context.Context, code currency.Pair) (TieredAdjustmentFactorData, error) { var resp TieredAdjustmentFactorData params := url.Values{} codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) @@ -230,11 +231,11 @@ func (h *HUOBI) GetTieredAjustmentFactorInfo(code currency.Pair) (TieredAdjustme return resp, err } params.Set("contract_code", codeValue) - return resp, h.SendHTTPRequest(exchange.RestFutures, huobiTieredAdjustmentFactor+params.Encode(), &resp) + return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, huobiTieredAdjustmentFactor+params.Encode(), &resp) } // GetOpenInterestInfo gets open interest data -func (h *HUOBI) GetOpenInterestInfo(code currency.Pair, period, amountType string, size int64) (OpenInterestData, error) { +func (h *HUOBI) GetOpenInterestInfo(ctx context.Context, code currency.Pair, period, amountType string, size int64) (OpenInterestData, error) { var resp OpenInterestData params := url.Values{} codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) @@ -255,11 +256,11 @@ func (h *HUOBI) GetOpenInterestInfo(code currency.Pair, period, amountType strin return resp, fmt.Errorf("invalid trade type") } params.Set("amount_type", strconv.FormatInt(aType, 10)) - return resp, h.SendHTTPRequest(exchange.RestFutures, huobiOpenInterestInfo+params.Encode(), &resp) + return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, huobiOpenInterestInfo+params.Encode(), &resp) } // GetSystemStatusInfo gets system status data -func (h *HUOBI) GetSystemStatusInfo(code currency.Pair, period, amountType string, size int64) (SystemStatusData, error) { +func (h *HUOBI) GetSystemStatusInfo(ctx context.Context, code currency.Pair, period, amountType string, size int64) (SystemStatusData, error) { var resp SystemStatusData params := url.Values{} codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) @@ -279,11 +280,11 @@ func (h *HUOBI) GetSystemStatusInfo(code currency.Pair, period, amountType strin return resp, fmt.Errorf("invalid trade type") } params.Set("amount_type", strconv.FormatInt(aType, 10)) - return resp, h.SendHTTPRequest(exchange.RestFutures, huobiSwapSystemStatus+params.Encode(), &resp) + return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, huobiSwapSystemStatus+params.Encode(), &resp) } // GetTraderSentimentIndexAccount gets top trader sentiment function-account -func (h *HUOBI) GetTraderSentimentIndexAccount(code currency.Pair, period string) (TraderSentimentIndexAccountData, error) { +func (h *HUOBI) GetTraderSentimentIndexAccount(ctx context.Context, code currency.Pair, period string) (TraderSentimentIndexAccountData, error) { var resp TraderSentimentIndexAccountData params := url.Values{} codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) @@ -295,11 +296,11 @@ func (h *HUOBI) GetTraderSentimentIndexAccount(code currency.Pair, period string return resp, fmt.Errorf("invalid period value received") } params.Set("period", period) - return resp, h.SendHTTPRequest(exchange.RestFutures, huobiSwapSentimentAccountData+params.Encode(), &resp) + return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, huobiSwapSentimentAccountData+params.Encode(), &resp) } // GetTraderSentimentIndexPosition gets top trader sentiment function-position -func (h *HUOBI) GetTraderSentimentIndexPosition(code currency.Pair, period string) (TraderSentimentIndexPositionData, error) { +func (h *HUOBI) GetTraderSentimentIndexPosition(ctx context.Context, code currency.Pair, period string) (TraderSentimentIndexPositionData, error) { var resp TraderSentimentIndexPositionData params := url.Values{} codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) @@ -311,11 +312,11 @@ func (h *HUOBI) GetTraderSentimentIndexPosition(code currency.Pair, period strin return resp, fmt.Errorf("invalid period value received") } params.Set("period", period) - return resp, h.SendHTTPRequest(exchange.RestFutures, huobiSwapSentimentPosition+params.Encode(), &resp) + return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, huobiSwapSentimentPosition+params.Encode(), &resp) } // GetLiquidationOrders gets liquidation orders for a given perp -func (h *HUOBI) GetLiquidationOrders(code currency.Pair, tradeType string, pageIndex, pageSize, createDate int64) (LiquidationOrdersData, error) { +func (h *HUOBI) GetLiquidationOrders(ctx context.Context, code currency.Pair, tradeType string, pageIndex, pageSize, createDate int64) (LiquidationOrdersData, error) { var resp LiquidationOrdersData params := url.Values{} codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) @@ -338,11 +339,11 @@ func (h *HUOBI) GetLiquidationOrders(code currency.Pair, tradeType string, pageI if pageSize != 0 { params.Set("page_size", strconv.FormatInt(pageIndex, 10)) } - return resp, h.SendHTTPRequest(exchange.RestFutures, huobiSwapLiquidationOrders+params.Encode(), &resp) + return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, huobiSwapLiquidationOrders+params.Encode(), &resp) } // GetHistoricalFundingRates gets historical funding rates for perpetual futures -func (h *HUOBI) GetHistoricalFundingRates(code currency.Pair, pageSize, pageIndex int64) (HistoricalFundingRateData, error) { +func (h *HUOBI) GetHistoricalFundingRates(ctx context.Context, code currency.Pair, pageSize, pageIndex int64) (HistoricalFundingRateData, error) { var resp HistoricalFundingRateData params := url.Values{} codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) @@ -356,11 +357,11 @@ func (h *HUOBI) GetHistoricalFundingRates(code currency.Pair, pageSize, pageInde if pageSize != 0 { params.Set("page_size", strconv.FormatInt(pageIndex, 10)) } - return resp, h.SendHTTPRequest(exchange.RestFutures, huobiSwapHistoricalFundingRate+params.Encode(), &resp) + return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, huobiSwapHistoricalFundingRate+params.Encode(), &resp) } // GetPremiumIndexKlineData gets kline data for premium index -func (h *HUOBI) GetPremiumIndexKlineData(code currency.Pair, period string, size int64) (PremiumIndexKlineData, error) { +func (h *HUOBI) GetPremiumIndexKlineData(ctx context.Context, code currency.Pair, period string, size int64) (PremiumIndexKlineData, error) { var resp PremiumIndexKlineData params := url.Values{} codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) @@ -376,11 +377,11 @@ func (h *HUOBI) GetPremiumIndexKlineData(code currency.Pair, period string, size return resp, fmt.Errorf("invalid size provided values from 1-1200 supported") } params.Set("size", strconv.FormatInt(size, 10)) - return resp, h.SendHTTPRequest(exchange.RestFutures, huobiPremiumIndexKlineData+params.Encode(), &resp) + return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, huobiPremiumIndexKlineData+params.Encode(), &resp) } // GetEstimatedFundingRates gets estimated funding rates for perpetual futures -func (h *HUOBI) GetEstimatedFundingRates(code currency.Pair, period string, size int64) (EstimatedFundingRateData, error) { +func (h *HUOBI) GetEstimatedFundingRates(ctx context.Context, code currency.Pair, period string, size int64) (EstimatedFundingRateData, error) { var resp EstimatedFundingRateData params := url.Values{} codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) @@ -396,11 +397,11 @@ func (h *HUOBI) GetEstimatedFundingRates(code currency.Pair, period string, size return resp, fmt.Errorf("invalid size provided values from 1-1200 supported") } params.Set("size", strconv.FormatInt(size, 10)) - return resp, h.SendHTTPRequest(exchange.RestFutures, huobiPredictedFundingRateData+params.Encode(), &resp) + return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, huobiPredictedFundingRateData+params.Encode(), &resp) } // GetBasisData gets basis data for perpetual futures -func (h *HUOBI) GetBasisData(code currency.Pair, period, basisPriceType string, size int64) (BasisData, error) { +func (h *HUOBI) GetBasisData(ctx context.Context, code currency.Pair, period, basisPriceType string, size int64) (BasisData, error) { var resp BasisData params := url.Values{} codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) @@ -419,11 +420,11 @@ func (h *HUOBI) GetBasisData(code currency.Pair, period, basisPriceType string, if !common.StringDataCompare(validBasisPriceTypes, basisPriceType) { return resp, fmt.Errorf("invalid period value received") } - return resp, h.SendHTTPRequest(exchange.RestFutures, huobiBasisData+params.Encode(), &resp) + return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, huobiBasisData+params.Encode(), &resp) } // GetSwapAccountInfo gets swap account info -func (h *HUOBI) GetSwapAccountInfo(code currency.Pair) (SwapAccountInformation, error) { +func (h *HUOBI) GetSwapAccountInfo(ctx context.Context, code currency.Pair) (SwapAccountInformation, error) { var resp SwapAccountInformation req := make(map[string]interface{}) codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) @@ -431,11 +432,11 @@ func (h *HUOBI) GetSwapAccountInfo(code currency.Pair) (SwapAccountInformation, return resp, err } req["contract_code"] = codeValue - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, huobiSwapAccInfo, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapAccInfo, nil, req, &resp) } // GetSwapPositionsInfo gets swap positions' info -func (h *HUOBI) GetSwapPositionsInfo(code currency.Pair) (SwapPositionInfo, error) { +func (h *HUOBI) GetSwapPositionsInfo(ctx context.Context, code currency.Pair) (SwapPositionInfo, error) { var resp SwapPositionInfo req := make(map[string]interface{}) codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) @@ -443,11 +444,11 @@ func (h *HUOBI) GetSwapPositionsInfo(code currency.Pair) (SwapPositionInfo, erro return resp, err } req["contract_code"] = codeValue - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, huobiSwapPosInfo, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapPosInfo, nil, req, &resp) } // GetSwapAssetsAndPositions gets swap positions and asset info -func (h *HUOBI) GetSwapAssetsAndPositions(code currency.Pair) (SwapAssetsAndPositionsData, error) { +func (h *HUOBI) GetSwapAssetsAndPositions(ctx context.Context, code currency.Pair) (SwapAssetsAndPositionsData, error) { var resp SwapAssetsAndPositionsData req := make(map[string]interface{}) codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) @@ -455,11 +456,11 @@ func (h *HUOBI) GetSwapAssetsAndPositions(code currency.Pair) (SwapAssetsAndPosi return resp, err } req["contract_code"] = codeValue - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, huobiSwapAssetsAndPos, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapAssetsAndPos, nil, req, &resp) } // GetSwapAllSubAccAssets gets asset info for all subaccounts -func (h *HUOBI) GetSwapAllSubAccAssets(code currency.Pair) (SubAccountsAssetData, error) { +func (h *HUOBI) GetSwapAllSubAccAssets(ctx context.Context, code currency.Pair) (SubAccountsAssetData, error) { var resp SubAccountsAssetData req := make(map[string]interface{}) if code != (currency.Pair{}) { @@ -469,11 +470,11 @@ func (h *HUOBI) GetSwapAllSubAccAssets(code currency.Pair) (SubAccountsAssetData } req["contract_code"] = codeValue } - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, huobiSwapSubAccList, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapSubAccList, nil, req, &resp) } // SwapSingleSubAccAssets gets a subaccount's assets info -func (h *HUOBI) SwapSingleSubAccAssets(code currency.Pair, subUID int64) (SingleSubAccountAssetsInfo, error) { +func (h *HUOBI) SwapSingleSubAccAssets(ctx context.Context, code currency.Pair, subUID int64) (SingleSubAccountAssetsInfo, error) { var resp SingleSubAccountAssetsInfo req := make(map[string]interface{}) codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) @@ -482,11 +483,11 @@ func (h *HUOBI) SwapSingleSubAccAssets(code currency.Pair, subUID int64) (Single } req["contract_code"] = codeValue req["sub_uid"] = subUID - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, huobiSwapSubAccInfo, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapSubAccInfo, nil, req, &resp) } // GetSubAccPositionInfo gets a subaccount's positions info -func (h *HUOBI) GetSubAccPositionInfo(code currency.Pair, subUID int64) (SingleSubAccountPositionsInfo, error) { +func (h *HUOBI) GetSubAccPositionInfo(ctx context.Context, code currency.Pair, subUID int64) (SingleSubAccountPositionsInfo, error) { var resp SingleSubAccountPositionsInfo req := make(map[string]interface{}) codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) @@ -495,11 +496,11 @@ func (h *HUOBI) GetSubAccPositionInfo(code currency.Pair, subUID int64) (SingleS } req["contract_code"] = codeValue req["sub_uid"] = subUID - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, huobiSwapSubAccPosInfo, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapSubAccPosInfo, nil, req, &resp) } // GetAccountFinancialRecords gets the account's financial records -func (h *HUOBI) GetAccountFinancialRecords(code currency.Pair, orderType string, createDate, pageIndex, pageSize int64) (FinancialRecordData, error) { +func (h *HUOBI) GetAccountFinancialRecords(ctx context.Context, code currency.Pair, orderType string, createDate, pageIndex, pageSize int64) (FinancialRecordData, error) { var resp FinancialRecordData req := make(map[string]interface{}) codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) @@ -519,11 +520,11 @@ func (h *HUOBI) GetAccountFinancialRecords(code currency.Pair, orderType string, if pageSize != 0 { req["page_size"] = pageSize } - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, huobiSwapFinancialRecords, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapFinancialRecords, nil, req, &resp) } // GetSwapSettlementRecords gets the swap account's settlement records -func (h *HUOBI) GetSwapSettlementRecords(code currency.Pair, startTime, endTime time.Time, pageIndex, pageSize int64) (FinancialRecordData, error) { +func (h *HUOBI) GetSwapSettlementRecords(ctx context.Context, code currency.Pair, startTime, endTime time.Time, pageIndex, pageSize int64) (FinancialRecordData, error) { var resp FinancialRecordData req := make(map[string]interface{}) codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) @@ -544,11 +545,11 @@ func (h *HUOBI) GetSwapSettlementRecords(code currency.Pair, startTime, endTime if pageSize != 0 { req["page_size"] = pageSize } - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, huobiSwapSettlementRecords, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapSettlementRecords, nil, req, &resp) } // GetAvailableLeverage gets user's available leverage data -func (h *HUOBI) GetAvailableLeverage(code currency.Pair) (AvailableLeverageData, error) { +func (h *HUOBI) GetAvailableLeverage(ctx context.Context, code currency.Pair) (AvailableLeverageData, error) { var resp AvailableLeverageData req := make(map[string]interface{}) if code != (currency.Pair{}) { @@ -558,11 +559,11 @@ func (h *HUOBI) GetAvailableLeverage(code currency.Pair) (AvailableLeverageData, } req["contract_code"] = codeValue } - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, huobiSwapAvailableLeverage, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapAvailableLeverage, nil, req, &resp) } // GetSwapOrderLimitInfo gets order limit info for swaps -func (h *HUOBI) GetSwapOrderLimitInfo(code currency.Pair, orderType string) (SwapOrderLimitInfo, error) { +func (h *HUOBI) GetSwapOrderLimitInfo(ctx context.Context, code currency.Pair, orderType string) (SwapOrderLimitInfo, error) { var resp SwapOrderLimitInfo req := make(map[string]interface{}) codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) @@ -574,11 +575,11 @@ func (h *HUOBI) GetSwapOrderLimitInfo(code currency.Pair, orderType string) (Swa return resp, fmt.Errorf("inavlid ordertype provided") } req["order_price_type"] = orderType - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, huobiSwapOrderLimitInfo, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapOrderLimitInfo, nil, req, &resp) } // GetSwapTradingFeeInfo gets trading fee info for swaps -func (h *HUOBI) GetSwapTradingFeeInfo(code currency.Pair) (SwapTradingFeeData, error) { +func (h *HUOBI) GetSwapTradingFeeInfo(ctx context.Context, code currency.Pair) (SwapTradingFeeData, error) { var resp SwapTradingFeeData req := make(map[string]interface{}) codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) @@ -586,11 +587,11 @@ func (h *HUOBI) GetSwapTradingFeeInfo(code currency.Pair) (SwapTradingFeeData, e return resp, err } req["contract_code"] = codeValue - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, huobiSwapTradingFeeInfo, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapTradingFeeInfo, nil, req, &resp) } // GetSwapTransferLimitInfo gets transfer limit info for swaps -func (h *HUOBI) GetSwapTransferLimitInfo(code currency.Pair) (TransferLimitData, error) { +func (h *HUOBI) GetSwapTransferLimitInfo(ctx context.Context, code currency.Pair) (TransferLimitData, error) { var resp TransferLimitData req := make(map[string]interface{}) codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) @@ -598,11 +599,11 @@ func (h *HUOBI) GetSwapTransferLimitInfo(code currency.Pair) (TransferLimitData, return resp, err } req["contract_code"] = codeValue - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, huobiSwapTransferLimitInfo, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapTransferLimitInfo, nil, req, &resp) } // GetSwapPositionLimitInfo gets transfer limit info for swaps -func (h *HUOBI) GetSwapPositionLimitInfo(code currency.Pair) (PositionLimitData, error) { +func (h *HUOBI) GetSwapPositionLimitInfo(ctx context.Context, code currency.Pair) (PositionLimitData, error) { var resp PositionLimitData req := make(map[string]interface{}) codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) @@ -610,11 +611,11 @@ func (h *HUOBI) GetSwapPositionLimitInfo(code currency.Pair) (PositionLimitData, return resp, err } req["contract_code"] = codeValue - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, huobiSwapPositionLimitInfo, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapPositionLimitInfo, nil, req, &resp) } // AccountTransferData gets asset transfer data between master and subaccounts -func (h *HUOBI) AccountTransferData(code currency.Pair, subUID, transferType string, amount float64) (InternalAccountTransferData, error) { +func (h *HUOBI) AccountTransferData(ctx context.Context, code currency.Pair, subUID, transferType string, amount float64) (InternalAccountTransferData, error) { var resp InternalAccountTransferData req := make(map[string]interface{}) codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) @@ -628,11 +629,11 @@ func (h *HUOBI) AccountTransferData(code currency.Pair, subUID, transferType str return resp, fmt.Errorf("inavlid transferType received") } req["type"] = transferType - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, huobiSwapInternalTransferData, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapInternalTransferData, nil, req, &resp) } // AccountTransferRecords gets asset transfer records between master and subaccounts -func (h *HUOBI) AccountTransferRecords(code currency.Pair, transferType string, createDate, pageIndex, pageSize int64) (InternalAccountTransferData, error) { +func (h *HUOBI) AccountTransferRecords(ctx context.Context, code currency.Pair, transferType string, createDate, pageIndex, pageSize int64) (InternalAccountTransferData, error) { var resp InternalAccountTransferData req := make(map[string]interface{}) codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) @@ -654,11 +655,11 @@ func (h *HUOBI) AccountTransferRecords(code currency.Pair, transferType string, if pageSize > 0 && pageSize <= 50 { req["page_size"] = pageSize } - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, huobiSwapInternalTransferRecords, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapInternalTransferRecords, nil, req, &resp) } // PlaceSwapOrders places orders for swaps -func (h *HUOBI) PlaceSwapOrders(code currency.Pair, clientOrderID, direction, offset, orderPriceType string, price, volume, leverage float64) (SwapOrderData, error) { +func (h *HUOBI) PlaceSwapOrders(ctx context.Context, code currency.Pair, clientOrderID, direction, offset, orderPriceType string, price, volume, leverage float64) (SwapOrderData, error) { var resp SwapOrderData req := make(map[string]interface{}) codeValue, err := h.FormatSymbol(code, asset.CoinMarginedFutures) @@ -678,11 +679,11 @@ func (h *HUOBI) PlaceSwapOrders(code currency.Pair, clientOrderID, direction, of req["price"] = price req["volume"] = volume req["lever_rate"] = leverage - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, huobiSwapPlaceOrder, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapPlaceOrder, nil, req, &resp) } // PlaceSwapBatchOrders places a batch of orders for swaps -func (h *HUOBI) PlaceSwapBatchOrders(data BatchOrderRequestType) (BatchOrderData, error) { +func (h *HUOBI) PlaceSwapBatchOrders(ctx context.Context, data BatchOrderRequestType) (BatchOrderData, error) { var resp BatchOrderData req := make(map[string]interface{}) if len(data.Data) > 10 || len(data.Data) == 0 { @@ -703,11 +704,11 @@ func (h *HUOBI) PlaceSwapBatchOrders(data BatchOrderRequestType) (BatchOrderData data.Data[x].ContractCode = codeValue } req["orders_data"] = data.Data - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, huobiSwapPlaceBatchOrder, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapPlaceBatchOrder, nil, req, &resp) } // CancelSwapOrder sends a request to cancel an order -func (h *HUOBI) CancelSwapOrder(orderID, clientOrderID string, contractCode currency.Pair) (CancelOrdersData, error) { +func (h *HUOBI) CancelSwapOrder(ctx context.Context, orderID, clientOrderID string, contractCode currency.Pair) (CancelOrdersData, error) { var resp CancelOrdersData req := make(map[string]interface{}) if orderID != "" { @@ -717,19 +718,19 @@ func (h *HUOBI) CancelSwapOrder(orderID, clientOrderID string, contractCode curr req["client_order_id"] = clientOrderID } req["contract_code"] = contractCode - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, huobiSwapCancelOrder, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapCancelOrder, nil, req, &resp) } // CancelAllSwapOrders sends a request to cancel an order -func (h *HUOBI) CancelAllSwapOrders(contractCode currency.Pair) (CancelOrdersData, error) { +func (h *HUOBI) CancelAllSwapOrders(ctx context.Context, contractCode currency.Pair) (CancelOrdersData, error) { var resp CancelOrdersData req := make(map[string]interface{}) req["contract_code"] = contractCode - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, huobiSwapCancelAllOrders, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapCancelAllOrders, nil, req, &resp) } // PlaceLightningCloseOrder places a lightning close order -func (h *HUOBI) PlaceLightningCloseOrder(contractCode currency.Pair, direction, orderPriceType string, volume float64, clientOrderID int64) (LightningCloseOrderData, error) { +func (h *HUOBI) PlaceLightningCloseOrder(ctx context.Context, contractCode currency.Pair, direction, orderPriceType string, volume float64, clientOrderID int64) (LightningCloseOrderData, error) { var resp LightningCloseOrderData req := make(map[string]interface{}) req["contract_code"] = contractCode @@ -744,11 +745,11 @@ func (h *HUOBI) PlaceLightningCloseOrder(contractCode currency.Pair, direction, } req["order_price_type"] = orderPriceType } - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, huobiSwapLightningCloseOrder, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapLightningCloseOrder, nil, req, &resp) } // GetSwapOrderDetails gets order info -func (h *HUOBI) GetSwapOrderDetails(contractCode currency.Pair, orderID, createdAt, orderType string, pageIndex, pageSize int64) (SwapOrderData, error) { +func (h *HUOBI) GetSwapOrderDetails(ctx context.Context, contractCode currency.Pair, orderID, createdAt, orderType string, pageIndex, pageSize int64) (SwapOrderData, error) { var resp SwapOrderData req := make(map[string]interface{}) req["contract_code"] = contractCode @@ -765,11 +766,11 @@ func (h *HUOBI) GetSwapOrderDetails(contractCode currency.Pair, orderID, created if pageSize > 0 && pageSize <= 50 { req["page_size"] = pageSize } - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, huobiSwapOrderDetails, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapOrderDetails, nil, req, &resp) } // GetSwapOrderInfo gets info on a swap order -func (h *HUOBI) GetSwapOrderInfo(contractCode currency.Pair, orderID, clientOrderID string) (SwapOrderInfo, error) { +func (h *HUOBI) GetSwapOrderInfo(ctx context.Context, contractCode currency.Pair, orderID, clientOrderID string) (SwapOrderInfo, error) { var resp SwapOrderInfo req := make(map[string]interface{}) if contractCode != (currency.Pair{}) { @@ -785,11 +786,11 @@ func (h *HUOBI) GetSwapOrderInfo(contractCode currency.Pair, orderID, clientOrde if clientOrderID != "" { req["client_order_id"] = clientOrderID } - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, huobiSwapOrderInfo, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapOrderInfo, nil, req, &resp) } // GetSwapOpenOrders gets open orders for swap -func (h *HUOBI) GetSwapOpenOrders(contractCode currency.Pair, pageIndex, pageSize int64) (SwapOpenOrdersData, error) { +func (h *HUOBI) GetSwapOpenOrders(ctx context.Context, contractCode currency.Pair, pageIndex, pageSize int64) (SwapOpenOrdersData, error) { var resp SwapOpenOrdersData req := make(map[string]interface{}) codeValue, err := h.FormatSymbol(contractCode, asset.CoinMarginedFutures) @@ -803,11 +804,11 @@ func (h *HUOBI) GetSwapOpenOrders(contractCode currency.Pair, pageIndex, pageSiz if pageSize > 0 && pageSize <= 50 { req["page_size"] = pageSize } - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, huobiSwapOpenOrders, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapOpenOrders, nil, req, &resp) } // GetSwapOrderHistory gets swap order history -func (h *HUOBI) GetSwapOrderHistory(contractCode currency.Pair, tradeType, reqType string, status []order.Status, createDate, pageIndex, pageSize int64) (SwapOrderHistory, error) { +func (h *HUOBI) GetSwapOrderHistory(ctx context.Context, contractCode currency.Pair, tradeType, reqType string, status []order.Status, createDate, pageIndex, pageSize int64) (SwapOrderHistory, error) { var resp SwapOrderHistory req := make(map[string]interface{}) codeValue, err := h.FormatSymbol(contractCode, asset.CoinMarginedFutures) @@ -852,11 +853,11 @@ func (h *HUOBI) GetSwapOrderHistory(contractCode currency.Pair, tradeType, reqTy if pageSize != 0 { req["page_size"] = pageSize } - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, huobiSwapOrderHistory, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapOrderHistory, nil, req, &resp) } // GetSwapTradeHistory gets swap trade history -func (h *HUOBI) GetSwapTradeHistory(contractCode currency.Pair, tradeType string, createDate, pageIndex, pageSize int64) (AccountTradeHistoryData, error) { +func (h *HUOBI) GetSwapTradeHistory(ctx context.Context, contractCode currency.Pair, tradeType string, createDate, pageIndex, pageSize int64) (AccountTradeHistoryData, error) { var resp AccountTradeHistoryData req := make(map[string]interface{}) codeValue, err := h.FormatSymbol(contractCode, asset.CoinMarginedFutures) @@ -879,11 +880,11 @@ func (h *HUOBI) GetSwapTradeHistory(contractCode currency.Pair, tradeType string if pageSize > 0 && pageSize <= 50 { req["page_size"] = pageSize } - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, huobiSwapTradeHistory, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapTradeHistory, nil, req, &resp) } // PlaceSwapTriggerOrder places a trigger order for a swap -func (h *HUOBI) PlaceSwapTriggerOrder(contractCode currency.Pair, triggerType, direction, offset, orderPriceType string, triggerPrice, orderPrice, volume, leverageRate float64) (AccountTradeHistoryData, error) { +func (h *HUOBI) PlaceSwapTriggerOrder(ctx context.Context, contractCode currency.Pair, triggerType, direction, offset, orderPriceType string, triggerPrice, orderPrice, volume, leverageRate float64) (AccountTradeHistoryData, error) { var resp AccountTradeHistoryData req := make(map[string]interface{}) codeValue, err := h.FormatSymbol(contractCode, asset.CoinMarginedFutures) @@ -906,20 +907,20 @@ func (h *HUOBI) PlaceSwapTriggerOrder(contractCode currency.Pair, triggerType, d return resp, fmt.Errorf("invalid order price type") } req["order_price_type"] = orderPriceType - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, huobiSwapTriggerOrder, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapTriggerOrder, nil, req, &resp) } // CancelSwapTriggerOrder cancels swap trigger order -func (h *HUOBI) CancelSwapTriggerOrder(contractCode currency.Pair, orderID string) (CancelTriggerOrdersData, error) { +func (h *HUOBI) CancelSwapTriggerOrder(ctx context.Context, contractCode currency.Pair, orderID string) (CancelTriggerOrdersData, error) { var resp CancelTriggerOrdersData req := make(map[string]interface{}) req["contract_code"] = contractCode req["order_id"] = orderID - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, huobiSwapCancelTriggerOrder, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapCancelTriggerOrder, nil, req, &resp) } // CancelAllSwapTriggerOrders cancels all swap trigger orders -func (h *HUOBI) CancelAllSwapTriggerOrders(contractCode currency.Pair) (CancelTriggerOrdersData, error) { +func (h *HUOBI) CancelAllSwapTriggerOrders(ctx context.Context, contractCode currency.Pair) (CancelTriggerOrdersData, error) { var resp CancelTriggerOrdersData req := make(map[string]interface{}) codeValue, err := h.FormatSymbol(contractCode, asset.CoinMarginedFutures) @@ -927,11 +928,11 @@ func (h *HUOBI) CancelAllSwapTriggerOrders(contractCode currency.Pair) (CancelTr return resp, err } req["contract_code"] = codeValue - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, huobiSwapCancelAllTriggerOrders, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapCancelAllTriggerOrders, nil, req, &resp) } // GetSwapTriggerOrderHistory gets history for swap trigger orders -func (h *HUOBI) GetSwapTriggerOrderHistory(contractCode currency.Pair, status, tradeType string, createDate, pageIndex, pageSize int64) (TriggerOrderHistory, error) { +func (h *HUOBI) GetSwapTriggerOrderHistory(ctx context.Context, contractCode currency.Pair, status, tradeType string, createDate, pageIndex, pageSize int64) (TriggerOrderHistory, error) { var resp TriggerOrderHistory req := make(map[string]interface{}) codeValue, err := h.FormatSymbol(contractCode, asset.CoinMarginedFutures) @@ -955,11 +956,11 @@ func (h *HUOBI) GetSwapTriggerOrderHistory(contractCode currency.Pair, status, t if pageSize > 0 && pageSize <= 50 { req["page_size"] = pageSize } - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, huobiSwapTriggerOrderHistory, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, huobiSwapTriggerOrderHistory, nil, req, &resp) } // GetSwapMarkets gets data of swap markets -func (h *HUOBI) GetSwapMarkets(contract currency.Pair) ([]SwapMarketsData, error) { +func (h *HUOBI) GetSwapMarkets(ctx context.Context, contract currency.Pair) ([]SwapMarketsData, error) { vals := url.Values{} if contract != (currency.Pair{}) { codeValue, err := h.FormatSymbol(contract, asset.CoinMarginedFutures) @@ -973,7 +974,7 @@ func (h *HUOBI) GetSwapMarkets(contract currency.Pair) ([]SwapMarketsData, error Data []SwapMarketsData `json:"data"` } var result response - err := h.SendHTTPRequest(exchange.RestFutures, huobiSwapMarkets+vals.Encode(), &result) + err := h.SendHTTPRequest(ctx, exchange.RestFutures, huobiSwapMarkets+vals.Encode(), &result) if result.ErrorMessage != "" { return nil, errors.New(result.ErrorMessage) } @@ -981,7 +982,7 @@ func (h *HUOBI) GetSwapMarkets(contract currency.Pair) ([]SwapMarketsData, error } // GetSwapFundingRates gets funding rates data -func (h *HUOBI) GetSwapFundingRates(contract currency.Pair) (FundingRatesData, error) { +func (h *HUOBI) GetSwapFundingRates(ctx context.Context, contract currency.Pair) (FundingRatesData, error) { vals := url.Values{} codeValue, err := h.FormatSymbol(contract, asset.CoinMarginedFutures) if err != nil { @@ -993,7 +994,7 @@ func (h *HUOBI) GetSwapFundingRates(contract currency.Pair) (FundingRatesData, e Data FundingRatesData `json:"data"` } var result response - err = h.SendHTTPRequest(exchange.RestFutures, huobiSwapFunding+vals.Encode(), &result) + err = h.SendHTTPRequest(ctx, exchange.RestFutures, huobiSwapFunding+vals.Encode(), &result) if result.ErrorMessage != "" { return FundingRatesData{}, errors.New(result.ErrorMessage) } diff --git a/exchanges/huobi/huobi_futures.go b/exchanges/huobi/huobi_futures.go index 7abcf89b..564a54af 100644 --- a/exchanges/huobi/huobi_futures.go +++ b/exchanges/huobi/huobi_futures.go @@ -78,7 +78,7 @@ const ( ) // FGetContractInfo gets contract info for futures -func (h *HUOBI) FGetContractInfo(symbol, contractType string, code currency.Pair) (FContractInfoData, error) { +func (h *HUOBI) FGetContractInfo(ctx context.Context, symbol, contractType string, code currency.Pair) (FContractInfoData, error) { var resp FContractInfoData params := url.Values{} if symbol != "" { @@ -98,11 +98,11 @@ func (h *HUOBI) FGetContractInfo(symbol, contractType string, code currency.Pair params.Set("contract_code", codeValue) } path := fContractInfo + params.Encode() - return resp, h.SendHTTPRequest(exchange.RestFutures, path, &resp) + return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // FIndexPriceInfo gets index price info for a futures contract -func (h *HUOBI) FIndexPriceInfo(symbol currency.Code) (FContractIndexPriceInfo, error) { +func (h *HUOBI) FIndexPriceInfo(ctx context.Context, symbol currency.Code) (FContractIndexPriceInfo, error) { var resp FContractIndexPriceInfo params := url.Values{} if symbol != (currency.Code{}) { @@ -113,11 +113,11 @@ func (h *HUOBI) FIndexPriceInfo(symbol currency.Code) (FContractIndexPriceInfo, params.Set("symbol", codeValue) } path := fContractIndexPrice + params.Encode() - return resp, h.SendHTTPRequest(exchange.RestFutures, path, &resp) + return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // FContractPriceLimitations gets price limits for a futures contract -func (h *HUOBI) FContractPriceLimitations(symbol, contractType string, code currency.Pair) (FContractIndexPriceInfo, error) { +func (h *HUOBI) FContractPriceLimitations(ctx context.Context, symbol, contractType string, code currency.Pair) (FContractIndexPriceInfo, error) { var resp FContractIndexPriceInfo params := url.Values{} if symbol != "" { @@ -137,11 +137,11 @@ func (h *HUOBI) FContractPriceLimitations(symbol, contractType string, code curr params.Set("contract_code", codeValue) } path := fContractPriceLimitation + params.Encode() - return resp, h.SendHTTPRequest(exchange.RestFutures, path, &resp) + return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // FContractOpenInterest gets open interest data for futures contracts -func (h *HUOBI) FContractOpenInterest(symbol, contractType string, code currency.Pair) (FContractOIData, error) { +func (h *HUOBI) FContractOpenInterest(ctx context.Context, symbol, contractType string, code currency.Pair) (FContractOIData, error) { var resp FContractOIData params := url.Values{} if symbol != "" { @@ -161,11 +161,11 @@ func (h *HUOBI) FContractOpenInterest(symbol, contractType string, code currency params.Set("contract_code", codeValue) } path := fContractOpenInterest + params.Encode() - return resp, h.SendHTTPRequest(exchange.RestFutures, path, &resp) + return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // FGetEstimatedDeliveryPrice gets estimated delivery price info for futures -func (h *HUOBI) FGetEstimatedDeliveryPrice(symbol currency.Code) (FEstimatedDeliveryPriceInfo, error) { +func (h *HUOBI) FGetEstimatedDeliveryPrice(ctx context.Context, symbol currency.Code) (FEstimatedDeliveryPriceInfo, error) { var resp FEstimatedDeliveryPriceInfo params := url.Values{} codeValue, err := h.formatFuturesCode(symbol) @@ -174,11 +174,11 @@ func (h *HUOBI) FGetEstimatedDeliveryPrice(symbol currency.Code) (FEstimatedDeli } params.Set("symbol", codeValue) path := fEstimatedDeliveryPrice + params.Encode() - return resp, h.SendHTTPRequest(exchange.RestFutures, path, &resp) + return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // FGetMarketDepth gets market depth data for futures contracts -func (h *HUOBI) FGetMarketDepth(symbol currency.Pair, dataType string) (OBData, error) { +func (h *HUOBI) FGetMarketDepth(ctx context.Context, symbol currency.Pair, dataType string) (OBData, error) { var resp OBData var tempData FMarketDepth params := url.Values{} @@ -189,7 +189,7 @@ func (h *HUOBI) FGetMarketDepth(symbol currency.Pair, dataType string) (OBData, params.Set("symbol", symbolValue) params.Set("type", dataType) path := fContractMarketDepth + params.Encode() - err = h.SendHTTPRequest(exchange.RestFutures, path, &tempData) + err = h.SendHTTPRequest(ctx, exchange.RestFutures, path, &tempData) if err != nil { return resp, err } @@ -210,7 +210,7 @@ func (h *HUOBI) FGetMarketDepth(symbol currency.Pair, dataType string) (OBData, } // FGetKlineData gets kline data for futures -func (h *HUOBI) FGetKlineData(symbol currency.Pair, period string, size int64, startTime, endTime time.Time) (FKlineData, error) { +func (h *HUOBI) FGetKlineData(ctx context.Context, symbol currency.Pair, period string, size int64, startTime, endTime time.Time) (FKlineData, error) { var resp FKlineData params := url.Values{} symbolValue, err := h.FormatSymbol(symbol, asset.Futures) @@ -234,11 +234,11 @@ func (h *HUOBI) FGetKlineData(symbol currency.Pair, period string, size int64, s params.Set("end_time", strconv.FormatInt(endTime.Unix(), 10)) } path := fContractKline + params.Encode() - return resp, h.SendHTTPRequest(exchange.RestFutures, path, &resp) + return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // FGetMarketOverviewData gets market overview data for futures -func (h *HUOBI) FGetMarketOverviewData(symbol currency.Pair) (FMarketOverviewData, error) { +func (h *HUOBI) FGetMarketOverviewData(ctx context.Context, symbol currency.Pair) (FMarketOverviewData, error) { var resp FMarketOverviewData params := url.Values{} symbolValue, err := h.FormatSymbol(symbol, asset.Futures) @@ -247,11 +247,11 @@ func (h *HUOBI) FGetMarketOverviewData(symbol currency.Pair) (FMarketOverviewDat } params.Set("symbol", symbolValue) path := fMarketOverview + params.Encode() - return resp, h.SendHTTPRequest(exchange.RestFutures, path, &resp) + return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // FLastTradeData gets last trade data for a futures contract -func (h *HUOBI) FLastTradeData(symbol currency.Pair) (FLastTradeData, error) { +func (h *HUOBI) FLastTradeData(ctx context.Context, symbol currency.Pair) (FLastTradeData, error) { var resp FLastTradeData params := url.Values{} symbolValue, err := h.FormatSymbol(symbol, asset.Futures) @@ -260,11 +260,11 @@ func (h *HUOBI) FLastTradeData(symbol currency.Pair) (FLastTradeData, error) { } params.Set("symbol", symbolValue) path := fLastTradeContract + params.Encode() - return resp, h.SendHTTPRequest(exchange.RestFutures, path, &resp) + return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // FRequestPublicBatchTrades gets public batch trades for a futures contract -func (h *HUOBI) FRequestPublicBatchTrades(symbol currency.Pair, size int64) (FBatchTradesForContractData, error) { +func (h *HUOBI) FRequestPublicBatchTrades(ctx context.Context, symbol currency.Pair, size int64) (FBatchTradesForContractData, error) { var resp FBatchTradesForContractData params := url.Values{} symbolValue, err := h.FormatSymbol(symbol, asset.Futures) @@ -276,11 +276,11 @@ func (h *HUOBI) FRequestPublicBatchTrades(symbol currency.Pair, size int64) (FBa params.Set("size", strconv.FormatInt(size, 10)) } path := fContractBatchTradeRecords + params.Encode() - return resp, h.SendHTTPRequest(exchange.RestFutures, path, &resp) + return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // FQueryInsuranceAndClawbackData gets insurance and clawback data for a futures contract -func (h *HUOBI) FQueryInsuranceAndClawbackData(symbol currency.Code) (FClawbackRateAndInsuranceData, error) { +func (h *HUOBI) FQueryInsuranceAndClawbackData(ctx context.Context, symbol currency.Code) (FClawbackRateAndInsuranceData, error) { var resp FClawbackRateAndInsuranceData params := url.Values{} if symbol != (currency.Code{}) { @@ -291,11 +291,11 @@ func (h *HUOBI) FQueryInsuranceAndClawbackData(symbol currency.Code) (FClawbackR params.Set("symbol", codeValue) } path := fInsuranceAndClawback + params.Encode() - return resp, h.SendHTTPRequest(exchange.RestFutures, path, &resp) + return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // FQueryHistoricalInsuranceData gets insurance data -func (h *HUOBI) FQueryHistoricalInsuranceData(symbol currency.Code) (FHistoricalInsuranceRecordsData, error) { +func (h *HUOBI) FQueryHistoricalInsuranceData(ctx context.Context, symbol currency.Code) (FHistoricalInsuranceRecordsData, error) { var resp FHistoricalInsuranceRecordsData params := url.Values{} if symbol != (currency.Code{}) { @@ -306,11 +306,11 @@ func (h *HUOBI) FQueryHistoricalInsuranceData(symbol currency.Code) (FHistorical params.Set("symbol", codeValue) } path := fInsuranceBalanceHistory + params.Encode() - return resp, h.SendHTTPRequest(exchange.RestFutures, path, &resp) + return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // FQueryTieredAdjustmentFactor gets tiered adjustment factor for futures contracts -func (h *HUOBI) FQueryTieredAdjustmentFactor(symbol currency.Code) (FTieredAdjustmentFactorInfo, error) { +func (h *HUOBI) FQueryTieredAdjustmentFactor(ctx context.Context, symbol currency.Code) (FTieredAdjustmentFactorInfo, error) { var resp FTieredAdjustmentFactorInfo params := url.Values{} if symbol != (currency.Code{}) { @@ -321,11 +321,11 @@ func (h *HUOBI) FQueryTieredAdjustmentFactor(symbol currency.Code) (FTieredAdjus params.Set("symbol", codeValue) } path := fTieredAdjustmentFactor + params.Encode() - return resp, h.SendHTTPRequest(exchange.RestFutures, path, &resp) + return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // FQueryHisOpenInterest gets open interest for futures contract -func (h *HUOBI) FQueryHisOpenInterest(symbol, contractType, period, amountType string, size int64) (FOIData, error) { +func (h *HUOBI) FQueryHisOpenInterest(ctx context.Context, symbol, contractType, period, amountType string, size int64) (FOIData, error) { var resp FOIData params := url.Values{} if symbol != "" { @@ -348,11 +348,11 @@ func (h *HUOBI) FQueryHisOpenInterest(symbol, contractType, period, amountType s } params.Set("amount_type", strconv.FormatInt(validAmount, 10)) path := fHisContractOpenInterest + params.Encode() - return resp, h.SendHTTPRequest(exchange.RestFutures, path, &resp) + return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // FQuerySystemStatus gets system status data -func (h *HUOBI) FQuerySystemStatus(symbol currency.Code) (FContractOIData, error) { +func (h *HUOBI) FQuerySystemStatus(ctx context.Context, symbol currency.Code) (FContractOIData, error) { var resp FContractOIData params := url.Values{} if symbol != (currency.Code{}) { @@ -363,11 +363,11 @@ func (h *HUOBI) FQuerySystemStatus(symbol currency.Code) (FContractOIData, error params.Set("symbol", codeValue) } path := fSystemStatus + params.Encode() - return resp, h.SendHTTPRequest(exchange.RestFutures, path, &resp) + return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // FQueryTopAccountsRatio gets top accounts' ratio -func (h *HUOBI) FQueryTopAccountsRatio(symbol, period string) (FTopAccountsLongShortRatio, error) { +func (h *HUOBI) FQueryTopAccountsRatio(ctx context.Context, symbol, period string) (FTopAccountsLongShortRatio, error) { var resp FTopAccountsLongShortRatio params := url.Values{} if symbol != "" { @@ -378,11 +378,11 @@ func (h *HUOBI) FQueryTopAccountsRatio(symbol, period string) (FTopAccountsLongS } params.Set("period", period) path := fTopAccountsSentiment + params.Encode() - return resp, h.SendHTTPRequest(exchange.RestFutures, path, &resp) + return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // FQueryTopPositionsRatio gets top positions' long/short ratio for futures -func (h *HUOBI) FQueryTopPositionsRatio(symbol, period string) (FTopPositionsLongShortRatio, error) { +func (h *HUOBI) FQueryTopPositionsRatio(ctx context.Context, symbol, period string) (FTopPositionsLongShortRatio, error) { var resp FTopPositionsLongShortRatio params := url.Values{} if symbol != "" { @@ -393,11 +393,11 @@ func (h *HUOBI) FQueryTopPositionsRatio(symbol, period string) (FTopPositionsLon } params.Set("period", period) path := fTopPositionsSentiment + params.Encode() - return resp, h.SendHTTPRequest(exchange.RestFutures, path, &resp) + return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // FLiquidationOrders gets liquidation orders for futures contracts -func (h *HUOBI) FLiquidationOrders(symbol, tradeType string, pageIndex, pageSize, createDate int64) (FLiquidationOrdersInfo, error) { +func (h *HUOBI) FLiquidationOrders(ctx context.Context, symbol, tradeType string, pageIndex, pageSize, createDate int64) (FLiquidationOrdersInfo, error) { var resp FLiquidationOrdersInfo params := url.Values{} params.Set("symbol", symbol) @@ -417,11 +417,11 @@ func (h *HUOBI) FLiquidationOrders(symbol, tradeType string, pageIndex, pageSize params.Set("page_size", strconv.FormatInt(pageIndex, 10)) } path := fLiquidationOrders + params.Encode() - return resp, h.SendHTTPRequest(exchange.RestFutures, path, &resp) + return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // FIndexKline gets index kline data for futures contracts -func (h *HUOBI) FIndexKline(symbol currency.Pair, period string, size int64) (FIndexKlineData, error) { +func (h *HUOBI) FIndexKline(ctx context.Context, symbol currency.Pair, period string, size int64) (FIndexKlineData, error) { var resp FIndexKlineData params := url.Values{} symbolValue, err := h.FormatSymbol(symbol, asset.Futures) @@ -438,11 +438,11 @@ func (h *HUOBI) FIndexKline(symbol currency.Pair, period string, size int64) (FI } params.Set("size", strconv.FormatInt(size, 10)) path := fIndexKline + params.Encode() - return resp, h.SendHTTPRequest(exchange.RestFutures, path, &resp) + return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // FGetBasisData gets basis data futures contracts -func (h *HUOBI) FGetBasisData(symbol currency.Pair, period, basisPriceType string, size int64) (FBasisData, error) { +func (h *HUOBI) FGetBasisData(ctx context.Context, symbol currency.Pair, period, basisPriceType string, size int64) (FBasisData, error) { var resp FBasisData params := url.Values{} symbolValue, err := h.FormatSymbol(symbol, asset.Futures) @@ -463,11 +463,11 @@ func (h *HUOBI) FGetBasisData(symbol currency.Pair, period, basisPriceType strin params.Set("size", strconv.FormatInt(size, 10)) } path := fBasisData + params.Encode() - return resp, h.SendHTTPRequest(exchange.RestFutures, path, &resp) + return resp, h.SendHTTPRequest(ctx, exchange.RestFutures, path, &resp) } // FGetAccountInfo gets user info for futures account -func (h *HUOBI) FGetAccountInfo(symbol currency.Code) (FUserAccountData, error) { +func (h *HUOBI) FGetAccountInfo(ctx context.Context, symbol currency.Code) (FUserAccountData, error) { var resp FUserAccountData req := make(map[string]interface{}) if symbol != (currency.Code{}) { @@ -477,11 +477,11 @@ func (h *HUOBI) FGetAccountInfo(symbol currency.Code) (FUserAccountData, error) } req["symbol"] = codeValue } - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, fAccountData, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fAccountData, nil, req, &resp) } // FGetPositionsInfo gets positions info for futures account -func (h *HUOBI) FGetPositionsInfo(symbol currency.Code) (FUserAccountData, error) { +func (h *HUOBI) FGetPositionsInfo(ctx context.Context, symbol currency.Code) (FUserAccountData, error) { var resp FUserAccountData req := make(map[string]interface{}) if symbol != (currency.Code{}) { @@ -491,11 +491,11 @@ func (h *HUOBI) FGetPositionsInfo(symbol currency.Code) (FUserAccountData, error } req["symbol"] = codeValue } - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, fPositionInformation, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fPositionInformation, nil, req, &resp) } // FGetAllSubAccountAssets gets assets info for all futures subaccounts -func (h *HUOBI) FGetAllSubAccountAssets(symbol currency.Code) (FSubAccountAssetsInfo, error) { +func (h *HUOBI) FGetAllSubAccountAssets(ctx context.Context, symbol currency.Code) (FSubAccountAssetsInfo, error) { var resp FSubAccountAssetsInfo req := make(map[string]interface{}) if symbol != (currency.Code{}) { @@ -505,33 +505,33 @@ func (h *HUOBI) FGetAllSubAccountAssets(symbol currency.Code) (FSubAccountAssets } req["symbol"] = codeValue } - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, fAllSubAccountAssets, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fAllSubAccountAssets, nil, req, &resp) } // FGetSingleSubAccountInfo gets assets info for a futures subaccount -func (h *HUOBI) FGetSingleSubAccountInfo(symbol, subUID string) (FSingleSubAccountAssetsInfo, error) { +func (h *HUOBI) FGetSingleSubAccountInfo(ctx context.Context, symbol, subUID string) (FSingleSubAccountAssetsInfo, error) { var resp FSingleSubAccountAssetsInfo req := make(map[string]interface{}) if symbol != "" { req["symbol"] = symbol } req["sub_uid"] = subUID - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, fSingleSubAccountAssets, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fSingleSubAccountAssets, nil, req, &resp) } // FGetSingleSubPositions gets positions info for a single sub account -func (h *HUOBI) FGetSingleSubPositions(symbol, subUID string) (FSingleSubAccountPositionsInfo, error) { +func (h *HUOBI) FGetSingleSubPositions(ctx context.Context, symbol, subUID string) (FSingleSubAccountPositionsInfo, error) { var resp FSingleSubAccountPositionsInfo req := make(map[string]interface{}) if symbol != "" { req["symbol"] = symbol } req["sub_uid"] = subUID - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, fSingleSubAccountPositions, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fSingleSubAccountPositions, nil, req, &resp) } // FGetFinancialRecords gets financial records for futures -func (h *HUOBI) FGetFinancialRecords(symbol, recordType string, createDate, pageIndex, pageSize int64) (FFinancialRecords, error) { +func (h *HUOBI) FGetFinancialRecords(ctx context.Context, symbol, recordType string, createDate, pageIndex, pageSize int64) (FFinancialRecords, error) { var resp FFinancialRecords req := make(map[string]interface{}) if symbol != "" { @@ -553,11 +553,11 @@ func (h *HUOBI) FGetFinancialRecords(symbol, recordType string, createDate, page if pageSize != 0 { req["page_size"] = pageSize } - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, fFinancialRecords, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fFinancialRecords, nil, req, &resp) } // FGetSettlementRecords gets settlement records for futures -func (h *HUOBI) FGetSettlementRecords(symbol currency.Code, pageIndex, pageSize int64, startTime, endTime time.Time) (FSettlementRecords, error) { +func (h *HUOBI) FGetSettlementRecords(ctx context.Context, symbol currency.Code, pageIndex, pageSize int64, startTime, endTime time.Time) (FSettlementRecords, error) { var resp FSettlementRecords req := make(map[string]interface{}) req["symbol"] = symbol @@ -574,11 +574,11 @@ func (h *HUOBI) FGetSettlementRecords(symbol currency.Code, pageIndex, pageSize req["start_time"] = strconv.FormatInt(startTime.Unix()*1000, 10) req["end_time"] = strconv.FormatInt(endTime.Unix()*1000, 10) } - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, fSettlementRecords, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fSettlementRecords, nil, req, &resp) } // FGetOrderLimits gets order limits for futures contracts -func (h *HUOBI) FGetOrderLimits(symbol, orderPriceType string) (FContractInfoOnOrderLimit, error) { +func (h *HUOBI) FGetOrderLimits(ctx context.Context, symbol, orderPriceType string) (FContractInfoOnOrderLimit, error) { var resp FContractInfoOnOrderLimit req := make(map[string]interface{}) if symbol != "" { @@ -590,11 +590,11 @@ func (h *HUOBI) FGetOrderLimits(symbol, orderPriceType string) (FContractInfoOnO } req["order_price_type"] = orderPriceType } - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, fOrderLimitInfo, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fOrderLimitInfo, nil, req, &resp) } // FContractTradingFee gets futures contract trading fees -func (h *HUOBI) FContractTradingFee(symbol currency.Code) (FContractTradingFeeData, error) { +func (h *HUOBI) FContractTradingFee(ctx context.Context, symbol currency.Code) (FContractTradingFeeData, error) { var resp FContractTradingFeeData req := make(map[string]interface{}) if symbol != (currency.Code{}) { @@ -604,11 +604,11 @@ func (h *HUOBI) FContractTradingFee(symbol currency.Code) (FContractTradingFeeDa } req["symbol"] = codeValue } - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, fContractTradingFee, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fContractTradingFee, nil, req, &resp) } // FGetTransferLimits gets transfer limits for futures -func (h *HUOBI) FGetTransferLimits(symbol currency.Code) (FTransferLimitData, error) { +func (h *HUOBI) FGetTransferLimits(ctx context.Context, symbol currency.Code) (FTransferLimitData, error) { var resp FTransferLimitData req := make(map[string]interface{}) if symbol != (currency.Code{}) { @@ -618,11 +618,11 @@ func (h *HUOBI) FGetTransferLimits(symbol currency.Code) (FTransferLimitData, er } req["symbol"] = codeValue } - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, fTransferLimitInfo, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fTransferLimitInfo, nil, req, &resp) } // FGetPositionLimits gets position limits for futures -func (h *HUOBI) FGetPositionLimits(symbol currency.Code) (FPositionLimitData, error) { +func (h *HUOBI) FGetPositionLimits(ctx context.Context, symbol currency.Code) (FPositionLimitData, error) { var resp FPositionLimitData req := make(map[string]interface{}) if symbol != (currency.Code{}) { @@ -632,19 +632,19 @@ func (h *HUOBI) FGetPositionLimits(symbol currency.Code) (FPositionLimitData, er } req["symbol"] = codeValue } - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, fPositionLimitInfo, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fPositionLimitInfo, nil, req, &resp) } // FGetAssetsAndPositions gets assets and positions for futures -func (h *HUOBI) FGetAssetsAndPositions(symbol currency.Code) (FAssetsAndPositionsData, error) { +func (h *HUOBI) FGetAssetsAndPositions(ctx context.Context, symbol currency.Code) (FAssetsAndPositionsData, error) { var resp FAssetsAndPositionsData req := make(map[string]interface{}) req["symbol"] = symbol - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, fQueryAssetsAndPositions, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fQueryAssetsAndPositions, nil, req, &resp) } // FTransfer transfers assets between master and subaccounts -func (h *HUOBI) FTransfer(subUID, symbol, transferType string, amount float64) (FAccountTransferData, error) { +func (h *HUOBI) FTransfer(ctx context.Context, subUID, symbol, transferType string, amount float64) (FAccountTransferData, error) { var resp FAccountTransferData req := make(map[string]interface{}) req["symbol"] = symbol @@ -654,11 +654,11 @@ func (h *HUOBI) FTransfer(subUID, symbol, transferType string, amount float64) ( return resp, fmt.Errorf("inavlid transferType received") } req["type"] = transferType - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, fTransfer, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fTransfer, nil, req, &resp) } // FGetTransferRecords gets transfer records data for futures -func (h *HUOBI) FGetTransferRecords(symbol, transferType string, createDate, pageIndex, pageSize int64) (FTransferRecords, error) { +func (h *HUOBI) FGetTransferRecords(ctx context.Context, symbol, transferType string, createDate, pageIndex, pageSize int64) (FTransferRecords, error) { var resp FTransferRecords req := make(map[string]interface{}) if symbol != "" { @@ -678,11 +678,11 @@ func (h *HUOBI) FGetTransferRecords(symbol, transferType string, createDate, pag if pageSize > 0 && pageSize <= 50 { req["page_size"] = pageSize } - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, fTransferRecords, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fTransferRecords, nil, req, &resp) } // FGetAvailableLeverage gets available leverage data for futures -func (h *HUOBI) FGetAvailableLeverage(symbol currency.Code) (FAvailableLeverageData, error) { +func (h *HUOBI) FGetAvailableLeverage(ctx context.Context, symbol currency.Code) (FAvailableLeverageData, error) { var resp FAvailableLeverageData req := make(map[string]interface{}) if symbol != (currency.Code{}) { @@ -692,11 +692,11 @@ func (h *HUOBI) FGetAvailableLeverage(symbol currency.Code) (FAvailableLeverageD } req["symbol"] = codeValue } - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, fAvailableLeverage, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fAvailableLeverage, nil, req, &resp) } // FOrder places an order for futures -func (h *HUOBI) FOrder(contractCode currency.Pair, symbol, contractType, clientOrderID, direction, offset, orderPriceType string, price, volume, leverageRate float64) (FOrderData, error) { +func (h *HUOBI) FOrder(ctx context.Context, contractCode currency.Pair, symbol, contractType, clientOrderID, direction, offset, orderPriceType string, price, volume, leverageRate float64) (FOrderData, error) { var resp FOrderData req := make(map[string]interface{}) if symbol != "" { @@ -730,11 +730,11 @@ func (h *HUOBI) FOrder(contractCode currency.Pair, symbol, contractType, clientO req["volume"] = volume req["price"] = price req["offset"] = offset - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, fOrder, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fOrder, nil, req, &resp) } // FPlaceBatchOrder places a batch of orders for futures -func (h *HUOBI) FPlaceBatchOrder(data []fBatchOrderData) (FBatchOrderResponse, error) { +func (h *HUOBI) FPlaceBatchOrder(ctx context.Context, data []fBatchOrderData) (FBatchOrderResponse, error) { var resp FBatchOrderResponse req := make(map[string]interface{}) if len(data) > 10 || len(data) == 0 { @@ -765,11 +765,11 @@ func (h *HUOBI) FPlaceBatchOrder(data []fBatchOrderData) (FBatchOrderResponse, e } } req["orders_data"] = data - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, fBatchOrder, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fBatchOrder, nil, req, &resp) } // FCancelOrder cancels a futures order -func (h *HUOBI) FCancelOrder(symbol, orderID, clientOrderID string) (FCancelOrderData, error) { +func (h *HUOBI) FCancelOrder(ctx context.Context, symbol, orderID, clientOrderID string) (FCancelOrderData, error) { var resp FCancelOrderData req := make(map[string]interface{}) if symbol != "" { @@ -781,11 +781,11 @@ func (h *HUOBI) FCancelOrder(symbol, orderID, clientOrderID string) (FCancelOrde if clientOrderID != "" { req["client_order_id"] = clientOrderID } - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, fCancelOrder, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fCancelOrder, nil, req, &resp) } // FCancelAllOrders cancels all futures order for a given symbol -func (h *HUOBI) FCancelAllOrders(contractCode currency.Pair, symbol, contractType string) (FCancelOrderData, error) { +func (h *HUOBI) FCancelAllOrders(ctx context.Context, contractCode currency.Pair, symbol, contractType string) (FCancelOrderData, error) { var resp FCancelOrderData req := make(map[string]interface{}) if symbol != "" { @@ -804,11 +804,11 @@ func (h *HUOBI) FCancelAllOrders(contractCode currency.Pair, symbol, contractTyp } req["contract_code"] = codeValue } - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, fCancelAllOrders, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fCancelAllOrders, nil, req, &resp) } // FFlashCloseOrder flash closes a futures order -func (h *HUOBI) FFlashCloseOrder(contractCode currency.Pair, symbol, contractType, direction, orderPriceType, clientOrderID string, volume float64) (FOrderData, error) { +func (h *HUOBI) FFlashCloseOrder(ctx context.Context, contractCode currency.Pair, symbol, contractType, direction, orderPriceType, clientOrderID string, volume float64) (FOrderData, error) { var resp FOrderData req := make(map[string]interface{}) req["symbol"] = symbol @@ -836,11 +836,11 @@ func (h *HUOBI) FFlashCloseOrder(contractCode currency.Pair, symbol, contractTyp } req["orderPriceType"] = orderPriceType } - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, fFlashCloseOrder, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fFlashCloseOrder, nil, req, &resp) } // FGetOrderInfo gets order info for futures -func (h *HUOBI) FGetOrderInfo(symbol, clientOrderID, orderID string) (FOrderInfo, error) { +func (h *HUOBI) FGetOrderInfo(ctx context.Context, symbol, clientOrderID, orderID string) (FOrderInfo, error) { var resp FOrderInfo req := make(map[string]interface{}) req["symbol"] = symbol @@ -850,11 +850,11 @@ func (h *HUOBI) FGetOrderInfo(symbol, clientOrderID, orderID string) (FOrderInfo if clientOrderID != "" { req["client_order_id"] = clientOrderID } - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, fOrderInfo, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fOrderInfo, nil, req, &resp) } // FOrderDetails gets order details for futures orders -func (h *HUOBI) FOrderDetails(symbol, orderID, orderType string, createdAt time.Time, pageIndex, pageSize int64) (FOrderDetailsData, error) { +func (h *HUOBI) FOrderDetails(ctx context.Context, symbol, orderID, orderType string, createdAt time.Time, pageIndex, pageSize int64) (FOrderDetailsData, error) { var resp FOrderDetailsData req := make(map[string]interface{}) req["symbol"] = symbol @@ -871,11 +871,11 @@ func (h *HUOBI) FOrderDetails(symbol, orderID, orderType string, createdAt time. if pageSize != 0 { req["page_size"] = pageSize } - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, fOrderDetails, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fOrderDetails, nil, req, &resp) } // FGetOpenOrders gets order details for futures orders -func (h *HUOBI) FGetOpenOrders(symbol currency.Code, pageIndex, pageSize int64) (FOpenOrdersData, error) { +func (h *HUOBI) FGetOpenOrders(ctx context.Context, symbol currency.Code, pageIndex, pageSize int64) (FOpenOrdersData, error) { var resp FOpenOrdersData req := make(map[string]interface{}) req["symbol"] = symbol @@ -885,11 +885,11 @@ func (h *HUOBI) FGetOpenOrders(symbol currency.Code, pageIndex, pageSize int64) if pageSize != 0 { req["page_size"] = pageSize } - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, fQueryOpenOrders, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fQueryOpenOrders, nil, req, &resp) } // FGetOrderHistory gets order order history for futures -func (h *HUOBI) FGetOrderHistory(contractCode currency.Pair, symbol, tradeType, reqType, orderType string, status []order.Status, createDate, pageIndex, pageSize int64) (FOrderHistoryData, error) { +func (h *HUOBI) FGetOrderHistory(ctx context.Context, contractCode currency.Pair, symbol, tradeType, reqType, orderType string, status []order.Status, createDate, pageIndex, pageSize int64) (FOrderHistoryData, error) { var resp FOrderHistoryData req := make(map[string]interface{}) req["symbol"] = symbol @@ -944,11 +944,11 @@ func (h *HUOBI) FGetOrderHistory(contractCode currency.Pair, symbol, tradeType, if pageSize != 0 { req["page_size"] = pageSize } - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, fOrderHistory, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fOrderHistory, nil, req, &resp) } // FTradeHistory gets trade history data for futures -func (h *HUOBI) FTradeHistory(contractCode currency.Pair, symbol, tradeType string, createDate, pageIndex, pageSize int64) (FOrderHistoryData, error) { +func (h *HUOBI) FTradeHistory(ctx context.Context, contractCode currency.Pair, symbol, tradeType string, createDate, pageIndex, pageSize int64) (FOrderHistoryData, error) { var resp FOrderHistoryData req := make(map[string]interface{}) req["symbol"] = symbol @@ -974,11 +974,11 @@ func (h *HUOBI) FTradeHistory(contractCode currency.Pair, symbol, tradeType stri if pageSize != 0 { req["page_size"] = pageSize } - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, fMatchResult, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fMatchResult, nil, req, &resp) } // FPlaceTriggerOrder places a trigger order for futures -func (h *HUOBI) FPlaceTriggerOrder(contractCode currency.Pair, symbol, contractType, triggerType, orderPriceType, direction, offset string, triggerPrice, orderPrice, volume, leverageRate float64) (FTriggerOrderData, error) { +func (h *HUOBI) FPlaceTriggerOrder(ctx context.Context, contractCode currency.Pair, symbol, contractType, triggerType, orderPriceType, direction, offset string, triggerPrice, orderPrice, volume, leverageRate float64) (FTriggerOrderData, error) { var resp FTriggerOrderData req := make(map[string]interface{}) if symbol != "" { @@ -1015,20 +1015,20 @@ func (h *HUOBI) FPlaceTriggerOrder(contractCode currency.Pair, symbol, contractT return resp, fmt.Errorf("invalid order price type") } req["order_price_type"] = orderPriceType - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, fTriggerOrder, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fTriggerOrder, nil, req, &resp) } // FCancelTriggerOrder cancels trigger order for futures -func (h *HUOBI) FCancelTriggerOrder(symbol, orderID string) (FCancelOrderData, error) { +func (h *HUOBI) FCancelTriggerOrder(ctx context.Context, symbol, orderID string) (FCancelOrderData, error) { var resp FCancelOrderData req := make(map[string]interface{}) req["symbol"] = symbol req["order_id"] = orderID - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, fCancelTriggerOrder, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fCancelTriggerOrder, nil, req, &resp) } // FCancelAllTriggerOrders cancels all trigger order for futures -func (h *HUOBI) FCancelAllTriggerOrders(contractCode currency.Pair, symbol, contractType string) (FCancelOrderData, error) { +func (h *HUOBI) FCancelAllTriggerOrders(ctx context.Context, contractCode currency.Pair, symbol, contractType string) (FCancelOrderData, error) { var resp FCancelOrderData req := make(map[string]interface{}) req["symbol"] = symbol @@ -1045,11 +1045,11 @@ func (h *HUOBI) FCancelAllTriggerOrders(contractCode currency.Pair, symbol, cont } req["contract_type"] = contractType } - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, fCancelAllTriggerOrders, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fCancelAllTriggerOrders, nil, req, &resp) } // FQueryTriggerOpenOrders queries open trigger orders for futures -func (h *HUOBI) FQueryTriggerOpenOrders(contractCode currency.Pair, symbol string, pageIndex, pageSize int64) (FTriggerOpenOrders, error) { +func (h *HUOBI) FQueryTriggerOpenOrders(ctx context.Context, contractCode currency.Pair, symbol string, pageIndex, pageSize int64) (FTriggerOpenOrders, error) { var resp FTriggerOpenOrders req := make(map[string]interface{}) req["symbol"] = symbol @@ -1066,11 +1066,11 @@ func (h *HUOBI) FQueryTriggerOpenOrders(contractCode currency.Pair, symbol strin if pageSize != 0 { req["page_size"] = pageSize } - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, fTriggerOpenOrders, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fTriggerOpenOrders, nil, req, &resp) } // FQueryTriggerOrderHistory queries trigger order history for futures -func (h *HUOBI) FQueryTriggerOrderHistory(contractCode currency.Pair, symbol, tradeType, status string, createDate, pageIndex, pageSize int64) (FTriggerOrderHistoryData, error) { +func (h *HUOBI) FQueryTriggerOrderHistory(ctx context.Context, contractCode currency.Pair, symbol, tradeType, status string, createDate, pageIndex, pageSize int64) (FTriggerOrderHistoryData, error) { var resp FTriggerOrderHistoryData req := make(map[string]interface{}) req["symbol"] = symbol @@ -1103,11 +1103,11 @@ func (h *HUOBI) FQueryTriggerOrderHistory(contractCode currency.Pair, symbol, tr if pageSize != 0 { req["page_size"] = pageSize } - return resp, h.FuturesAuthenticatedHTTPRequest(exchange.RestFutures, http.MethodPost, fTriggerOrderHistory, nil, req, &resp) + return resp, h.FuturesAuthenticatedHTTPRequest(ctx, exchange.RestFutures, http.MethodPost, fTriggerOrderHistory, nil, req, &resp) } // FuturesAuthenticatedHTTPRequest sends authenticated requests to the HUOBI API -func (h *HUOBI) FuturesAuthenticatedHTTPRequest(ep exchange.URL, method, endpoint string, values url.Values, data, result interface{}) error { +func (h *HUOBI) FuturesAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, method, endpoint string, values url.Values, data, result interface{}) error { if !h.AllowAuthenticatedRequest() { return fmt.Errorf("%s %w", h.Name, exchange.ErrAuthenticatedRequestWithoutCredentialsSet) } @@ -1169,7 +1169,7 @@ func (h *HUOBI) FuturesAuthenticatedHTTPRequest(ep exchange.URL, method, endpoin }, nil } - err = h.SendPayload(context.Background(), request.Unset, newRequest) + err = h.SendPayload(ctx, request.Unset, newRequest) if err != nil { return err } diff --git a/exchanges/huobi/huobi_test.go b/exchanges/huobi/huobi_test.go index 3a0f11b1..f233f49b 100644 --- a/exchanges/huobi/huobi_test.go +++ b/exchanges/huobi/huobi_test.go @@ -1,6 +1,7 @@ package huobi import ( + "context" "log" "os" "strconv" @@ -79,7 +80,7 @@ func setupWsTests(t *testing.T) { func TestFGetContractInfo(t *testing.T) { t.Parallel() - _, err := h.FGetContractInfo("", "", currency.Pair{}) + _, err := h.FGetContractInfo(context.Background(), "", "", currency.Pair{}) if err != nil { t.Error(err) } @@ -87,7 +88,7 @@ func TestFGetContractInfo(t *testing.T) { func TestFIndexPriceInfo(t *testing.T) { t.Parallel() - _, err := h.FIndexPriceInfo(currency.BTC) + _, err := h.FIndexPriceInfo(context.Background(), currency.BTC) if err != nil { t.Error(err) } @@ -95,7 +96,8 @@ func TestFIndexPriceInfo(t *testing.T) { func TestFContractPriceLimitations(t *testing.T) { t.Parallel() - _, err := h.FContractPriceLimitations("BTC", "this_week", currency.Pair{}) + _, err := h.FContractPriceLimitations(context.Background(), + "BTC", "this_week", currency.Pair{}) if err != nil { t.Error(err) } @@ -103,7 +105,8 @@ func TestFContractPriceLimitations(t *testing.T) { func TestFContractOpenInterest(t *testing.T) { t.Parallel() - _, err := h.FContractOpenInterest("BTC", "this_week", currency.Pair{}) + _, err := h.FContractOpenInterest(context.Background(), + "BTC", "this_week", currency.Pair{}) if err != nil { t.Error(err) } @@ -111,7 +114,7 @@ func TestFContractOpenInterest(t *testing.T) { func TestFGetEstimatedDeliveryPrice(t *testing.T) { t.Parallel() - _, err := h.FGetEstimatedDeliveryPrice(currency.BTC) + _, err := h.FGetEstimatedDeliveryPrice(context.Background(), currency.BTC) if err != nil { t.Error(err) } @@ -123,7 +126,7 @@ func TestFGetMarketDepth(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.FGetMarketDepth(cp, "step5") + _, err = h.FGetMarketDepth(context.Background(), cp, "step5") if err != nil { t.Error(err) } @@ -135,7 +138,8 @@ func TestFGetKlineData(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.FGetKlineData(cp, "5min", 5, time.Now().Add(-time.Minute*5), time.Now()) + _, err = h.FGetKlineData(context.Background(), + cp, "5min", 5, time.Now().Add(-time.Minute*5), time.Now()) if err != nil { t.Error(err) } @@ -147,7 +151,7 @@ func TestFGetMarketOverviewData(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.FGetMarketOverviewData(cp) + _, err = h.FGetMarketOverviewData(context.Background(), cp) if err != nil { t.Error(err) } @@ -159,7 +163,7 @@ func TestFLastTradeData(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.FLastTradeData(cp) + _, err = h.FLastTradeData(context.Background(), cp) if err != nil { t.Error(err) } @@ -171,7 +175,7 @@ func TestFRequestPublicBatchTrades(t *testing.T) { if err != nil { t.Error(err) } - a, err := h.FRequestPublicBatchTrades(cp, 50) + a, err := h.FRequestPublicBatchTrades(context.Background(), cp, 50) if err != nil { t.Error(err) } @@ -182,7 +186,7 @@ func TestFRequestPublicBatchTrades(t *testing.T) { func TestFQueryInsuranceAndClawbackData(t *testing.T) { t.Parallel() - _, err := h.FQueryInsuranceAndClawbackData(currency.BTC) + _, err := h.FQueryInsuranceAndClawbackData(context.Background(), currency.BTC) if err != nil { t.Error(err) } @@ -190,7 +194,7 @@ func TestFQueryInsuranceAndClawbackData(t *testing.T) { func TestFQueryHistoricalInsuranceData(t *testing.T) { t.Parallel() - _, err := h.FQueryHistoricalInsuranceData(currency.BTC) + _, err := h.FQueryHistoricalInsuranceData(context.Background(), currency.BTC) if err != nil { t.Error(err) } @@ -198,7 +202,7 @@ func TestFQueryHistoricalInsuranceData(t *testing.T) { func TestFQueryTieredAdjustmentFactor(t *testing.T) { t.Parallel() - _, err := h.FQueryTieredAdjustmentFactor(currency.BTC) + _, err := h.FQueryTieredAdjustmentFactor(context.Background(), currency.BTC) if err != nil { t.Error(err) } @@ -206,7 +210,8 @@ func TestFQueryTieredAdjustmentFactor(t *testing.T) { func TestFQueryHisOpenInterest(t *testing.T) { t.Parallel() - _, err := h.FQueryHisOpenInterest("BTC", "next_week", "60min", "cont", 3) + _, err := h.FQueryHisOpenInterest(context.Background(), + "BTC", "next_week", "60min", "cont", 3) if err != nil { t.Error(err) } @@ -215,7 +220,7 @@ func TestFQueryHisOpenInterest(t *testing.T) { func TestFQuerySystemStatus(t *testing.T) { t.Parallel() - _, err := h.FQuerySystemStatus(currency.BTC) + _, err := h.FQuerySystemStatus(context.Background(), currency.BTC) if err != nil { t.Error(err) } @@ -223,7 +228,7 @@ func TestFQuerySystemStatus(t *testing.T) { func TestFQueryTopAccountsRatio(t *testing.T) { t.Parallel() - _, err := h.FQueryTopAccountsRatio("BTC", "5min") + _, err := h.FQueryTopAccountsRatio(context.Background(), "BTC", "5min") if err != nil { t.Error(err) } @@ -231,7 +236,7 @@ func TestFQueryTopAccountsRatio(t *testing.T) { func TestFQueryTopPositionsRatio(t *testing.T) { t.Parallel() - _, err := h.FQueryTopPositionsRatio("BTC", "5min") + _, err := h.FQueryTopPositionsRatio(context.Background(), "BTC", "5min") if err != nil { t.Error(err) } @@ -239,7 +244,7 @@ func TestFQueryTopPositionsRatio(t *testing.T) { func TestFLiquidationOrders(t *testing.T) { t.Parallel() - _, err := h.FLiquidationOrders("BTC", "filled", 0, 0, 7) + _, err := h.FLiquidationOrders(context.Background(), "BTC", "filled", 0, 0, 7) if err != nil { t.Error(err) } @@ -251,7 +256,7 @@ func TestFIndexKline(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.FIndexKline(cp, "5min", 5) + _, err = h.FIndexKline(context.Background(), cp, "5min", 5) if err != nil { t.Error(err) } @@ -263,7 +268,7 @@ func TestFGetBasisData(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.FGetBasisData(cp, "5min", "open", 3) + _, err = h.FGetBasisData(context.Background(), cp, "5min", "open", 3) if err != nil { t.Error(err) } @@ -274,7 +279,7 @@ func TestFGetAccountInfo(t *testing.T) { t.Skip("skipping test: api keys not set") } t.Parallel() - _, err := h.FGetAccountInfo(currency.Code{}) + _, err := h.FGetAccountInfo(context.Background(), currency.Code{}) if err != nil { t.Error(err) } @@ -285,7 +290,7 @@ func TestFGetPositionsInfo(t *testing.T) { t.Skip("skipping test: api keys not set") } t.Parallel() - _, err := h.FGetPositionsInfo(currency.Code{}) + _, err := h.FGetPositionsInfo(context.Background(), currency.Code{}) if err != nil { t.Error(err) } @@ -296,7 +301,7 @@ func TestFGetAllSubAccountAssets(t *testing.T) { t.Skip("skipping test: api keys not set") } t.Parallel() - _, err := h.FGetAllSubAccountAssets(currency.Code{}) + _, err := h.FGetAllSubAccountAssets(context.Background(), currency.Code{}) if err != nil { t.Error(err) } @@ -307,7 +312,7 @@ func TestFGetSingleSubAccountInfo(t *testing.T) { t.Skip("skipping test: api keys not set") } t.Parallel() - _, err := h.FGetSingleSubAccountInfo("", "154263566") + _, err := h.FGetSingleSubAccountInfo(context.Background(), "", "154263566") if err != nil { t.Error(err) } @@ -318,7 +323,7 @@ func TestFGetSingleSubPositions(t *testing.T) { t.Skip("skipping test: api keys not set") } t.Parallel() - _, err := h.FGetSingleSubPositions("", "154263566") + _, err := h.FGetSingleSubPositions(context.Background(), "", "154263566") if err != nil { t.Error(err) } @@ -329,7 +334,8 @@ func TestFGetFinancialRecords(t *testing.T) { t.Skip("skipping test: api keys not set") } t.Parallel() - _, err := h.FGetFinancialRecords("BTC", "closeLong", 2, 0, 0) + _, err := h.FGetFinancialRecords(context.Background(), + "BTC", "closeLong", 2, 0, 0) if err != nil { t.Error(err) } @@ -340,7 +346,8 @@ func TestFGetSettlementRecords(t *testing.T) { t.Skip("skipping test: api keys not set") } t.Parallel() - _, err := h.FGetSettlementRecords(currency.BTC, 0, 0, time.Now().Add(-48*time.Hour), time.Now()) + _, err := h.FGetSettlementRecords(context.Background(), + currency.BTC, 0, 0, time.Now().Add(-48*time.Hour), time.Now()) if err != nil { t.Error(err) } @@ -351,7 +358,7 @@ func TestFContractTradingFee(t *testing.T) { t.Skip("skipping test: api keys not set") } t.Parallel() - _, err := h.FContractTradingFee(currency.Code{}) + _, err := h.FContractTradingFee(context.Background(), currency.Code{}) if err != nil { t.Error(err) } @@ -362,7 +369,7 @@ func TestFGetTransferLimits(t *testing.T) { t.Skip("skipping test: api keys not set") } t.Parallel() - _, err := h.FGetTransferLimits(currency.Code{}) + _, err := h.FGetTransferLimits(context.Background(), currency.Code{}) if err != nil { t.Error(err) } @@ -373,7 +380,7 @@ func TestFGetPositionLimits(t *testing.T) { t.Skip("skipping test: api keys not set") } t.Parallel() - _, err := h.FGetPositionLimits(currency.Code{}) + _, err := h.FGetPositionLimits(context.Background(), currency.Code{}) if err != nil { t.Error(err) } @@ -384,7 +391,7 @@ func TestFGetAssetsAndPositions(t *testing.T) { t.Skip("skipping test: api keys not set") } t.Parallel() - _, err := h.FGetAssetsAndPositions(currency.HT) + _, err := h.FGetAssetsAndPositions(context.Background(), currency.HT) if err != nil { t.Error(err) } @@ -395,7 +402,8 @@ func TestFTransfer(t *testing.T) { t.Skip("skipping test: api keys not set") } t.Parallel() - _, err := h.FTransfer("154263566", "HT", "sub_to_master", 5) + _, err := h.FTransfer(context.Background(), + "154263566", "HT", "sub_to_master", 5) if err != nil { t.Error(err) } @@ -406,7 +414,8 @@ func TestFGetTransferRecords(t *testing.T) { t.Skip("skipping test: api keys not set") } t.Parallel() - _, err := h.FGetTransferRecords("HT", "master_to_sub", 90, 0, 0) + _, err := h.FGetTransferRecords(context.Background(), + "HT", "master_to_sub", 90, 0, 0) if err != nil { t.Error(err) } @@ -417,7 +426,7 @@ func TestFGetAvailableLeverage(t *testing.T) { t.Skip("skipping test: api keys not set") } t.Parallel() - _, err := h.FGetAvailableLeverage(currency.BTC) + _, err := h.FGetAvailableLeverage(context.Background(), currency.BTC) if err != nil { t.Error(err) } @@ -428,7 +437,8 @@ func TestFOrder(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test: api keys not set or canManipulateRealOrders set to false") } - tradablePairs, err := h.FetchTradablePairs(asset.Futures) + tradablePairs, err := h.FetchTradablePairs(context.Background(), + asset.Futures) if err != nil { t.Error(err) } @@ -439,7 +449,9 @@ func TestFOrder(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.FOrder(currency.Pair{}, cp.Base.Upper().String(), "quarter", "123", "BUY", "open", "limit", 1, 1, 1) + _, err = h.FOrder(context.Background(), + currency.Pair{}, cp.Base.Upper().String(), + "quarter", "123", "BUY", "open", "limit", 1, 1, 1) if err != nil { t.Error(err) } @@ -474,7 +486,7 @@ func TestFPlaceBatchOrder(t *testing.T) { OrderPriceType: "limit", } req = append(req, order1, order2) - _, err := h.FPlaceBatchOrder(req) + _, err := h.FPlaceBatchOrder(context.Background(), req) if err != nil { t.Error(err) } @@ -485,7 +497,7 @@ func TestFCancelOrder(t *testing.T) { t.Skip("skipping test: api keys not set or canManipulateRealOrders set to false") } t.Parallel() - _, err := h.FCancelOrder("BTC", "123", "") + _, err := h.FCancelOrder(context.Background(), "BTC", "123", "") if err != nil { t.Error(err) } @@ -496,7 +508,8 @@ func TestFCancelAllOrders(t *testing.T) { t.Skip("skipping test: api keys not set or canManipulateRealOrders set to false") } t.Parallel() - tradablePairs, err := h.FetchTradablePairs(asset.Futures) + tradablePairs, err := h.FetchTradablePairs(context.Background(), + asset.Futures) if err != nil { t.Error(err) } @@ -507,7 +520,7 @@ func TestFCancelAllOrders(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.FCancelAllOrders(cp, "", "") + _, err = h.FCancelAllOrders(context.Background(), cp, "", "") if err != nil { t.Error(err) } @@ -518,7 +531,8 @@ func TestFFlashCloseOrder(t *testing.T) { t.Skip("skipping test: api keys not set or canManipulateRealOrders set to false") } t.Parallel() - _, err := h.FFlashCloseOrder(currency.Pair{}, "BTC", "quarter", "BUY", "lightning", "", 1) + _, err := h.FFlashCloseOrder(context.Background(), + currency.Pair{}, "BTC", "quarter", "BUY", "lightning", "", 1) if err != nil { t.Error(err) } @@ -529,7 +543,7 @@ func TestFGetOrderInfo(t *testing.T) { t.Skip("skipping test: api keys not set") } t.Parallel() - _, err := h.FGetOrderInfo("BTC", "", "123") + _, err := h.FGetOrderInfo(context.Background(), "BTC", "", "123") if err != nil { t.Error(err) } @@ -540,7 +554,8 @@ func TestFOrderDetails(t *testing.T) { t.Skip("skipping test: api keys not set") } t.Parallel() - _, err := h.FOrderDetails("BTC", "123", "quotation", time.Now().Add(-1*time.Hour), 0, 0) + _, err := h.FOrderDetails(context.Background(), + "BTC", "123", "quotation", time.Now().Add(-1*time.Hour), 0, 0) if err != nil { t.Error(err) } @@ -551,7 +566,7 @@ func TestFGetOpenOrders(t *testing.T) { t.Skip("skipping test: api keys not set") } t.Parallel() - _, err := h.FGetOpenOrders(currency.BTC, 1, 2) + _, err := h.FGetOpenOrders(context.Background(), currency.BTC, 1, 2) if err != nil { t.Error(err) } @@ -562,7 +577,8 @@ func TestFGetOrderHistory(t *testing.T) { t.Skip("skipping test: api keys not set") } t.Parallel() - tradablePairs, err := h.FetchTradablePairs(asset.Futures) + tradablePairs, err := h.FetchTradablePairs(context.Background(), + asset.Futures) if err != nil { t.Error(err) } @@ -573,7 +589,11 @@ func TestFGetOrderHistory(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.FGetOrderHistory(currency.Pair{}, cp.Base.Upper().String(), "all", "all", "limit", []order.Status{}, 5, 0, 0) + _, err = h.FGetOrderHistory(context.Background(), + currency.Pair{}, cp.Base.Upper().String(), + "all", "all", "limit", + []order.Status{}, + 5, 0, 0) if err != nil { t.Error(err) } @@ -584,7 +604,8 @@ func TestFTradeHistory(t *testing.T) { t.Skip("skipping test: api keys not set") } t.Parallel() - _, err := h.FTradeHistory(currency.Pair{}, "BTC", "all", 10, 0, 0) + _, err := h.FTradeHistory(context.Background(), + currency.Pair{}, "BTC", "all", 10, 0, 0) if err != nil { t.Error(err) } @@ -595,7 +616,8 @@ func TestFPlaceTriggerOrder(t *testing.T) { t.Skip("skipping test: api keys not set or canManipulateRealOrders set to false") } t.Parallel() - _, err := h.FPlaceTriggerOrder(currency.Pair{}, "EOS", "quarter", "greaterOrEqual", + _, err := h.FPlaceTriggerOrder(context.Background(), + currency.Pair{}, "EOS", "quarter", "greaterOrEqual", "limit", "buy", "close", 1.1, 1.05, 5, 2) if err != nil { t.Error(err) @@ -607,7 +629,7 @@ func TestFCancelTriggerOrder(t *testing.T) { t.Skip("skipping test: api keys not set or canManipulateRealOrders set to false") } t.Parallel() - _, err := h.FCancelTriggerOrder("ETH", "123") + _, err := h.FCancelTriggerOrder(context.Background(), "ETH", "123") if err != nil { t.Error(err) } @@ -618,7 +640,8 @@ func TestFCancelAllTriggerOrders(t *testing.T) { t.Skip("skipping test: api keys not set or canManipulateRealOrders set to false") } t.Parallel() - _, err := h.FCancelAllTriggerOrders(currency.Pair{}, "BTC", "this_week") + _, err := h.FCancelAllTriggerOrders(context.Background(), + currency.Pair{}, "BTC", "this_week") if err != nil { t.Error(err) } @@ -629,7 +652,8 @@ func TestFQueryTriggerOpenOrders(t *testing.T) { t.Skip("skipping test: api keys not set") } t.Parallel() - _, err := h.FQueryTriggerOpenOrders(currency.Pair{}, "BTC", 0, 0) + _, err := h.FQueryTriggerOpenOrders(context.Background(), + currency.Pair{}, "BTC", 0, 0) if err != nil { t.Error(err) } @@ -640,7 +664,8 @@ func TestFQueryTriggerOrderHistory(t *testing.T) { t.Skip("skipping test: api keys not set or canManipulateRealOrders set to false") } t.Parallel() - _, err := h.FQueryTriggerOrderHistory(currency.Pair{}, "EOS", "all", "all", 10, 0, 0) + _, err := h.FQueryTriggerOrderHistory(context.Background(), + currency.Pair{}, "EOS", "all", "all", 10, 0, 0) if err != nil { t.Error(err) } @@ -648,7 +673,7 @@ func TestFQueryTriggerOrderHistory(t *testing.T) { func TestFetchTradablePairs(t *testing.T) { t.Parallel() - _, err := h.FetchTradablePairs(asset.Futures) + _, err := h.FetchTradablePairs(context.Background(), asset.Futures) if err != nil { t.Error(err) } @@ -660,7 +685,7 @@ func TestUpdateTickerSpot(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.UpdateTicker(sp, asset.Spot) + _, err = h.UpdateTicker(context.Background(), sp, asset.Spot) if err != nil { t.Error(err) } @@ -672,7 +697,7 @@ func TestUpdateTickerCMF(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.UpdateTicker(cp1, asset.CoinMarginedFutures) + _, err = h.UpdateTicker(context.Background(), cp1, asset.CoinMarginedFutures) if err != nil { t.Error(err) } @@ -680,7 +705,8 @@ func TestUpdateTickerCMF(t *testing.T) { func TestUpdateTickerFutures(t *testing.T) { t.Parallel() - tradablePairs, err := h.FetchTradablePairs(asset.Futures) + tradablePairs, err := h.FetchTradablePairs(context.Background(), + asset.Futures) if err != nil { t.Error(err) } @@ -691,7 +717,7 @@ func TestUpdateTickerFutures(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.UpdateTicker(cp2, asset.Futures) + _, err = h.UpdateTicker(context.Background(), cp2, asset.Futures) if err != nil { t.Error(err) } @@ -703,7 +729,7 @@ func TestUpdateOrderbookSpot(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.UpdateOrderbook(sp, asset.Spot) + _, err = h.UpdateOrderbook(context.Background(), sp, asset.Spot) if err != nil { t.Error(err) } @@ -715,7 +741,7 @@ func TestUpdateOrderbookCMF(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.UpdateOrderbook(cp1, asset.CoinMarginedFutures) + _, err = h.UpdateOrderbook(context.Background(), cp1, asset.CoinMarginedFutures) if err != nil { t.Error(err) } @@ -723,7 +749,8 @@ func TestUpdateOrderbookCMF(t *testing.T) { func TestUpdateOrderbookFuture(t *testing.T) { t.Parallel() - tradablePairs, err := h.FetchTradablePairs(asset.Futures) + tradablePairs, err := h.FetchTradablePairs(context.Background(), + asset.Futures) if err != nil { t.Error(err) } @@ -734,11 +761,12 @@ func TestUpdateOrderbookFuture(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.UpdateOrderbook(cp2, asset.Futures) + _, err = h.UpdateOrderbook(context.Background(), cp2, asset.Futures) if err != nil { t.Error(err) } - tradablePairs, err = h.FetchTradablePairs(asset.CoinMarginedFutures) + tradablePairs, err = h.FetchTradablePairs(context.Background(), + asset.CoinMarginedFutures) if err != nil { t.Error(err) } @@ -749,7 +777,7 @@ func TestUpdateOrderbookFuture(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.UpdateOrderbook(cp2, asset.Futures) + _, err = h.UpdateOrderbook(context.Background(), cp2, asset.Futures) if err != nil { t.Error(err) } @@ -760,7 +788,7 @@ func TestUpdateAccountInfo(t *testing.T) { t.Skip("skipping test: api keys not set") } t.Parallel() - _, err := h.UpdateAccountInfo(asset.Spot) + _, err := h.UpdateAccountInfo(context.Background(), asset.Spot) if err != nil { t.Error(err) } @@ -777,7 +805,7 @@ func TestGetOrderHistory(t *testing.T) { Pairs: []currency.Pair{currency.NewPair(currency.BTC, currency.USDT)}, AssetType: asset.Spot, } - _, err := h.GetOrderHistory(&getOrdersRequest) + _, err := h.GetOrderHistory(context.Background(), &getOrdersRequest) if err != nil { t.Error(err) } @@ -788,11 +816,12 @@ func TestGetOrderHistory(t *testing.T) { } getOrdersRequest.Pairs = []currency.Pair{cp1} getOrdersRequest.AssetType = asset.CoinMarginedFutures - _, err = h.GetOrderHistory(&getOrdersRequest) + _, err = h.GetOrderHistory(context.Background(), &getOrdersRequest) if err != nil { t.Error(err) } - tradablePairs, err := h.FetchTradablePairs(asset.Futures) + tradablePairs, err := h.FetchTradablePairs(context.Background(), + asset.Futures) if err != nil { t.Error(err) } @@ -805,7 +834,7 @@ func TestGetOrderHistory(t *testing.T) { } getOrdersRequest.Pairs = []currency.Pair{cp2} getOrdersRequest.AssetType = asset.Futures - _, err = h.GetOrderHistory(&getOrdersRequest) + _, err = h.GetOrderHistory(context.Background(), &getOrdersRequest) if err != nil { t.Error(err) } @@ -816,7 +845,8 @@ func TestCancelAllOrders(t *testing.T) { t.Skip("skipping test: api keys not set or canManipulateRealOrders set to false") } t.Parallel() - _, err := h.CancelAllOrders(&order.Cancel{AssetType: asset.Futures}) + _, err := h.CancelAllOrders(context.Background(), + &order.Cancel{AssetType: asset.Futures}) if err != nil { t.Error(err) } @@ -828,7 +858,7 @@ func TestQuerySwapIndexPriceInfo(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.QuerySwapIndexPriceInfo(cp) + _, err = h.QuerySwapIndexPriceInfo(context.Background(), cp) if err != nil { t.Error(err) } @@ -840,7 +870,7 @@ func TestSwapOpenInterestInformation(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.SwapOpenInterestInformation(cp) + _, err = h.SwapOpenInterestInformation(context.Background(), cp) if err != nil { t.Error(err) } @@ -852,7 +882,7 @@ func TestGetSwapMarketDepth(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.GetSwapMarketDepth(cp, "step0") + _, err = h.GetSwapMarketDepth(context.Background(), cp, "step0") if err != nil { t.Error(err) } @@ -864,7 +894,8 @@ func TestGetSwapKlineData(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.GetSwapKlineData(cp, "5min", 5, time.Now().Add(-time.Hour), time.Now()) + _, err = h.GetSwapKlineData(context.Background(), + cp, "5min", 5, time.Now().Add(-time.Hour), time.Now()) if err != nil { t.Error(err) } @@ -876,7 +907,7 @@ func TestGetSwapMarketOverview(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.GetSwapMarketOverview(cp) + _, err = h.GetSwapMarketOverview(context.Background(), cp) if err != nil { t.Error(err) } @@ -888,7 +919,7 @@ func TestGetLastTrade(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.GetLastTrade(cp) + _, err = h.GetLastTrade(context.Background(), cp) if err != nil { t.Error(err) } @@ -900,7 +931,7 @@ func TestGetBatchTrades(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.GetBatchTrades(cp, 5) + _, err = h.GetBatchTrades(context.Background(), cp, 5) if err != nil { t.Error(err) } @@ -912,7 +943,7 @@ func TestGetInsuranceData(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.GetInsuranceData(cp) + _, err = h.GetInsuranceData(context.Background(), cp) if err != nil { t.Error(err) } @@ -924,7 +955,7 @@ func TestGetHistoricalInsuranceData(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.GetHistoricalInsuranceData(cp, 0, 0) + _, err = h.GetHistoricalInsuranceData(context.Background(), cp, 0, 0) if err != nil { t.Error(err) } @@ -936,7 +967,7 @@ func TestGetTieredAjustmentFactorInfo(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.GetTieredAjustmentFactorInfo(cp) + _, err = h.GetTieredAjustmentFactorInfo(context.Background(), cp) if err != nil { t.Error(err) } @@ -948,7 +979,8 @@ func TestGetOpenInterestInfo(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.GetOpenInterestInfo(cp, "5min", "cryptocurrency", 50) + _, err = h.GetOpenInterestInfo(context.Background(), + cp, "5min", "cryptocurrency", 50) if err != nil { t.Error(err) } @@ -960,7 +992,7 @@ func TestGetTraderSentimentIndexAccount(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.GetTraderSentimentIndexAccount(cp, "5min") + _, err = h.GetTraderSentimentIndexAccount(context.Background(), cp, "5min") if err != nil { t.Error(err) } @@ -972,7 +1004,7 @@ func TestGetTraderSentimentIndexPosition(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.GetTraderSentimentIndexPosition(cp, "5min") + _, err = h.GetTraderSentimentIndexPosition(context.Background(), cp, "5min") if err != nil { t.Error(err) } @@ -984,7 +1016,7 @@ func TestGetLiquidationOrders(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.GetLiquidationOrders(cp, "closed", 0, 0, 7) + _, err = h.GetLiquidationOrders(context.Background(), cp, "closed", 0, 0, 7) if err != nil { t.Error(err) } @@ -996,7 +1028,7 @@ func TestGetHistoricalFundingRates(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.GetHistoricalFundingRates(cp, 0, 0) + _, err = h.GetHistoricalFundingRates(context.Background(), cp, 0, 0) if err != nil { t.Error(err) } @@ -1008,7 +1040,7 @@ func TestGetPremiumIndexKlineData(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.GetPremiumIndexKlineData(cp, "5min", 15) + _, err = h.GetPremiumIndexKlineData(context.Background(), cp, "5min", 15) if err != nil { t.Error(err) } @@ -1020,7 +1052,7 @@ func TestGetEstimatedFundingRates(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.GetPremiumIndexKlineData(cp, "5min", 15) + _, err = h.GetPremiumIndexKlineData(context.Background(), cp, "5min", 15) if err != nil { t.Error(err) } @@ -1032,7 +1064,7 @@ func TestGetBasisData(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.GetBasisData(cp, "5min", "close", 5) + _, err = h.GetBasisData(context.Background(), cp, "5min", "close", 5) if err != nil { t.Error(err) } @@ -1044,7 +1076,8 @@ func TestGetSystemStatusInfo(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.GetSystemStatusInfo(cp, "5min", "cryptocurrency", 50) + _, err = h.GetSystemStatusInfo(context.Background(), + cp, "5min", "cryptocurrency", 50) if err != nil { t.Error(err) } @@ -1056,7 +1089,7 @@ func TestGetSwapPriceLimits(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.GetSwapPriceLimits(cp) + _, err = h.GetSwapPriceLimits(context.Background(), cp) if err != nil { t.Error(err) } @@ -1071,7 +1104,7 @@ func TestGetMarginRates(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.GetMarginRates(cp) + _, err = h.GetMarginRates(context.Background(), cp) if err != nil { t.Error(err) } @@ -1086,7 +1119,7 @@ func TestGetSwapAccountInfo(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.GetSwapAccountInfo(cp) + _, err = h.GetSwapAccountInfo(context.Background(), cp) if err != nil { t.Error(err) } @@ -1101,7 +1134,7 @@ func TestGetSwapPositionsInfo(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.GetSwapPositionsInfo(cp) + _, err = h.GetSwapPositionsInfo(context.Background(), cp) if err != nil { t.Error(err) } @@ -1116,7 +1149,7 @@ func TestGetSwapAssetsAndPositions(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.GetSwapAssetsAndPositions(cp) + _, err = h.GetSwapAssetsAndPositions(context.Background(), cp) if err != nil { t.Error(err) } @@ -1131,7 +1164,7 @@ func TestGetSwapAllSubAccAssets(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.GetSwapAllSubAccAssets(cp) + _, err = h.GetSwapAllSubAccAssets(context.Background(), cp) if err != nil { t.Error(err) } @@ -1146,7 +1179,7 @@ func TestGetSubAccPositionInfo(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.GetSubAccPositionInfo(cp, 0) + _, err = h.GetSubAccPositionInfo(context.Background(), cp, 0) if err != nil { t.Error(err) } @@ -1161,7 +1194,7 @@ func TestGetAccountFinancialRecords(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.GetAccountFinancialRecords(cp, "3,4", 15, 0, 0) + _, err = h.GetAccountFinancialRecords(context.Background(), cp, "3,4", 15, 0, 0) if err != nil { t.Error(err) } @@ -1176,7 +1209,8 @@ func TestGetSwapSettlementRecords(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.GetSwapSettlementRecords(cp, time.Time{}, time.Time{}, 0, 0) + _, err = h.GetSwapSettlementRecords(context.Background(), + cp, time.Time{}, time.Time{}, 0, 0) if err != nil { t.Error(err) } @@ -1191,7 +1225,7 @@ func TestGetAvailableLeverage(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.GetAvailableLeverage(cp) + _, err = h.GetAvailableLeverage(context.Background(), cp) if err != nil { t.Error(err) } @@ -1206,7 +1240,7 @@ func TestGetSwapOrderLimitInfo(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.GetSwapOrderLimitInfo(cp, "limit") + _, err = h.GetSwapOrderLimitInfo(context.Background(), cp, "limit") if err != nil { t.Error(err) } @@ -1221,7 +1255,7 @@ func TestGetSwapTradingFeeInfo(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.GetSwapTradingFeeInfo(cp) + _, err = h.GetSwapTradingFeeInfo(context.Background(), cp) if err != nil { t.Error(err) } @@ -1236,7 +1270,7 @@ func TestGetSwapTransferLimitInfo(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.GetSwapTransferLimitInfo(cp) + _, err = h.GetSwapTransferLimitInfo(context.Background(), cp) if err != nil { t.Error(err) } @@ -1251,7 +1285,7 @@ func TestGetSwapPositionLimitInfo(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.GetSwapPositionLimitInfo(cp) + _, err = h.GetSwapPositionLimitInfo(context.Background(), cp) if err != nil { t.Error(err) } @@ -1266,7 +1300,8 @@ func TestAccountTransferData(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.AccountTransferData(cp, "123", "master_to_sub", 15) + _, err = h.AccountTransferData(context.Background(), + cp, "123", "master_to_sub", 15) if err != nil { t.Error(err) } @@ -1281,7 +1316,8 @@ func TestAccountTransferRecords(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.AccountTransferRecords(cp, "master_to_sub", 12, 0, 0) + _, err = h.AccountTransferRecords(context.Background(), + cp, "master_to_sub", 12, 0, 0) if err != nil { t.Error(err) } @@ -1296,7 +1332,8 @@ func TestPlaceSwapOrders(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.PlaceSwapOrders(cp, "", "buy", "open", "limit", 0.01, 1, 1) + _, err = h.PlaceSwapOrders(context.Background(), + cp, "", "buy", "open", "limit", 0.01, 1, 1) if err != nil { t.Error(err) } @@ -1330,7 +1367,7 @@ func TestPlaceSwapBatchOrders(t *testing.T) { } req.Data = append(req.Data, order1, order2) - _, err := h.PlaceSwapBatchOrders(req) + _, err := h.PlaceSwapBatchOrders(context.Background(), req) if err != nil { t.Error(err) } @@ -1345,7 +1382,7 @@ func TestCancelSwapOrder(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.CancelSwapOrder("test123", "", cp) + _, err = h.CancelSwapOrder(context.Background(), "test123", "", cp) if err != nil { t.Error(err) } @@ -1360,7 +1397,7 @@ func TestCancelAllSwapOrders(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.CancelAllSwapOrders(cp) + _, err = h.CancelAllSwapOrders(context.Background(), cp) if err != nil { t.Error(err) } @@ -1375,7 +1412,8 @@ func TestPlaceLightningCloseOrder(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.PlaceLightningCloseOrder(cp, "buy", "lightning", 5, 1) + _, err = h.PlaceLightningCloseOrder(context.Background(), + cp, "buy", "lightning", 5, 1) if err != nil { t.Error(err) } @@ -1390,7 +1428,7 @@ func TestGetSwapOrderInfo(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.GetSwapOrderInfo(cp, "123", "") + _, err = h.GetSwapOrderInfo(context.Background(), cp, "123", "") if err != nil { t.Error(err) } @@ -1405,7 +1443,8 @@ func TestGetSwapOrderDetails(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.GetSwapOrderDetails(cp, "123", "10", "cancelledOrder", 0, 0) + _, err = h.GetSwapOrderDetails(context.Background(), + cp, "123", "10", "cancelledOrder", 0, 0) if err != nil { t.Error(err) } @@ -1420,7 +1459,7 @@ func TestGetSwapOpenOrders(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.GetSwapOpenOrders(cp, 0, 0) + _, err = h.GetSwapOpenOrders(context.Background(), cp, 0, 0) if err != nil { t.Error(err) } @@ -1435,7 +1474,9 @@ func TestGetSwapOrderHistory(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.GetSwapOrderHistory(cp, "all", "all", []order.Status{order.PartiallyCancelled, order.Active}, 25, 0, 0) + _, err = h.GetSwapOrderHistory(context.Background(), + cp, "all", "all", + []order.Status{order.PartiallyCancelled, order.Active}, 25, 0, 0) if err != nil { t.Error(err) } @@ -1450,7 +1491,8 @@ func TestGetSwapTradeHistory(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.GetSwapTradeHistory(cp, "liquidateShort", 10, 0, 0) + _, err = h.GetSwapTradeHistory(context.Background(), + cp, "liquidateShort", 10, 0, 0) if err != nil { t.Error(err) } @@ -1465,7 +1507,8 @@ func TestPlaceSwapTriggerOrder(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.PlaceSwapTriggerOrder(cp, "greaterOrEqual", "buy", "open", "optimal_5", 5, 3, 1, 1) + _, err = h.PlaceSwapTriggerOrder(context.Background(), + cp, "greaterOrEqual", "buy", "open", "optimal_5", 5, 3, 1, 1) if err != nil { t.Error(err) } @@ -1480,7 +1523,7 @@ func TestCancelSwapTriggerOrder(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.CancelSwapTriggerOrder(cp, "test123") + _, err = h.CancelSwapTriggerOrder(context.Background(), cp, "test123") if err != nil { t.Error(err) } @@ -1495,7 +1538,7 @@ func TestCancelAllSwapTriggerOrders(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.CancelAllSwapTriggerOrders(cp) + _, err = h.CancelAllSwapTriggerOrders(context.Background(), cp) if err != nil { t.Error(err) } @@ -1510,7 +1553,8 @@ func TestGetSwapTriggerOrderHistory(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.GetSwapTriggerOrderHistory(cp, "open", "all", 15, 0, 0) + _, err = h.GetSwapTriggerOrderHistory(context.Background(), + cp, "open", "all", 15, 0, 0) if err != nil { t.Error(err) } @@ -1518,7 +1562,7 @@ func TestGetSwapTriggerOrderHistory(t *testing.T) { func TestGetSwapMarkets(t *testing.T) { t.Parallel() - _, err := h.GetSwapMarkets(currency.Pair{}) + _, err := h.GetSwapMarkets(context.Background(), currency.Pair{}) if err != nil { t.Error(err) } @@ -1530,11 +1574,12 @@ func TestGetSpotKline(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.GetSpotKline(KlinesRequestParams{ - Symbol: cp, - Period: "1min", - Size: 0, - }) + _, err = h.GetSpotKline(context.Background(), + KlinesRequestParams{ + Symbol: cp, + Period: "1min", + Size: 0, + }) if err != nil { t.Errorf("Huobi TestGetSpotKline: %s", err) } @@ -1546,17 +1591,20 @@ func TestGetHistoricCandles(t *testing.T) { t.Fatal(err) } startTime := time.Now().Add(-time.Hour * 1) - _, err = h.GetHistoricCandles(currencyPair, asset.Spot, startTime, time.Now(), kline.OneMin) + _, err = h.GetHistoricCandles(context.Background(), + currencyPair, asset.Spot, startTime, time.Now(), kline.OneMin) if err != nil { t.Fatal(err) } - _, err = h.GetHistoricCandles(currencyPair, asset.Spot, startTime.AddDate(0, 0, -7), time.Now(), kline.OneDay) + _, err = h.GetHistoricCandles(context.Background(), + currencyPair, asset.Spot, startTime.AddDate(0, 0, -7), time.Now(), kline.OneDay) if err != nil { t.Fatal(err) } - _, err = h.GetHistoricCandles(currencyPair, asset.Spot, startTime, time.Now(), kline.Interval(time.Hour*7)) + _, err = h.GetHistoricCandles(context.Background(), + currencyPair, asset.Spot, startTime, time.Now(), kline.Interval(time.Hour*7)) if err == nil { t.Fatal("unexpected result") } @@ -1568,12 +1616,14 @@ func TestGetHistoricCandlesExtended(t *testing.T) { t.Fatal(err) } startTime := time.Now().Add(-time.Minute * 2) - _, err = h.GetHistoricCandlesExtended(currencyPair, asset.Spot, startTime, time.Now(), kline.OneMin) + _, err = h.GetHistoricCandlesExtended(context.Background(), + currencyPair, asset.Spot, startTime, time.Now(), kline.OneMin) if err != nil { t.Fatal(err) } - _, err = h.GetHistoricCandlesExtended(currencyPair, asset.Spot, startTime, time.Now(), kline.Interval(time.Hour*7)) + _, err = h.GetHistoricCandlesExtended(context.Background(), + currencyPair, asset.Spot, startTime, time.Now(), kline.Interval(time.Hour*7)) if err == nil { t.Fatal("unexpected result") } @@ -1585,7 +1635,7 @@ func TestGetMarketDetailMerged(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.GetMarketDetailMerged(cp) + _, err = h.GetMarketDetailMerged(context.Background(), cp) if err != nil { t.Errorf("Huobi TestGetMarketDetailMerged: %s", err) } @@ -1597,10 +1647,11 @@ func TestGetDepth(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.GetDepth(OrderBookDataRequestParams{ - Symbol: cp, - Type: OrderBookDataRequestParamsTypeStep1, - }) + _, err = h.GetDepth(context.Background(), + OrderBookDataRequestParams{ + Symbol: cp, + Type: OrderBookDataRequestParamsTypeStep1, + }) if err != nil { t.Errorf("Huobi TestGetDepth: %s", err) } @@ -1612,7 +1663,7 @@ func TestGetTrades(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.GetTrades(cp) + _, err = h.GetTrades(context.Background(), cp) if err != nil { t.Errorf("Huobi TestGetTrades: %s", err) } @@ -1624,7 +1675,7 @@ func TestGetLatestSpotPrice(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.GetLatestSpotPrice(cp) + _, err = h.GetLatestSpotPrice(context.Background(), cp) if err != nil { t.Errorf("Huobi GetLatestSpotPrice: %s", err) } @@ -1636,7 +1687,7 @@ func TestGetTradeHistory(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.GetTradeHistory(cp, 50) + _, err = h.GetTradeHistory(context.Background(), cp, 50) if err != nil { t.Errorf("Huobi TestGetTradeHistory: %s", err) } @@ -1648,7 +1699,7 @@ func TestGetMarketDetail(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.GetMarketDetail(cp) + _, err = h.GetMarketDetail(context.Background(), cp) if err != nil { t.Errorf("Huobi TestGetTradeHistory: %s", err) } @@ -1656,7 +1707,7 @@ func TestGetMarketDetail(t *testing.T) { func TestGetSymbols(t *testing.T) { t.Parallel() - _, err := h.GetSymbols() + _, err := h.GetSymbols(context.Background()) if err != nil { t.Errorf("Huobi TestGetSymbols: %s", err) } @@ -1664,7 +1715,7 @@ func TestGetSymbols(t *testing.T) { func TestGetCurrencies(t *testing.T) { t.Parallel() - _, err := h.GetCurrencies() + _, err := h.GetCurrencies(context.Background()) if err != nil { t.Errorf("Huobi TestGetCurrencies: %s", err) } @@ -1676,7 +1727,7 @@ func TestGet24HrMarketSummary(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.Get24HrMarketSummary(cp) + _, err = h.Get24HrMarketSummary(context.Background(), cp) if err != nil { t.Error(err) } @@ -1684,7 +1735,7 @@ func TestGet24HrMarketSummary(t *testing.T) { func TestGetTicker(t *testing.T) { t.Parallel() - _, err := h.GetTickers() + _, err := h.GetTickers(context.Background()) if err != nil { t.Error(err) } @@ -1692,7 +1743,7 @@ func TestGetTicker(t *testing.T) { func TestGetTimestamp(t *testing.T) { t.Parallel() - _, err := h.GetTimestamp() + _, err := h.GetTimestamp(context.Background()) if err != nil { t.Errorf("Huobi TestGetTimestamp: %s", err) } @@ -1703,7 +1754,7 @@ func TestGetAccounts(t *testing.T) { if !h.ValidateAPICredentials() || !canManipulateRealOrders { t.Skip() } - _, err := h.GetAccounts() + _, err := h.GetAccounts(context.Background()) if err != nil { t.Errorf("Huobi GetAccounts: %s", err) } @@ -1714,13 +1765,13 @@ func TestGetAccountBalance(t *testing.T) { if !h.ValidateAPICredentials() { t.Skip() } - result, err := h.GetAccounts() + result, err := h.GetAccounts(context.Background()) if err != nil { t.Errorf("Huobi GetAccounts: %s", err) } userID := strconv.FormatInt(result[0].ID, 10) - _, err = h.GetAccountBalance(userID) + _, err = h.GetAccountBalance(context.Background(), userID) if err != nil { t.Errorf("Huobi GetAccountBalance: %s", err) } @@ -1732,7 +1783,7 @@ func TestGetAggregatedBalance(t *testing.T) { t.Skip() } - _, err := h.GetAggregatedBalance() + _, err := h.GetAggregatedBalance(context.Background()) if err != nil { t.Errorf("Huobi GetAggregatedBalance: %s", err) } @@ -1755,7 +1806,7 @@ func TestSpotNewOrder(t *testing.T) { Type: SpotNewOrderRequestTypeBuyLimit, } - _, err = h.SpotNewOrder(&arg) + _, err = h.SpotNewOrder(context.Background(), &arg) if err != nil { t.Errorf("Huobi SpotNewOrder: %s", err) } @@ -1766,7 +1817,7 @@ func TestCancelExistingOrder(t *testing.T) { if !h.ValidateAPICredentials() || !canManipulateRealOrders { t.Skip() } - _, err := h.CancelExistingOrder(1337) + _, err := h.CancelExistingOrder(context.Background(), 1337) if err == nil { t.Error("Huobi TestCancelExistingOrder Expected error") } @@ -1777,7 +1828,7 @@ func TestGetOrder(t *testing.T) { if !h.ValidateAPICredentials() || !canManipulateRealOrders { t.Skip() } - _, err := h.GetOrder(1337) + _, err := h.GetOrder(context.Background(), 1337) if err != nil { t.Error(err) } @@ -1792,7 +1843,8 @@ func TestGetMarginLoanOrders(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.GetMarginLoanOrders(cp, "", "", "", "", "", "", "") + _, err = h.GetMarginLoanOrders(context.Background(), + cp, "", "", "", "", "", "", "") if err != nil { t.Errorf("Huobi TestGetMarginLoanOrders: %s", err) } @@ -1807,7 +1859,7 @@ func TestGetMarginAccountBalance(t *testing.T) { if err != nil { t.Error(err) } - _, err = h.GetMarginAccountBalance(cp) + _, err = h.GetMarginAccountBalance(context.Background(), cp) if err != nil { t.Errorf("Huobi TestGetMarginAccountBalance: %s", err) } @@ -1818,7 +1870,7 @@ func TestCancelWithdraw(t *testing.T) { if !h.ValidateAPICredentials() || !canManipulateRealOrders { t.Skip() } - _, err := h.CancelWithdraw(1337) + _, err := h.CancelWithdraw(context.Background(), 1337) if err == nil { t.Error("Huobi TestCancelWithdraw Expected error") } @@ -1840,7 +1892,7 @@ func setFeeBuilder() *exchange.FeeBuilder { // TestGetFeeByTypeOfflineTradeFee logic test func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { var feeBuilder = setFeeBuilder() - _, err := h.GetFeeByType(feeBuilder) + _, err := h.GetFeeByType(context.Background(), feeBuilder) if err != nil { t.Fatal(err) } @@ -1931,7 +1983,7 @@ func TestGetActiveOrders(t *testing.T) { Pairs: []currency.Pair{currency.NewPair(currency.BTC, currency.USDT)}, } - _, err := h.GetActiveOrders(&getOrdersRequest) + _, err := h.GetActiveOrders(context.Background(), &getOrdersRequest) if areTestAPIKeysSet() && err == nil { t.Errorf("Could not get open orders: %s", err) } else if !areTestAPIKeysSet() && err == nil { @@ -1954,7 +2006,7 @@ func TestSubmitOrder(t *testing.T) { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - accounts, err := h.GetAccounts() + accounts, err := h.GetAccounts(context.Background()) if err != nil { t.Fatalf("Failed to get accounts. Err: %s", err) } @@ -1971,7 +2023,7 @@ func TestSubmitOrder(t *testing.T) { ClientID: strconv.FormatInt(accounts[0].ID, 10), AssetType: asset.Spot, } - response, err := h.SubmitOrder(orderSubmission) + response, err := h.SubmitOrder(context.Background(), orderSubmission) if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) { t.Errorf("Order failed to be placed: %v", err) } @@ -1991,7 +2043,7 @@ func TestCancelExchangeOrder(t *testing.T) { AssetType: asset.Spot, } - err := h.CancelOrder(orderCancellation) + err := h.CancelOrder(context.Background(), orderCancellation) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") @@ -2014,7 +2066,7 @@ func TestCancelAllExchangeOrders(t *testing.T) { AssetType: asset.Spot, } - _, err := h.CancelAllOrders(&orderCancellation) + _, err := h.CancelAllOrders(context.Background(), &orderCancellation) if err != nil { t.Error(err) } @@ -2023,21 +2075,23 @@ func TestCancelAllExchangeOrders(t *testing.T) { func TestGetAccountInfo(t *testing.T) { t.Parallel() if !areTestAPIKeysSet() { - _, err := h.UpdateAccountInfo(asset.CoinMarginedFutures) + _, err := h.UpdateAccountInfo(context.Background(), + asset.CoinMarginedFutures) if err == nil { t.Error("GetAccountInfo() Expected error") } - _, err = h.UpdateAccountInfo(asset.Futures) + _, err = h.UpdateAccountInfo(context.Background(), asset.Futures) if err == nil { t.Error("GetAccountInfo() Expected error") } } else { - _, err := h.UpdateAccountInfo(asset.CoinMarginedFutures) + _, err := h.UpdateAccountInfo(context.Background(), + asset.CoinMarginedFutures) if err != nil { // Spot and Futures have separate api keys. Please ensure that the correct keys are provided t.Error(err) } - _, err = h.UpdateAccountInfo(asset.Futures) + _, err = h.UpdateAccountInfo(context.Background(), asset.Futures) if err != nil { // Spot and Futures have separate api keys. Please ensure that the correct keys are provided t.Error(err) @@ -2050,7 +2104,7 @@ func TestGetSpotAccountInfo(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("skipping test: api keys not set") } - _, err := h.UpdateAccountInfo(asset.Spot) + _, err := h.UpdateAccountInfo(context.Background(), asset.Spot) if err != nil { // Spot and Futures have separate api keys. Please ensure that the correct keys are provided t.Error(err) @@ -2061,7 +2115,8 @@ func TestModifyOrder(t *testing.T) { if areTestAPIKeysSet() && !canManipulateRealOrders { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - _, err := h.ModifyOrder(&order.Modify{AssetType: asset.Spot}) + _, err := h.ModifyOrder(context.Background(), + &order.Modify{AssetType: asset.Spot}) if err == nil { t.Error("ModifyOrder() Expected error") } @@ -2081,7 +2136,8 @@ func TestWithdraw(t *testing.T) { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - _, err := h.WithdrawCryptocurrencyFunds(&withdrawCryptoRequest) + _, err := h.WithdrawCryptocurrencyFunds(context.Background(), + &withdrawCryptoRequest) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") } @@ -2096,7 +2152,7 @@ func TestWithdrawFiat(t *testing.T) { } var withdrawFiatRequest = withdraw.Request{} - _, err := h.WithdrawFiatFunds(&withdrawFiatRequest) + _, err := h.WithdrawFiatFunds(context.Background(), &withdrawFiatRequest) if err != common.ErrFunctionNotSupported { t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err) } @@ -2108,14 +2164,16 @@ func TestWithdrawInternationalBank(t *testing.T) { } var withdrawFiatRequest = withdraw.Request{} - _, err := h.WithdrawFiatFundsToInternationalBank(&withdrawFiatRequest) + _, err := h.WithdrawFiatFundsToInternationalBank(context.Background(), + &withdrawFiatRequest) if err != common.ErrFunctionNotSupported { t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err) } } func TestQueryDepositAddress(t *testing.T) { - _, err := h.QueryDepositAddress(currency.BTC.Lower().String()) + _, err := h.QueryDepositAddress(context.Background(), + currency.BTC.Lower().String()) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") } @@ -2125,7 +2183,8 @@ func TestQueryDepositAddress(t *testing.T) { } func TestQueryWithdrawQuota(t *testing.T) { - _, err := h.QueryWithdrawQuotas(currency.BTC.Lower().String()) + _, err := h.QueryWithdrawQuotas(context.Background(), + currency.BTC.Lower().String()) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") } @@ -2600,7 +2659,7 @@ func TestGetRecentTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = h.GetRecentTrades(currencyPair, asset.Spot) + _, err = h.GetRecentTrades(context.Background(), currencyPair, asset.Spot) if err != nil { t.Error(err) } @@ -2612,7 +2671,8 @@ func TestGetHistoricTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = h.GetHistoricTrades(currencyPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) + _, err = h.GetHistoricTrades(context.Background(), + currencyPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) if err != nil && err != common.ErrFunctionNotSupported { t.Error(err) } diff --git a/exchanges/huobi/huobi_wrapper.go b/exchanges/huobi/huobi_wrapper.go index 13b461ee..73fdbcb3 100644 --- a/exchanges/huobi/huobi_wrapper.go +++ b/exchanges/huobi/huobi_wrapper.go @@ -1,6 +1,7 @@ package huobi import ( + "context" "errors" "fmt" "sort" @@ -41,7 +42,7 @@ func (h *HUOBI) GetDefaultConfig() (*config.ExchangeConfig, error) { } if h.Features.Supports.RESTCapabilities.AutoPairUpdates { - err = h.UpdateTradablePairs(true) + err = h.UpdateTradablePairs(context.TODO(), true) if err != nil { return nil, err } @@ -319,7 +320,7 @@ func (h *HUOBI) Run() { return } - err = h.UpdateTradablePairs(forceUpdate) + err = h.UpdateTradablePairs(context.TODO(), forceUpdate) if err != nil { log.Errorf(log.ExchangeSys, "%s failed to update tradable pairs. Err: %s", @@ -329,7 +330,7 @@ func (h *HUOBI) Run() { } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (h *HUOBI) FetchTradablePairs(a asset.Item) ([]string, error) { +func (h *HUOBI) FetchTradablePairs(ctx context.Context, a asset.Item) ([]string, error) { if !h.SupportsAsset(a) { return nil, fmt.Errorf("asset type of %s is not supported by %s", a, h.Name) } @@ -343,7 +344,7 @@ func (h *HUOBI) FetchTradablePairs(a asset.Item) ([]string, error) { switch a { case asset.Spot: - symbols, err := h.GetSymbols() + symbols, err := h.GetSymbols(ctx) if err != nil { return nil, err } @@ -358,7 +359,7 @@ func (h *HUOBI) FetchTradablePairs(a asset.Item) ([]string, error) { } case asset.CoinMarginedFutures: - symbols, err := h.GetSwapMarkets(currency.Pair{}) + symbols, err := h.GetSwapMarkets(ctx, currency.Pair{}) if err != nil { return nil, err } @@ -373,7 +374,7 @@ func (h *HUOBI) FetchTradablePairs(a asset.Item) ([]string, error) { } } case asset.Futures: - symbols, err := h.FGetContractInfo("", "", currency.Pair{}) + symbols, err := h.FGetContractInfo(ctx, "", "", currency.Pair{}) if err != nil { return nil, err } @@ -393,8 +394,8 @@ func (h *HUOBI) FetchTradablePairs(a asset.Item) ([]string, error) { // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (h *HUOBI) UpdateTradablePairs(forceUpdate bool) error { - spotPairs, err := h.FetchTradablePairs(asset.Spot) +func (h *HUOBI) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { + spotPairs, err := h.FetchTradablePairs(ctx, asset.Spot) if err != nil { return err } @@ -407,7 +408,7 @@ func (h *HUOBI) UpdateTradablePairs(forceUpdate bool) error { return err } - futuresPairs, err := h.FetchTradablePairs(asset.Futures) + futuresPairs, err := h.FetchTradablePairs(ctx, asset.Futures) if err != nil { return err } @@ -420,7 +421,7 @@ func (h *HUOBI) UpdateTradablePairs(forceUpdate bool) error { return err } - coinmarginedFuturesPairs, err := h.FetchTradablePairs(asset.CoinMarginedFutures) + coinmarginedFuturesPairs, err := h.FetchTradablePairs(ctx, asset.CoinMarginedFutures) if err != nil { return err } @@ -432,18 +433,18 @@ func (h *HUOBI) UpdateTradablePairs(forceUpdate bool) error { } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (h *HUOBI) UpdateTickers(a asset.Item) error { +func (h *HUOBI) UpdateTickers(ctx context.Context, a asset.Item) error { return common.ErrFunctionNotSupported } // UpdateTicker updates and returns the ticker for a currency pair -func (h *HUOBI) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) { +func (h *HUOBI) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { if !h.SupportsAsset(a) { return nil, fmt.Errorf("asset type of %s is not supported by %s", a, h.Name) } switch a { case asset.Spot: - tickerData, err := h.Get24HrMarketSummary(p) + tickerData, err := h.Get24HrMarketSummary(ctx, p) if err != nil { return nil, err } @@ -461,7 +462,7 @@ func (h *HUOBI) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, erro return nil, err } case asset.CoinMarginedFutures: - marketData, err := h.GetSwapMarketOverview(p) + marketData, err := h.GetSwapMarketOverview(ctx, p) if err != nil { return nil, err } @@ -489,7 +490,7 @@ func (h *HUOBI) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, erro return nil, err } case asset.Futures: - marketData, err := h.FGetMarketOverviewData(p) + marketData, err := h.FGetMarketOverviewData(ctx, p) if err != nil { return nil, err } @@ -514,25 +515,25 @@ func (h *HUOBI) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, erro } // FetchTicker returns the ticker for a currency pair -func (h *HUOBI) FetchTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) { +func (h *HUOBI) FetchTicker(ctx context.Context, p currency.Pair, assetType asset.Item) (*ticker.Price, error) { tickerNew, err := ticker.GetTicker(h.Name, p, assetType) if err != nil { - return h.UpdateTicker(p, assetType) + return h.UpdateTicker(ctx, p, assetType) } return tickerNew, nil } // FetchOrderbook returns orderbook base on the currency pair -func (h *HUOBI) FetchOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (h *HUOBI) FetchOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { ob, err := orderbook.Get(h.Name, p, assetType) if err != nil { - return h.UpdateOrderbook(p, assetType) + return h.UpdateOrderbook(ctx, p, assetType) } return ob, nil } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (h *HUOBI) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (h *HUOBI) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { book := &orderbook.Base{ Exchange: h.Name, Pair: p, @@ -543,10 +544,11 @@ func (h *HUOBI) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderbo switch assetType { case asset.Spot: var orderbookNew Orderbook - orderbookNew, err = h.GetDepth(OrderBookDataRequestParams{ - Symbol: p, - Type: OrderBookDataRequestParamsTypeStep0, - }) + orderbookNew, err = h.GetDepth(ctx, + OrderBookDataRequestParams{ + Symbol: p, + Type: OrderBookDataRequestParamsTypeStep0, + }) if err != nil { return nil, err } @@ -567,7 +569,7 @@ func (h *HUOBI) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderbo case asset.Futures: var orderbookNew OBData - orderbookNew, err = h.FGetMarketDepth(p, "step0") + orderbookNew, err = h.FGetMarketDepth(ctx, p, "step0") if err != nil { return nil, err } @@ -587,7 +589,7 @@ func (h *HUOBI) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderbo case asset.CoinMarginedFutures: var orderbookNew SwapMarketDepthData - orderbookNew, err = h.GetSwapMarketDepth(p, "step0") + orderbookNew, err = h.GetSwapMarketDepth(ctx, p, "step0") if err != nil { return nil, err } @@ -613,8 +615,8 @@ func (h *HUOBI) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderbo } // GetAccountID returns the account ID for trades -func (h *HUOBI) GetAccountID() ([]Account, error) { - acc, err := h.GetAccounts() +func (h *HUOBI) GetAccountID(ctx context.Context) ([]Account, error) { + acc, err := h.GetAccounts(ctx) if err != nil { return nil, err } @@ -628,7 +630,7 @@ func (h *HUOBI) GetAccountID() ([]Account, error) { // UpdateAccountInfo retrieves balances for all enabled currencies for the // HUOBI exchange - to-do -func (h *HUOBI) UpdateAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (h *HUOBI) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { var info account.Holdings var acc account.SubAccount info.Exchange = h.Name @@ -655,13 +657,13 @@ func (h *HUOBI) UpdateAccountInfo(assetType asset.Item) (account.Holdings, error } acc.Currencies = currencyDetails } else { - accounts, err := h.GetAccountID() + accounts, err := h.GetAccountID(ctx) if err != nil { return info, err } for i := range accounts { acc.ID = strconv.FormatInt(accounts[i].ID, 10) - balances, err := h.GetAccountBalance(acc.ID) + balances, err := h.GetAccountBalance(ctx, acc.ID) if err != nil { return info, err } @@ -700,13 +702,15 @@ func (h *HUOBI) UpdateAccountInfo(assetType asset.Item) (account.Holdings, error } case asset.CoinMarginedFutures: - subAccsData, err := h.GetSwapAllSubAccAssets(currency.Pair{}) + subAccsData, err := h.GetSwapAllSubAccAssets(ctx, currency.Pair{}) if err != nil { return info, err } var currencyDetails []account.Balance for x := range subAccsData.Data { - a, err := h.SwapSingleSubAccAssets(currency.Pair{}, subAccsData.Data[x].SubUID) + a, err := h.SwapSingleSubAccAssets(ctx, + currency.Pair{}, + subAccsData.Data[x].SubUID) if err != nil { return info, err } @@ -720,13 +724,15 @@ func (h *HUOBI) UpdateAccountInfo(assetType asset.Item) (account.Holdings, error } acc.Currencies = currencyDetails case asset.Futures: - subAccsData, err := h.FGetAllSubAccountAssets(currency.Code{}) + subAccsData, err := h.FGetAllSubAccountAssets(ctx, currency.Code{}) if err != nil { return info, err } var currencyDetails []account.Balance for x := range subAccsData.Data { - a, err := h.FGetSingleSubAccountInfo("", strconv.FormatInt(subAccsData.Data[x].SubUID, 10)) + a, err := h.FGetSingleSubAccountInfo(ctx, + "", + strconv.FormatInt(subAccsData.Data[x].SubUID, 10)) if err != nil { return info, err } @@ -750,30 +756,30 @@ func (h *HUOBI) UpdateAccountInfo(assetType asset.Item) (account.Holdings, error } // FetchAccountInfo retrieves balances for all enabled currencies -func (h *HUOBI) FetchAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (h *HUOBI) FetchAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { acc, err := account.GetHoldings(h.Name, assetType) if err != nil { - return h.UpdateAccountInfo(assetType) + return h.UpdateAccountInfo(ctx, assetType) } return acc, nil } // GetFundingHistory returns funding history, deposits and // withdrawals -func (h *HUOBI) GetFundingHistory() ([]exchange.FundHistory, error) { +func (h *HUOBI) GetFundingHistory(ctx context.Context) ([]exchange.FundHistory, error) { return nil, common.ErrFunctionNotSupported } // GetWithdrawalsHistory returns previous withdrawals data -func (h *HUOBI) GetWithdrawalsHistory(c currency.Code) (resp []exchange.WithdrawalHistory, err error) { +func (h *HUOBI) GetWithdrawalsHistory(ctx context.Context, c currency.Code) (resp []exchange.WithdrawalHistory, err error) { return nil, common.ErrNotYetImplemented } // GetRecentTrades returns the most recent trades for a currency and asset -func (h *HUOBI) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade.Data, error) { +func (h *HUOBI) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { var err error var tradeData []TradeHistory - tradeData, err = h.GetTradeHistory(p, 2000) + tradeData, err = h.GetTradeHistory(ctx, p, 2000) if err != nil { return nil, err } @@ -808,12 +814,12 @@ func (h *HUOBI) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade. } // GetHistoricTrades returns historic trade data within the timeframe provided -func (h *HUOBI) GetHistoricTrades(_ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { +func (h *HUOBI) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { return nil, common.ErrFunctionNotSupported } // SubmitOrder submits a new order -func (h *HUOBI) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { +func (h *HUOBI) SubmitOrder(ctx context.Context, s *order.Submit) (order.SubmitResponse, error) { var submitOrderResponse order.SubmitResponse if err := s.Validate(); err != nil { return submitOrderResponse, err @@ -844,7 +850,7 @@ func (h *HUOBI) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { params.Price = s.Price } params.Type = formattedType - response, err := h.SpotNewOrder(¶ms) + response, err := h.SpotNewOrder(ctx, ¶ms) if err != nil { return submitOrderResponse, err } @@ -870,7 +876,15 @@ func (h *HUOBI) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { case order.PostOnly: oType = "post_only" } - order, err := h.PlaceSwapOrders(s.Pair, s.ClientOrderID, oDirection, s.Offset, oType, s.Price, s.Amount, s.Leverage) + order, err := h.PlaceSwapOrders(ctx, + s.Pair, + s.ClientOrderID, + oDirection, + s.Offset, + oType, + s.Price, + s.Amount, + s.Leverage) if err != nil { return submitOrderResponse, err } @@ -891,7 +905,17 @@ func (h *HUOBI) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { case order.PostOnly: oType = "post_only" } - order, err := h.FOrder(s.Pair, "", "", s.ClientOrderID, oDirection, s.Offset, oType, s.Price, s.Amount, s.Leverage) + order, err := h.FOrder(ctx, + s.Pair, + "", + "", + s.ClientOrderID, + oDirection, + s.Offset, + oType, + s.Price, + s.Amount, + s.Leverage) if err != nil { return submitOrderResponse, err } @@ -903,12 +927,12 @@ func (h *HUOBI) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (h *HUOBI) ModifyOrder(action *order.Modify) (order.Modify, error) { +func (h *HUOBI) ModifyOrder(ctx context.Context, action *order.Modify) (order.Modify, error) { return order.Modify{}, common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number -func (h *HUOBI) CancelOrder(o *order.Cancel) error { +func (h *HUOBI) CancelOrder(ctx context.Context, o *order.Cancel) error { if err := o.Validate(o.StandardCancel()); err != nil { return err } @@ -920,11 +944,11 @@ func (h *HUOBI) CancelOrder(o *order.Cancel) error { if err != nil { return err } - _, err = h.CancelExistingOrder(orderIDInt) + _, err = h.CancelExistingOrder(ctx, orderIDInt) case asset.CoinMarginedFutures: - _, err = h.CancelSwapOrder(o.ID, o.ClientID, o.Pair) + _, err = h.CancelSwapOrder(ctx, o.ID, o.ClientID, o.Pair) case asset.Futures: - _, err = h.FCancelOrder(o.Symbol, o.ClientID, o.ClientOrderID) + _, err = h.FCancelOrder(ctx, o.Symbol, o.ClientID, o.ClientOrderID) default: return fmt.Errorf("%v assetType not supported", o.AssetType) } @@ -932,12 +956,12 @@ func (h *HUOBI) CancelOrder(o *order.Cancel) error { } // CancelBatchOrders cancels an orders by their corresponding ID numbers -func (h *HUOBI) CancelBatchOrders(o []order.Cancel) (order.CancelBatchResponse, error) { +func (h *HUOBI) CancelBatchOrders(ctx context.Context, o []order.Cancel) (order.CancelBatchResponse, error) { return order.CancelBatchResponse{}, common.ErrNotYetImplemented } // CancelAllOrders cancels all orders associated with a currency pair -func (h *HUOBI) CancelAllOrders(orderCancellation *order.Cancel) (order.CancelAllResponse, error) { +func (h *HUOBI) CancelAllOrders(ctx context.Context, orderCancellation *order.Cancel) (order.CancelAllResponse, error) { if err := orderCancellation.Validate(); err != nil { return order.CancelAllResponse{}, err } @@ -950,7 +974,8 @@ func (h *HUOBI) CancelAllOrders(orderCancellation *order.Cancel) (order.CancelAl return cancelAllOrdersResponse, err } for i := range enabledPairs { - resp, err := h.CancelOpenOrdersBatch(orderCancellation.AccountID, + resp, err := h.CancelOpenOrdersBatch(ctx, + orderCancellation.AccountID, enabledPairs[i]) if err != nil { return cancelAllOrdersResponse, err @@ -971,7 +996,7 @@ func (h *HUOBI) CancelAllOrders(orderCancellation *order.Cancel) (order.CancelAl return cancelAllOrdersResponse, err } for i := range enabledPairs { - a, err := h.CancelAllSwapOrders(enabledPairs[i]) + a, err := h.CancelAllSwapOrders(ctx, enabledPairs[i]) if err != nil { return cancelAllOrdersResponse, err } @@ -984,7 +1009,7 @@ func (h *HUOBI) CancelAllOrders(orderCancellation *order.Cancel) (order.CancelAl } } } else { - a, err := h.CancelAllSwapOrders(orderCancellation.Pair) + a, err := h.CancelAllSwapOrders(ctx, orderCancellation.Pair) if err != nil { return cancelAllOrdersResponse, err } @@ -1003,7 +1028,7 @@ func (h *HUOBI) CancelAllOrders(orderCancellation *order.Cancel) (order.CancelAl return cancelAllOrdersResponse, err } for i := range enabledPairs { - a, err := h.FCancelAllOrders(enabledPairs[i], "", "") + a, err := h.FCancelAllOrders(ctx, enabledPairs[i], "", "") if err != nil { return cancelAllOrdersResponse, err } @@ -1016,7 +1041,7 @@ func (h *HUOBI) CancelAllOrders(orderCancellation *order.Cancel) (order.CancelAl } } } else { - a, err := h.FCancelAllOrders(orderCancellation.Pair, "", "") + a, err := h.FCancelAllOrders(ctx, orderCancellation.Pair, "", "") if err != nil { return cancelAllOrdersResponse, err } @@ -1033,7 +1058,7 @@ func (h *HUOBI) CancelAllOrders(orderCancellation *order.Cancel) (order.CancelAl } // GetOrderInfo returns order information based on order ID -func (h *HUOBI) GetOrderInfo(orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { +func (h *HUOBI) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { var orderDetail order.Detail switch assetType { case asset.Spot: @@ -1049,7 +1074,7 @@ func (h *HUOBI) GetOrderInfo(orderID string, pair currency.Pair, assetType asset if err != nil { return orderDetail, err } - resp, err := h.GetOrder(oID) + resp, err := h.GetOrder(ctx, oID) if err != nil { return orderDetail, err } @@ -1122,7 +1147,7 @@ func (h *HUOBI) GetOrderInfo(orderID string, pair currency.Pair, assetType asset AssetType: a, } case asset.CoinMarginedFutures: - orderInfo, err := h.GetSwapOrderInfo(pair, orderID, "") + orderInfo, err := h.GetSwapOrderInfo(ctx, pair, orderID, "") if err != nil { return orderDetail, err } @@ -1148,7 +1173,7 @@ func (h *HUOBI) GetOrderInfo(orderID string, pair currency.Pair, assetType asset }) } case asset.Futures: - orderInfo, err := h.FGetOrderInfo("", orderID, "") + orderInfo, err := h.FGetOrderInfo(ctx, "", orderID, "") if err != nil { return orderDetail, err } @@ -1175,18 +1200,19 @@ func (h *HUOBI) GetOrderInfo(orderID string, pair currency.Pair, assetType asset } // GetDepositAddress returns a deposit address for a specified currency -func (h *HUOBI) GetDepositAddress(cryptocurrency currency.Code, _ string) (string, error) { - resp, err := h.QueryDepositAddress(cryptocurrency.Lower().String()) +func (h *HUOBI) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _ string) (string, error) { + resp, err := h.QueryDepositAddress(ctx, cryptocurrency.Lower().String()) return resp.Address, err } // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is // submitted -func (h *HUOBI) WithdrawCryptocurrencyFunds(withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (h *HUOBI) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } - resp, err := h.Withdraw(withdrawRequest.Currency, + resp, err := h.Withdraw(ctx, + withdrawRequest.Currency, withdrawRequest.Crypto.Address, withdrawRequest.Crypto.AddressTag, withdrawRequest.Amount, @@ -1201,18 +1227,18 @@ func (h *HUOBI) WithdrawCryptocurrencyFunds(withdrawRequest *withdraw.Request) ( // WithdrawFiatFunds returns a withdrawal ID when a // withdrawal is submitted -func (h *HUOBI) WithdrawFiatFunds(_ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (h *HUOBI) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a // withdrawal is submitted -func (h *HUOBI) WithdrawFiatFundsToInternationalBank(_ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (h *HUOBI) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // GetFeeByType returns an estimate of fee based on type of transaction -func (h *HUOBI) GetFeeByType(feeBuilder *exchange.FeeBuilder) (float64, error) { +func (h *HUOBI) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { if !h.AllowAuthenticatedRequest() && // Todo check connection status feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { feeBuilder.FeeType = exchange.OfflineTradeFee @@ -1221,7 +1247,7 @@ func (h *HUOBI) GetFeeByType(feeBuilder *exchange.FeeBuilder) (float64, error) { } // GetActiveOrders retrieves any orders that are active/open -func (h *HUOBI) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, error) { +func (h *HUOBI) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) { if err := req.Validate(); err != nil { return nil, err } @@ -1290,7 +1316,8 @@ func (h *HUOBI) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, er } } else { for i := range req.Pairs { - resp, err := h.GetOpenOrders(req.Pairs[i], + resp, err := h.GetOpenOrders(ctx, + req.Pairs[i], h.API.Credentials.ClientID, side, 500) @@ -1319,7 +1346,8 @@ func (h *HUOBI) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, er for x := range req.Pairs { var currentPage int64 = 0 for done := false; !done; { - openOrders, err := h.GetSwapOpenOrders(req.Pairs[x], currentPage, 50) + openOrders, err := h.GetSwapOpenOrders(ctx, + req.Pairs[x], currentPage, 50) if err != nil { return orders, err } @@ -1358,7 +1386,8 @@ func (h *HUOBI) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, er for x := range req.Pairs { var currentPage int64 = 0 for done := false; !done; { - openOrders, err := h.FGetOpenOrders(req.Pairs[x].Base, currentPage, 50) + openOrders, err := h.FGetOpenOrders(ctx, + req.Pairs[x].Base, currentPage, 50) if err != nil { return orders, err } @@ -1402,7 +1431,7 @@ func (h *HUOBI) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, er // GetOrderHistory retrieves account order information // Can Limit response to specific order status -func (h *HUOBI) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, error) { +func (h *HUOBI) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) { if err := req.Validate(); err != nil { return nil, err } @@ -1414,7 +1443,7 @@ func (h *HUOBI) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, er } states := "partial-canceled,filled,canceled" for i := range req.Pairs { - resp, err := h.GetOrders( + resp, err := h.GetOrders(ctx, req.Pairs[i], "", "", @@ -1447,7 +1476,14 @@ func (h *HUOBI) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, er for x := range req.Pairs { var currentPage int64 = 0 for done := false; !done; { - orderHistory, err := h.GetSwapOrderHistory(req.Pairs[x], "all", "all", []order.Status{order.AnyStatus}, int64(req.EndTime.Sub(req.StartTime).Hours()/24), currentPage, 50) + orderHistory, err := h.GetSwapOrderHistory(ctx, + req.Pairs[x], + "all", + "all", + []order.Status{order.AnyStatus}, + int64(req.EndTime.Sub(req.StartTime).Hours()/24), + currentPage, + 50) if err != nil { return orders, err } @@ -1491,7 +1527,16 @@ func (h *HUOBI) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, er for x := range req.Pairs { var currentPage int64 = 0 for done := false; !done; { - openOrders, err := h.FGetOrderHistory(req.Pairs[x], "", "all", "all", "limit", []order.Status{order.AnyStatus}, int64(req.EndTime.Sub(req.StartTime).Hours()/24), currentPage, 50) + openOrders, err := h.FGetOrderHistory(ctx, + req.Pairs[x], + "", + "all", + "all", + "limit", + []order.Status{order.AnyStatus}, + int64(req.EndTime.Sub(req.StartTime).Hours()/24), + currentPage, + 50) if err != nil { return orders, err } @@ -1562,14 +1607,14 @@ func setOrderSideAndType(requestType string, orderDetail *order.Detail) { } // AuthenticateWebsocket sends an authentication message to the websocket -func (h *HUOBI) AuthenticateWebsocket() error { +func (h *HUOBI) AuthenticateWebsocket(_ context.Context) error { return h.wsLogin() } // ValidateCredentials validates current credentials used for wrapper // functionality -func (h *HUOBI) ValidateCredentials(assetType asset.Item) error { - _, err := h.UpdateAccountInfo(assetType) +func (h *HUOBI) ValidateCredentials(ctx context.Context, assetType asset.Item) error { + _, err := h.UpdateAccountInfo(ctx, assetType) return h.CheckTransientError(err) } @@ -1593,7 +1638,7 @@ func (h *HUOBI) FormatExchangeKlineInterval(in kline.Interval) string { } // GetHistoricCandles returns candles between a time period for a set time interval -func (h *HUOBI) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (h *HUOBI) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { if err := h.ValidateKline(pair, a, interval); err != nil { return kline.Item{}, err } @@ -1601,7 +1646,7 @@ func (h *HUOBI) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end Period: h.FormatExchangeKlineInterval(interval), Symbol: pair, } - candles, err := h.GetSpotKline(klineParams) + candles, err := h.GetSpotKline(ctx, klineParams) if err != nil { return kline.Item{}, err } @@ -1630,8 +1675,8 @@ func (h *HUOBI) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (h *HUOBI) GetHistoricCandlesExtended(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { - return h.GetHistoricCandles(pair, a, start, end, interval) +func (h *HUOBI) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { + return h.GetHistoricCandles(ctx, pair, a, start, end, interval) } // compatibleVars gets compatible variables for order vars diff --git a/exchanges/interfaces.go b/exchanges/interfaces.go index 4e9853ca..54937bf3 100644 --- a/exchanges/interfaces.go +++ b/exchanges/interfaces.go @@ -1,6 +1,7 @@ package exchange import ( + "context" "sync" "time" @@ -26,44 +27,44 @@ type IBotExchange interface { GetName() string IsEnabled() bool SetEnabled(bool) - ValidateCredentials(a asset.Item) error - FetchTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) - UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) - UpdateTickers(a asset.Item) error - FetchOrderbook(p currency.Pair, a asset.Item) (*orderbook.Base, error) - UpdateOrderbook(p currency.Pair, a asset.Item) (*orderbook.Base, error) - FetchTradablePairs(a asset.Item) ([]string, error) - UpdateTradablePairs(forceUpdate bool) error + ValidateCredentials(ctx context.Context, a asset.Item) error + FetchTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) + UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) + UpdateTickers(ctx context.Context, a asset.Item) error + FetchOrderbook(ctx context.Context, p currency.Pair, a asset.Item) (*orderbook.Base, error) + UpdateOrderbook(ctx context.Context, p currency.Pair, a asset.Item) (*orderbook.Base, error) + FetchTradablePairs(ctx context.Context, a asset.Item) ([]string, error) + UpdateTradablePairs(ctx context.Context, forceUpdate bool) error GetEnabledPairs(a asset.Item) (currency.Pairs, error) GetAvailablePairs(a asset.Item) (currency.Pairs, error) - FetchAccountInfo(a asset.Item) (account.Holdings, error) - UpdateAccountInfo(a asset.Item) (account.Holdings, error) + FetchAccountInfo(ctx context.Context, a asset.Item) (account.Holdings, error) + UpdateAccountInfo(ctx context.Context, a asset.Item) (account.Holdings, error) GetAuthenticatedAPISupport(endpoint uint8) bool SetPairs(pairs currency.Pairs, a asset.Item, enabled bool) error GetAssetTypes(enabled bool) asset.Items - GetRecentTrades(p currency.Pair, a asset.Item) ([]trade.Data, error) - GetHistoricTrades(p currency.Pair, a asset.Item, startTime, endTime time.Time) ([]trade.Data, error) + GetRecentTrades(ctx context.Context, p currency.Pair, a asset.Item) ([]trade.Data, error) + GetHistoricTrades(ctx context.Context, p currency.Pair, a asset.Item, startTime, endTime time.Time) ([]trade.Data, error) SupportsAutoPairUpdates() bool SupportsRESTTickerBatchUpdates() bool - GetFeeByType(f *FeeBuilder) (float64, error) + GetFeeByType(ctx context.Context, f *FeeBuilder) (float64, error) GetLastPairsUpdateTime() int64 GetWithdrawPermissions() uint32 FormatWithdrawPermissions() string SupportsWithdrawPermissions(permissions uint32) bool - GetFundingHistory() ([]FundHistory, error) - SubmitOrder(s *order.Submit) (order.SubmitResponse, error) - ModifyOrder(action *order.Modify) (order.Modify, error) - CancelOrder(o *order.Cancel) error - CancelBatchOrders(o []order.Cancel) (order.CancelBatchResponse, error) - CancelAllOrders(orders *order.Cancel) (order.CancelAllResponse, error) - GetOrderInfo(orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) - GetDepositAddress(cryptocurrency currency.Code, accountID string) (string, error) - GetOrderHistory(getOrdersRequest *order.GetOrdersRequest) ([]order.Detail, error) - GetWithdrawalsHistory(code currency.Code) ([]WithdrawalHistory, error) - GetActiveOrders(getOrdersRequest *order.GetOrdersRequest) ([]order.Detail, error) - WithdrawCryptocurrencyFunds(withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) - WithdrawFiatFunds(withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) - WithdrawFiatFundsToInternationalBank(withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) + GetFundingHistory(ctx context.Context) ([]FundHistory, error) + SubmitOrder(ctx context.Context, s *order.Submit) (order.SubmitResponse, error) + ModifyOrder(ctx context.Context, action *order.Modify) (order.Modify, error) + CancelOrder(ctx context.Context, o *order.Cancel) error + CancelBatchOrders(ctx context.Context, o []order.Cancel) (order.CancelBatchResponse, error) + CancelAllOrders(ctx context.Context, orders *order.Cancel) (order.CancelAllResponse, error) + GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) + GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, accountID string) (string, error) + GetOrderHistory(ctx context.Context, getOrdersRequest *order.GetOrdersRequest) ([]order.Detail, error) + GetWithdrawalsHistory(ctx context.Context, code currency.Code) ([]WithdrawalHistory, error) + GetActiveOrders(ctx context.Context, getOrdersRequest *order.GetOrdersRequest) ([]order.Detail, error) + WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) + WithdrawFiatFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) + WithdrawFiatFundsToInternationalBank(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) SetHTTPClientUserAgent(ua string) GetHTTPClientUserAgent() string SetClientProxyAddress(addr string) error @@ -72,8 +73,8 @@ type IBotExchange interface { GetDefaultConfig() (*config.ExchangeConfig, error) GetBase() *Base SupportsAsset(assetType asset.Item) bool - GetHistoricCandles(p currency.Pair, a asset.Item, timeStart, timeEnd time.Time, interval kline.Interval) (kline.Item, error) - GetHistoricCandlesExtended(p currency.Pair, a asset.Item, timeStart, timeEnd time.Time, interval kline.Interval) (kline.Item, error) + GetHistoricCandles(ctx context.Context, p currency.Pair, a asset.Item, timeStart, timeEnd time.Time, interval kline.Interval) (kline.Item, error) + GetHistoricCandlesExtended(ctx context.Context, p currency.Pair, a asset.Item, timeStart, timeEnd time.Time, interval kline.Interval) (kline.Item, error) DisableRateLimiter() error EnableRateLimiter() error @@ -84,9 +85,9 @@ type IBotExchange interface { UnsubscribeToWebsocketChannels(channels []stream.ChannelSubscription) error IsAssetWebsocketSupported(aType asset.Item) bool FlushWebsocketChannels() error - AuthenticateWebsocket() error + AuthenticateWebsocket(ctx context.Context) error GetOrderExecutionLimits(a asset.Item, cp currency.Pair) (*order.Limits, error) CheckOrderExecutionLimits(a asset.Item, cp currency.Pair, price, amount float64, orderType order.Type) error - UpdateOrderExecutionLimits(a asset.Item) error + UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) error } diff --git a/exchanges/itbit/itbit.go b/exchanges/itbit/itbit.go index b4793f3a..ea769c7e 100644 --- a/exchanges/itbit/itbit.go +++ b/exchanges/itbit/itbit.go @@ -40,27 +40,27 @@ type ItBit struct { // GetTicker returns ticker info for a specified market. // currencyPair - example "XBTUSD" "XBTSGD" "XBTEUR" -func (i *ItBit) GetTicker(currencyPair string) (Ticker, error) { +func (i *ItBit) GetTicker(ctx context.Context, currencyPair string) (Ticker, error) { var response Ticker path := fmt.Sprintf("/%s/%s/%s", itbitMarkets, currencyPair, itbitTicker) - return response, i.SendHTTPRequest(exchange.RestSpot, path, &response) + return response, i.SendHTTPRequest(ctx, exchange.RestSpot, path, &response) } // GetOrderbook returns full order book for the specified market. // currencyPair - example "XBTUSD" "XBTSGD" "XBTEUR" -func (i *ItBit) GetOrderbook(currencyPair string) (OrderbookResponse, error) { +func (i *ItBit) GetOrderbook(ctx context.Context, currencyPair string) (OrderbookResponse, error) { response := OrderbookResponse{} path := fmt.Sprintf("/%s/%s/%s", itbitMarkets, currencyPair, itbitOrderbook) - return response, i.SendHTTPRequest(exchange.RestSpot, path, &response) + return response, i.SendHTTPRequest(ctx, exchange.RestSpot, path, &response) } // GetTradeHistory returns recent trades for a specified market. // // currencyPair - example "XBTUSD" "XBTSGD" "XBTEUR" // timestamp - matchNumber, only executions after this will be returned -func (i *ItBit) GetTradeHistory(currencyPair, tradeID string) (Trades, error) { +func (i *ItBit) GetTradeHistory(ctx context.Context, currencyPair, tradeID string) (Trades, error) { response := Trades{} var req = itbitTrades @@ -69,7 +69,7 @@ func (i *ItBit) GetTradeHistory(currencyPair, tradeID string) (Trades, error) { } path := fmt.Sprintf("/%s/%s/%s", itbitMarkets, currencyPair, req) - return response, i.SendHTTPRequest(exchange.RestSpot, path, &response) + return response, i.SendHTTPRequest(ctx, exchange.RestSpot, path, &response) } // GetWallets returns information about all wallets associated with the account. @@ -77,21 +77,21 @@ func (i *ItBit) GetTradeHistory(currencyPair, tradeID string) (Trades, error) { // params -- // page - [optional] page to return example 1. default 1 // perPage - [optional] items per page example 50, default 50 max 50 -func (i *ItBit) GetWallets(params url.Values) ([]Wallet, error) { +func (i *ItBit) GetWallets(ctx context.Context, params url.Values) ([]Wallet, error) { var resp []Wallet params.Set("userId", i.API.Credentials.ClientID) path := fmt.Sprintf("/%s?%s", itbitWallets, params.Encode()) - return resp, i.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, path, nil, &resp) + return resp, i.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, path, nil, &resp) } // CreateWallet creates a new wallet with a specified name. -func (i *ItBit) CreateWallet(walletName string) (Wallet, error) { +func (i *ItBit) CreateWallet(ctx context.Context, walletName string) (Wallet, error) { resp := Wallet{} params := make(map[string]interface{}) params["userId"] = i.API.Credentials.ClientID params["name"] = walletName - err := i.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, "/"+itbitWallets, params, &resp) + err := i.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, "/"+itbitWallets, params, &resp) if err != nil { return resp, err } @@ -102,11 +102,11 @@ func (i *ItBit) CreateWallet(walletName string) (Wallet, error) { } // GetWallet returns wallet information by walletID -func (i *ItBit) GetWallet(walletID string) (Wallet, error) { +func (i *ItBit) GetWallet(ctx context.Context, walletID string) (Wallet, error) { resp := Wallet{} path := fmt.Sprintf("/%s/%s", itbitWallets, walletID) - err := i.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, path, nil, &resp) + err := i.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, path, nil, &resp) if err != nil { return resp, err } @@ -118,11 +118,11 @@ func (i *ItBit) GetWallet(walletID string) (Wallet, error) { // GetWalletBalance returns balance information for a specific currency in a // wallet. -func (i *ItBit) GetWalletBalance(walletID, currency string) (Balance, error) { +func (i *ItBit) GetWalletBalance(ctx context.Context, walletID, currency string) (Balance, error) { resp := Balance{} path := fmt.Sprintf("/%s/%s/%s/%s", itbitWallets, walletID, itbitBalances, currency) - err := i.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, path, nil, &resp) + err := i.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, path, nil, &resp) if err != nil { return resp, err } @@ -134,7 +134,7 @@ func (i *ItBit) GetWalletBalance(walletID, currency string) (Balance, error) { // GetOrders returns active orders for itBit // perPage defaults to & has a limit of 50 -func (i *ItBit) GetOrders(walletID, symbol, status string, page, perPage int64) ([]Order, error) { +func (i *ItBit) GetOrders(ctx context.Context, walletID, symbol, status string, page, perPage int64) ([]Order, error) { var resp []Order params := make(map[string]interface{}) params["walletID"] = walletID @@ -152,16 +152,16 @@ func (i *ItBit) GetOrders(walletID, symbol, status string, page, perPage int64) params["perPage"] = strconv.FormatInt(perPage, 10) } - return resp, i.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, itbitOrders, params, &resp) + return resp, i.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, itbitOrders, params, &resp) } // GetWalletTrades returns all trades for a specified wallet. -func (i *ItBit) GetWalletTrades(walletID string, params url.Values) (Records, error) { +func (i *ItBit) GetWalletTrades(ctx context.Context, walletID string, params url.Values) (Records, error) { resp := Records{} urlPath := fmt.Sprintf("/%s/%s/%s", itbitWallets, walletID, itbitTrades) path := common.EncodeURLValues(urlPath, params) - err := i.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, path, nil, &resp) + err := i.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, path, nil, &resp) if err != nil { return resp, err } @@ -172,12 +172,12 @@ func (i *ItBit) GetWalletTrades(walletID string, params url.Values) (Records, er } // GetFundingHistoryForWallet returns all funding history for a specified wallet. -func (i *ItBit) GetFundingHistoryForWallet(walletID string, params url.Values) (FundingRecords, error) { +func (i *ItBit) GetFundingHistoryForWallet(ctx context.Context, walletID string, params url.Values) (FundingRecords, error) { resp := FundingRecords{} urlPath := fmt.Sprintf("/%s/%s/%s", itbitWallets, walletID, itbitFundingHistory) path := common.EncodeURLValues(urlPath, params) - err := i.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, path, nil, &resp) + err := i.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, path, nil, &resp) if err != nil { return resp, err } @@ -188,7 +188,7 @@ func (i *ItBit) GetFundingHistoryForWallet(walletID string, params url.Values) ( } // PlaceOrder places a new order -func (i *ItBit) PlaceOrder(walletID, side, orderType, currency string, amount, price float64, instrument, clientRef string) (Order, error) { +func (i *ItBit) PlaceOrder(ctx context.Context, walletID, side, orderType, currency string, amount, price float64, instrument, clientRef string) (Order, error) { resp := Order{} path := fmt.Sprintf("/%s/%s/%s", itbitWallets, walletID, itbitOrders) @@ -204,7 +204,7 @@ func (i *ItBit) PlaceOrder(walletID, side, orderType, currency string, amount, p params["clientOrderIdentifier"] = clientRef } - err := i.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, path, params, &resp) + err := i.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, path, params, &resp) if err != nil { return resp, err } @@ -215,12 +215,12 @@ func (i *ItBit) PlaceOrder(walletID, side, orderType, currency string, amount, p } // GetOrder returns an order by id. -func (i *ItBit) GetOrder(walletID string, params url.Values) (Order, error) { +func (i *ItBit) GetOrder(ctx context.Context, walletID string, params url.Values) (Order, error) { resp := Order{} urlPath := fmt.Sprintf("/%s/%s/%s", itbitWallets, walletID, itbitOrders) path := common.EncodeURLValues(urlPath, params) - err := i.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, path, nil, &resp) + err := i.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, path, nil, &resp) if err != nil { return resp, err } @@ -232,20 +232,20 @@ func (i *ItBit) GetOrder(walletID string, params url.Values) (Order, error) { // CancelExistingOrder cancels and open order. *This is not a guarantee that the // order has been cancelled!* -func (i *ItBit) CancelExistingOrder(walletID, orderID string) error { +func (i *ItBit) CancelExistingOrder(ctx context.Context, walletID, orderID string) error { path := fmt.Sprintf("/%s/%s/%s/%s", itbitWallets, walletID, itbitOrders, orderID) - return i.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodDelete, path, nil, nil) + return i.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodDelete, path, nil, nil) } // GetCryptoDepositAddress returns a deposit address to send cryptocurrency to. -func (i *ItBit) GetCryptoDepositAddress(walletID, currency string) (CryptoCurrencyDeposit, error) { +func (i *ItBit) GetCryptoDepositAddress(ctx context.Context, walletID, currency string) (CryptoCurrencyDeposit, error) { resp := CryptoCurrencyDeposit{} path := fmt.Sprintf("/%s/%s/%s", itbitWallets, walletID, itbitCryptoDeposits) params := make(map[string]interface{}) params["currency"] = currency - err := i.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, path, params, &resp) + err := i.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, path, params, &resp) if err != nil { return resp, err } @@ -256,7 +256,7 @@ func (i *ItBit) GetCryptoDepositAddress(walletID, currency string) (CryptoCurren } // WalletTransfer transfers funds between wallets. -func (i *ItBit) WalletTransfer(walletID, sourceWallet, destWallet string, amount float64, currency string) (WalletTransfer, error) { +func (i *ItBit) WalletTransfer(ctx context.Context, walletID, sourceWallet, destWallet string, amount float64, currency string) (WalletTransfer, error) { resp := WalletTransfer{} path := fmt.Sprintf("/%s/%s/%s", itbitWallets, walletID, itbitWalletTransfer) @@ -266,7 +266,7 @@ func (i *ItBit) WalletTransfer(walletID, sourceWallet, destWallet string, amount params["amount"] = strconv.FormatFloat(amount, 'f', -1, 64) params["currencyCode"] = currency - err := i.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, path, params, &resp) + err := i.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, path, params, &resp) if err != nil { return resp, err } @@ -277,7 +277,7 @@ func (i *ItBit) WalletTransfer(walletID, sourceWallet, destWallet string, amount } // SendHTTPRequest sends an unauthenticated HTTP request -func (i *ItBit) SendHTTPRequest(ep exchange.URL, path string, result interface{}) error { +func (i *ItBit) SendHTTPRequest(ctx context.Context, ep exchange.URL, path string, result interface{}) error { endpoint, err := i.API.Endpoints.GetURL(ep) if err != nil { return err @@ -292,13 +292,13 @@ func (i *ItBit) SendHTTPRequest(ep exchange.URL, path string, result interface{} HTTPRecording: i.HTTPRecording, } - return i.SendPayload(context.Background(), request.Unset, func() (*request.Item, error) { + return i.SendPayload(ctx, request.Unset, func() (*request.Item, error) { return item, nil }) } // SendAuthenticatedHTTPRequest sends an authenticated request to itBit -func (i *ItBit) SendAuthenticatedHTTPRequest(ep exchange.URL, method, path string, params map[string]interface{}, result interface{}) error { +func (i *ItBit) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, method, path string, params map[string]interface{}, result interface{}) error { if !i.AllowAuthenticatedRequest() { return fmt.Errorf("%s %w", i.Name, exchange.ErrAuthenticatedRequestWithoutCredentialsSet) } @@ -322,7 +322,7 @@ func (i *ItBit) SendAuthenticatedHTTPRequest(ep exchange.URL, method, path strin } var intermediary json.RawMessage - err = i.SendPayload(context.Background(), request.Unset, func() (*request.Item, error) { + err = i.SendPayload(ctx, request.Unset, func() (*request.Item, error) { n := i.Requester.GetNonce(true).String() timestamp := strconv.FormatInt(time.Now().UnixNano()/1000000, 10) @@ -382,7 +382,6 @@ func (i *ItBit) SendAuthenticatedHTTPRequest(ep exchange.URL, method, path strin errCheck.Description) } } - return json.Unmarshal(intermediary, result) } diff --git a/exchanges/itbit/itbit_test.go b/exchanges/itbit/itbit_test.go index a7f0f19a..6f18c02b 100644 --- a/exchanges/itbit/itbit_test.go +++ b/exchanges/itbit/itbit_test.go @@ -1,6 +1,7 @@ package itbit import ( + "context" "log" "net/url" "os" @@ -53,7 +54,7 @@ func TestMain(m *testing.M) { func TestGetTicker(t *testing.T) { t.Parallel() - _, err := i.GetTicker("XBTUSD") + _, err := i.GetTicker(context.Background(), "XBTUSD") if err != nil { t.Error("GetTicker() error", err) } @@ -61,7 +62,7 @@ func TestGetTicker(t *testing.T) { func TestGetOrderbook(t *testing.T) { t.Parallel() - _, err := i.GetOrderbook("XBTUSD") + _, err := i.GetOrderbook(context.Background(), "XBTUSD") if err != nil { t.Error("GetOrderbook() error", err) } @@ -69,56 +70,57 @@ func TestGetOrderbook(t *testing.T) { func TestGetTradeHistory(t *testing.T) { t.Parallel() - _, err := i.GetTradeHistory("XBTUSD", "0") + _, err := i.GetTradeHistory(context.Background(), "XBTUSD", "0") if err != nil { t.Error("GetTradeHistory() error", err) } } func TestGetWallets(t *testing.T) { - _, err := i.GetWallets(url.Values{}) + _, err := i.GetWallets(context.Background(), url.Values{}) if err == nil { t.Error("GetWallets() Expected error") } } func TestCreateWallet(t *testing.T) { - _, err := i.CreateWallet("test") + _, err := i.CreateWallet(context.Background(), "test") if err == nil { t.Error("CreateWallet() Expected error") } } func TestGetWallet(t *testing.T) { - _, err := i.GetWallet("1337") + _, err := i.GetWallet(context.Background(), "1337") if err == nil { t.Error("GetWallet() Expected error") } } func TestGetWalletBalance(t *testing.T) { - _, err := i.GetWalletBalance("1337", "XRT") + _, err := i.GetWalletBalance(context.Background(), "1337", "XRT") if err == nil { t.Error("GetWalletBalance() Expected error") } } func TestGetWalletTrades(t *testing.T) { - _, err := i.GetWalletTrades("1337", url.Values{}) + _, err := i.GetWalletTrades(context.Background(), "1337", url.Values{}) if err == nil { t.Error("GetWalletTrades() Expected error") } } func TestGetFundingHistory(t *testing.T) { - _, err := i.GetFundingHistoryForWallet("1337", url.Values{}) + _, err := i.GetFundingHistoryForWallet(context.Background(), "1337", url.Values{}) if err == nil { t.Error("GetFundingHistory() Expected error") } } func TestPlaceOrder(t *testing.T) { - _, err := i.PlaceOrder("1337", order.Buy.Lower(), + _, err := i.PlaceOrder(context.Background(), + "1337", order.Buy.Lower(), order.Limit.Lower(), "USD", 1, 0.2, "banjo", "sauce") if err == nil { @@ -127,7 +129,7 @@ func TestPlaceOrder(t *testing.T) { } func TestGetOrder(t *testing.T) { - _, err := i.GetOrder("1337", url.Values{}) + _, err := i.GetOrder(context.Background(), "1337", url.Values{}) if err == nil { t.Error("GetOrder() Expected error") } @@ -135,21 +137,22 @@ func TestGetOrder(t *testing.T) { func TestCancelExistingOrder(t *testing.T) { t.Skip() - err := i.CancelExistingOrder("1337", "1337order") + err := i.CancelExistingOrder(context.Background(), "1337", "1337order") if err == nil { t.Error("CancelOrder() Expected error") } } func TestGetCryptoDepositAddress(t *testing.T) { - _, err := i.GetCryptoDepositAddress("1337", "AUD") + _, err := i.GetCryptoDepositAddress(context.Background(), "1337", "AUD") if err == nil { t.Error("GetCryptoDepositAddress() Expected error") } } func TestWalletTransfer(t *testing.T) { - _, err := i.WalletTransfer("1337", "mywallet", "anotherwallet", 200, "USD") + _, err := i.WalletTransfer(context.Background(), + "1337", "mywallet", "anotherwallet", 200, "USD") if err == nil { t.Error("WalletTransfer() Expected error") } @@ -171,7 +174,7 @@ func setFeeBuilder() *exchange.FeeBuilder { // TestGetFeeByTypeOfflineTradeFee logic test func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { var feeBuilder = setFeeBuilder() - _, err := i.GetFeeByType(feeBuilder) + _, err := i.GetFeeByType(context.Background(), feeBuilder) if err != nil { t.Fatal(err) } @@ -267,7 +270,7 @@ func TestGetActiveOrders(t *testing.T) { AssetType: asset.Spot, } - _, err := i.GetActiveOrders(&getOrdersRequest) + _, err := i.GetActiveOrders(context.Background(), &getOrdersRequest) if areTestAPIKeysSet() && err != nil { t.Errorf("Could not get open orders: %s", err) } else if !areTestAPIKeysSet() && err == nil { @@ -281,7 +284,7 @@ func TestGetOrderHistory(t *testing.T) { AssetType: asset.Spot, } - _, err := i.GetOrderHistory(&getOrdersRequest) + _, err := i.GetOrderHistory(context.Background(), &getOrdersRequest) if areTestAPIKeysSet() && err != nil { t.Errorf("Could not get order history: %s", err) } else if !areTestAPIKeysSet() && err == nil { @@ -312,7 +315,7 @@ func TestSubmitOrder(t *testing.T) { ClientID: "meowOrder", AssetType: asset.Spot, } - response, err := i.SubmitOrder(orderSubmission) + response, err := i.SubmitOrder(context.Background(), orderSubmission) if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) { t.Errorf("Order failed to be placed: %v", err) } else if !areTestAPIKeysSet() && err == nil { @@ -334,7 +337,7 @@ func TestCancelExchangeOrder(t *testing.T) { AssetType: asset.Spot, } - err := i.CancelOrder(orderCancellation) + err := i.CancelOrder(context.Background(), orderCancellation) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") @@ -358,7 +361,7 @@ func TestCancelAllExchangeOrders(t *testing.T) { AssetType: asset.Spot, } - resp, err := i.CancelAllOrders(orderCancellation) + resp, err := i.CancelAllOrders(context.Background(), orderCancellation) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") @@ -374,7 +377,7 @@ func TestCancelAllExchangeOrders(t *testing.T) { func TestGetAccountInfo(t *testing.T) { if areTestAPIKeysSet() { - _, err := i.UpdateAccountInfo(asset.Spot) + _, err := i.UpdateAccountInfo(context.Background(), asset.Spot) if err == nil { t.Error("GetAccountInfo() Expected error") } @@ -385,7 +388,7 @@ func TestModifyOrder(t *testing.T) { if areTestAPIKeysSet() && !canManipulateRealOrders { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - _, err := i.ModifyOrder(&order.Modify{AssetType: asset.Spot}) + _, err := i.ModifyOrder(context.Background(), &order.Modify{AssetType: asset.Spot}) if err == nil { t.Error("ModifyOrder() Expected error") } @@ -405,7 +408,8 @@ func TestWithdraw(t *testing.T) { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - _, err := i.WithdrawCryptocurrencyFunds(&withdrawCryptoRequest) + _, err := i.WithdrawCryptocurrencyFunds(context.Background(), + &withdrawCryptoRequest) if err != common.ErrFunctionNotSupported { t.Errorf("Expected 'Not supported', received %v", err) } @@ -417,7 +421,8 @@ func TestWithdrawFiat(t *testing.T) { } var withdrawFiatRequest = withdraw.Request{} - _, err := i.WithdrawFiatFunds(&withdrawFiatRequest) + _, err := i.WithdrawFiatFunds(context.Background(), + &withdrawFiatRequest) if err != common.ErrFunctionNotSupported { t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err) } @@ -429,14 +434,15 @@ func TestWithdrawInternationalBank(t *testing.T) { } var withdrawFiatRequest = withdraw.Request{} - _, err := i.WithdrawFiatFundsToInternationalBank(&withdrawFiatRequest) + _, err := i.WithdrawFiatFundsToInternationalBank(context.Background(), + &withdrawFiatRequest) if err != common.ErrFunctionNotSupported { t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err) } } func TestGetDepositAddress(t *testing.T) { - _, err := i.GetDepositAddress(currency.BTC, "") + _, err := i.GetDepositAddress(context.Background(), currency.BTC, "") if err == nil { t.Error("GetDepositAddress() error cannot be nil") } @@ -448,7 +454,7 @@ func TestGetRecentTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = i.GetRecentTrades(currencyPair, asset.Spot) + _, err = i.GetRecentTrades(context.Background(), currencyPair, asset.Spot) if err != nil { t.Error(err) } @@ -460,7 +466,8 @@ func TestGetHistoricTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = i.GetHistoricTrades(currencyPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) + _, err = i.GetHistoricTrades(context.Background(), + currencyPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) if err != nil && err != common.ErrFunctionNotSupported { t.Error(err) } diff --git a/exchanges/itbit/itbit_wrapper.go b/exchanges/itbit/itbit_wrapper.go index aced5d39..b79e51c0 100644 --- a/exchanges/itbit/itbit_wrapper.go +++ b/exchanges/itbit/itbit_wrapper.go @@ -1,6 +1,7 @@ package itbit import ( + "context" "fmt" "net/url" "sort" @@ -40,7 +41,7 @@ func (i *ItBit) GetDefaultConfig() (*config.ExchangeConfig, error) { } if i.Features.Supports.RESTCapabilities.AutoPairUpdates { - err = i.UpdateTradablePairs(true) + err = i.UpdateTradablePairs(context.TODO(), true) if err != nil { return nil, err } @@ -129,29 +130,29 @@ func (i *ItBit) Run() { } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (i *ItBit) FetchTradablePairs(asset asset.Item) ([]string, error) { +func (i *ItBit) FetchTradablePairs(ctx context.Context, asset asset.Item) ([]string, error) { return nil, common.ErrFunctionNotSupported } // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (i *ItBit) UpdateTradablePairs(forceUpdate bool) error { +func (i *ItBit) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { return common.ErrFunctionNotSupported } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (i *ItBit) UpdateTickers(a asset.Item) error { +func (i *ItBit) UpdateTickers(ctx context.Context, a asset.Item) error { return common.ErrFunctionNotSupported } // UpdateTicker updates and returns the ticker for a currency pair -func (i *ItBit) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) { +func (i *ItBit) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { fpair, err := i.FormatExchangeCurrency(p, a) if err != nil { return nil, err } - tick, err := i.GetTicker(fpair.String()) + tick, err := i.GetTicker(ctx, fpair.String()) if err != nil { return nil, err } @@ -176,25 +177,25 @@ func (i *ItBit) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, erro } // FetchTicker returns the ticker for a currency pair -func (i *ItBit) FetchTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) { +func (i *ItBit) FetchTicker(ctx context.Context, p currency.Pair, assetType asset.Item) (*ticker.Price, error) { tickerNew, err := ticker.GetTicker(i.Name, p, assetType) if err != nil { - return i.UpdateTicker(p, assetType) + return i.UpdateTicker(ctx, p, assetType) } return tickerNew, nil } // FetchOrderbook returns orderbook base on the currency pair -func (i *ItBit) FetchOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (i *ItBit) FetchOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { ob, err := orderbook.Get(i.Name, p, assetType) if err != nil { - return i.UpdateOrderbook(p, assetType) + return i.UpdateOrderbook(ctx, p, assetType) } return ob, nil } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (i *ItBit) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (i *ItBit) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { book := &orderbook.Base{ Exchange: i.Name, Pair: p, @@ -207,7 +208,7 @@ func (i *ItBit) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderbo return book, err } - orderbookNew, err := i.GetOrderbook(fpair.String()) + orderbookNew, err := i.GetOrderbook(ctx, fpair.String()) if err != nil { return nil, err } @@ -253,11 +254,11 @@ func (i *ItBit) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderbo } // UpdateAccountInfo retrieves balances for all enabled currencies -func (i *ItBit) UpdateAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (i *ItBit) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { var info account.Holdings info.Exchange = i.Name - wallets, err := i.GetWallets(url.Values{}) + wallets, err := i.GetWallets(ctx, url.Values{}) if err != nil { return info, err } @@ -302,10 +303,10 @@ func (i *ItBit) UpdateAccountInfo(assetType asset.Item) (account.Holdings, error } // FetchAccountInfo retrieves balances for all enabled currencies -func (i *ItBit) FetchAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (i *ItBit) FetchAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { acc, err := account.GetHoldings(i.Name, assetType) if err != nil { - return i.UpdateAccountInfo(assetType) + return i.UpdateAccountInfo(ctx, assetType) } return acc, nil @@ -313,24 +314,24 @@ func (i *ItBit) FetchAccountInfo(assetType asset.Item) (account.Holdings, error) // GetFundingHistory returns funding history, deposits and // withdrawals -func (i *ItBit) GetFundingHistory() ([]exchange.FundHistory, error) { +func (i *ItBit) GetFundingHistory(ctx context.Context) ([]exchange.FundHistory, error) { return nil, common.ErrFunctionNotSupported } // GetWithdrawalsHistory returns previous withdrawals data -func (i *ItBit) GetWithdrawalsHistory(c currency.Code) (resp []exchange.WithdrawalHistory, err error) { +func (i *ItBit) GetWithdrawalsHistory(ctx context.Context, c currency.Code) (resp []exchange.WithdrawalHistory, err error) { return nil, common.ErrNotYetImplemented } // GetRecentTrades returns the most recent trades for a currency and asset -func (i *ItBit) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade.Data, error) { +func (i *ItBit) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { var err error p, err = i.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err } var tradeData Trades - tradeData, err = i.GetTradeHistory(p.String(), "") + tradeData, err = i.GetTradeHistory(ctx, p.String(), "") if err != nil { return nil, err } @@ -357,20 +358,20 @@ func (i *ItBit) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade. } // GetHistoricTrades returns historic trade data within the timeframe provided -func (i *ItBit) GetHistoricTrades(_ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { +func (i *ItBit) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { // cannot do time based retrieval of trade data return nil, common.ErrFunctionNotSupported } // SubmitOrder submits a new order -func (i *ItBit) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { +func (i *ItBit) SubmitOrder(ctx context.Context, s *order.Submit) (order.SubmitResponse, error) { var submitOrderResponse order.SubmitResponse if err := s.Validate(); err != nil { return submitOrderResponse, err } var wallet string - wallets, err := i.GetWallets(url.Values{}) + wallets, err := i.GetWallets(ctx, url.Values{}) if err != nil { return submitOrderResponse, err } @@ -397,7 +398,8 @@ func (i *ItBit) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { return submitOrderResponse, err } - response, err := i.PlaceOrder(wallet, + response, err := i.PlaceOrder(ctx, + wallet, s.Side.String(), s.Type.String(), fPair.Base.String(), @@ -421,38 +423,45 @@ func (i *ItBit) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (i *ItBit) ModifyOrder(action *order.Modify) (order.Modify, error) { +func (i *ItBit) ModifyOrder(ctx context.Context, action *order.Modify) (order.Modify, error) { return order.Modify{}, common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number -func (i *ItBit) CancelOrder(o *order.Cancel) error { +func (i *ItBit) CancelOrder(ctx context.Context, o *order.Cancel) error { if err := o.Validate(o.StandardCancel()); err != nil { return err } - return i.CancelExistingOrder(o.WalletAddress, o.ID) + return i.CancelExistingOrder(ctx, o.WalletAddress, o.ID) } // CancelBatchOrders cancels an orders by their corresponding ID numbers -func (i *ItBit) CancelBatchOrders(o []order.Cancel) (order.CancelBatchResponse, error) { +func (i *ItBit) CancelBatchOrders(ctx context.Context, o []order.Cancel) (order.CancelBatchResponse, error) { return order.CancelBatchResponse{}, common.ErrNotYetImplemented } // CancelAllOrders cancels all orders associated with a currency pair -func (i *ItBit) CancelAllOrders(orderCancellation *order.Cancel) (order.CancelAllResponse, error) { +func (i *ItBit) CancelAllOrders(ctx context.Context, orderCancellation *order.Cancel) (order.CancelAllResponse, error) { if err := orderCancellation.Validate(); err != nil { return order.CancelAllResponse{}, err } cancelAllOrdersResponse := order.CancelAllResponse{ Status: make(map[string]string), } - openOrders, err := i.GetOrders(orderCancellation.WalletAddress, "", "open", 0, 0) + openOrders, err := i.GetOrders(ctx, + orderCancellation.WalletAddress, + "", + "open", + 0, + 0) if err != nil { return cancelAllOrdersResponse, err } for j := range openOrders { - err = i.CancelExistingOrder(orderCancellation.WalletAddress, openOrders[j].ID) + err = i.CancelExistingOrder(ctx, + orderCancellation.WalletAddress, + openOrders[j].ID) if err != nil { cancelAllOrdersResponse.Status[openOrders[j].ID] = err.Error() } @@ -462,7 +471,7 @@ func (i *ItBit) CancelAllOrders(orderCancellation *order.Cancel) (order.CancelAl } // GetOrderInfo returns order information based on order ID -func (i *ItBit) GetOrderInfo(orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { +func (i *ItBit) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { var orderDetail order.Detail return orderDetail, common.ErrNotYetImplemented } @@ -471,30 +480,30 @@ func (i *ItBit) GetOrderInfo(orderID string, pair currency.Pair, assetType asset // NOTE: This has not been implemented due to the fact you need to generate a // a specific wallet ID and they restrict the amount of deposit address you can // request limiting them to 2. -func (i *ItBit) GetDepositAddress(_ currency.Code, _ string) (string, error) { +func (i *ItBit) GetDepositAddress(_ context.Context, _ currency.Code, _ string) (string, error) { return "", common.ErrNotYetImplemented } // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is // submitted -func (i *ItBit) WithdrawCryptocurrencyFunds(_ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (i *ItBit) WithdrawCryptocurrencyFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // WithdrawFiatFunds returns a withdrawal ID when a // withdrawal is submitted -func (i *ItBit) WithdrawFiatFunds(_ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (i *ItBit) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a // withdrawal is submitted -func (i *ItBit) WithdrawFiatFundsToInternationalBank(_ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (i *ItBit) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // GetFeeByType returns an estimate of fee based on type of transaction -func (i *ItBit) GetFeeByType(feeBuilder *exchange.FeeBuilder) (float64, error) { +func (i *ItBit) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { if !i.AllowAuthenticatedRequest() && // Todo check connection status feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { feeBuilder.FeeType = exchange.OfflineTradeFee @@ -503,11 +512,11 @@ func (i *ItBit) GetFeeByType(feeBuilder *exchange.FeeBuilder) (float64, error) { } // GetActiveOrders retrieves any orders that are active/open -func (i *ItBit) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, error) { +func (i *ItBit) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) { if err := req.Validate(); err != nil { return nil, err } - wallets, err := i.GetWallets(url.Values{}) + wallets, err := i.GetWallets(ctx, url.Values{}) if err != nil { return nil, err } @@ -515,7 +524,7 @@ func (i *ItBit) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, er var allOrders []Order for x := range wallets { var resp []Order - resp, err = i.GetOrders(wallets[x].ID, "", "open", 0, 0) + resp, err = i.GetOrders(ctx, wallets[x].ID, "", "open", 0, 0) if err != nil { return nil, err } @@ -566,12 +575,12 @@ func (i *ItBit) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, er // GetOrderHistory retrieves account order information // Can Limit response to specific order status -func (i *ItBit) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, error) { +func (i *ItBit) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) { if err := req.Validate(); err != nil { return nil, err } - wallets, err := i.GetWallets(url.Values{}) + wallets, err := i.GetWallets(ctx, url.Values{}) if err != nil { return nil, err } @@ -579,7 +588,7 @@ func (i *ItBit) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, er var allOrders []Order for x := range wallets { var resp []Order - resp, err = i.GetOrders(wallets[x].ID, "", "", 0, 0) + resp, err = i.GetOrders(ctx, wallets[x].ID, "", "", 0, 0) if err != nil { return nil, err } @@ -634,17 +643,17 @@ func (i *ItBit) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, er // ValidateCredentials validates current credentials used for wrapper // functionality -func (i *ItBit) ValidateCredentials(assetType asset.Item) error { - _, err := i.UpdateAccountInfo(assetType) +func (i *ItBit) ValidateCredentials(ctx context.Context, assetType asset.Item) error { + _, err := i.UpdateAccountInfo(ctx, assetType) return i.CheckTransientError(err) } // GetHistoricCandles returns candles between a time period for a set time interval -func (i *ItBit) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (i *ItBit) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { return kline.Item{}, common.ErrFunctionNotSupported } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (i *ItBit) GetHistoricCandlesExtended(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (i *ItBit) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { return kline.Item{}, common.ErrFunctionNotSupported } diff --git a/exchanges/kraken/kraken.go b/exchanges/kraken/kraken.go index 392b19bc..ad228224 100644 --- a/exchanges/kraken/kraken.go +++ b/exchanges/kraken/kraken.go @@ -36,7 +36,7 @@ type Kraken struct { } // GetServerTime returns current server time -func (k *Kraken) GetServerTime() (TimeResponse, error) { +func (k *Kraken) GetServerTime(ctx context.Context) (TimeResponse, error) { path := fmt.Sprintf("/%s/public/%s", krakenAPIVersion, krakenServerTime) var response struct { @@ -44,7 +44,7 @@ func (k *Kraken) GetServerTime() (TimeResponse, error) { Result TimeResponse `json:"result"` } - if err := k.SendHTTPRequest(exchange.RestSpot, path, &response); err != nil { + if err := k.SendHTTPRequest(ctx, exchange.RestSpot, path, &response); err != nil { return response.Result, err } @@ -53,8 +53,8 @@ func (k *Kraken) GetServerTime() (TimeResponse, error) { // SeedAssets seeds Kraken's asset list and stores it in the // asset translator -func (k *Kraken) SeedAssets() error { - assets, err := k.GetAssets() +func (k *Kraken) SeedAssets(ctx context.Context) error { + assets, err := k.GetAssets(ctx) if err != nil { return err } @@ -62,7 +62,7 @@ func (k *Kraken) SeedAssets() error { assetTranslator.Seed(orig, val.Altname) } - assetPairs, err := k.GetAssetPairs([]string{}, "") + assetPairs, err := k.GetAssetPairs(ctx, []string{}, "") if err != nil { return err } @@ -73,7 +73,7 @@ func (k *Kraken) SeedAssets() error { } // GetAssets returns a full asset list -func (k *Kraken) GetAssets() (map[string]*Asset, error) { +func (k *Kraken) GetAssets(ctx context.Context) (map[string]*Asset, error) { path := fmt.Sprintf("/%s/public/%s", krakenAPIVersion, krakenAssets) var response struct { @@ -81,7 +81,7 @@ func (k *Kraken) GetAssets() (map[string]*Asset, error) { Result map[string]*Asset `json:"result"` } - if err := k.SendHTTPRequest(exchange.RestSpot, path, &response); err != nil { + if err := k.SendHTTPRequest(ctx, exchange.RestSpot, path, &response); err != nil { return response.Result, err } return response.Result, GetError(response.Error) @@ -89,7 +89,7 @@ func (k *Kraken) GetAssets() (map[string]*Asset, error) { // GetAssetPairs returns a full asset pair list // Parameter 'info' only supports 4 strings: "fees", "leverage", "margin", "info" <- (default) -func (k *Kraken) GetAssetPairs(assetPairs []string, info string) (map[string]AssetPairs, error) { +func (k *Kraken) GetAssetPairs(ctx context.Context, assetPairs []string, info string) (map[string]AssetPairs, error) { path := fmt.Sprintf("/%s/public/%s", krakenAPIVersion, krakenAssetPairs) params := url.Values{} var assets string @@ -107,14 +107,14 @@ func (k *Kraken) GetAssetPairs(assetPairs []string, info string) (map[string]Ass } params.Set("info", info) } - if err := k.SendHTTPRequest(exchange.RestSpot, path+params.Encode(), &response); err != nil { + if err := k.SendHTTPRequest(ctx, exchange.RestSpot, path+params.Encode(), &response); err != nil { return response.Result, err } return response.Result, GetError(response.Error) } // GetTicker returns ticker information from kraken -func (k *Kraken) GetTicker(symbol currency.Pair) (Ticker, error) { +func (k *Kraken) GetTicker(ctx context.Context, symbol currency.Pair) (Ticker, error) { tick := Ticker{} values := url.Values{} symbolValue, err := k.FormatSymbol(symbol, asset.Spot) @@ -131,7 +131,7 @@ func (k *Kraken) GetTicker(symbol currency.Pair) (Ticker, error) { resp := Response{} path := fmt.Sprintf("/%s/public/%s?%s", krakenAPIVersion, krakenTicker, values.Encode()) - err = k.SendHTTPRequest(exchange.RestSpot, path, &resp) + err = k.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) if err != nil { return tick, err } @@ -157,7 +157,7 @@ func (k *Kraken) GetTicker(symbol currency.Pair) (Ticker, error) { // GetTickers supports fetching multiple tickers from Kraken // pairList must be in the format pairs separated by commas // ("LTCUSD,ETCUSD") -func (k *Kraken) GetTickers(pairList string) (map[string]Ticker, error) { +func (k *Kraken) GetTickers(ctx context.Context, pairList string) (map[string]Ticker, error) { values := url.Values{} values.Set("pair", pairList) @@ -169,7 +169,7 @@ func (k *Kraken) GetTickers(pairList string) (map[string]Ticker, error) { resp := Response{} path := fmt.Sprintf("/%s/public/%s?%s", krakenAPIVersion, krakenTicker, values.Encode()) - err := k.SendHTTPRequest(exchange.RestSpot, path, &resp) + err := k.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) if err != nil { return nil, err } @@ -197,7 +197,7 @@ func (k *Kraken) GetTickers(pairList string) (map[string]Ticker, error) { } // GetOHLC returns an array of open high low close values of a currency pair -func (k *Kraken) GetOHLC(symbol currency.Pair, interval string) ([]OpenHighLowClose, error) { +func (k *Kraken) GetOHLC(ctx context.Context, symbol currency.Pair, interval string) ([]OpenHighLowClose, error) { values := url.Values{} symbolValue, err := k.FormatSymbol(symbol, asset.Spot) if err != nil { @@ -219,7 +219,7 @@ func (k *Kraken) GetOHLC(symbol currency.Pair, interval string) ([]OpenHighLowCl path := fmt.Sprintf("/%s/public/%s?%s", krakenAPIVersion, krakenOHLC, values.Encode()) - err = k.SendHTTPRequest(exchange.RestSpot, path, &result) + err = k.SendHTTPRequest(ctx, exchange.RestSpot, path, &result) if err != nil { return OHLC, err } @@ -261,7 +261,7 @@ func (k *Kraken) GetOHLC(symbol currency.Pair, interval string) ([]OpenHighLowCl } // GetDepth returns the orderbook for a particular currency -func (k *Kraken) GetDepth(symbol currency.Pair) (Orderbook, error) { +func (k *Kraken) GetDepth(ctx context.Context, symbol currency.Pair) (Orderbook, error) { var result interface{} var orderBook Orderbook values := url.Values{} @@ -271,7 +271,7 @@ func (k *Kraken) GetDepth(symbol currency.Pair) (Orderbook, error) { } values.Set("pair", symbolValue) path := fmt.Sprintf("/%s/public/%s?%s", krakenAPIVersion, krakenDepth, values.Encode()) - err = k.SendHTTPRequest(exchange.RestSpot, path, &result) + err = k.SendHTTPRequest(ctx, exchange.RestSpot, path, &result) if err != nil { return orderBook, err } @@ -324,7 +324,7 @@ func (k *Kraken) GetDepth(symbol currency.Pair) (Orderbook, error) { } // GetTrades returns current trades on Kraken -func (k *Kraken) GetTrades(symbol currency.Pair) ([]RecentTrades, error) { +func (k *Kraken) GetTrades(ctx context.Context, symbol currency.Pair) ([]RecentTrades, error) { values := url.Values{} symbolValue, err := k.FormatSymbol(symbol, asset.Spot) if err != nil { @@ -338,7 +338,7 @@ func (k *Kraken) GetTrades(symbol currency.Pair) ([]RecentTrades, error) { path := fmt.Sprintf("/%s/public/%s?%s", krakenAPIVersion, krakenTrades, values.Encode()) - err = k.SendHTTPRequest(exchange.RestSpot, path, &result) + err = k.SendHTTPRequest(ctx, exchange.RestSpot, path, &result) if err != nil { return nil, err } @@ -431,7 +431,7 @@ func (k *Kraken) GetTrades(symbol currency.Pair) ([]RecentTrades, error) { } // GetSpread returns the full spread on Kraken -func (k *Kraken) GetSpread(symbol currency.Pair) ([]Spread, error) { +func (k *Kraken) GetSpread(ctx context.Context, symbol currency.Pair) ([]Spread, error) { values := url.Values{} symbolValue, err := k.FormatSymbol(symbol, asset.Spot) if err != nil { @@ -444,7 +444,7 @@ func (k *Kraken) GetSpread(symbol currency.Pair) ([]Spread, error) { path := fmt.Sprintf("/%s/public/%s?%s", krakenAPIVersion, krakenSpread, values.Encode()) - err = k.SendHTTPRequest(exchange.RestSpot, path, &response) + err = k.SendHTTPRequest(ctx, exchange.RestSpot, path, &response) if err != nil { return peanutButter, err } @@ -470,13 +470,13 @@ func (k *Kraken) GetSpread(symbol currency.Pair) ([]Spread, error) { } // GetBalance returns your balance associated with your keys -func (k *Kraken) GetBalance() (map[string]float64, error) { +func (k *Kraken) GetBalance(ctx context.Context) (map[string]float64, error) { var response struct { Error []string `json:"error"` Result map[string]string `json:"result"` } - if err := k.SendAuthenticatedHTTPRequest(exchange.RestSpot, krakenBalance, url.Values{}, &response); err != nil { + if err := k.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenBalance, url.Values{}, &response); err != nil { return nil, err } @@ -492,7 +492,7 @@ func (k *Kraken) GetBalance() (map[string]float64, error) { } // GetWithdrawInfo gets withdrawal fees -func (k *Kraken) GetWithdrawInfo(currency string, amount float64) (WithdrawInformation, error) { +func (k *Kraken) GetWithdrawInfo(ctx context.Context, currency string, amount float64) (WithdrawInformation, error) { var response struct { Error []string `json:"error"` Result WithdrawInformation `json:"result"` @@ -502,7 +502,7 @@ func (k *Kraken) GetWithdrawInfo(currency string, amount float64) (WithdrawInfor params.Set("key", "") params.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) - if err := k.SendAuthenticatedHTTPRequest(exchange.RestSpot, krakenWithdrawInfo, params, &response); err != nil { + if err := k.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenWithdrawInfo, params, &response); err != nil { return response.Result, err } @@ -510,7 +510,7 @@ func (k *Kraken) GetWithdrawInfo(currency string, amount float64) (WithdrawInfor } // Withdraw withdraws funds -func (k *Kraken) Withdraw(asset, key string, amount float64) (string, error) { +func (k *Kraken) Withdraw(ctx context.Context, asset, key string, amount float64) (string, error) { var response struct { Error []string `json:"error"` ReferenceID string `json:"refid"` @@ -520,7 +520,7 @@ func (k *Kraken) Withdraw(asset, key string, amount float64) (string, error) { params.Set("key", key) params.Set("amount", fmt.Sprintf("%f", amount)) - if err := k.SendAuthenticatedHTTPRequest(exchange.RestSpot, krakenWithdraw, params, &response); err != nil { + if err := k.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenWithdraw, params, &response); err != nil { return response.ReferenceID, err } @@ -528,7 +528,7 @@ func (k *Kraken) Withdraw(asset, key string, amount float64) (string, error) { } // GetDepositMethods gets withdrawal fees -func (k *Kraken) GetDepositMethods(currency string) ([]DepositMethods, error) { +func (k *Kraken) GetDepositMethods(ctx context.Context, currency string) ([]DepositMethods, error) { var response struct { Error []string `json:"error"` Result []DepositMethods `json:"result"` @@ -536,7 +536,7 @@ func (k *Kraken) GetDepositMethods(currency string) ([]DepositMethods, error) { params := url.Values{} params.Set("asset", currency) - err := k.SendAuthenticatedHTTPRequest(exchange.RestSpot, krakenDepositMethods, params, &response) + err := k.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenDepositMethods, params, &response) if err != nil { return response.Result, err } @@ -545,7 +545,7 @@ func (k *Kraken) GetDepositMethods(currency string) ([]DepositMethods, error) { } // GetTradeBalance returns full information about your trades on Kraken -func (k *Kraken) GetTradeBalance(args ...TradeBalanceOptions) (TradeBalanceInfo, error) { +func (k *Kraken) GetTradeBalance(ctx context.Context, args ...TradeBalanceOptions) (TradeBalanceInfo, error) { params := url.Values{} if args != nil { @@ -563,7 +563,7 @@ func (k *Kraken) GetTradeBalance(args ...TradeBalanceOptions) (TradeBalanceInfo, Result TradeBalanceInfo `json:"result"` } - if err := k.SendAuthenticatedHTTPRequest(exchange.RestSpot, krakenTradeBalance, params, &response); err != nil { + if err := k.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenTradeBalance, params, &response); err != nil { return response.Result, err } @@ -571,7 +571,7 @@ func (k *Kraken) GetTradeBalance(args ...TradeBalanceOptions) (TradeBalanceInfo, } // GetOpenOrders returns all current open orders -func (k *Kraken) GetOpenOrders(args OrderInfoOptions) (OpenOrders, error) { +func (k *Kraken) GetOpenOrders(ctx context.Context, args OrderInfoOptions) (OpenOrders, error) { params := url.Values{} if args.Trades { @@ -587,7 +587,7 @@ func (k *Kraken) GetOpenOrders(args OrderInfoOptions) (OpenOrders, error) { Result OpenOrders `json:"result"` } - if err := k.SendAuthenticatedHTTPRequest(exchange.RestSpot, krakenOpenOrders, params, &response); err != nil { + if err := k.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenOpenOrders, params, &response); err != nil { return response.Result, err } @@ -595,7 +595,7 @@ func (k *Kraken) GetOpenOrders(args OrderInfoOptions) (OpenOrders, error) { } // GetClosedOrders returns a list of closed orders -func (k *Kraken) GetClosedOrders(args GetClosedOrdersOptions) (ClosedOrders, error) { +func (k *Kraken) GetClosedOrders(ctx context.Context, args GetClosedOrdersOptions) (ClosedOrders, error) { params := url.Values{} if args.Trades { @@ -627,7 +627,7 @@ func (k *Kraken) GetClosedOrders(args GetClosedOrdersOptions) (ClosedOrders, err Result ClosedOrders `json:"result"` } - if err := k.SendAuthenticatedHTTPRequest(exchange.RestSpot, krakenClosedOrders, params, &response); err != nil { + if err := k.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenClosedOrders, params, &response); err != nil { return response.Result, err } @@ -635,7 +635,7 @@ func (k *Kraken) GetClosedOrders(args GetClosedOrdersOptions) (ClosedOrders, err } // QueryOrdersInfo returns order information -func (k *Kraken) QueryOrdersInfo(args OrderInfoOptions, txid string, txids ...string) (map[string]OrderInfo, error) { +func (k *Kraken) QueryOrdersInfo(ctx context.Context, args OrderInfoOptions, txid string, txids ...string) (map[string]OrderInfo, error) { params := url.Values{ "txid": {txid}, } @@ -657,7 +657,7 @@ func (k *Kraken) QueryOrdersInfo(args OrderInfoOptions, txid string, txids ...st Result map[string]OrderInfo `json:"result"` } - if err := k.SendAuthenticatedHTTPRequest(exchange.RestSpot, krakenQueryOrders, params, &response); err != nil { + if err := k.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenQueryOrders, params, &response); err != nil { return response.Result, err } @@ -665,7 +665,7 @@ func (k *Kraken) QueryOrdersInfo(args OrderInfoOptions, txid string, txids ...st } // GetTradesHistory returns trade history information -func (k *Kraken) GetTradesHistory(args ...GetTradesHistoryOptions) (TradesHistory, error) { +func (k *Kraken) GetTradesHistory(ctx context.Context, args ...GetTradesHistoryOptions) (TradesHistory, error) { params := url.Values{} if args != nil { @@ -695,7 +695,7 @@ func (k *Kraken) GetTradesHistory(args ...GetTradesHistoryOptions) (TradesHistor Result TradesHistory `json:"result"` } - if err := k.SendAuthenticatedHTTPRequest(exchange.RestSpot, krakenTradeHistory, params, &response); err != nil { + if err := k.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenTradeHistory, params, &response); err != nil { return response.Result, err } @@ -703,7 +703,7 @@ func (k *Kraken) GetTradesHistory(args ...GetTradesHistoryOptions) (TradesHistor } // QueryTrades returns information on a specific trade -func (k *Kraken) QueryTrades(trades bool, txid string, txids ...string) (map[string]TradeInfo, error) { +func (k *Kraken) QueryTrades(ctx context.Context, trades bool, txid string, txids ...string) (map[string]TradeInfo, error) { params := url.Values{ "txid": {txid}, } @@ -721,7 +721,7 @@ func (k *Kraken) QueryTrades(trades bool, txid string, txids ...string) (map[str Result map[string]TradeInfo `json:"result"` } - if err := k.SendAuthenticatedHTTPRequest(exchange.RestSpot, krakenQueryTrades, params, &response); err != nil { + if err := k.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenQueryTrades, params, &response); err != nil { return response.Result, err } @@ -729,7 +729,7 @@ func (k *Kraken) QueryTrades(trades bool, txid string, txids ...string) (map[str } // OpenPositions returns current open positions -func (k *Kraken) OpenPositions(docalcs bool, txids ...string) (map[string]Position, error) { +func (k *Kraken) OpenPositions(ctx context.Context, docalcs bool, txids ...string) (map[string]Position, error) { params := url.Values{} if txids != nil { @@ -745,7 +745,7 @@ func (k *Kraken) OpenPositions(docalcs bool, txids ...string) (map[string]Positi Result map[string]Position `json:"result"` } - if err := k.SendAuthenticatedHTTPRequest(exchange.RestSpot, krakenOpenPositions, params, &response); err != nil { + if err := k.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenOpenPositions, params, &response); err != nil { return response.Result, err } @@ -753,7 +753,7 @@ func (k *Kraken) OpenPositions(docalcs bool, txids ...string) (map[string]Positi } // GetLedgers returns current ledgers -func (k *Kraken) GetLedgers(args ...GetLedgersOptions) (Ledgers, error) { +func (k *Kraken) GetLedgers(ctx context.Context, args ...GetLedgersOptions) (Ledgers, error) { params := url.Values{} if args != nil { @@ -787,7 +787,7 @@ func (k *Kraken) GetLedgers(args ...GetLedgersOptions) (Ledgers, error) { Result Ledgers `json:"result"` } - if err := k.SendAuthenticatedHTTPRequest(exchange.RestSpot, krakenLedgers, params, &response); err != nil { + if err := k.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenLedgers, params, &response); err != nil { return response.Result, err } @@ -795,7 +795,7 @@ func (k *Kraken) GetLedgers(args ...GetLedgersOptions) (Ledgers, error) { } // QueryLedgers queries an individual ledger by ID -func (k *Kraken) QueryLedgers(id string, ids ...string) (map[string]LedgerInfo, error) { +func (k *Kraken) QueryLedgers(ctx context.Context, id string, ids ...string) (map[string]LedgerInfo, error) { params := url.Values{ "id": {id}, } @@ -809,7 +809,7 @@ func (k *Kraken) QueryLedgers(id string, ids ...string) (map[string]LedgerInfo, Result map[string]LedgerInfo `json:"result"` } - if err := k.SendAuthenticatedHTTPRequest(exchange.RestSpot, krakenQueryLedgers, params, &response); err != nil { + if err := k.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenQueryLedgers, params, &response); err != nil { return response.Result, err } @@ -817,7 +817,7 @@ func (k *Kraken) QueryLedgers(id string, ids ...string) (map[string]LedgerInfo, } // GetTradeVolume returns your trade volume by currency -func (k *Kraken) GetTradeVolume(feeinfo bool, symbol ...currency.Pair) (TradeVolumeResponse, error) { +func (k *Kraken) GetTradeVolume(ctx context.Context, feeinfo bool, symbol ...currency.Pair) (TradeVolumeResponse, error) { var response struct { Error []string `json:"error"` Result TradeVolumeResponse `json:"result"` @@ -839,7 +839,7 @@ func (k *Kraken) GetTradeVolume(feeinfo bool, symbol ...currency.Pair) (TradeVol params.Set("fee-info", "true") } - if err := k.SendAuthenticatedHTTPRequest(exchange.RestSpot, krakenTradeVolume, params, &response); err != nil { + if err := k.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenTradeVolume, params, &response); err != nil { return response.Result, err } @@ -847,7 +847,7 @@ func (k *Kraken) GetTradeVolume(feeinfo bool, symbol ...currency.Pair) (TradeVol } // AddOrder adds a new order for Kraken exchange -func (k *Kraken) AddOrder(symbol currency.Pair, side, orderType string, volume, price, price2, leverage float64, args *AddOrderOptions) (AddOrderResponse, error) { +func (k *Kraken) AddOrder(ctx context.Context, symbol currency.Pair, side, orderType string, volume, price, price2, leverage float64, args *AddOrderOptions) (AddOrderResponse, error) { var response struct { Error []string `json:"error"` Result AddOrderResponse `json:"result"` @@ -903,7 +903,7 @@ func (k *Kraken) AddOrder(symbol currency.Pair, side, orderType string, volume, params.Set("validate", "true") } - if err := k.SendAuthenticatedHTTPRequest(exchange.RestSpot, krakenOrderPlace, params, &response); err != nil { + if err := k.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenOrderPlace, params, &response); err != nil { return response.Result, err } @@ -911,7 +911,7 @@ func (k *Kraken) AddOrder(symbol currency.Pair, side, orderType string, volume, } // CancelExistingOrder cancels order by orderID -func (k *Kraken) CancelExistingOrder(txid string) (CancelOrderResponse, error) { +func (k *Kraken) CancelExistingOrder(ctx context.Context, txid string) (CancelOrderResponse, error) { values := url.Values{ "txid": {txid}, } @@ -921,7 +921,7 @@ func (k *Kraken) CancelExistingOrder(txid string) (CancelOrderResponse, error) { Result CancelOrderResponse `json:"result"` } - if err := k.SendAuthenticatedHTTPRequest(exchange.RestSpot, krakenOrderCancel, values, &response); err != nil { + if err := k.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenOrderCancel, values, &response); err != nil { return response.Result, err } @@ -948,7 +948,7 @@ func GetError(apiErrors []string) error { } // SendHTTPRequest sends an unauthenticated HTTP requests -func (k *Kraken) SendHTTPRequest(ep exchange.URL, path string, result interface{}) error { +func (k *Kraken) SendHTTPRequest(ctx context.Context, ep exchange.URL, path string, result interface{}) error { endpoint, err := k.API.Endpoints.GetURL(ep) if err != nil { return err @@ -963,13 +963,13 @@ func (k *Kraken) SendHTTPRequest(ep exchange.URL, path string, result interface{ HTTPRecording: k.HTTPRecording, } - return k.SendPayload(context.Background(), request.Unset, func() (*request.Item, error) { + return k.SendPayload(ctx, request.Unset, func() (*request.Item, error) { return item, nil }) } // SendAuthenticatedHTTPRequest sends an authenticated HTTP request -func (k *Kraken) SendAuthenticatedHTTPRequest(ep exchange.URL, method string, params url.Values, result interface{}) error { +func (k *Kraken) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, method string, params url.Values, result interface{}) error { if !k.AllowAuthenticatedRequest() { return fmt.Errorf("%s %w", k.Name, exchange.ErrAuthenticatedRequestWithoutCredentialsSet) } @@ -980,7 +980,7 @@ func (k *Kraken) SendAuthenticatedHTTPRequest(ep exchange.URL, method string, pa path := fmt.Sprintf("/%s/private/%s", krakenAPIVersion, method) interim := json.RawMessage{} - err = k.SendPayload(context.Background(), request.Unset, func() (*request.Item, error) { + err = k.SendPayload(ctx, request.Unset, func() (*request.Item, error) { nonce := k.Requester.GetNonce(true).String() params.Set("nonce", nonce) encoded := params.Encode() @@ -1030,11 +1030,11 @@ func (k *Kraken) SendAuthenticatedHTTPRequest(ep exchange.URL, method string, pa } // GetFee returns an estimate of fee based on type of transaction -func (k *Kraken) GetFee(feeBuilder *exchange.FeeBuilder) (float64, error) { +func (k *Kraken) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { var fee float64 switch feeBuilder.FeeType { case exchange.CryptocurrencyTradeFee: - feePair, err := k.GetTradeVolume(true, feeBuilder.Pair) + feePair, err := k.GetTradeVolume(ctx, true, feeBuilder.Pair) if err != nil { return 0, err } @@ -1052,7 +1052,8 @@ func (k *Kraken) GetFee(feeBuilder *exchange.FeeBuilder) (float64, error) { case exchange.CryptocurrencyWithdrawalFee: fee = getWithdrawalFee(feeBuilder.Pair.Base) case exchange.InternationalBankDepositFee: - depositMethods, err := k.GetDepositMethods(feeBuilder.FiatCurrency.String()) + depositMethods, err := k.GetDepositMethods(ctx, + feeBuilder.FiatCurrency.String()) if err != nil { return 0, err } @@ -1098,7 +1099,7 @@ func calculateTradingFee(currency string, feePair map[string]TradeVolumeFee, pur } // GetCryptoDepositAddress returns a deposit address for a cryptocurrency -func (k *Kraken) GetCryptoDepositAddress(method, code string) (string, error) { +func (k *Kraken) GetCryptoDepositAddress(ctx context.Context, method, code string) (string, error) { var resp = struct { Error []string `json:"error"` Result []DepositAddress `json:"result"` @@ -1108,7 +1109,7 @@ func (k *Kraken) GetCryptoDepositAddress(method, code string) (string, error) { values.Set("asset", code) values.Set("method", method) - err := k.SendAuthenticatedHTTPRequest(exchange.RestSpot, krakenDepositAddresses, values, &resp) + err := k.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenDepositAddresses, values, &resp) if err != nil { return "", err } @@ -1121,7 +1122,7 @@ func (k *Kraken) GetCryptoDepositAddress(method, code string) (string, error) { } // WithdrawStatus gets the status of recent withdrawals -func (k *Kraken) WithdrawStatus(c currency.Code, method string) ([]WithdrawStatusResponse, error) { +func (k *Kraken) WithdrawStatus(ctx context.Context, c currency.Code, method string) ([]WithdrawStatusResponse, error) { var response struct { Error []string `json:"error"` Result []WithdrawStatusResponse `json:"result"` @@ -1133,7 +1134,7 @@ func (k *Kraken) WithdrawStatus(c currency.Code, method string) ([]WithdrawStatu params.Set("method", method) } - if err := k.SendAuthenticatedHTTPRequest(exchange.RestSpot, krakenWithdrawStatus, params, &response); err != nil { + if err := k.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenWithdrawStatus, params, &response); err != nil { return response.Result, err } @@ -1141,7 +1142,7 @@ func (k *Kraken) WithdrawStatus(c currency.Code, method string) ([]WithdrawStatu } // WithdrawCancel sends a withdrawal cancelation request -func (k *Kraken) WithdrawCancel(c currency.Code, refID string) (bool, error) { +func (k *Kraken) WithdrawCancel(ctx context.Context, c currency.Code, refID string) (bool, error) { var response struct { Error []string `json:"error"` Result bool `json:"result"` @@ -1151,7 +1152,7 @@ func (k *Kraken) WithdrawCancel(c currency.Code, refID string) (bool, error) { params.Set("asset", c.String()) params.Set("refid", refID) - if err := k.SendAuthenticatedHTTPRequest(exchange.RestSpot, krakenWithdrawCancel, params, &response); err != nil { + if err := k.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenWithdrawCancel, params, &response); err != nil { return response.Result, err } @@ -1159,9 +1160,9 @@ func (k *Kraken) WithdrawCancel(c currency.Code, refID string) (bool, error) { } // GetWebsocketToken returns a websocket token -func (k *Kraken) GetWebsocketToken() (string, error) { +func (k *Kraken) GetWebsocketToken(ctx context.Context) (string, error) { var response WsTokenResponse - if err := k.SendAuthenticatedHTTPRequest(exchange.RestSpot, krakenWebsocketToken, url.Values{}, &response); err != nil { + if err := k.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, krakenWebsocketToken, url.Values{}, &response); err != nil { return "", err } if len(response.Error) > 0 { diff --git a/exchanges/kraken/kraken_futures.go b/exchanges/kraken/kraken_futures.go index 4b326d48..b862a60d 100644 --- a/exchanges/kraken/kraken_futures.go +++ b/exchanges/kraken/kraken_futures.go @@ -21,7 +21,7 @@ import ( ) // GetFuturesOrderbook gets orderbook data for futures -func (k *Kraken) GetFuturesOrderbook(symbol currency.Pair) (FuturesOrderbookData, error) { +func (k *Kraken) GetFuturesOrderbook(ctx context.Context, symbol currency.Pair) (FuturesOrderbookData, error) { var resp FuturesOrderbookData params := url.Values{} symbolValue, err := k.FormatSymbol(symbol, asset.Futures) @@ -29,23 +29,23 @@ func (k *Kraken) GetFuturesOrderbook(symbol currency.Pair) (FuturesOrderbookData return resp, err } params.Set("symbol", symbolValue) - return resp, k.SendHTTPRequest(exchange.RestFutures, futuresOrderbook+"?"+params.Encode(), &resp) + return resp, k.SendHTTPRequest(ctx, exchange.RestFutures, futuresOrderbook+"?"+params.Encode(), &resp) } // GetFuturesMarkets gets a list of futures markets and their data -func (k *Kraken) GetFuturesMarkets() (FuturesInstrumentData, error) { +func (k *Kraken) GetFuturesMarkets(ctx context.Context) (FuturesInstrumentData, error) { var resp FuturesInstrumentData - return resp, k.SendHTTPRequest(exchange.RestFutures, futuresInstruments, &resp) + return resp, k.SendHTTPRequest(ctx, exchange.RestFutures, futuresInstruments, &resp) } // GetFuturesTickers gets a list of futures tickers and their data -func (k *Kraken) GetFuturesTickers() (FuturesTickerData, error) { +func (k *Kraken) GetFuturesTickers(ctx context.Context) (FuturesTickerData, error) { var resp FuturesTickerData - return resp, k.SendHTTPRequest(exchange.RestFutures, futuresTickers, &resp) + return resp, k.SendHTTPRequest(ctx, exchange.RestFutures, futuresTickers, &resp) } // GetFuturesTradeHistory gets public trade history data for futures -func (k *Kraken) GetFuturesTradeHistory(symbol currency.Pair, lastTime time.Time) (FuturesTradeHistoryData, error) { +func (k *Kraken) GetFuturesTradeHistory(ctx context.Context, symbol currency.Pair, lastTime time.Time) (FuturesTradeHistoryData, error) { var resp FuturesTradeHistoryData params := url.Values{} symbolValue, err := k.FormatSymbol(symbol, asset.Futures) @@ -56,11 +56,11 @@ func (k *Kraken) GetFuturesTradeHistory(symbol currency.Pair, lastTime time.Time if !lastTime.IsZero() { params.Set("lastTime", lastTime.Format("2006-01-02T15:04:05.070Z")) } - return resp, k.SendHTTPRequest(exchange.RestFutures, futuresTradeHistory+"?"+params.Encode(), &resp) + return resp, k.SendHTTPRequest(ctx, exchange.RestFutures, futuresTradeHistory+"?"+params.Encode(), &resp) } // FuturesBatchOrder places a batch order for futures -func (k *Kraken) FuturesBatchOrder(data []PlaceBatchOrderData) (FuturesAccountsData, error) { +func (k *Kraken) FuturesBatchOrder(ctx context.Context, data []PlaceBatchOrderData) (FuturesAccountsData, error) { var resp FuturesAccountsData for x := range data { unformattedPair, err := currency.NewPairFromString(data[x].Symbol) @@ -75,11 +75,11 @@ func (k *Kraken) FuturesBatchOrder(data []PlaceBatchOrderData) (FuturesAccountsD } req := make(map[string]interface{}) req["batchOrder"] = data - return resp, k.SendFuturesAuthRequest(http.MethodPost, futuresBatchOrder, nil, req, &resp) + return resp, k.SendFuturesAuthRequest(ctx, http.MethodPost, futuresBatchOrder, nil, req, &resp) } // FuturesEditOrder edits a futures order -func (k *Kraken) FuturesEditOrder(orderID, clientOrderID string, size, limitPrice, stopPrice float64) (FuturesAccountsData, error) { +func (k *Kraken) FuturesEditOrder(ctx context.Context, orderID, clientOrderID string, size, limitPrice, stopPrice float64) (FuturesAccountsData, error) { var resp FuturesAccountsData params := url.Values{} if orderID != "" { @@ -91,11 +91,11 @@ func (k *Kraken) FuturesEditOrder(orderID, clientOrderID string, size, limitPric params.Set("size", strconv.FormatFloat(size, 'f', -1, 64)) params.Set("limitPrice", strconv.FormatFloat(limitPrice, 'f', -1, 64)) params.Set("stopPrice", strconv.FormatFloat(stopPrice, 'f', -1, 64)) - return resp, k.SendFuturesAuthRequest(http.MethodPost, futuresEditOrder, params, nil, &resp) + return resp, k.SendFuturesAuthRequest(ctx, http.MethodPost, futuresEditOrder, params, nil, &resp) } // FuturesSendOrder sends a futures order -func (k *Kraken) FuturesSendOrder(orderType order.Type, symbol currency.Pair, side, triggerSignal, clientOrderID, reduceOnly string, +func (k *Kraken) FuturesSendOrder(ctx context.Context, orderType order.Type, symbol currency.Pair, side, triggerSignal, clientOrderID, reduceOnly string, size, limitPrice, stopPrice float64) (FuturesSendOrderData, error) { var resp FuturesSendOrderData oType, ok := validOrderTypes[orderType] @@ -133,11 +133,11 @@ func (k *Kraken) FuturesSendOrder(orderType order.Type, symbol currency.Pair, si if stopPrice != 0 { params.Set("stopPrice", strconv.FormatFloat(stopPrice, 'f', -1, 64)) } - return resp, k.SendFuturesAuthRequest(http.MethodPost, futuresSendOrder, params, nil, &resp) + return resp, k.SendFuturesAuthRequest(ctx, http.MethodPost, futuresSendOrder, params, nil, &resp) } // FuturesCancelOrder cancels an order -func (k *Kraken) FuturesCancelOrder(orderID, clientOrderID string) (FuturesCancelOrderData, error) { +func (k *Kraken) FuturesCancelOrder(ctx context.Context, orderID, clientOrderID string) (FuturesCancelOrderData, error) { var resp FuturesCancelOrderData params := url.Values{} if orderID != "" { @@ -146,44 +146,44 @@ func (k *Kraken) FuturesCancelOrder(orderID, clientOrderID string) (FuturesCance if clientOrderID != "" { params.Set("cliOrdId", clientOrderID) } - return resp, k.SendFuturesAuthRequest(http.MethodPost, futuresCancelOrder, params, nil, &resp) + return resp, k.SendFuturesAuthRequest(ctx, http.MethodPost, futuresCancelOrder, params, nil, &resp) } // FuturesGetFills gets order fills for futures -func (k *Kraken) FuturesGetFills(lastFillTime time.Time) (FuturesFillsData, error) { +func (k *Kraken) FuturesGetFills(ctx context.Context, lastFillTime time.Time) (FuturesFillsData, error) { var resp FuturesFillsData params := url.Values{} if !lastFillTime.IsZero() { params.Set("lastFillTime", lastFillTime.UTC().Format("2006-01-02T15:04:05.999Z")) } - return resp, k.SendFuturesAuthRequest(http.MethodGet, futuresOrderFills, params, nil, &resp) + return resp, k.SendFuturesAuthRequest(ctx, http.MethodGet, futuresOrderFills, params, nil, &resp) } // FuturesTransfer transfers funds between accounts -func (k *Kraken) FuturesTransfer(fromAccount, toAccount, unit string, amount float64) (FuturesTransferData, error) { +func (k *Kraken) FuturesTransfer(ctx context.Context, fromAccount, toAccount, unit string, amount float64) (FuturesTransferData, error) { var resp FuturesTransferData req := make(map[string]interface{}) req["fromAccount"] = fromAccount req["toAccount"] = toAccount req["unit"] = unit req["amount"] = amount - return resp, k.SendFuturesAuthRequest(http.MethodPost, futuresTransfer, nil, nil, &resp) + return resp, k.SendFuturesAuthRequest(ctx, http.MethodPost, futuresTransfer, nil, nil, &resp) } // FuturesGetOpenPositions gets futures platform's notifications -func (k *Kraken) FuturesGetOpenPositions() (FuturesOpenPositions, error) { +func (k *Kraken) FuturesGetOpenPositions(ctx context.Context) (FuturesOpenPositions, error) { var resp FuturesOpenPositions - return resp, k.SendFuturesAuthRequest(http.MethodGet, futuresOpenPositions, nil, nil, &resp) + return resp, k.SendFuturesAuthRequest(ctx, http.MethodGet, futuresOpenPositions, nil, nil, &resp) } // FuturesNotifications gets futures notifications -func (k *Kraken) FuturesNotifications() (FuturesNotificationData, error) { +func (k *Kraken) FuturesNotifications(ctx context.Context) (FuturesNotificationData, error) { var resp FuturesNotificationData - return resp, k.SendFuturesAuthRequest(http.MethodGet, futuresNotifications, nil, nil, &resp) + return resp, k.SendFuturesAuthRequest(ctx, http.MethodGet, futuresNotifications, nil, nil, &resp) } // FuturesCancelAllOrders cancels all futures orders for a given symbol or all symbols -func (k *Kraken) FuturesCancelAllOrders(symbol currency.Pair) (CancelAllOrdersData, error) { +func (k *Kraken) FuturesCancelAllOrders(ctx context.Context, symbol currency.Pair) (CancelAllOrdersData, error) { var resp CancelAllOrdersData params := url.Values{} if !symbol.IsEmpty() { @@ -193,25 +193,25 @@ func (k *Kraken) FuturesCancelAllOrders(symbol currency.Pair) (CancelAllOrdersDa } params.Set("symbol", symbolValue) } - return resp, k.SendFuturesAuthRequest(http.MethodPost, futuresCancelAllOrders, params, nil, &resp) + return resp, k.SendFuturesAuthRequest(ctx, http.MethodPost, futuresCancelAllOrders, params, nil, &resp) } // FuturesCancelAllOrdersAfter cancels all futures orders for all symbols after a period of time (timeout measured in seconds) -func (k *Kraken) FuturesCancelAllOrdersAfter(timeout int64) (CancelOrdersAfterData, error) { +func (k *Kraken) FuturesCancelAllOrdersAfter(ctx context.Context, timeout int64) (CancelOrdersAfterData, error) { var resp CancelOrdersAfterData params := url.Values{} params.Set("timeout", strconv.FormatInt(timeout, 10)) - return resp, k.SendFuturesAuthRequest(http.MethodPost, futuresCancelOrdersAfter, params, nil, &resp) + return resp, k.SendFuturesAuthRequest(ctx, http.MethodPost, futuresCancelOrdersAfter, params, nil, &resp) } // FuturesOpenOrders gets all futures open orders -func (k *Kraken) FuturesOpenOrders() (FuturesOpenOrdersData, error) { +func (k *Kraken) FuturesOpenOrders(ctx context.Context) (FuturesOpenOrdersData, error) { var resp FuturesOpenOrdersData - return resp, k.SendFuturesAuthRequest(http.MethodGet, futuresOpenOrders, nil, nil, &resp) + return resp, k.SendFuturesAuthRequest(ctx, http.MethodGet, futuresOpenOrders, nil, nil, &resp) } // FuturesRecentOrders gets recent futures orders for a symbol or all symbols -func (k *Kraken) FuturesRecentOrders(symbol currency.Pair) (FuturesRecentOrdersData, error) { +func (k *Kraken) FuturesRecentOrders(ctx context.Context, symbol currency.Pair) (FuturesRecentOrdersData, error) { var resp FuturesRecentOrdersData params := url.Values{} if !symbol.IsEmpty() { @@ -221,32 +221,32 @@ func (k *Kraken) FuturesRecentOrders(symbol currency.Pair) (FuturesRecentOrdersD } params.Set("symbol", symbolValue) } - return resp, k.SendFuturesAuthRequest(http.MethodGet, futuresRecentOrders, nil, nil, &resp) + return resp, k.SendFuturesAuthRequest(ctx, http.MethodGet, futuresRecentOrders, nil, nil, &resp) } // FuturesWithdrawToSpotWallet withdraws currencies from futures wallet to spot wallet -func (k *Kraken) FuturesWithdrawToSpotWallet(currency string, amount float64) (GenericResponse, error) { +func (k *Kraken) FuturesWithdrawToSpotWallet(ctx context.Context, currency string, amount float64) (GenericResponse, error) { var resp GenericResponse params := url.Values{} params.Set("currency", currency) params.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) - return resp, k.SendFuturesAuthRequest(http.MethodPost, futuresWithdraw, params, nil, &resp) + return resp, k.SendFuturesAuthRequest(ctx, http.MethodPost, futuresWithdraw, params, nil, &resp) } // FuturesGetTransfers withdraws currencies from futures wallet to spot wallet -func (k *Kraken) FuturesGetTransfers(lastTransferTime time.Time) (GenericResponse, error) { +func (k *Kraken) FuturesGetTransfers(ctx context.Context, lastTransferTime time.Time) (GenericResponse, error) { var resp GenericResponse params := url.Values{} if !lastTransferTime.IsZero() { params.Set("lastTransferTime", lastTransferTime.UTC().Format(time.RFC3339)) } - return resp, k.SendFuturesAuthRequest(http.MethodGet, futuresTransfers, params, nil, &resp) + return resp, k.SendFuturesAuthRequest(ctx, http.MethodGet, futuresTransfers, params, nil, &resp) } // GetFuturesAccountData gets account data for futures -func (k *Kraken) GetFuturesAccountData() (FuturesAccountsData, error) { +func (k *Kraken) GetFuturesAccountData(ctx context.Context) (FuturesAccountsData, error) { var resp FuturesAccountsData - return resp, k.SendFuturesAuthRequest(http.MethodGet, futuresAccountData, nil, nil, &resp) + return resp, k.SendFuturesAuthRequest(ctx, http.MethodGet, futuresAccountData, nil, nil, &resp) } func (k *Kraken) signFuturesRequest(endpoint, nonce, data string) (string, error) { @@ -265,7 +265,7 @@ func (k *Kraken) signFuturesRequest(endpoint, nonce, data string) (string, error } // SendFuturesAuthRequest will send an auth req -func (k *Kraken) SendFuturesAuthRequest(method, path string, postData url.Values, data map[string]interface{}, result interface{}) error { +func (k *Kraken) SendFuturesAuthRequest(ctx context.Context, method, path string, postData url.Values, data map[string]interface{}, result interface{}) error { if !k.AllowAuthenticatedRequest() { return fmt.Errorf("%s %w", k.Name, exchange.ErrAuthenticatedRequestWithoutCredentialsSet) } @@ -307,7 +307,7 @@ func (k *Kraken) SendFuturesAuthRequest(method, path string, postData url.Values }, nil } - err := k.SendPayload(context.Background(), request.Unset, newRequest) + err := k.SendPayload(ctx, request.Unset, newRequest) if err != nil { return err } diff --git a/exchanges/kraken/kraken_test.go b/exchanges/kraken/kraken_test.go index d42b2b04..fe136a4b 100644 --- a/exchanges/kraken/kraken_test.go +++ b/exchanges/kraken/kraken_test.go @@ -1,6 +1,7 @@ package kraken import ( + "context" "fmt" "log" "net/http" @@ -61,7 +62,7 @@ func TestMain(m *testing.M) { // TestGetServerTime API endpoint test func TestGetServerTime(t *testing.T) { t.Parallel() - _, err := k.GetServerTime() + _, err := k.GetServerTime(context.Background()) if err != nil { t.Error("GetServerTime() error", err) } @@ -69,7 +70,7 @@ func TestGetServerTime(t *testing.T) { func TestFetchTradablePairs(t *testing.T) { t.Parallel() - _, err := k.FetchTradablePairs(asset.Futures) + _, err := k.FetchTradablePairs(context.Background(), asset.Futures) if err != nil { t.Error(err) } @@ -81,7 +82,7 @@ func TestUpdateTicker(t *testing.T) { if err != nil { t.Error(err) } - _, err = k.UpdateTicker(sp, asset.Spot) + _, err = k.UpdateTicker(context.Background(), sp, asset.Spot) if err != nil { t.Error(err) } @@ -90,7 +91,7 @@ func TestUpdateTicker(t *testing.T) { if err != nil { t.Error(err) } - _, err = k.UpdateTicker(fp, asset.Futures) + _, err = k.UpdateTicker(context.Background(), fp, asset.Futures) if err != nil { t.Error(err) } @@ -98,12 +99,12 @@ func TestUpdateTicker(t *testing.T) { func TestUpdateTickers(t *testing.T) { t.Parallel() - err := k.UpdateTickers(asset.Spot) + err := k.UpdateTickers(context.Background(), asset.Spot) if err != nil { t.Error(err) } - err = k.UpdateTickers(asset.Futures) + err = k.UpdateTickers(context.Background(), asset.Futures) if err != nil { t.Error(err) } @@ -115,7 +116,7 @@ func TestUpdateOrderbook(t *testing.T) { if err != nil { t.Error(err) } - _, err = k.UpdateOrderbook(sp, asset.Spot) + _, err = k.UpdateOrderbook(context.Background(), sp, asset.Spot) if err != nil { t.Error(err) } @@ -124,7 +125,7 @@ func TestUpdateOrderbook(t *testing.T) { if err != nil { t.Error(err) } - _, err = k.UpdateOrderbook(fp, asset.Futures) + _, err = k.UpdateOrderbook(context.Background(), fp, asset.Futures) if err != nil { t.Error(err) } @@ -135,7 +136,7 @@ func TestUpdateAccountInfo(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("skipping test: api keys not set") } - _, err := k.UpdateAccountInfo(asset.Spot) + _, err := k.UpdateAccountInfo(context.Background(), asset.Spot) if err != nil { t.Error(err) } @@ -146,7 +147,8 @@ func TestWrapperGetOrderInfo(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("skipping test: api keys not set") } - _, err := k.GetOrderInfo("123", currency.Pair{}, asset.Futures) + _, err := k.GetOrderInfo(context.Background(), + "123", currency.Pair{}, asset.Futures) if err != nil { t.Error(err) } @@ -163,7 +165,7 @@ func TestFuturesBatchOrder(t *testing.T) { tempData.OrderID = "test123" tempData.Symbol = "pi_xbtusd" data = append(data, tempData) - _, err := k.FuturesBatchOrder(data) + _, err := k.FuturesBatchOrder(context.Background(), data) if err != nil { t.Error(err) } @@ -174,7 +176,7 @@ func TestFuturesEditOrder(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test: api keys not set or canManipulateRealOrders") } - _, err := k.FuturesEditOrder("test123", "", 5.2, 1, 0) + _, err := k.FuturesEditOrder(context.Background(), "test123", "", 5.2, 1, 0) if err != nil { t.Error(err) } @@ -189,7 +191,8 @@ func TestFuturesSendOrder(t *testing.T) { if err != nil { t.Error(err) } - _, err = k.FuturesSendOrder(order.Limit, cp, "buy", "", "", "", 1, 1, 0.9) + _, err = k.FuturesSendOrder(context.Background(), + order.Limit, cp, "buy", "", "", "", 1, 1, 0.9) if err != nil { t.Error(err) } @@ -200,7 +203,7 @@ func TestFuturesCancelOrder(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test: api keys not set or canManipulateRealOrders") } - _, err := k.FuturesCancelOrder("test123", "") + _, err := k.FuturesCancelOrder(context.Background(), "test123", "") if err != nil { t.Error(err) } @@ -211,7 +214,7 @@ func TestFuturesGetFills(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("skipping test: api keys not set") } - _, err := k.FuturesGetFills(time.Now().Add(-time.Hour * 24)) + _, err := k.FuturesGetFills(context.Background(), time.Now().Add(-time.Hour*24)) if err != nil { t.Error(err) } @@ -222,7 +225,7 @@ func TestFuturesTransfer(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("skipping test: api keys not set") } - _, err := k.FuturesTransfer("cash", "futures", "btc", 2) + _, err := k.FuturesTransfer(context.Background(), "cash", "futures", "btc", 2) if err != nil { t.Error(err) } @@ -233,7 +236,7 @@ func TestFuturesGetOpenPositions(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("skipping test: api keys not set") } - _, err := k.FuturesGetOpenPositions() + _, err := k.FuturesGetOpenPositions(context.Background()) if err != nil { t.Error(err) } @@ -244,7 +247,7 @@ func TestFuturesNotifications(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("skipping test: api keys not set") } - _, err := k.FuturesNotifications() + _, err := k.FuturesNotifications(context.Background()) if err != nil { t.Error(err) } @@ -259,7 +262,7 @@ func TestFuturesCancelAllOrders(t *testing.T) { if err != nil { t.Error(err) } - _, err = k.FuturesCancelAllOrders(cp) + _, err = k.FuturesCancelAllOrders(context.Background(), cp) if err != nil { t.Error(err) } @@ -270,7 +273,7 @@ func TestGetFuturesAccountData(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("skipping test: api keys not set") } - _, err := k.GetFuturesAccountData() + _, err := k.GetFuturesAccountData(context.Background()) if err != nil { t.Error(err) } @@ -281,7 +284,7 @@ func TestFuturesCancelAllOrdersAfter(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test: api keys not set or canManipulateRealOrders") } - _, err := k.FuturesCancelAllOrdersAfter(50) + _, err := k.FuturesCancelAllOrdersAfter(context.Background(), 50) if err != nil { t.Error(err) } @@ -292,7 +295,7 @@ func TestFuturesOpenOrders(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("skipping test: api keys not set") } - _, err := k.FuturesOpenOrders() + _, err := k.FuturesOpenOrders(context.Background()) if err != nil { t.Error(err) } @@ -307,7 +310,7 @@ func TestFuturesRecentOrders(t *testing.T) { if err != nil { t.Error(err) } - _, err = k.FuturesRecentOrders(cp) + _, err = k.FuturesRecentOrders(context.Background(), cp) if err != nil { t.Error(err) } @@ -318,7 +321,7 @@ func TestFuturesWithdrawToSpotWallet(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test: api keys not set or canManipulateRealOrders") } - _, err := k.FuturesWithdrawToSpotWallet("xbt", 5) + _, err := k.FuturesWithdrawToSpotWallet(context.Background(), "xbt", 5) if err != nil { t.Error(err) } @@ -329,7 +332,8 @@ func TestFuturesGetTransfers(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("skipping test: api keys not set") } - _, err := k.FuturesGetTransfers(time.Now().Add(-time.Hour * 24)) + _, err := k.FuturesGetTransfers(context.Background(), + time.Now().Add(-time.Hour*24)) if err != nil { t.Error(err) } @@ -341,7 +345,7 @@ func TestGetFuturesOrderbook(t *testing.T) { if err != nil { t.Error(err) } - _, err = k.GetFuturesOrderbook(cp) + _, err = k.GetFuturesOrderbook(context.Background(), cp) if err != nil { t.Error(err) } @@ -349,7 +353,7 @@ func TestGetFuturesOrderbook(t *testing.T) { func TestGetFuturesMarkets(t *testing.T) { t.Parallel() - _, err := k.GetFuturesMarkets() + _, err := k.GetFuturesMarkets(context.Background()) if err != nil { t.Error(err) } @@ -357,7 +361,7 @@ func TestGetFuturesMarkets(t *testing.T) { func TestGetFuturesTickers(t *testing.T) { t.Parallel() - _, err := k.GetFuturesTickers() + _, err := k.GetFuturesTickers(context.Background()) if err != nil { t.Error(err) } @@ -369,7 +373,8 @@ func TestGetFuturesTradeHistory(t *testing.T) { if err != nil { t.Error(err) } - _, err = k.GetFuturesTradeHistory(cp, time.Now().Add(-time.Hour*24)) + _, err = k.GetFuturesTradeHistory(context.Background(), + cp, time.Now().Add(-time.Hour*24)) if err != nil { t.Error(err) } @@ -378,7 +383,7 @@ func TestGetFuturesTradeHistory(t *testing.T) { // TestGetAssets API endpoint test func TestGetAssets(t *testing.T) { t.Parallel() - _, err := k.GetAssets() + _, err := k.GetAssets(context.Background()) if err != nil { t.Error("GetAssets() error", err) } @@ -445,19 +450,19 @@ func TestLookupCurrency(t *testing.T) { // TestGetAssetPairs API endpoint test func TestGetAssetPairs(t *testing.T) { t.Parallel() - _, err := k.GetAssetPairs([]string{}, "fees") + _, err := k.GetAssetPairs(context.Background(), []string{}, "fees") if err != nil { t.Error("GetAssetPairs() error", err) } - _, err = k.GetAssetPairs([]string{}, "leverage") + _, err = k.GetAssetPairs(context.Background(), []string{}, "leverage") if err != nil { t.Error("GetAssetPairs() error", err) } - _, err = k.GetAssetPairs([]string{}, "margin") + _, err = k.GetAssetPairs(context.Background(), []string{}, "margin") if err != nil { t.Error("GetAssetPairs() error", err) } - _, err = k.GetAssetPairs([]string{}, "") + _, err = k.GetAssetPairs(context.Background(), []string{}, "") if err != nil { t.Error("GetAssetPairs() error", err) } @@ -470,7 +475,7 @@ func TestGetTicker(t *testing.T) { if err != nil { t.Error(err) } - _, err = k.GetTicker(cp) + _, err = k.GetTicker(context.Background(), cp) if err != nil { t.Error("GetTicker() error", err) } @@ -479,7 +484,7 @@ func TestGetTicker(t *testing.T) { // TestGetTickers API endpoint test func TestGetTickers(t *testing.T) { t.Parallel() - _, err := k.GetTickers("LTCUSD,ETCUSD") + _, err := k.GetTickers(context.Background(), "LTCUSD,ETCUSD") if err != nil { t.Error("GetTickers() error", err) } @@ -492,7 +497,7 @@ func TestGetOHLC(t *testing.T) { if err != nil { t.Error(err) } - _, err = k.GetOHLC(cp, "1440") + _, err = k.GetOHLC(context.Background(), cp, "1440") if err != nil { t.Error("GetOHLC() error", err) } @@ -505,7 +510,7 @@ func TestGetDepth(t *testing.T) { if err != nil { t.Error(err) } - _, err = k.GetDepth(cp) + _, err = k.GetDepth(context.Background(), cp) if err != nil { t.Error("GetDepth() error", err) } @@ -518,7 +523,7 @@ func TestGetTrades(t *testing.T) { if err != nil { t.Error(err) } - _, err = k.GetTrades(cp) + _, err = k.GetTrades(context.Background(), cp) if err != nil { t.Error("GetTrades() error", err) } @@ -540,7 +545,7 @@ func TestGetSpread(t *testing.T) { if err != nil { t.Error(err) } - _, err = k.GetSpread(cp) + _, err = k.GetSpread(context.Background(), cp) if err != nil { t.Error("GetSpread() error", err) } @@ -549,7 +554,7 @@ func TestGetSpread(t *testing.T) { // TestGetBalance API endpoint test func TestGetBalance(t *testing.T) { t.Parallel() - _, err := k.GetBalance() + _, err := k.GetBalance(context.Background()) if err == nil { t.Error("GetBalance() Expected error") } @@ -559,7 +564,7 @@ func TestGetBalance(t *testing.T) { func TestGetTradeBalance(t *testing.T) { t.Parallel() args := TradeBalanceOptions{Asset: "ZEUR"} - _, err := k.GetTradeBalance(args) + _, err := k.GetTradeBalance(context.Background(), args) if err == nil { t.Error("GetTradeBalance() Expected error") } @@ -569,7 +574,7 @@ func TestGetTradeBalance(t *testing.T) { func TestGetOpenOrders(t *testing.T) { t.Parallel() args := OrderInfoOptions{Trades: true} - _, err := k.GetOpenOrders(args) + _, err := k.GetOpenOrders(context.Background(), args) if err == nil { t.Error("GetOpenOrders() Expected error") } @@ -579,7 +584,7 @@ func TestGetOpenOrders(t *testing.T) { func TestGetClosedOrders(t *testing.T) { t.Parallel() args := GetClosedOrdersOptions{Trades: true, Start: "OE4KV4-4FVQ5-V7XGPU"} - _, err := k.GetClosedOrders(args) + _, err := k.GetClosedOrders(context.Background(), args) if err == nil { t.Error("GetClosedOrders() Expected error") } @@ -589,7 +594,8 @@ func TestGetClosedOrders(t *testing.T) { func TestQueryOrdersInfo(t *testing.T) { t.Parallel() args := OrderInfoOptions{Trades: true} - _, err := k.QueryOrdersInfo(args, "OR6ZFV-AA6TT-CKFFIW", "OAMUAJ-HLVKG-D3QJ5F") + _, err := k.QueryOrdersInfo(context.Background(), + args, "OR6ZFV-AA6TT-CKFFIW", "OAMUAJ-HLVKG-D3QJ5F") if err == nil { t.Error("QueryOrdersInfo() Expected error") } @@ -599,7 +605,7 @@ func TestQueryOrdersInfo(t *testing.T) { func TestGetTradesHistory(t *testing.T) { t.Parallel() args := GetTradesHistoryOptions{Trades: true, Start: "TMZEDR-VBJN2-NGY6DX", End: "TVRXG2-R62VE-RWP3UW"} - _, err := k.GetTradesHistory(args) + _, err := k.GetTradesHistory(context.Background(), args) if err == nil { t.Error("GetTradesHistory() Expected error") } @@ -608,7 +614,8 @@ func TestGetTradesHistory(t *testing.T) { // TestQueryTrades API endpoint test func TestQueryTrades(t *testing.T) { t.Parallel() - _, err := k.QueryTrades(true, "TMZEDR-VBJN2-NGY6DX", "TFLWIB-KTT7L-4TWR3L", "TDVRAH-2H6OS-SLSXRX") + _, err := k.QueryTrades(context.Background(), + true, "TMZEDR-VBJN2-NGY6DX", "TFLWIB-KTT7L-4TWR3L", "TDVRAH-2H6OS-SLSXRX") if err == nil { t.Error("QueryTrades() Expected error") } @@ -617,7 +624,7 @@ func TestQueryTrades(t *testing.T) { // TestOpenPositions API endpoint test func TestOpenPositions(t *testing.T) { t.Parallel() - _, err := k.OpenPositions(false) + _, err := k.OpenPositions(context.Background(), false) if err == nil { t.Error("OpenPositions() Expected error") } @@ -627,7 +634,7 @@ func TestOpenPositions(t *testing.T) { func TestGetLedgers(t *testing.T) { t.Parallel() args := GetLedgersOptions{Start: "LRUHXI-IWECY-K4JYGO", End: "L5NIY7-JZQJD-3J4M2V", Ofs: 15} - _, err := k.GetLedgers(args) + _, err := k.GetLedgers(context.Background(), args) if err == nil { t.Error("GetLedgers() Expected error") } @@ -636,7 +643,7 @@ func TestGetLedgers(t *testing.T) { // TestQueryLedgers API endpoint test func TestQueryLedgers(t *testing.T) { t.Parallel() - _, err := k.QueryLedgers("LVTSFS-NHZVM-EXNZ5M") + _, err := k.QueryLedgers(context.Background(), "LVTSFS-NHZVM-EXNZ5M") if err == nil { t.Error("QueryLedgers() Expected error") } @@ -649,7 +656,7 @@ func TestGetTradeVolume(t *testing.T) { if err != nil { t.Error(err) } - _, err = k.GetTradeVolume(true, cp) + _, err = k.GetTradeVolume(context.Background(), true, cp) if err == nil { t.Error("GetTradeVolume() Expected error") } @@ -663,7 +670,8 @@ func TestAddOrder(t *testing.T) { if err != nil { t.Error(err) } - _, err = k.AddOrder(cp, + _, err = k.AddOrder(context.Background(), + cp, order.Sell.Lower(), order.Limit.Lower(), 0.00000001, 0, 0, 0, &args) if err == nil { @@ -674,7 +682,7 @@ func TestAddOrder(t *testing.T) { // TestCancelExistingOrder API endpoint test func TestCancelExistingOrder(t *testing.T) { t.Parallel() - _, err := k.CancelExistingOrder("OAVY7T-MV5VK-KHDF5X") + _, err := k.CancelExistingOrder(context.Background(), "OAVY7T-MV5VK-KHDF5X") if err == nil { t.Error("CancelExistingOrder() Expected error") } @@ -697,7 +705,7 @@ func setFeeBuilder() *exchange.FeeBuilder { func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { t.Parallel() var feeBuilder = setFeeBuilder() - _, err := k.GetFeeByType(feeBuilder) + _, err := k.GetFeeByType(context.Background(), feeBuilder) if err != nil { t.Fatal(err) } @@ -718,7 +726,7 @@ func TestGetFee(t *testing.T) { if areTestAPIKeysSet() { // CryptocurrencyTradeFee Basic - if _, err := k.GetFee(feeBuilder); err != nil { + if _, err := k.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } @@ -726,28 +734,28 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.Amount = 1000 feeBuilder.PurchasePrice = 1000 - if _, err := k.GetFee(feeBuilder); err != nil { + if _, err := k.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyTradeFee IsMaker feeBuilder = setFeeBuilder() feeBuilder.IsMaker = true - if _, err := k.GetFee(feeBuilder); err != nil { + if _, err := k.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyTradeFee Negative purchase price feeBuilder = setFeeBuilder() feeBuilder.PurchasePrice = -1000 - if _, err := k.GetFee(feeBuilder); err != nil { + if _, err := k.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } // InternationalBankDepositFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankDepositFee - if _, err := k.GetFee(feeBuilder); err != nil { + if _, err := k.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } } @@ -756,14 +764,14 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.CryptocurrencyDepositFee feeBuilder.Pair.Base = currency.XXBT - if _, err := k.GetFee(feeBuilder); err != nil { + if _, err := k.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyWithdrawalFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee - if _, err := k.GetFee(feeBuilder); err != nil { + if _, err := k.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } @@ -771,7 +779,7 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.Pair.Base = currency.NewCode("hello") feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee - if _, err := k.GetFee(feeBuilder); err != nil { + if _, err := k.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } @@ -779,7 +787,7 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee feeBuilder.FiatCurrency = currency.USD - if _, err := k.GetFee(feeBuilder); err != nil { + if _, err := k.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } } @@ -810,7 +818,7 @@ func TestGetActiveOrders(t *testing.T) { Pairs: currency.Pairs{pair}, } - _, err = k.GetActiveOrders(&getOrdersRequest) + _, err = k.GetActiveOrders(context.Background(), &getOrdersRequest) if err != nil { t.Error(err) } @@ -824,7 +832,7 @@ func TestGetOrderHistory(t *testing.T) { AssetType: asset.Spot, } - _, err := k.GetOrderHistory(&getOrdersRequest) + _, err := k.GetOrderHistory(context.Background(), &getOrdersRequest) if areTestAPIKeysSet() && err != nil { t.Errorf("Could not get order history: %s", err) } else if !areTestAPIKeysSet() && err == nil { @@ -839,7 +847,8 @@ func TestGetOrderInfo(t *testing.T) { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - _, err := k.GetOrderInfo("OZPTPJ-HVYHF-EDIGXS", currency.Pair{}, asset.Spot) + _, err := k.GetOrderInfo(context.Background(), + "OZPTPJ-HVYHF-EDIGXS", currency.Pair{}, asset.Spot) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting error") } @@ -877,7 +886,7 @@ func TestSubmitOrder(t *testing.T) { ClientID: "meowOrder", AssetType: asset.Spot, } - response, err := k.SubmitOrder(orderSubmission) + response, err := k.SubmitOrder(context.Background(), orderSubmission) if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) { t.Errorf("Order failed to be placed: %v", err) } else if !areTestAPIKeysSet() && err == nil { @@ -897,7 +906,7 @@ func TestCancelExchangeOrder(t *testing.T) { AssetType: asset.Spot, } - err := k.CancelOrder(orderCancellation) + err := k.CancelOrder(context.Background(), orderCancellation) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") } @@ -926,7 +935,7 @@ func TestCancelBatchExchangeOrder(t *testing.T) { AssetType: asset.Spot, }) - _, err := k.CancelBatchOrders(ordersCancellation) + _, err := k.CancelBatchOrders(context.Background(), ordersCancellation) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") } @@ -942,7 +951,8 @@ func TestCancelAllExchangeOrders(t *testing.T) { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - resp, err := k.CancelAllOrders(&order.Cancel{AssetType: asset.Spot}) + resp, err := k.CancelAllOrders(context.Background(), + &order.Cancel{AssetType: asset.Spot}) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") } @@ -959,13 +969,13 @@ func TestCancelAllExchangeOrders(t *testing.T) { func TestGetAccountInfo(t *testing.T) { t.Parallel() if areTestAPIKeysSet() { - _, err := k.UpdateAccountInfo(asset.Spot) + _, err := k.UpdateAccountInfo(context.Background(), asset.Spot) if err != nil { // Spot and Futures have separate api keys. Please ensure that the correct one is provided t.Error("GetAccountInfo() error", err) } } else { - _, err := k.UpdateAccountInfo(asset.Spot) + _, err := k.UpdateAccountInfo(context.Background(), asset.Spot) if err == nil { t.Error("GetAccountInfo() Expected error") } @@ -977,7 +987,7 @@ func TestUpdateFuturesAccountInfo(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys not set. Skipping the test") } - _, err := k.UpdateAccountInfo(asset.Futures) + _, err := k.UpdateAccountInfo(context.Background(), asset.Futures) if err != nil { // Spot and Futures have separate api keys. Please ensure that the correct one is provided t.Error(err) @@ -990,7 +1000,8 @@ func TestModifyOrder(t *testing.T) { if areTestAPIKeysSet() && !canManipulateRealOrders { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - _, err := k.ModifyOrder(&order.Modify{AssetType: asset.Spot}) + _, err := k.ModifyOrder(context.Background(), + &order.Modify{AssetType: asset.Spot}) if err == nil { t.Error("ModifyOrder() Expected error") } @@ -1014,7 +1025,8 @@ func TestWithdraw(t *testing.T) { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - _, err := k.WithdrawCryptocurrencyFunds(&withdrawCryptoRequest) + _, err := k.WithdrawCryptocurrencyFunds(context.Background(), + &withdrawCryptoRequest) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") } @@ -1037,7 +1049,7 @@ func TestWithdrawFiat(t *testing.T) { TradePassword: "someBank", } - _, err := k.WithdrawFiatFunds(&withdrawFiatRequest) + _, err := k.WithdrawFiatFunds(context.Background(), &withdrawFiatRequest) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") } @@ -1060,7 +1072,8 @@ func TestWithdrawInternationalBank(t *testing.T) { TradePassword: "someBank", } - _, err := k.WithdrawFiatFundsToInternationalBank(&withdrawFiatRequest) + _, err := k.WithdrawFiatFundsToInternationalBank(context.Background(), + &withdrawFiatRequest) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") } @@ -1073,12 +1086,12 @@ func TestWithdrawInternationalBank(t *testing.T) { func TestGetDepositAddress(t *testing.T) { t.Parallel() if areTestAPIKeysSet() { - _, err := k.GetDepositAddress(currency.BTC, "") + _, err := k.GetDepositAddress(context.Background(), currency.BTC, "") if err != nil { t.Error("GetDepositAddress() error", err) } } else { - _, err := k.GetDepositAddress(currency.BTC, "") + _, err := k.GetDepositAddress(context.Background(), currency.BTC, "") if err == nil { t.Error("GetDepositAddress() error can not be nil") } @@ -1089,12 +1102,12 @@ func TestGetDepositAddress(t *testing.T) { func TestWithdrawStatus(t *testing.T) { t.Parallel() if areTestAPIKeysSet() { - _, err := k.WithdrawStatus(currency.BTC, "") + _, err := k.WithdrawStatus(context.Background(), currency.BTC, "") if err != nil { t.Error("WithdrawStatus() error", err) } } else { - _, err := k.WithdrawStatus(currency.BTC, "") + _, err := k.WithdrawStatus(context.Background(), currency.BTC, "") if err == nil { t.Error("GetDepositAddress() error can not be nil") } @@ -1104,7 +1117,7 @@ func TestWithdrawStatus(t *testing.T) { // TestWithdrawCancel wrapper test func TestWithdrawCancel(t *testing.T) { t.Parallel() - _, err := k.WithdrawCancel(currency.BTC, "") + _, err := k.WithdrawCancel(context.Background(), currency.BTC, "") if areTestAPIKeysSet() && err == nil { t.Error("WithdrawCancel() error cannot be nil") } else if !areTestAPIKeysSet() && err == nil { @@ -1131,7 +1144,7 @@ func setupWsTests(t *testing.T) { t.Fatal(err) } - token, err := k.GetWebsocketToken() + token, err := k.GetWebsocketToken(context.Background()) if err != nil { t.Error(err) } @@ -1168,7 +1181,7 @@ func TestGetWSToken(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys required, skipping") } - resp, err := k.GetWebsocketToken() + resp, err := k.GetWebsocketToken(context.Background()) if err != nil { t.Error(err) } @@ -1926,12 +1939,14 @@ func TestGetHistoricCandles(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = k.GetHistoricCandles(currencyPair, asset.Spot, time.Now(), time.Now().Add(-time.Minute*3), kline.OneMin) + _, err = k.GetHistoricCandles(context.Background(), + currencyPair, asset.Spot, time.Now(), time.Now().Add(-time.Minute*3), kline.OneMin) if err != nil { t.Fatal(err) } - _, err = k.GetHistoricCandles(currencyPair, asset.Spot, time.Now(), time.Now(), kline.Interval(time.Hour*7)) + _, err = k.GetHistoricCandles(context.Background(), + currencyPair, asset.Spot, time.Now(), time.Now(), kline.Interval(time.Hour*7)) if err == nil { t.Fatal("unexpected result") } @@ -1943,12 +1958,14 @@ func TestGetHistoricCandlesExtended(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = k.GetHistoricCandlesExtended(currencyPair, asset.Spot, time.Now().Add(-time.Hour*48), time.Now(), kline.OneDay) + _, err = k.GetHistoricCandlesExtended(context.Background(), + currencyPair, asset.Spot, time.Now().Add(-time.Hour*48), time.Now(), kline.OneDay) if err != nil { t.Fatal(err) } - _, err = k.GetHistoricCandlesExtended(currencyPair, asset.Spot, time.Now(), time.Now(), kline.Interval(time.Hour*7)) + _, err = k.GetHistoricCandlesExtended(context.Background(), + currencyPair, asset.Spot, time.Now(), time.Now(), kline.Interval(time.Hour*7)) if err == nil { t.Fatal("unexpected result") } @@ -1992,7 +2009,7 @@ func TestGetRecentTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = k.GetRecentTrades(currencyPair, asset.Spot) + _, err = k.GetRecentTrades(context.Background(), currencyPair, asset.Spot) if err != nil { t.Error(err) } @@ -2004,7 +2021,8 @@ func TestGetHistoricTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = k.GetHistoricTrades(currencyPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) + _, err = k.GetHistoricTrades(context.Background(), + currencyPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) if err != nil && err != common.ErrFunctionNotSupported { t.Error(err) } diff --git a/exchanges/kraken/kraken_websocket.go b/exchanges/kraken/kraken_websocket.go index dbee8a1f..47e7e9fe 100644 --- a/exchanges/kraken/kraken_websocket.go +++ b/exchanges/kraken/kraken_websocket.go @@ -1,6 +1,7 @@ package kraken import ( + "context" "encoding/json" "errors" "fmt" @@ -101,7 +102,7 @@ func (k *Kraken) WsConnect() error { go k.wsFunnelConnectionData(k.Websocket.Conn, comms) if k.GetAuthenticatedAPISupport(exchange.WebsocketAuthentication) { - authToken, err = k.GetWebsocketToken() + authToken, err = k.GetWebsocketToken(context.TODO()) if err != nil { k.Websocket.SetCanUseAuthenticatedEndpoints(false) log.Errorf(log.ExchangeSys, diff --git a/exchanges/kraken/kraken_wrapper.go b/exchanges/kraken/kraken_wrapper.go index 544a3224..f9287909 100644 --- a/exchanges/kraken/kraken_wrapper.go +++ b/exchanges/kraken/kraken_wrapper.go @@ -1,6 +1,7 @@ package kraken import ( + "context" "errors" "fmt" "sort" @@ -42,7 +43,7 @@ func (k *Kraken) GetDefaultConfig() (*config.ExchangeConfig, error) { } if k.Features.Supports.RESTCapabilities.AutoPairUpdates { - err = k.UpdateTradablePairs(true) + err = k.UpdateTradablePairs(context.TODO(), true) if err != nil { return nil, err } @@ -197,7 +198,7 @@ func (k *Kraken) Setup(exch *config.ExchangeConfig) error { return err } - err = k.SeedAssets() + err = k.SeedAssets(context.TODO()) if err != nil { return err } @@ -318,7 +319,7 @@ func (k *Kraken) Run() { return } - err = k.UpdateTradablePairs(forceUpdate) + err = k.UpdateTradablePairs(context.TODO(), forceUpdate) if err != nil { log.Errorf(log.ExchangeSys, "%s failed to update tradable pairs. Err: %s", @@ -328,7 +329,7 @@ func (k *Kraken) Run() { } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (k *Kraken) FetchTradablePairs(assetType asset.Item) ([]string, error) { +func (k *Kraken) FetchTradablePairs(ctx context.Context, assetType asset.Item) ([]string, error) { var products []string format, err := k.GetPairFormat(assetType, false) if err != nil { @@ -337,11 +338,11 @@ func (k *Kraken) FetchTradablePairs(assetType asset.Item) ([]string, error) { switch assetType { case asset.Spot: if !assetTranslator.Seeded() { - if err := k.SeedAssets(); err != nil { + if err := k.SeedAssets(ctx); err != nil { return nil, err } } - pairs, err := k.GetAssetPairs([]string{}, "") + pairs, err := k.GetAssetPairs(ctx, []string{}, "") if err != nil { return nil, err } @@ -368,7 +369,7 @@ func (k *Kraken) FetchTradablePairs(assetType asset.Item) ([]string, error) { products = append(products, base+format.Delimiter+quote) } case asset.Futures: - pairs, err := k.GetFuturesMarkets() + pairs, err := k.GetFuturesMarkets(ctx) if err != nil { return nil, err } @@ -387,10 +388,10 @@ func (k *Kraken) FetchTradablePairs(assetType asset.Item) ([]string, error) { // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (k *Kraken) UpdateTradablePairs(forceUpdate bool) error { +func (k *Kraken) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { assets := k.GetAssetTypes(false) for x := range assets { - pairs, err := k.FetchTradablePairs(assets[x]) + pairs, err := k.FetchTradablePairs(ctx, assets[x]) if err != nil { return err } @@ -407,7 +408,7 @@ func (k *Kraken) UpdateTradablePairs(forceUpdate bool) error { } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (k *Kraken) UpdateTickers(a asset.Item) error { +func (k *Kraken) UpdateTickers(ctx context.Context, a asset.Item) error { switch a { case asset.Spot: pairs, err := k.GetEnabledPairs(a) @@ -418,7 +419,7 @@ func (k *Kraken) UpdateTickers(a asset.Item) error { if err != nil { return err } - tickers, err := k.GetTickers(pairsCollated) + tickers, err := k.GetTickers(ctx, pairsCollated) if err != nil { return err } @@ -456,7 +457,7 @@ func (k *Kraken) UpdateTickers(a asset.Item) error { } } case asset.Futures: - t, err := k.GetFuturesTickers() + t, err := k.GetFuturesTickers(ctx) if err != nil { return err } @@ -485,8 +486,8 @@ func (k *Kraken) UpdateTickers(a asset.Item) error { } // UpdateTicker updates and returns the ticker for a currency pair -func (k *Kraken) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) { - err := k.UpdateTickers(a) +func (k *Kraken) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { + err := k.UpdateTickers(ctx, a) if err != nil { return nil, err } @@ -494,25 +495,25 @@ func (k *Kraken) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, err } // FetchTicker returns the ticker for a currency pair -func (k *Kraken) FetchTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) { +func (k *Kraken) FetchTicker(ctx context.Context, p currency.Pair, assetType asset.Item) (*ticker.Price, error) { tickerNew, err := ticker.GetTicker(k.Name, p, assetType) if err != nil { - return k.UpdateTicker(p, assetType) + return k.UpdateTicker(ctx, p, assetType) } return tickerNew, nil } // FetchOrderbook returns orderbook base on the currency pair -func (k *Kraken) FetchOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (k *Kraken) FetchOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { ob, err := orderbook.Get(k.Name, p, assetType) if err != nil { - return k.UpdateOrderbook(p, assetType) + return k.UpdateOrderbook(ctx, p, assetType) } return ob, nil } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (k *Kraken) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (k *Kraken) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { book := &orderbook.Base{ Exchange: k.Name, Pair: p, @@ -523,7 +524,7 @@ func (k *Kraken) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderb switch assetType { case asset.Spot: var orderbookNew Orderbook - orderbookNew, err = k.GetDepth(p) + orderbookNew, err = k.GetDepth(ctx, p) if err != nil { return nil, err } @@ -541,7 +542,7 @@ func (k *Kraken) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderb } case asset.Futures: var futuresOB FuturesOrderbookData - futuresOB, err = k.GetFuturesOrderbook(p) + futuresOB, err = k.GetFuturesOrderbook(ctx, p) if err != nil { return nil, err } @@ -569,13 +570,13 @@ func (k *Kraken) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderb // UpdateAccountInfo retrieves balances for all enabled currencies for the // Kraken exchange - to-do -func (k *Kraken) UpdateAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (k *Kraken) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { var info account.Holdings var balances []account.Balance info.Exchange = k.Name switch assetType { case asset.Spot: - bal, err := k.GetBalance() + bal, err := k.GetBalance(ctx) if err != nil { return info, err } @@ -596,7 +597,7 @@ func (k *Kraken) UpdateAccountInfo(assetType asset.Item) (account.Holdings, erro Currencies: balances, }) case asset.Futures: - bal, err := k.GetFuturesAccountData() + bal, err := k.GetFuturesAccountData(ctx) if err != nil { return info, err } @@ -622,23 +623,23 @@ func (k *Kraken) UpdateAccountInfo(assetType asset.Item) (account.Holdings, erro } // FetchAccountInfo retrieves balances for all enabled currencies -func (k *Kraken) FetchAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (k *Kraken) FetchAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { acc, err := account.GetHoldings(k.Name, assetType) if err != nil { - return k.UpdateAccountInfo(assetType) + return k.UpdateAccountInfo(ctx, assetType) } return acc, nil } // GetFundingHistory returns funding history, deposits and // withdrawals -func (k *Kraken) GetFundingHistory() ([]exchange.FundHistory, error) { +func (k *Kraken) GetFundingHistory(ctx context.Context) ([]exchange.FundHistory, error) { return nil, common.ErrFunctionNotSupported } // GetWithdrawalsHistory returns previous withdrawals data -func (k *Kraken) GetWithdrawalsHistory(c currency.Code) (resp []exchange.WithdrawalHistory, err error) { - withdrawals, err := k.WithdrawStatus(c, "") +func (k *Kraken) GetWithdrawalsHistory(ctx context.Context, c currency.Code) (resp []exchange.WithdrawalHistory, err error) { + withdrawals, err := k.WithdrawStatus(ctx, c, "") for i := range withdrawals { resp = append(resp, exchange.WithdrawalHistory{ Status: withdrawals[i].Status, @@ -656,10 +657,10 @@ func (k *Kraken) GetWithdrawalsHistory(c currency.Code) (resp []exchange.Withdra } // GetRecentTrades returns the most recent trades for a currency and asset -func (k *Kraken) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade.Data, error) { +func (k *Kraken) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { var err error var tradeData []RecentTrades - tradeData, err = k.GetTrades(p) + tradeData, err = k.GetTrades(ctx, p) if err != nil { return nil, err } @@ -690,12 +691,12 @@ func (k *Kraken) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade } // GetHistoricTrades returns historic trade data within the timeframe provided -func (k *Kraken) GetHistoricTrades(_ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { +func (k *Kraken) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { return nil, common.ErrFunctionNotSupported } // SubmitOrder submits a new order -func (k *Kraken) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { +func (k *Kraken) SubmitOrder(ctx context.Context, s *order.Submit) (order.SubmitResponse, error) { var submitOrderResponse order.SubmitResponse err := s.Validate() if err != nil { @@ -720,7 +721,8 @@ func (k *Kraken) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { submitOrderResponse.IsOrderPlaced = true } else { var response AddOrderResponse - response, err = k.AddOrder(s.Pair, + response, err = k.AddOrder(ctx, + s.Pair, s.Side.String(), s.Type.String(), s.Amount, @@ -740,7 +742,7 @@ func (k *Kraken) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { } submitOrderResponse.IsOrderPlaced = true case asset.Futures: - order, err := k.FuturesSendOrder( + order, err := k.FuturesSendOrder(ctx, s.Type, s.Pair, s.Side.Lower(), @@ -764,12 +766,12 @@ func (k *Kraken) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (k *Kraken) ModifyOrder(action *order.Modify) (order.Modify, error) { +func (k *Kraken) ModifyOrder(ctx context.Context, action *order.Modify) (order.Modify, error) { return order.Modify{}, common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number -func (k *Kraken) CancelOrder(o *order.Cancel) error { +func (k *Kraken) CancelOrder(ctx context.Context, o *order.Cancel) error { if err := o.Validate(o.StandardCancel()); err != nil { return err } @@ -778,10 +780,10 @@ func (k *Kraken) CancelOrder(o *order.Cancel) error { if k.Websocket.CanUseAuthenticatedWebsocketForWrapper() { return k.wsCancelOrders([]string{o.ID}) } - _, err := k.CancelExistingOrder(o.ID) + _, err := k.CancelExistingOrder(ctx, o.ID) return err case asset.Futures: - _, err := k.FuturesCancelOrder(o.ID, "") + _, err := k.FuturesCancelOrder(ctx, o.ID, "") if err != nil { return err } @@ -790,7 +792,7 @@ func (k *Kraken) CancelOrder(o *order.Cancel) error { } // CancelBatchOrders cancels an orders by their corresponding ID numbers -func (k *Kraken) CancelBatchOrders(orders []order.Cancel) (order.CancelBatchResponse, error) { +func (k *Kraken) CancelBatchOrders(ctx context.Context, orders []order.Cancel) (order.CancelBatchResponse, error) { var ordersList []string for i := range orders { if err := orders[i].Validate(orders[i].StandardCancel()); err != nil { @@ -808,7 +810,7 @@ func (k *Kraken) CancelBatchOrders(orders []order.Cancel) (order.CancelBatchResp } // CancelAllOrders cancels all orders associated with a currency pair -func (k *Kraken) CancelAllOrders(req *order.Cancel) (order.CancelAllResponse, error) { +func (k *Kraken) CancelAllOrders(ctx context.Context, req *order.Cancel) (order.CancelAllResponse, error) { if err := req.Validate(); err != nil { return order.CancelAllResponse{}, err } @@ -828,7 +830,7 @@ func (k *Kraken) CancelAllOrders(req *order.Cancel) (order.CancelAllResponse, er } var emptyOrderOptions OrderInfoOptions - openOrders, err := k.GetOpenOrders(emptyOrderOptions) + openOrders, err := k.GetOpenOrders(ctx, emptyOrderOptions) if err != nil { return cancelAllOrdersResponse, err } @@ -837,14 +839,14 @@ func (k *Kraken) CancelAllOrders(req *order.Cancel) (order.CancelAllResponse, er if k.Websocket.CanUseAuthenticatedWebsocketForWrapper() { err = k.wsCancelOrders([]string{orderID}) } else { - _, err = k.CancelExistingOrder(orderID) + _, err = k.CancelExistingOrder(ctx, orderID) } if err != nil { cancelAllOrdersResponse.Status[orderID] = err.Error() } } case asset.Futures: - cancelData, err := k.FuturesCancelAllOrders(req.Pair) + cancelData, err := k.FuturesCancelAllOrders(ctx, req.Pair) if err != nil { return cancelAllOrdersResponse, err } @@ -856,13 +858,14 @@ func (k *Kraken) CancelAllOrders(req *order.Cancel) (order.CancelAllResponse, er } // GetOrderInfo returns information on a current open order -func (k *Kraken) GetOrderInfo(orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { +func (k *Kraken) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { var orderDetail order.Detail switch assetType { case asset.Spot: - resp, err := k.QueryOrdersInfo(OrderInfoOptions{ - Trades: true, - }, orderID) + resp, err := k.QueryOrdersInfo(ctx, + OrderInfoOptions{ + Trades: true, + }, orderID) if err != nil { return orderDetail, err } @@ -935,7 +938,7 @@ func (k *Kraken) GetOrderInfo(orderID string, pair currency.Pair, assetType asse Cost: orderInfo.Cost, } case asset.Futures: - orderInfo, err := k.FuturesGetFills(time.Time{}) + orderInfo, err := k.FuturesGetFills(ctx, time.Time{}) if err != nil { return orderDetail, err } @@ -975,8 +978,8 @@ func (k *Kraken) GetOrderInfo(orderID string, pair currency.Pair, assetType asse } // GetDepositAddress returns a deposit address for a specified currency -func (k *Kraken) GetDepositAddress(cryptocurrency currency.Code, _ string) (string, error) { - methods, err := k.GetDepositMethods(cryptocurrency.String()) +func (k *Kraken) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _ string) (string, error) { + methods, err := k.GetDepositMethods(ctx, cryptocurrency.String()) if err != nil { return "", err } @@ -987,16 +990,19 @@ func (k *Kraken) GetDepositAddress(cryptocurrency currency.Code, _ string) (stri if method == "" { return "", errors.New("method not found") } - return k.GetCryptoDepositAddress(method, cryptocurrency.String()) + return k.GetCryptoDepositAddress(ctx, method, cryptocurrency.String()) } // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal // Populate exchange.WithdrawRequest.TradePassword with withdrawal key name, as set up on your account -func (k *Kraken) WithdrawCryptocurrencyFunds(withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (k *Kraken) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } - v, err := k.Withdraw(withdrawRequest.Currency.String(), withdrawRequest.TradePassword, withdrawRequest.Amount) + v, err := k.Withdraw(ctx, + withdrawRequest.Currency.String(), + withdrawRequest.TradePassword, + withdrawRequest.Amount) if err != nil { return nil, err } @@ -1007,11 +1013,14 @@ func (k *Kraken) WithdrawCryptocurrencyFunds(withdrawRequest *withdraw.Request) // WithdrawFiatFunds returns a withdrawal ID when a // withdrawal is submitted -func (k *Kraken) WithdrawFiatFunds(withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (k *Kraken) WithdrawFiatFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } - v, err := k.Withdraw(withdrawRequest.Currency.String(), withdrawRequest.TradePassword, withdrawRequest.Amount) + v, err := k.Withdraw(ctx, + withdrawRequest.Currency.String(), + withdrawRequest.TradePassword, + withdrawRequest.Amount) if err != nil { return nil, err } @@ -1022,11 +1031,14 @@ func (k *Kraken) WithdrawFiatFunds(withdrawRequest *withdraw.Request) (*withdraw // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a // withdrawal is submitted -func (k *Kraken) WithdrawFiatFundsToInternationalBank(withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (k *Kraken) WithdrawFiatFundsToInternationalBank(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } - v, err := k.Withdraw(withdrawRequest.Currency.String(), withdrawRequest.TradePassword, withdrawRequest.Amount) + v, err := k.Withdraw(ctx, + withdrawRequest.Currency.String(), + withdrawRequest.TradePassword, + withdrawRequest.Amount) if err != nil { return nil, err } @@ -1036,23 +1048,23 @@ func (k *Kraken) WithdrawFiatFundsToInternationalBank(withdrawRequest *withdraw. } // GetFeeByType returns an estimate of fee based on type of transaction -func (k *Kraken) GetFeeByType(feeBuilder *exchange.FeeBuilder) (float64, error) { +func (k *Kraken) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { if !k.AllowAuthenticatedRequest() && // Todo check connection status feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { feeBuilder.FeeType = exchange.OfflineTradeFee } - return k.GetFee(feeBuilder) + return k.GetFee(ctx, feeBuilder) } // GetActiveOrders retrieves any orders that are active/open -func (k *Kraken) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, error) { +func (k *Kraken) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) { if err := req.Validate(); err != nil { return nil, err } var orders []order.Detail switch req.AssetType { case asset.Spot: - resp, err := k.GetOpenOrders(OrderInfoOptions{}) + resp, err := k.GetOpenOrders(ctx, OrderInfoOptions{}) if err != nil { return nil, err } @@ -1104,7 +1116,7 @@ func (k *Kraken) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, e return orders, err } } - activeOrders, err := k.FuturesOpenOrders() + activeOrders, err := k.FuturesOpenOrders(ctx) if err != nil { return orders, err } @@ -1152,7 +1164,7 @@ func (k *Kraken) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, e // GetOrderHistory retrieves account order information // Can Limit response to specific order status -func (k *Kraken) GetOrderHistory(getOrdersRequest *order.GetOrdersRequest) ([]order.Detail, error) { +func (k *Kraken) GetOrderHistory(ctx context.Context, getOrdersRequest *order.GetOrdersRequest) ([]order.Detail, error) { if err := getOrdersRequest.Validate(); err != nil { return nil, err } @@ -1182,7 +1194,7 @@ func (k *Kraken) GetOrderHistory(getOrdersRequest *order.GetOrdersRequest) ([]or return nil, err } - resp, err := k.GetClosedOrders(req) + resp, err := k.GetClosedOrders(ctx, req) if err != nil { return nil, err } @@ -1224,7 +1236,7 @@ func (k *Kraken) GetOrderHistory(getOrdersRequest *order.GetOrdersRequest) ([]or } } for p := range pairs { - orderHistory, err = k.FuturesRecentOrders(pairs[p]) + orderHistory, err = k.FuturesRecentOrders(ctx, pairs[p]) if err != nil { return orders, err } @@ -1361,8 +1373,8 @@ func (k *Kraken) GetOrderHistory(getOrdersRequest *order.GetOrdersRequest) ([]or } // AuthenticateWebsocket sends an authentication message to the websocket -func (k *Kraken) AuthenticateWebsocket() error { - resp, err := k.GetWebsocketToken() +func (k *Kraken) AuthenticateWebsocket(ctx context.Context) error { + resp, err := k.GetWebsocketToken(ctx) if resp != "" { authToken = resp } @@ -1371,8 +1383,8 @@ func (k *Kraken) AuthenticateWebsocket() error { // ValidateCredentials validates current credentials used for wrapper // functionality -func (k *Kraken) ValidateCredentials(assetType asset.Item) error { - _, err := k.UpdateAccountInfo(assetType) +func (k *Kraken) ValidateCredentials(ctx context.Context, assetType asset.Item) error { + _, err := k.UpdateAccountInfo(ctx, assetType) return k.CheckTransientError(err) } @@ -1382,7 +1394,7 @@ func (k *Kraken) FormatExchangeKlineInterval(in kline.Interval) string { } // GetHistoricCandles returns candles between a time period for a set time interval -func (k *Kraken) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (k *Kraken) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { if err := k.ValidateKline(pair, a, interval); err != nil { return kline.Item{}, err } @@ -1392,7 +1404,7 @@ func (k *Kraken) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end Asset: a, Interval: interval, } - candles, err := k.GetOHLC(pair, k.FormatExchangeKlineInterval(interval)) + candles, err := k.GetOHLC(ctx, pair, k.FormatExchangeKlineInterval(interval)) if err != nil { return kline.Item{}, err } @@ -1418,7 +1430,7 @@ func (k *Kraken) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (k *Kraken) GetHistoricCandlesExtended(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (k *Kraken) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { if err := k.ValidateKline(pair, a, interval); err != nil { return kline.Item{}, err } @@ -1428,7 +1440,7 @@ func (k *Kraken) GetHistoricCandlesExtended(pair currency.Pair, a asset.Item, st Asset: a, Interval: interval, } - candles, err := k.GetOHLC(pair, k.FormatExchangeKlineInterval(interval)) + candles, err := k.GetOHLC(ctx, pair, k.FormatExchangeKlineInterval(interval)) if err != nil { return kline.Item{}, err } diff --git a/exchanges/lbank/lbank.go b/exchanges/lbank/lbank.go index b38d4d2b..11471407 100644 --- a/exchanges/lbank/lbank.go +++ b/exchanges/lbank/lbank.go @@ -62,44 +62,44 @@ const ( // GetTicker returns a ticker for the specified symbol // symbol: eth_btc -func (l *Lbank) GetTicker(symbol string) (TickerResponse, error) { +func (l *Lbank) GetTicker(ctx context.Context, symbol string) (TickerResponse, error) { var t TickerResponse params := url.Values{} params.Set("symbol", symbol) path := fmt.Sprintf("/v%s/%s?%s", lbankAPIVersion, lbankTicker, params.Encode()) - return t, l.SendHTTPRequest(exchange.RestSpot, path, &t) + return t, l.SendHTTPRequest(ctx, exchange.RestSpot, path, &t) } // GetTickers returns all tickers -func (l *Lbank) GetTickers() ([]TickerResponse, error) { +func (l *Lbank) GetTickers(ctx context.Context) ([]TickerResponse, error) { var t []TickerResponse params := url.Values{} params.Set("symbol", "all") path := fmt.Sprintf("/v%s/%s?%s", lbankAPIVersion, lbankTicker, params.Encode()) - return t, l.SendHTTPRequest(exchange.RestSpot, path, &t) + return t, l.SendHTTPRequest(ctx, exchange.RestSpot, path, &t) } // GetCurrencyPairs returns a list of supported currency pairs by the exchange -func (l *Lbank) GetCurrencyPairs() ([]string, error) { +func (l *Lbank) GetCurrencyPairs(ctx context.Context) ([]string, error) { path := fmt.Sprintf("/v%s/%s", lbankAPIVersion, lbankCurrencyPairs) var result []string - return result, l.SendHTTPRequest(exchange.RestSpot, path, &result) + return result, l.SendHTTPRequest(ctx, exchange.RestSpot, path, &result) } // GetMarketDepths returns arrays of asks, bids and timestamp -func (l *Lbank) GetMarketDepths(symbol, size, merge string) (MarketDepthResponse, error) { +func (l *Lbank) GetMarketDepths(ctx context.Context, symbol, size, merge string) (MarketDepthResponse, error) { var m MarketDepthResponse params := url.Values{} params.Set("symbol", symbol) params.Set("size", size) params.Set("merge", merge) path := fmt.Sprintf("/v%s/%s?%s", lbankAPIVersion2, lbankMarketDepths, params.Encode()) - return m, l.SendHTTPRequest(exchange.RestSpot, path, &m) + return m, l.SendHTTPRequest(ctx, exchange.RestSpot, path, &m) } // GetTrades returns an array of available trades regarding a particular exchange -func (l *Lbank) GetTrades(symbol string, limit, time int64) ([]TradeResponse, error) { +func (l *Lbank) GetTrades(ctx context.Context, symbol string, limit, time int64) ([]TradeResponse, error) { var g []TradeResponse params := url.Values{} params.Set("symbol", symbol) @@ -110,11 +110,11 @@ func (l *Lbank) GetTrades(symbol string, limit, time int64) ([]TradeResponse, er params.Set("time", strconv.FormatInt(time, 10)) } path := fmt.Sprintf("/v%s/%s?%s", lbankAPIVersion, lbankTrades, params.Encode()) - return g, l.SendHTTPRequest(exchange.RestSpot, path, &g) + return g, l.SendHTTPRequest(ctx, exchange.RestSpot, path, &g) } // GetKlines returns kline data -func (l *Lbank) GetKlines(symbol, size, klineType, time string) ([]KlineResponse, error) { +func (l *Lbank) GetKlines(ctx context.Context, symbol, size, klineType, time string) ([]KlineResponse, error) { var klineTemp interface{} var k []KlineResponse params := url.Values{} @@ -123,7 +123,7 @@ func (l *Lbank) GetKlines(symbol, size, klineType, time string) ([]KlineResponse params.Set("type", klineType) params.Set("time", time) path := fmt.Sprintf("/v%s/%s?%s", lbankAPIVersion, lbankKlines, params.Encode()) - err := l.SendHTTPRequest(exchange.RestSpot, path, &klineTemp) + err := l.SendHTTPRequest(ctx, exchange.RestSpot, path, &klineTemp) if err != nil { return k, err } @@ -183,10 +183,10 @@ func (l *Lbank) GetKlines(symbol, size, klineType, time string) ([]KlineResponse } // GetUserInfo gets users account info -func (l *Lbank) GetUserInfo() (InfoFinalResponse, error) { +func (l *Lbank) GetUserInfo(ctx context.Context) (InfoFinalResponse, error) { var resp InfoFinalResponse path := fmt.Sprintf("/v%s/%s?", lbankAPIVersion, lbankUserInfo) - err := l.SendAuthHTTPRequest(http.MethodPost, path, nil, &resp) + err := l.SendAuthHTTPRequest(ctx, http.MethodPost, path, nil, &resp) if err != nil { return resp, err } @@ -199,7 +199,7 @@ func (l *Lbank) GetUserInfo() (InfoFinalResponse, error) { } // CreateOrder creates an order -func (l *Lbank) CreateOrder(pair, side string, amount, price float64) (CreateOrderResponse, error) { +func (l *Lbank) CreateOrder(ctx context.Context, pair, side string, amount, price float64) (CreateOrderResponse, error) { var resp CreateOrderResponse if !strings.EqualFold(side, order.Buy.String()) && !strings.EqualFold(side, order.Sell.String()) { @@ -218,7 +218,7 @@ func (l *Lbank) CreateOrder(pair, side string, amount, price float64) (CreateOrd params.Set("price", strconv.FormatFloat(price, 'f', -1, 64)) params.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) path := fmt.Sprintf("/v%s/%s?", lbankAPIVersion, lbankPlaceOrder) - err := l.SendAuthHTTPRequest(http.MethodPost, path, params, &resp) + err := l.SendAuthHTTPRequest(ctx, http.MethodPost, path, params, &resp) if err != nil { return resp, err } @@ -231,13 +231,13 @@ func (l *Lbank) CreateOrder(pair, side string, amount, price float64) (CreateOrd } // RemoveOrder cancels a given order -func (l *Lbank) RemoveOrder(pair, orderID string) (RemoveOrderResponse, error) { +func (l *Lbank) RemoveOrder(ctx context.Context, pair, orderID string) (RemoveOrderResponse, error) { var resp RemoveOrderResponse params := url.Values{} params.Set("symbol", pair) params.Set("order_id", orderID) path := fmt.Sprintf("/v%s/%s", lbankAPIVersion, lbankCancelOrder) - err := l.SendAuthHTTPRequest(http.MethodPost, path, params, &resp) + err := l.SendAuthHTTPRequest(ctx, http.MethodPost, path, params, &resp) if err != nil { return resp, err } @@ -251,14 +251,14 @@ func (l *Lbank) RemoveOrder(pair, orderID string) (RemoveOrderResponse, error) { // QueryOrder finds out information about orders (can pass up to 3 comma separated values to this) // Lbank returns an empty string as their []OrderResponse instead of returning an empty array, so when len(tempResp.Orders) > 2 its not empty and should be unmarshalled separately -func (l *Lbank) QueryOrder(pair, orderIDs string) (QueryOrderFinalResponse, error) { +func (l *Lbank) QueryOrder(ctx context.Context, pair, orderIDs string) (QueryOrderFinalResponse, error) { var resp QueryOrderFinalResponse var tempResp QueryOrderResponse params := url.Values{} params.Set("symbol", pair) params.Set("order_id", orderIDs) path := fmt.Sprintf("/v%s/%s?", lbankAPIVersion, lbankQueryOrder) - err := l.SendAuthHTTPRequest(http.MethodPost, path, params, &tempResp) + err := l.SendAuthHTTPRequest(ctx, http.MethodPost, path, params, &tempResp) if err != nil { return resp, err } @@ -286,7 +286,7 @@ func (l *Lbank) QueryOrder(pair, orderIDs string) (QueryOrderFinalResponse, erro // QueryOrderHistory finds order info in the past 2 days // Lbank returns an empty string as their []OrderResponse instead of returning an empty array, so when len(tempResp.Orders) > 2 its not empty and should be unmarshalled separately -func (l *Lbank) QueryOrderHistory(pair, pageNumber, pageLength string) (OrderHistoryFinalResponse, error) { +func (l *Lbank) QueryOrderHistory(ctx context.Context, pair, pageNumber, pageLength string) (OrderHistoryFinalResponse, error) { var resp OrderHistoryFinalResponse var tempResp OrderHistoryResponse params := url.Values{} @@ -294,7 +294,7 @@ func (l *Lbank) QueryOrderHistory(pair, pageNumber, pageLength string) (OrderHis params.Set("current_page", pageNumber) params.Set("page_length", pageLength) path := fmt.Sprintf("/v%s/%s?", lbankAPIVersion, lbankQueryHistoryOrder) - err := l.SendAuthHTTPRequest(http.MethodPost, path, params, &tempResp) + err := l.SendAuthHTTPRequest(ctx, http.MethodPost, path, params, &tempResp) if err != nil { return resp, err } @@ -319,20 +319,20 @@ func (l *Lbank) QueryOrderHistory(pair, pageNumber, pageLength string) (OrderHis } // GetPairInfo finds information about all trading pairs -func (l *Lbank) GetPairInfo() ([]PairInfoResponse, error) { +func (l *Lbank) GetPairInfo(ctx context.Context) ([]PairInfoResponse, error) { var resp []PairInfoResponse path := fmt.Sprintf("/v%s/%s?", lbankAPIVersion, lbankPairInfo) - return resp, l.SendHTTPRequest(exchange.RestSpot, path, &resp) + return resp, l.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) } // OrderTransactionDetails gets info about transactions -func (l *Lbank) OrderTransactionDetails(symbol, orderID string) (TransactionHistoryResp, error) { +func (l *Lbank) OrderTransactionDetails(ctx context.Context, symbol, orderID string) (TransactionHistoryResp, error) { var resp TransactionHistoryResp params := url.Values{} params.Set("symbol", symbol) params.Set("order_id", orderID) path := fmt.Sprintf("/v%s/%s?", lbankAPIVersion, lbankOrderTransactionDetails) - err := l.SendAuthHTTPRequest(http.MethodPost, path, params, &resp) + err := l.SendAuthHTTPRequest(ctx, http.MethodPost, path, params, &resp) if err != nil { return resp, err } @@ -345,7 +345,7 @@ func (l *Lbank) OrderTransactionDetails(symbol, orderID string) (TransactionHist } // TransactionHistory stores info about transactions -func (l *Lbank) TransactionHistory(symbol, transactionType, startDate, endDate, from, direct, size string) (TransactionHistoryResp, error) { +func (l *Lbank) TransactionHistory(ctx context.Context, symbol, transactionType, startDate, endDate, from, direct, size string) (TransactionHistoryResp, error) { var resp TransactionHistoryResp params := url.Values{} params.Set("symbol", symbol) @@ -356,7 +356,7 @@ func (l *Lbank) TransactionHistory(symbol, transactionType, startDate, endDate, params.Set("direct", direct) params.Set("size", size) path := fmt.Sprintf("/v%s/%s?", lbankAPIVersion, lbankPastTransactions) - err := l.SendAuthHTTPRequest(http.MethodPost, path, params, &resp) + err := l.SendAuthHTTPRequest(ctx, http.MethodPost, path, params, &resp) if err != nil { return resp, err } @@ -370,7 +370,7 @@ func (l *Lbank) TransactionHistory(symbol, transactionType, startDate, endDate, // GetOpenOrders gets opening orders // Lbank returns an empty string as their []OrderResponse instead of returning an empty array, so when len(tempResp.Orders) > 2 its not empty and should be unmarshalled separately -func (l *Lbank) GetOpenOrders(pair, pageNumber, pageLength string) (OpenOrderFinalResponse, error) { +func (l *Lbank) GetOpenOrders(ctx context.Context, pair, pageNumber, pageLength string) (OpenOrderFinalResponse, error) { var resp OpenOrderFinalResponse var tempResp OpenOrderResponse params := url.Values{} @@ -378,7 +378,7 @@ func (l *Lbank) GetOpenOrders(pair, pageNumber, pageLength string) (OpenOrderFin params.Set("current_page", pageNumber) params.Set("page_length", pageLength) path := fmt.Sprintf("/v%s/%s", lbankAPIVersion, lbankOpeningOrders) - err := l.SendAuthHTTPRequest(http.MethodPost, path, params, &tempResp) + err := l.SendAuthHTTPRequest(ctx, http.MethodPost, path, params, &tempResp) if err != nil { return resp, err } @@ -403,23 +403,23 @@ func (l *Lbank) GetOpenOrders(pair, pageNumber, pageLength string) (OpenOrderFin } // USD2RMBRate finds USD-CNY Rate -func (l *Lbank) USD2RMBRate() (ExchangeRateResponse, error) { +func (l *Lbank) USD2RMBRate(ctx context.Context) (ExchangeRateResponse, error) { var resp ExchangeRateResponse path := fmt.Sprintf("/v%s/%s", lbankAPIVersion, lbankUSD2CNYRate) - return resp, l.SendHTTPRequest(exchange.RestSpot, path, &resp) + return resp, l.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) } // GetWithdrawConfig gets information about withdrawals -func (l *Lbank) GetWithdrawConfig(assetCode string) ([]WithdrawConfigResponse, error) { +func (l *Lbank) GetWithdrawConfig(ctx context.Context, assetCode string) ([]WithdrawConfigResponse, error) { var resp []WithdrawConfigResponse params := url.Values{} params.Set("assetCode", assetCode) path := fmt.Sprintf("/v%s/%s?%s", lbankAPIVersion, lbankWithdrawConfig, params.Encode()) - return resp, l.SendHTTPRequest(exchange.RestSpot, path, &resp) + return resp, l.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) } // Withdraw sends a withdrawal request -func (l *Lbank) Withdraw(account, assetCode, amount, memo, mark, withdrawType string) (WithdrawResponse, error) { +func (l *Lbank) Withdraw(ctx context.Context, account, assetCode, amount, memo, mark, withdrawType string) (WithdrawResponse, error) { var resp WithdrawResponse params := url.Values{} params.Set("account", account) @@ -436,7 +436,7 @@ func (l *Lbank) Withdraw(account, assetCode, amount, memo, mark, withdrawType st } path := fmt.Sprintf("/v%s/%s", lbankAPIVersion, lbankWithdraw) - err := l.SendAuthHTTPRequest(http.MethodPost, path, params, &resp) + err := l.SendAuthHTTPRequest(ctx, http.MethodPost, path, params, &resp) if err != nil { return resp, err } @@ -449,14 +449,14 @@ func (l *Lbank) Withdraw(account, assetCode, amount, memo, mark, withdrawType st } // RevokeWithdraw cancels the withdrawal given the withdrawalID -func (l *Lbank) RevokeWithdraw(withdrawID string) (RevokeWithdrawResponse, error) { +func (l *Lbank) RevokeWithdraw(ctx context.Context, withdrawID string) (RevokeWithdrawResponse, error) { var resp RevokeWithdrawResponse params := url.Values{} if withdrawID != "" { params.Set("withdrawId", withdrawID) } path := fmt.Sprintf("/v%s/%s?", lbankAPIVersion, lbankRevokeWithdraw) - err := l.SendAuthHTTPRequest(http.MethodPost, path, params, &resp) + err := l.SendAuthHTTPRequest(ctx, http.MethodPost, path, params, &resp) if err != nil { return resp, err } @@ -469,7 +469,7 @@ func (l *Lbank) RevokeWithdraw(withdrawID string) (RevokeWithdrawResponse, error } // GetWithdrawalRecords gets withdrawal records -func (l *Lbank) GetWithdrawalRecords(assetCode, status, pageNo, pageSize string) (WithdrawalResponse, error) { +func (l *Lbank) GetWithdrawalRecords(ctx context.Context, assetCode, status, pageNo, pageSize string) (WithdrawalResponse, error) { var resp WithdrawalResponse params := url.Values{} params.Set("assetCode", assetCode) @@ -477,7 +477,7 @@ func (l *Lbank) GetWithdrawalRecords(assetCode, status, pageNo, pageSize string) params.Set("pageNo", pageNo) params.Set("pageSize", pageSize) path := fmt.Sprintf("/v%s/%s", lbankAPIVersion, lbankWithdrawalRecords) - err := l.SendAuthHTTPRequest(http.MethodPost, path, params, &resp) + err := l.SendAuthHTTPRequest(ctx, http.MethodPost, path, params, &resp) if err != nil { return resp, err } @@ -499,7 +499,7 @@ func ErrorCapture(code int64) error { } // SendHTTPRequest sends an unauthenticated HTTP request -func (l *Lbank) SendHTTPRequest(ep exchange.URL, path string, result interface{}) error { +func (l *Lbank) SendHTTPRequest(ctx context.Context, ep exchange.URL, path string, result interface{}) error { endpoint, err := l.API.Endpoints.GetURL(ep) if err != nil { return err @@ -514,7 +514,7 @@ func (l *Lbank) SendHTTPRequest(ep exchange.URL, path string, result interface{} HTTPRecording: l.HTTPRecording, } - return l.SendPayload(context.Background(), request.Unset, func() (*request.Item, error) { + return l.SendPayload(ctx, request.Unset, func() (*request.Item, error) { return item, nil }) } @@ -565,7 +565,7 @@ func (l *Lbank) sign(data string) (string, error) { } // SendAuthHTTPRequest sends an authenticated request -func (l *Lbank) SendAuthHTTPRequest(method, endpoint string, vals url.Values, result interface{}) error { +func (l *Lbank) SendAuthHTTPRequest(ctx context.Context, method, endpoint string, vals url.Values, result interface{}) error { if !l.AllowAuthenticatedRequest() { return fmt.Errorf("%s %w", l.Name, exchange.ErrAuthenticatedRequestWithoutCredentialsSet) } @@ -596,7 +596,7 @@ func (l *Lbank) SendAuthHTTPRequest(method, endpoint string, vals url.Values, re HTTPRecording: l.HTTPRecording, } - return l.SendPayload(context.Background(), request.Unset, func() (*request.Item, error) { + return l.SendPayload(ctx, request.Unset, func() (*request.Item, error) { item.Body = bytes.NewBufferString(payload) return item, nil }) diff --git a/exchanges/lbank/lbank_test.go b/exchanges/lbank/lbank_test.go index 40cbd6cf..2f1512e1 100644 --- a/exchanges/lbank/lbank_test.go +++ b/exchanges/lbank/lbank_test.go @@ -1,6 +1,7 @@ package lbank import ( + "context" "log" "os" "strconv" @@ -52,7 +53,7 @@ func areTestAPIKeysSet() bool { func TestGetTicker(t *testing.T) { t.Parallel() - _, err := l.GetTicker(testCurrencyPair) + _, err := l.GetTicker(context.Background(), testCurrencyPair) if err != nil { t.Error(err) } @@ -60,7 +61,7 @@ func TestGetTicker(t *testing.T) { func TestGetTickers(t *testing.T) { t.Parallel() - tickers, err := l.GetTickers() + tickers, err := l.GetTickers(context.Background()) if err != nil { t.Fatal(err) } @@ -71,7 +72,7 @@ func TestGetTickers(t *testing.T) { func TestGetCurrencyPairs(t *testing.T) { t.Parallel() - _, err := l.GetCurrencyPairs() + _, err := l.GetCurrencyPairs(context.Background()) if err != nil { t.Error(err) } @@ -79,11 +80,11 @@ func TestGetCurrencyPairs(t *testing.T) { func TestGetMarketDepths(t *testing.T) { t.Parallel() - _, err := l.GetMarketDepths(testCurrencyPair, "600", "1") + _, err := l.GetMarketDepths(context.Background(), testCurrencyPair, "600", "1") if err != nil { t.Fatal(err) } - a, _ := l.GetMarketDepths(testCurrencyPair, "4", "0") + a, _ := l.GetMarketDepths(context.Background(), testCurrencyPair, "4", "0") if len(a.Data.Asks) != 4 { t.Errorf("asks length requested doesnt match the output") } @@ -91,11 +92,11 @@ func TestGetMarketDepths(t *testing.T) { func TestGetTrades(t *testing.T) { t.Parallel() - _, err := l.GetTrades(testCurrencyPair, 600, time.Now().Unix()) + _, err := l.GetTrades(context.Background(), testCurrencyPair, 600, time.Now().Unix()) if err != nil { t.Error(err) } - a, err := l.GetTrades(testCurrencyPair, 600, 0) + a, err := l.GetTrades(context.Background(), testCurrencyPair, 600, 0) if len(a) != 600 && err != nil { t.Error(err) } @@ -103,7 +104,8 @@ func TestGetTrades(t *testing.T) { func TestGetKlines(t *testing.T) { t.Parallel() - _, err := l.GetKlines(testCurrencyPair, "600", "minute1", + _, err := l.GetKlines(context.Background(), + testCurrencyPair, "600", "minute1", strconv.FormatInt(time.Now().Unix(), 10)) if err != nil { t.Error(err) @@ -117,7 +119,7 @@ func TestUpdateOrderbook(t *testing.T) { Base: currency.ETH, Quote: currency.BTC} - _, err := l.UpdateOrderbook(p.Lower(), asset.Spot) + _, err := l.UpdateOrderbook(context.Background(), p.Lower(), asset.Spot) if err != nil { t.Error(err) } @@ -128,7 +130,7 @@ func TestGetUserInfo(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys required but not set, skipping test") } - _, err := l.GetUserInfo() + _, err := l.GetUserInfo(context.Background()) if err != nil { t.Error(err) } @@ -140,19 +142,19 @@ func TestCreateOrder(t *testing.T) { t.Skip("skipping test, either api keys or manipulaterealorders isnt set correctly") } cp := currency.NewPairWithDelimiter(currency.BTC.String(), currency.USDT.String(), "_") - _, err := l.CreateOrder(cp.Lower().String(), "what", 1231, 12314) + _, err := l.CreateOrder(context.Background(), cp.Lower().String(), "what", 1231, 12314) if err == nil { t.Error("CreateOrder error cannot be nil") } - _, err = l.CreateOrder(cp.Lower().String(), order.Buy.Lower(), 0, 0) + _, err = l.CreateOrder(context.Background(), cp.Lower().String(), order.Buy.Lower(), 0, 0) if err == nil { t.Error("CreateOrder error cannot be nil") } - _, err = l.CreateOrder(cp.Lower().String(), order.Sell.Lower(), 1231, 0) + _, err = l.CreateOrder(context.Background(), cp.Lower().String(), order.Sell.Lower(), 1231, 0) if err == nil { t.Error("CreateOrder error cannot be nil") } - _, err = l.CreateOrder(cp.Lower().String(), order.Buy.Lower(), 58, 681) + _, err = l.CreateOrder(context.Background(), cp.Lower().String(), order.Buy.Lower(), 58, 681) if err != nil { t.Errorf("Unexpected error: %v", err) } @@ -164,7 +166,8 @@ func TestRemoveOrder(t *testing.T) { t.Skip("skipping test, either api keys or manipulaterealorders isnt set correctly") } cp := currency.NewPairWithDelimiter(currency.ETH.String(), currency.BTC.String(), "_") - _, err := l.RemoveOrder(cp.Lower().String(), "24f7ce27-af1d-4dca-a8c1-ef1cbeec1b23") + _, err := l.RemoveOrder(context.Background(), + cp.Lower().String(), "24f7ce27-af1d-4dca-a8c1-ef1cbeec1b23") if err != nil { t.Error(err) } @@ -176,7 +179,7 @@ func TestQueryOrder(t *testing.T) { t.Skip("API keys required but not set, skipping test") } cp := currency.NewPairWithDelimiter(currency.BTC.String(), currency.USDT.String(), "_") - _, err := l.QueryOrder(cp.Lower().String(), "1") + _, err := l.QueryOrder(context.Background(), cp.Lower().String(), "1") if err != nil { t.Error(err) } @@ -188,7 +191,8 @@ func TestQueryOrderHistory(t *testing.T) { t.Skip("API keys required but not set, skipping test") } cp := currency.NewPairWithDelimiter(currency.BTC.String(), currency.USDT.String(), "_") - _, err := l.QueryOrderHistory(cp.Lower().String(), "1", "100") + _, err := l.QueryOrderHistory(context.Background(), + cp.Lower().String(), "1", "100") if err != nil { t.Error(err) } @@ -196,7 +200,7 @@ func TestQueryOrderHistory(t *testing.T) { func TestGetPairInfo(t *testing.T) { t.Parallel() - _, err := l.GetPairInfo() + _, err := l.GetPairInfo(context.Background()) if err != nil { t.Error(err) } @@ -207,7 +211,8 @@ func TestOrderTransactionDetails(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys required but not set, skipping test") } - _, err := l.OrderTransactionDetails(testCurrencyPair, "24f7ce27-af1d-4dca-a8c1-ef1cbeec1b23") + _, err := l.OrderTransactionDetails(context.Background(), + testCurrencyPair, "24f7ce27-af1d-4dca-a8c1-ef1cbeec1b23") if err != nil { t.Error(err) } @@ -218,7 +223,8 @@ func TestTransactionHistory(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys required but not set, skipping test") } - _, err := l.TransactionHistory(testCurrencyPair, "", "", "", "", "", "") + _, err := l.TransactionHistory(context.Background(), + testCurrencyPair, "", "", "", "", "", "") if err != nil { t.Error(err) } @@ -230,7 +236,7 @@ func TestGetOpenOrders(t *testing.T) { t.Skip("API keys required but not set, skipping test") } cp := currency.NewPairWithDelimiter(currency.BTC.String(), currency.USDT.String(), "_") - _, err := l.GetOpenOrders(cp.Lower().String(), "1", "50") + _, err := l.GetOpenOrders(context.Background(), cp.Lower().String(), "1", "50") if err != nil { t.Error(err) } @@ -238,7 +244,7 @@ func TestGetOpenOrders(t *testing.T) { func TestUSD2RMBRate(t *testing.T) { t.Parallel() - _, err := l.USD2RMBRate() + _, err := l.USD2RMBRate(context.Background()) if err != nil { t.Error(err) } @@ -246,7 +252,8 @@ func TestUSD2RMBRate(t *testing.T) { func TestGetWithdrawConfig(t *testing.T) { t.Parallel() - _, err := l.GetWithdrawConfig(currency.ETH.Lower().String()) + _, err := l.GetWithdrawConfig(context.Background(), + currency.ETH.Lower().String()) if err != nil { t.Error(err) } @@ -257,7 +264,7 @@ func TestWithdraw(t *testing.T) { if !areTestAPIKeysSet() || !canManipulateRealOrders { t.Skip("skipping test, either api keys or manipulaterealorders isnt set correctly") } - _, err := l.Withdraw("", "", "", "", "", "") + _, err := l.Withdraw(context.Background(), "", "", "", "", "", "") if err != nil { t.Error(err) } @@ -268,7 +275,8 @@ func TestGetWithdrawRecords(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys required but not set, skipping test") } - _, err := l.GetWithdrawalRecords(currency.ETH.Lower().String(), + _, err := l.GetWithdrawalRecords(context.Background(), + currency.ETH.Lower().String(), "0", "1", "20") if err != nil { t.Error(err) @@ -326,7 +334,7 @@ func TestSubmitOrder(t *testing.T) { ClientID: "meowOrder", AssetType: asset.Spot, } - response, err := l.SubmitOrder(orderSubmission) + response, err := l.SubmitOrder(context.Background(), orderSubmission) if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) { t.Errorf("Order failed to be placed: %v", err) } else if !areTestAPIKeysSet() && err == nil { @@ -344,7 +352,7 @@ func TestCancelOrder(t *testing.T) { a.Pair = cp a.AssetType = asset.Spot a.ID = "24f7ce27-af1d-4dca-a8c1-ef1cbeec1b23" - err := l.CancelOrder(&a) + err := l.CancelOrder(context.Background(), &a) if err != nil { t.Error(err) } @@ -355,7 +363,8 @@ func TestGetOrderInfo(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys required but not set, skipping test") } - _, err := l.GetOrderInfo("9ead39f5-701a-400b-b635-d7349eb0f6b", currency.Pair{}, asset.Spot) + _, err := l.GetOrderInfo(context.Background(), + "9ead39f5-701a-400b-b635-d7349eb0f6b", currency.Pair{}, asset.Spot) if err != nil { t.Error(err) } @@ -366,7 +375,7 @@ func TestGetAllOpenOrderID(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys required but not set, skipping test") } - _, err := l.getAllOpenOrderID() + _, err := l.getAllOpenOrderID(context.Background()) if err != nil { t.Error(err) } @@ -379,7 +388,7 @@ func TestGetFeeByType(t *testing.T) { input.Amount = 2 input.FeeType = exchange.CryptocurrencyWithdrawalFee input.Pair = cp - _, err := l.GetFeeByType(&input) + _, err := l.GetFeeByType(context.Background(), &input) if err != nil { t.Error(err) } @@ -390,7 +399,7 @@ func TestGetAccountInfo(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("API keys required but not set, skipping test") } - _, err := l.UpdateAccountInfo(asset.Spot) + _, err := l.UpdateAccountInfo(context.Background(), asset.Spot) if err != nil { t.Error(err) } @@ -404,7 +413,7 @@ func TestGetOrderHistory(t *testing.T) { var input order.GetOrdersRequest input.Side = order.Buy input.AssetType = asset.Spot - _, err := l.GetOrderHistory(&input) + _, err := l.GetOrderHistory(context.Background(), &input) if err != nil { t.Error(err) } @@ -416,12 +425,14 @@ func TestGetHistoricCandles(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = l.GetHistoricCandles(pair, asset.Spot, time.Now().Add(-24*time.Hour), time.Now(), kline.OneMin) + _, err = l.GetHistoricCandles(context.Background(), + pair, asset.Spot, time.Now().Add(-24*time.Hour), time.Now(), kline.OneMin) if err != nil { t.Fatal(err) } - _, err = l.GetHistoricCandles(pair, asset.Spot, time.Now().Add(-24*time.Hour), time.Now(), kline.OneHour) + _, err = l.GetHistoricCandles(context.Background(), + pair, asset.Spot, time.Now().Add(-24*time.Hour), time.Now(), kline.OneHour) if err != nil { t.Fatal(err) } @@ -436,7 +447,8 @@ func TestGetHistoricCandlesExtended(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = l.GetHistoricCandlesExtended(pair, asset.Spot, startTime, end, kline.OneMin) + _, err = l.GetHistoricCandlesExtended(context.Background(), + pair, asset.Spot, startTime, end, kline.OneMin) if err != nil { t.Fatal(err) } @@ -494,7 +506,7 @@ func TestGetRecentTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = l.GetRecentTrades(currencyPair, asset.Spot) + _, err = l.GetRecentTrades(context.Background(), currencyPair, asset.Spot) if err != nil { t.Error(err) } @@ -506,12 +518,14 @@ func TestGetHistoricTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = l.GetHistoricTrades(currencyPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) + _, err = l.GetHistoricTrades(context.Background(), + currencyPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) if err != nil { t.Error(err) } // longer term - _, err = l.GetHistoricTrades(currencyPair, asset.Spot, time.Now().Add(-time.Minute*60*200), time.Now().Add(-time.Minute*60*199)) + _, err = l.GetHistoricTrades(context.Background(), + currencyPair, asset.Spot, time.Now().Add(-time.Minute*60*200), time.Now().Add(-time.Minute*60*199)) if err != nil { t.Error(err) } @@ -523,7 +537,7 @@ func TestUpdateTicker(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = l.UpdateTicker(cp, asset.Spot) + _, err = l.UpdateTicker(context.Background(), cp, asset.Spot) if err != nil { t.Error(err) } @@ -531,7 +545,7 @@ func TestUpdateTicker(t *testing.T) { func TestUpdateTickers(t *testing.T) { t.Parallel() - err := l.UpdateTickers(asset.Spot) + err := l.UpdateTickers(context.Background(), asset.Spot) if err != nil { t.Error(err) } diff --git a/exchanges/lbank/lbank_wrapper.go b/exchanges/lbank/lbank_wrapper.go index 4b3cca38..32d3dcde 100644 --- a/exchanges/lbank/lbank_wrapper.go +++ b/exchanges/lbank/lbank_wrapper.go @@ -1,6 +1,7 @@ package lbank import ( + "context" "fmt" "sort" "strconv" @@ -39,7 +40,7 @@ func (l *Lbank) GetDefaultConfig() (*config.ExchangeConfig, error) { } if l.Features.Supports.RESTCapabilities.AutoPairUpdates { - err = l.UpdateTradablePairs(true) + err = l.UpdateTradablePairs(context.TODO(), true) if err != nil { return nil, err } @@ -158,15 +159,15 @@ func (l *Lbank) Run() { return } - err := l.UpdateTradablePairs(false) + err := l.UpdateTradablePairs(context.TODO(), false) if err != nil { log.Errorf(log.ExchangeSys, "%s failed to update tradable pairs. Err: %s", l.Name, err) } } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (l *Lbank) FetchTradablePairs(asset asset.Item) ([]string, error) { - currencies, err := l.GetCurrencyPairs() +func (l *Lbank) FetchTradablePairs(ctx context.Context, asset asset.Item) ([]string, error) { + currencies, err := l.GetCurrencyPairs(ctx) if err != nil { return nil, err } @@ -175,8 +176,8 @@ func (l *Lbank) FetchTradablePairs(asset asset.Item) ([]string, error) { // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (l *Lbank) UpdateTradablePairs(forceUpdate bool) error { - pairs, err := l.FetchTradablePairs(asset.Spot) +func (l *Lbank) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { + pairs, err := l.FetchTradablePairs(ctx, asset.Spot) if err != nil { return err } @@ -189,8 +190,8 @@ func (l *Lbank) UpdateTradablePairs(forceUpdate bool) error { } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (l *Lbank) UpdateTickers(a asset.Item) error { - tickerInfo, err := l.GetTickers() +func (l *Lbank) UpdateTickers(ctx context.Context, a asset.Item) error { + tickerInfo, err := l.GetTickers(ctx) if err != nil { return err } @@ -222,8 +223,8 @@ func (l *Lbank) UpdateTickers(a asset.Item) error { } // UpdateTicker updates and returns the ticker for a currency pair -func (l *Lbank) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) { - err := l.UpdateTickers(a) +func (l *Lbank) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { + err := l.UpdateTickers(ctx, a) if err != nil { return nil, err } @@ -231,7 +232,7 @@ func (l *Lbank) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, erro } // FetchTicker returns the ticker for a currency pair -func (l *Lbank) FetchTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) { +func (l *Lbank) FetchTicker(ctx context.Context, p currency.Pair, assetType asset.Item) (*ticker.Price, error) { fpair, err := l.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err @@ -239,22 +240,22 @@ func (l *Lbank) FetchTicker(p currency.Pair, assetType asset.Item) (*ticker.Pric tickerNew, err := ticker.GetTicker(l.Name, fpair, assetType) if err != nil { - return l.UpdateTicker(p, assetType) + return l.UpdateTicker(ctx, p, assetType) } return tickerNew, nil } // FetchOrderbook returns orderbook base on the currency pair -func (l *Lbank) FetchOrderbook(currency currency.Pair, assetType asset.Item) (*orderbook.Base, error) { - ob, err := orderbook.Get(l.Name, currency, assetType) +func (l *Lbank) FetchOrderbook(ctx context.Context, c currency.Pair, assetType asset.Item) (*orderbook.Base, error) { + ob, err := orderbook.Get(l.Name, c, assetType) if err != nil { - return l.UpdateOrderbook(currency, assetType) + return l.UpdateOrderbook(ctx, c, assetType) } return ob, nil } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (l *Lbank) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (l *Lbank) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { book := &orderbook.Base{ Exchange: l.Name, Pair: p, @@ -266,7 +267,7 @@ func (l *Lbank) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderbo return book, err } - a, err := l.GetMarketDepths(fpair.String(), "60", "1") + a, err := l.GetMarketDepths(ctx, fpair.String(), "60", "1") if err != nil { return book, err } @@ -305,9 +306,9 @@ func (l *Lbank) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderbo // UpdateAccountInfo retrieves balances for all enabled currencies for the // Lbank exchange -func (l *Lbank) UpdateAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (l *Lbank) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { var info account.Holdings - data, err := l.GetUserInfo() + data, err := l.GetUserInfo(ctx) if err != nil { return info, err } @@ -343,33 +344,32 @@ func (l *Lbank) UpdateAccountInfo(assetType asset.Item) (account.Holdings, error } // FetchAccountInfo retrieves balances for all enabled currencies -func (l *Lbank) FetchAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (l *Lbank) FetchAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { acc, err := account.GetHoldings(l.Name, assetType) if err != nil { - return l.UpdateAccountInfo(assetType) + return l.UpdateAccountInfo(ctx, assetType) } - return acc, nil } // GetFundingHistory returns funding history, deposits and // withdrawals -func (l *Lbank) GetFundingHistory() ([]exchange.FundHistory, error) { +func (l *Lbank) GetFundingHistory(ctx context.Context) ([]exchange.FundHistory, error) { return nil, common.ErrFunctionNotSupported } // GetWithdrawalsHistory returns previous withdrawals data -func (l *Lbank) GetWithdrawalsHistory(c currency.Code) (resp []exchange.WithdrawalHistory, err error) { +func (l *Lbank) GetWithdrawalsHistory(ctx context.Context, c currency.Code) (resp []exchange.WithdrawalHistory, err error) { return nil, common.ErrNotYetImplemented } // GetRecentTrades returns the most recent trades for a currency and asset -func (l *Lbank) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade.Data, error) { - return l.GetHistoricTrades(p, assetType, time.Now().Add(-time.Minute*15), time.Now()) +func (l *Lbank) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { + return l.GetHistoricTrades(ctx, p, assetType, time.Now().Add(-time.Minute*15), time.Now()) } // GetHistoricTrades returns historic trade data within the timeframe provided -func (l *Lbank) GetHistoricTrades(p currency.Pair, assetType asset.Item, timestampStart, timestampEnd time.Time) ([]trade.Data, error) { +func (l *Lbank) GetHistoricTrades(ctx context.Context, p currency.Pair, assetType asset.Item, timestampStart, timestampEnd time.Time) ([]trade.Data, error) { if err := common.StartEndTimeCheck(timestampStart, timestampEnd); err != nil { return nil, fmt.Errorf("invalid time range supplied. Start: %v End %v %w", timestampStart, timestampEnd, err) } @@ -384,7 +384,10 @@ func (l *Lbank) GetHistoricTrades(p currency.Pair, assetType asset.Item, timesta allTrades: for { var tradeData []TradeResponse - tradeData, err = l.GetTrades(p.String(), int64(limit), ts.UnixNano()/int64(time.Millisecond)) + tradeData, err = l.GetTrades(ctx, + p.String(), + int64(limit), + ts.UnixNano()/int64(time.Millisecond)) if err != nil { return nil, err } @@ -430,7 +433,7 @@ allTrades: } // SubmitOrder submits a new order -func (l *Lbank) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { +func (l *Lbank) SubmitOrder(ctx context.Context, s *order.Submit) (order.SubmitResponse, error) { var resp order.SubmitResponse if err := s.Validate(); err != nil { return resp, err @@ -447,7 +450,7 @@ func (l *Lbank) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { return resp, err } - tempResp, err := l.CreateOrder( + tempResp, err := l.CreateOrder(ctx, fpair.String(), s.Side.String(), s.Amount, @@ -465,12 +468,12 @@ func (l *Lbank) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (l *Lbank) ModifyOrder(action *order.Modify) (order.Modify, error) { +func (l *Lbank) ModifyOrder(ctx context.Context, action *order.Modify) (order.Modify, error) { return order.Modify{}, common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number -func (l *Lbank) CancelOrder(o *order.Cancel) error { +func (l *Lbank) CancelOrder(ctx context.Context, o *order.Cancel) error { if err := o.Validate(o.StandardCancel()); err != nil { return err } @@ -478,23 +481,23 @@ func (l *Lbank) CancelOrder(o *order.Cancel) error { if err != nil { return err } - _, err = l.RemoveOrder(fpair.String(), o.ID) + _, err = l.RemoveOrder(ctx, fpair.String(), o.ID) return err } // CancelBatchOrders cancels an orders by their corresponding ID numbers -func (l *Lbank) CancelBatchOrders(o []order.Cancel) (order.CancelBatchResponse, error) { +func (l *Lbank) CancelBatchOrders(ctx context.Context, o []order.Cancel) (order.CancelBatchResponse, error) { return order.CancelBatchResponse{}, common.ErrNotYetImplemented } // CancelAllOrders cancels all orders associated with a currency pair -func (l *Lbank) CancelAllOrders(o *order.Cancel) (order.CancelAllResponse, error) { +func (l *Lbank) CancelAllOrders(ctx context.Context, o *order.Cancel) (order.CancelAllResponse, error) { if err := o.Validate(); err != nil { return order.CancelAllResponse{}, err } var resp order.CancelAllResponse - orderIDs, err := l.getAllOpenOrderID() + orderIDs, err := l.getAllOpenOrderID(ctx) if err != nil { return resp, nil } @@ -512,7 +515,7 @@ func (l *Lbank) CancelAllOrders(o *order.Cancel) (order.CancelAllResponse, error tempSlice = append(tempSlice, orderIDs[key][y]) if y%3 == 0 { input = strings.Join(tempSlice, ",") - CancelResponse, err2 := l.RemoveOrder(key, input) + CancelResponse, err2 := l.RemoveOrder(ctx, key, input) if err2 != nil { return resp, err2 } @@ -530,7 +533,7 @@ func (l *Lbank) CancelAllOrders(o *order.Cancel) (order.CancelAllResponse, error y++ } input = strings.Join(tempSlice, ",") - CancelResponse, err2 := l.RemoveOrder(key, input) + CancelResponse, err2 := l.RemoveOrder(ctx, key, input) if err2 != nil { return resp, err2 } @@ -549,9 +552,9 @@ func (l *Lbank) CancelAllOrders(o *order.Cancel) (order.CancelAllResponse, error } // GetOrderInfo returns order information based on order ID -func (l *Lbank) GetOrderInfo(orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { +func (l *Lbank) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { var resp order.Detail - orderIDs, err := l.getAllOpenOrderID() + orderIDs, err := l.getAllOpenOrderID(ctx) if err != nil { return resp, err } @@ -561,7 +564,7 @@ func (l *Lbank) GetOrderInfo(orderID string, pair currency.Pair, assetType asset if val[i] != orderID { continue } - tempResp, err := l.QueryOrder(key, orderID) + tempResp, err := l.QueryOrder(ctx, key, orderID) if err != nil { return resp, err } @@ -595,10 +598,11 @@ func (l *Lbank) GetOrderInfo(orderID string, pair currency.Pair, assetType asset resp.Amount = tempResp.Orders[0].Amount resp.ExecutedAmount = tempResp.Orders[0].DealAmount resp.RemainingAmount = tempResp.Orders[0].Amount - tempResp.Orders[0].DealAmount - resp.Fee, err = l.GetFeeByType(&exchange.FeeBuilder{ - FeeType: exchange.CryptocurrencyTradeFee, - Amount: tempResp.Orders[0].Amount, - PurchasePrice: tempResp.Orders[0].Price}) + resp.Fee, err = l.GetFeeByType(ctx, + &exchange.FeeBuilder{ + FeeType: exchange.CryptocurrencyTradeFee, + Amount: tempResp.Orders[0].Amount, + PurchasePrice: tempResp.Orders[0].Price}) if err != nil { resp.Fee = lbankFeeNotFound } @@ -608,19 +612,22 @@ func (l *Lbank) GetOrderInfo(orderID string, pair currency.Pair, assetType asset } // GetDepositAddress returns a deposit address for a specified currency -func (l *Lbank) GetDepositAddress(cryptocurrency currency.Code, accountID string) (string, error) { +func (l *Lbank) GetDepositAddress(ctx context.Context, c currency.Code, accountID string) (string, error) { return "", common.ErrFunctionNotSupported } // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is // submitted -func (l *Lbank) WithdrawCryptocurrencyFunds(withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (l *Lbank) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } - resp, err := l.Withdraw(withdrawRequest.Crypto.Address, withdrawRequest.Currency.String(), - strconv.FormatFloat(withdrawRequest.Amount, 'f', -1, 64), "", - withdrawRequest.Description, "") + resp, err := l.Withdraw(ctx, + withdrawRequest.Crypto.Address, withdrawRequest.Currency.String(), + strconv.FormatFloat(withdrawRequest.Amount, 'f', -1, 64), + "", + withdrawRequest.Description, + "") if err != nil { return nil, err } @@ -631,32 +638,32 @@ func (l *Lbank) WithdrawCryptocurrencyFunds(withdrawRequest *withdraw.Request) ( // WithdrawFiatFunds returns a withdrawal ID when a withdrawal is // submitted -func (l *Lbank) WithdrawFiatFunds(_ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (l *Lbank) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a withdrawal is // submitted -func (l *Lbank) WithdrawFiatFundsToInternationalBank(_ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (l *Lbank) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // GetActiveOrders retrieves any orders that are active/open -func (l *Lbank) GetActiveOrders(getOrdersRequest *order.GetOrdersRequest) ([]order.Detail, error) { +func (l *Lbank) GetActiveOrders(ctx context.Context, getOrdersRequest *order.GetOrdersRequest) ([]order.Detail, error) { if err := getOrdersRequest.Validate(); err != nil { return nil, err } var finalResp []order.Detail var resp order.Detail - tempData, err := l.getAllOpenOrderID() + tempData, err := l.getAllOpenOrderID(ctx) if err != nil { return finalResp, err } for key, val := range tempData { for x := range val { - tempResp, err := l.QueryOrder(key, val[x]) + tempResp, err := l.QueryOrder(ctx, key, val[x]) if err != nil { return finalResp, err } @@ -691,10 +698,11 @@ func (l *Lbank) GetActiveOrders(getOrdersRequest *order.GetOrdersRequest) ([]ord resp.Date = time.Unix(tempResp.Orders[0].CreateTime, 0) resp.ExecutedAmount = tempResp.Orders[0].DealAmount resp.RemainingAmount = tempResp.Orders[0].Amount - tempResp.Orders[0].DealAmount - resp.Fee, err = l.GetFeeByType(&exchange.FeeBuilder{ - FeeType: exchange.CryptocurrencyTradeFee, - Amount: tempResp.Orders[0].Amount, - PurchasePrice: tempResp.Orders[0].Price}) + resp.Fee, err = l.GetFeeByType(ctx, + &exchange.FeeBuilder{ + FeeType: exchange.CryptocurrencyTradeFee, + Amount: tempResp.Orders[0].Amount, + PurchasePrice: tempResp.Orders[0].Price}) if err != nil { resp.Fee = lbankFeeNotFound } @@ -718,7 +726,7 @@ func (l *Lbank) GetActiveOrders(getOrdersRequest *order.GetOrdersRequest) ([]ord // GetOrderHistory retrieves account order information * // Can Limit response to specific order status -func (l *Lbank) GetOrderHistory(getOrdersRequest *order.GetOrdersRequest) ([]order.Detail, error) { +func (l *Lbank) GetOrderHistory(ctx context.Context, getOrdersRequest *order.GetOrdersRequest) ([]order.Detail, error) { if err := getOrdersRequest.Validate(); err != nil { return nil, err } @@ -742,12 +750,14 @@ func (l *Lbank) GetOrderHistory(getOrdersRequest *order.GetOrdersRequest) ([]ord } b := int64(1) - tempResp, err := l.QueryOrderHistory(fpair.String(), strconv.FormatInt(b, 10), "200") + tempResp, err := l.QueryOrderHistory(ctx, + fpair.String(), strconv.FormatInt(b, 10), "200") if err != nil { return finalResp, err } for len(tempResp.Orders) != 0 { - tempResp, err = l.QueryOrderHistory(fpair.String(), strconv.FormatInt(b, 10), "200") + tempResp, err = l.QueryOrderHistory(ctx, + fpair.String(), strconv.FormatInt(b, 10), "200") if err != nil { return finalResp, err } @@ -783,10 +793,11 @@ func (l *Lbank) GetOrderHistory(getOrdersRequest *order.GetOrdersRequest) ([]ord resp.Date = time.Unix(tempResp.Orders[x].CreateTime, 0) resp.ExecutedAmount = tempResp.Orders[x].DealAmount resp.RemainingAmount = tempResp.Orders[x].Price - tempResp.Orders[x].DealAmount - resp.Fee, err = l.GetFeeByType(&exchange.FeeBuilder{ - FeeType: exchange.CryptocurrencyTradeFee, - Amount: tempResp.Orders[x].Amount, - PurchasePrice: tempResp.Orders[x].Price}) + resp.Fee, err = l.GetFeeByType(ctx, + &exchange.FeeBuilder{ + FeeType: exchange.CryptocurrencyTradeFee, + Amount: tempResp.Orders[x].Amount, + PurchasePrice: tempResp.Orders[x].Price}) if err != nil { resp.Fee = lbankFeeNotFound } @@ -799,13 +810,14 @@ func (l *Lbank) GetOrderHistory(getOrdersRequest *order.GetOrdersRequest) ([]ord } // GetFeeByType returns an estimate of fee based on the type of transaction * -func (l *Lbank) GetFeeByType(feeBuilder *exchange.FeeBuilder) (float64, error) { +func (l *Lbank) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { var resp float64 if feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { return feeBuilder.Amount * feeBuilder.PurchasePrice * 0.002, nil } if feeBuilder.FeeType == exchange.CryptocurrencyWithdrawalFee { - withdrawalFee, err := l.GetWithdrawConfig(feeBuilder.Pair.Base.Lower().String()) + withdrawalFee, err := l.GetWithdrawConfig(ctx, + feeBuilder.Pair.Base.Lower().String()) if err != nil { return resp, err } @@ -826,7 +838,7 @@ func (l *Lbank) GetFeeByType(feeBuilder *exchange.FeeBuilder) (float64, error) { } // GetAllOpenOrderID returns all open orders by currency pairs -func (l *Lbank) getAllOpenOrderID() (map[string][]string, error) { +func (l *Lbank) getAllOpenOrderID(ctx context.Context) (map[string][]string, error) { allPairs, err := l.GetEnabledPairs(asset.Spot) if err != nil { return nil, err @@ -838,7 +850,8 @@ func (l *Lbank) getAllOpenOrderID() (map[string][]string, error) { return nil, err } b := int64(1) - tempResp, err := l.GetOpenOrders(fpair.String(), + tempResp, err := l.GetOpenOrders(ctx, + fpair.String(), strconv.FormatInt(b, 10), "200") if err != nil { @@ -846,7 +859,8 @@ func (l *Lbank) getAllOpenOrderID() (map[string][]string, error) { } tempData := len(tempResp.Orders) for tempData != 0 { - tempResp, err = l.GetOpenOrders(fpair.String(), + tempResp, err = l.GetOpenOrders(ctx, + fpair.String(), strconv.FormatInt(b, 10), "200") if err != nil { @@ -870,8 +884,8 @@ func (l *Lbank) getAllOpenOrderID() (map[string][]string, error) { // ValidateCredentials validates current credentials used for wrapper // functionality -func (l *Lbank) ValidateCredentials(assetType asset.Item) error { - _, err := l.UpdateAccountInfo(assetType) +func (l *Lbank) ValidateCredentials(ctx context.Context, assetType asset.Item) error { + _, err := l.UpdateAccountInfo(ctx, assetType) return l.CheckTransientError(err) } @@ -893,7 +907,7 @@ func (l *Lbank) FormatExchangeKlineInterval(in kline.Interval) string { } // GetHistoricCandles returns candles between a time period for a set time interval -func (l *Lbank) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (l *Lbank) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { if err := l.ValidateKline(pair, a, interval); err != nil { return kline.Item{}, err } @@ -903,7 +917,8 @@ func (l *Lbank) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end return kline.Item{}, err } - data, err := l.GetKlines(formattedPair.String(), + data, err := l.GetKlines(ctx, + formattedPair.String(), strconv.FormatInt(int64(l.Features.Enabled.Kline.ResultLimit), 10), l.FormatExchangeKlineInterval(interval), strconv.FormatInt(start.Unix(), 10)) @@ -934,7 +949,7 @@ func (l *Lbank) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (l *Lbank) GetHistoricCandlesExtended(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (l *Lbank) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { if err := l.ValidateKline(pair, a, interval); err != nil { return kline.Item{}, err } @@ -957,7 +972,8 @@ func (l *Lbank) GetHistoricCandlesExtended(pair currency.Pair, a asset.Item, sta for x := range dates.Ranges { var data []KlineResponse - data, err = l.GetKlines(formattedPair.String(), + data, err = l.GetKlines(ctx, + formattedPair.String(), strconv.FormatInt(int64(l.Features.Enabled.Kline.ResultLimit), 10), l.FormatExchangeKlineInterval(interval), strconv.FormatInt(dates.Ranges[x].Start.Ticks, 10)) diff --git a/exchanges/localbitcoins/localbitcoins.go b/exchanges/localbitcoins/localbitcoins.go index a8dc3309..cff4e828 100644 --- a/exchanges/localbitcoins/localbitcoins.go +++ b/exchanges/localbitcoins/localbitcoins.go @@ -116,20 +116,20 @@ type LocalBitcoins struct { // GetAccountInformation lets you retrieve the public user information on a // LocalBitcoins user. The response contains the same information that is found // on an account's public profile page. -func (l *LocalBitcoins) GetAccountInformation(username string, self bool) (AccountInfo, error) { +func (l *LocalBitcoins) GetAccountInformation(ctx context.Context, username string, self bool) (AccountInfo, error) { type response struct { Data AccountInfo `json:"data"` } resp := response{} if self { - err := l.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, localbitcoinsAPIMyself, nil, &resp) + err := l.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, localbitcoinsAPIMyself, nil, &resp) if err != nil { return resp.Data, err } } else { path := fmt.Sprintf("/%s/%s/", localbitcoinsAPIAccountInfo, username) - err := l.SendHTTPRequest(exchange.RestSpot, path, &resp, request.Unset) + err := l.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp, request.Unset) if err != nil { return resp.Data, err } @@ -142,7 +142,7 @@ func (l *LocalBitcoins) GetAccountInformation(username string, self bool) (Accou // adID omitted. // // adID - [optional] string if omitted returns all ads -func (l *LocalBitcoins) Getads(args ...string) (AdData, error) { +func (l *LocalBitcoins) Getads(ctx context.Context, args ...string) (AdData, error) { var resp struct { Data AdData `json:"data"` Error struct { @@ -153,14 +153,13 @@ func (l *LocalBitcoins) Getads(args ...string) (AdData, error) { var err error if len(args) == 0 { - err = l.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, + err = l.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, localbitcoinsAPIAds, nil, &resp) } else { params := url.Values{"ads": {strings.Join(args, ",")}} - - err = l.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, + err = l.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, localbitcoinsAPIAdGet, params, &resp) @@ -181,7 +180,7 @@ func (l *LocalBitcoins) Getads(args ...string) (AdData, error) { // params - see localbitcoins_types.go AdEdit for reference // adID - string for the ad you already created // TODO -func (l *LocalBitcoins) EditAd(_ *AdEdit, adID string) error { +func (l *LocalBitcoins) EditAd(ctx context.Context, _ *AdEdit, adID string) error { resp := struct { Data AdData `json:"data"` Error struct { @@ -190,7 +189,9 @@ func (l *LocalBitcoins) EditAd(_ *AdEdit, adID string) error { } }{} - err := l.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + err := l.SendAuthenticatedHTTPRequest(ctx, + exchange.RestSpot, + http.MethodPost, localbitcoinsAPIAdEdit+adID+"/", nil, &resp) @@ -209,8 +210,8 @@ func (l *LocalBitcoins) EditAd(_ *AdEdit, adID string) error { // // params - see localbitcoins_types.go AdCreate for reference // TODO -func (l *LocalBitcoins) CreateAd(_ *AdCreate) error { - return l.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, localbitcoinsAPIAdCreate, nil, nil) +func (l *LocalBitcoins) CreateAd(ctx context.Context, _ *AdCreate) error { + return l.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, localbitcoinsAPIAdCreate, nil, nil) } // UpdatePriceEquation updates price equation of an advertisement. If there are @@ -220,15 +221,15 @@ func (l *LocalBitcoins) CreateAd(_ *AdCreate) error { // equation - string of equation // adID - string of specific ad identification // TODO -func (l *LocalBitcoins) UpdatePriceEquation(adID string) error { - return l.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, localbitcoinsAPIUpdateEquation+adID, nil, nil) +func (l *LocalBitcoins) UpdatePriceEquation(ctx context.Context, adID string) error { + return l.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, localbitcoinsAPIUpdateEquation+adID, nil, nil) } // DeleteAd deletes the advertisement by adID. // // adID - string of specific ad identification // TODO -func (l *LocalBitcoins) DeleteAd(adID string) error { +func (l *LocalBitcoins) DeleteAd(ctx context.Context, adID string) error { resp := struct { Error struct { Message string `json:"message"` @@ -236,7 +237,9 @@ func (l *LocalBitcoins) DeleteAd(adID string) error { } `json:"error"` }{} - err := l.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + err := l.SendAuthenticatedHTTPRequest(ctx, + exchange.RestSpot, + http.MethodPost, localbitcoinsAPIDeleteAd+adID+"/", nil, &resp) @@ -253,39 +256,39 @@ func (l *LocalBitcoins) DeleteAd(adID string) error { // ReleaseFunds releases Bitcoin trades specified by ID {contact_id}. If the // release was successful a message is returned on the data key. -func (l *LocalBitcoins) ReleaseFunds(contactID string) error { - return l.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, localbitcoinsAPIRelease+contactID, nil, nil) +func (l *LocalBitcoins) ReleaseFunds(ctx context.Context, contactID string) error { + return l.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, localbitcoinsAPIRelease+contactID, nil, nil) } // ReleaseFundsByPin releases Bitcoin trades specified by ID {contact_id}. if // the current pincode is provided. If the release was successful a message is // returned on the data key. // TODO -func (l *LocalBitcoins) ReleaseFundsByPin(contactID string) error { - return l.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, localbitcoinsAPIReleaseByPin+contactID, nil, nil) +func (l *LocalBitcoins) ReleaseFundsByPin(ctx context.Context, contactID string) error { + return l.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, localbitcoinsAPIReleaseByPin+contactID, nil, nil) } // MarkAsPaid marks a trade as paid. -func (l *LocalBitcoins) MarkAsPaid(contactID string) error { - return l.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, localbitcoinsAPIMarkAsPaid+contactID, nil, nil) +func (l *LocalBitcoins) MarkAsPaid(ctx context.Context, contactID string) error { + return l.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, localbitcoinsAPIMarkAsPaid+contactID, nil, nil) } // GetMessages returns all chat messages from the trade. Messages are on the message_list key. -func (l *LocalBitcoins) GetMessages(contactID string) (Message, error) { +func (l *LocalBitcoins) GetMessages(ctx context.Context, contactID string) (Message, error) { type response struct { MessageList Message `json:"message_list"` } resp := response{} return resp.MessageList, - l.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, localbitcoinsAPIMessages+contactID, nil, &resp) + l.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, localbitcoinsAPIMessages+contactID, nil, &resp) } // SendMessage posts a message and/or uploads an image to the trade. Encode // images with multipart/form-data encoding. // TODO -func (l *LocalBitcoins) SendMessage(contactID string) error { - return l.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, localbitcoinsAPISendMessage+contactID, nil, nil) +func (l *LocalBitcoins) SendMessage(ctx context.Context, contactID string) error { + return l.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, localbitcoinsAPISendMessage+contactID, nil, nil) } // Dispute starts a dispute on the specified trade ID if the requirements for @@ -293,57 +296,57 @@ func (l *LocalBitcoins) SendMessage(contactID string) error { // // topic - [optional] String Short description of issue to LocalBitcoins customer support. // TODO -func (l *LocalBitcoins) Dispute(_, contactID string) error { - return l.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, localbitcoinsAPIDispute+contactID, nil, nil) +func (l *LocalBitcoins) Dispute(ctx context.Context, _, contactID string) error { + return l.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, localbitcoinsAPIDispute+contactID, nil, nil) } // CancelTrade cancels the trade if the token owner is the Bitcoin buyer. // Bitcoin sellers cannot cancel trades. -func (l *LocalBitcoins) CancelTrade(contactID string) error { - return l.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, localbitcoinsAPICancelTrade+contactID, nil, nil) +func (l *LocalBitcoins) CancelTrade(ctx context.Context, contactID string) error { + return l.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, localbitcoinsAPICancelTrade+contactID, nil, nil) } // FundTrade attempts to fund an unfunded local trade from the token owners // wallet. Works only if the token owner is the Bitcoin seller in the trade. -func (l *LocalBitcoins) FundTrade(contactID string) error { - return l.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, localbitcoinsAPIFundTrade+contactID, nil, nil) +func (l *LocalBitcoins) FundTrade(ctx context.Context, contactID string) error { + return l.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, localbitcoinsAPIFundTrade+contactID, nil, nil) } // ConfirmRealName creates or updates real name confirmation. -func (l *LocalBitcoins) ConfirmRealName(contactID string) error { - return l.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, localbitcoinsAPIConfirmRealName+contactID, nil, nil) +func (l *LocalBitcoins) ConfirmRealName(ctx context.Context, contactID string) error { + return l.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, localbitcoinsAPIConfirmRealName+contactID, nil, nil) } // VerifyIdentity marks the identity of trade partner as verified. You must be // the advertiser in this trade. -func (l *LocalBitcoins) VerifyIdentity(contactID string) error { - return l.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, localbitcoinsAPIVerifyIdentity+contactID, nil, nil) +func (l *LocalBitcoins) VerifyIdentity(ctx context.Context, contactID string) error { + return l.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, localbitcoinsAPIVerifyIdentity+contactID, nil, nil) } // InitiateTrade sttempts to start a Bitcoin trade from the specified // advertisement ID. // TODO -func (l *LocalBitcoins) InitiateTrade(adID string) error { - return l.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, localbitcoinsAPIInitiateTrade+adID, nil, nil) +func (l *LocalBitcoins) InitiateTrade(ctx context.Context, adID string) error { + return l.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, localbitcoinsAPIInitiateTrade+adID, nil, nil) } // GetTradeInfo returns information about a single trade that the token owner is // part in. -func (l *LocalBitcoins) GetTradeInfo(contactID string) (dbi DashBoardInfo, err error) { - err = l.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, localbitcoinsAPITradeInfo+contactID+"/", nil, &dbi) +func (l *LocalBitcoins) GetTradeInfo(ctx context.Context, contactID string) (dbi DashBoardInfo, err error) { + err = l.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, localbitcoinsAPITradeInfo+contactID+"/", nil, &dbi) return } // GetCountryCodes returns a list of valid and recognized countrycodes -func (l *LocalBitcoins) GetCountryCodes() error { - return l.SendHTTPRequest(exchange.RestSpot, localbitcoinsAPICountryCodes, nil, request.Unset) +func (l *LocalBitcoins) GetCountryCodes(ctx context.Context) error { + return l.SendHTTPRequest(ctx, exchange.RestSpot, localbitcoinsAPICountryCodes, nil, request.Unset) } // GetCurrencies returns a list of valid and recognized fiat currencies. Also // contains human readable name for every currency and boolean that tells if // currency is an altcoin. -func (l *LocalBitcoins) GetCurrencies() error { - return l.SendHTTPRequest(exchange.RestSpot, localbitcoinsAPICurrencies, nil, request.Unset) +func (l *LocalBitcoins) GetCurrencies(ctx context.Context) error { + return l.SendHTTPRequest(ctx, exchange.RestSpot, localbitcoinsAPICurrencies, nil, request.Unset) } // GetDashboardInfo returns a list of trades on the data key contact_list. This @@ -353,7 +356,7 @@ func (l *LocalBitcoins) GetCurrencies() error { // view contacts where the token owner is either buying or selling, respectively. // E.g. /api/dashboard/buyer/. All contacts where the token owner is // participating are returned. -func (l *LocalBitcoins) GetDashboardInfo() ([]DashBoardInfo, error) { +func (l *LocalBitcoins) GetDashboardInfo(ctx context.Context) ([]DashBoardInfo, error) { var resp struct { Data struct { ContactList []DashBoardInfo `json:"contact_list"` @@ -362,12 +365,12 @@ func (l *LocalBitcoins) GetDashboardInfo() ([]DashBoardInfo, error) { } return resp.Data.ContactList, - l.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, localbitcoinsAPIDashboard, nil, &resp) + l.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, localbitcoinsAPIDashboard, nil, &resp) } // GetDashboardReleasedTrades returns a list of all released trades where the // token owner is either a buyer or seller. -func (l *LocalBitcoins) GetDashboardReleasedTrades() ([]DashBoardInfo, error) { +func (l *LocalBitcoins) GetDashboardReleasedTrades(ctx context.Context) ([]DashBoardInfo, error) { var resp struct { Data struct { ContactList []DashBoardInfo `json:"contact_list"` @@ -376,12 +379,12 @@ func (l *LocalBitcoins) GetDashboardReleasedTrades() ([]DashBoardInfo, error) { } return resp.Data.ContactList, - l.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, localbitcoinsAPIDashboardReleased, nil, &resp) + l.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, localbitcoinsAPIDashboardReleased, nil, &resp) } // GetDashboardCancelledTrades returns a list of all canceled trades where the // token owner is either a buyer or seller. -func (l *LocalBitcoins) GetDashboardCancelledTrades() ([]DashBoardInfo, error) { +func (l *LocalBitcoins) GetDashboardCancelledTrades(ctx context.Context) ([]DashBoardInfo, error) { var resp struct { Data struct { ContactList []DashBoardInfo `json:"contact_list"` @@ -390,12 +393,12 @@ func (l *LocalBitcoins) GetDashboardCancelledTrades() ([]DashBoardInfo, error) { } return resp.Data.ContactList, - l.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, localbitcoinsAPIDashboardCancelled, nil, &resp) + l.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, localbitcoinsAPIDashboardCancelled, nil, &resp) } // GetDashboardClosedTrades returns a list of all closed trades where the token // owner is either a buyer or seller. -func (l *LocalBitcoins) GetDashboardClosedTrades() ([]DashBoardInfo, error) { +func (l *LocalBitcoins) GetDashboardClosedTrades(ctx context.Context) ([]DashBoardInfo, error) { var resp struct { Data struct { ContactList []DashBoardInfo `json:"contact_list"` @@ -404,7 +407,7 @@ func (l *LocalBitcoins) GetDashboardClosedTrades() ([]DashBoardInfo, error) { } return resp.Data.ContactList, - l.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, localbitcoinsAPIDashboardClosed, nil, &resp) + l.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, localbitcoinsAPIDashboardClosed, nil, &resp) } // SetFeedback gives feedback to user. Possible feedback values are: trust, @@ -420,29 +423,29 @@ func (l *LocalBitcoins) GetDashboardClosedTrades() ([]DashBoardInfo, error) { // profile page. // username - username of trade contact // TODO -func (l *LocalBitcoins) SetFeedback() error { - return l.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, localbitcoinsAPIFeedback, nil, nil) +func (l *LocalBitcoins) SetFeedback(ctx context.Context) error { + return l.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, localbitcoinsAPIFeedback, nil, nil) } // Logout expires the current access token immediately. To get a new token // afterwards, public apps will need to re-authenticate, confidential apps can // turn in a refresh token. -func (l *LocalBitcoins) Logout() error { - return l.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, localbitcoinsAPILogout, nil, nil) +func (l *LocalBitcoins) Logout(ctx context.Context) error { + return l.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, localbitcoinsAPILogout, nil, nil) } // CreateNewInvoice creates a new invoice. // TODO -func (l *LocalBitcoins) CreateNewInvoice() error { - return l.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, localbitcoinsAPICreateInvoice, nil, nil) +func (l *LocalBitcoins) CreateNewInvoice(ctx context.Context) error { + return l.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, localbitcoinsAPICreateInvoice, nil, nil) } // GetInvoice returns information about a specific invoice created by the token // owner. // TODO -func (l *LocalBitcoins) GetInvoice() (Invoice, error) { +func (l *LocalBitcoins) GetInvoice(ctx context.Context) (Invoice, error) { resp := Invoice{} - return resp, l.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, localbitcoinsAPICreateInvoice, nil, &resp) + return resp, l.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, localbitcoinsAPICreateInvoice, nil, &resp) } // DeleteInvoice deletes a specific invoice. Deleting invoices is possible when @@ -450,34 +453,34 @@ func (l *LocalBitcoins) GetInvoice() (Invoice, error) { // as the merchant is deleting it. You can use the API request // /api/merchant/invoice/{invoice_id}/ to check if deleting is possible. // TODO -func (l *LocalBitcoins) DeleteInvoice() (Invoice, error) { +func (l *LocalBitcoins) DeleteInvoice(ctx context.Context) (Invoice, error) { resp := Invoice{} - return resp, l.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, localbitcoinsAPICreateInvoice, nil, &resp) + return resp, l.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, localbitcoinsAPICreateInvoice, nil, &resp) } // GetNotifications returns recent notifications. -func (l *LocalBitcoins) GetNotifications() ([]NotificationInfo, error) { +func (l *LocalBitcoins) GetNotifications(ctx context.Context) ([]NotificationInfo, error) { var resp []NotificationInfo - return resp, l.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, localbitcoinsAPIGetNotification, nil, &resp) + return resp, l.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, localbitcoinsAPIGetNotification, nil, &resp) } // MarkNotifications marks a specific notification as read. // TODO -func (l *LocalBitcoins) MarkNotifications() error { - return l.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, localbitcoinsAPIMarkNotification, nil, nil) +func (l *LocalBitcoins) MarkNotifications(ctx context.Context) error { + return l.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, localbitcoinsAPIMarkNotification, nil, nil) } // GetPaymentMethods returns a list of valid payment methods. Also contains name // and code for payment methods, and possible limitations in currencies and bank // name choices. -func (l *LocalBitcoins) GetPaymentMethods() error { - return l.SendHTTPRequest(exchange.RestSpot, localbitcoinsAPIPaymentMethods, nil, request.Unset) +func (l *LocalBitcoins) GetPaymentMethods(ctx context.Context) error { + return l.SendHTTPRequest(ctx, exchange.RestSpot, localbitcoinsAPIPaymentMethods, nil, request.Unset) } // GetPaymentMethodsByCountry returns a list of valid payment methods filtered // by countrycodes. -func (l *LocalBitcoins) GetPaymentMethodsByCountry(countryCode string) error { - return l.SendHTTPRequest(exchange.RestSpot, localbitcoinsAPIPaymentMethods+countryCode, nil, request.Unset) +func (l *LocalBitcoins) GetPaymentMethodsByCountry(ctx context.Context, countryCode string) error { + return l.SendHTTPRequest(ctx, exchange.RestSpot, localbitcoinsAPIPaymentMethods+countryCode, nil, request.Unset) } // CheckPincode checks the given PIN code against the token owners currently @@ -486,7 +489,7 @@ func (l *LocalBitcoins) GetPaymentMethodsByCountry(countryCode string) error { // Due to only requiring the read scope, the user is not guaranteed to have set // a PIN code. If you protect your application using this request, please make // the user has set a PIN code for his account. -func (l *LocalBitcoins) CheckPincode(pin int) (bool, error) { +func (l *LocalBitcoins) CheckPincode(ctx context.Context, pin int) (bool, error) { type response struct { Data struct { PinOK bool `json:"pincode_ok"` @@ -495,7 +498,7 @@ func (l *LocalBitcoins) CheckPincode(pin int) (bool, error) { resp := response{} values := url.Values{} values.Set("pincode", strconv.Itoa(pin)) - err := l.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, localbitcoinsAPIPinCode, values, &resp) + err := l.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, localbitcoinsAPIPinCode, values, &resp) if err != nil { return false, err @@ -511,31 +514,31 @@ func (l *LocalBitcoins) CheckPincode(pin int) (bool, error) { // GetPlaces Looks up places near lat, lon and provides full URLs to buy and // sell listings for each. // TODO -func (l *LocalBitcoins) GetPlaces() error { - return l.SendHTTPRequest(exchange.RestSpot, localbitcoinsAPIPlaces, nil, request.Unset) +func (l *LocalBitcoins) GetPlaces(ctx context.Context) error { + return l.SendHTTPRequest(ctx, exchange.RestSpot, localbitcoinsAPIPlaces, nil, request.Unset) } // VerifyUsername returns list of real name verifiers for the user. Returns a // list only when you have a trade with the user where you are the seller. -func (l *LocalBitcoins) VerifyUsername() error { - return l.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, localbitcoinsAPIVerifyUsername, nil, nil) +func (l *LocalBitcoins) VerifyUsername(ctx context.Context) error { + return l.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, localbitcoinsAPIVerifyUsername, nil, nil) } // GetRecentMessages returns maximum of 25 newest trade messages. Does not // return messages older than one month. Messages are ordered by sending time, // and the newest one is first. // TODO -func (l *LocalBitcoins) GetRecentMessages() error { - return l.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, localbitcoinsAPIVerifyUsername, nil, nil) +func (l *LocalBitcoins) GetRecentMessages(ctx context.Context) error { + return l.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, localbitcoinsAPIVerifyUsername, nil, nil) } // GetWalletInfo gets information about the token owner's wallet balance. -func (l *LocalBitcoins) GetWalletInfo() (WalletInfo, error) { +func (l *LocalBitcoins) GetWalletInfo(ctx context.Context) (WalletInfo, error) { type response struct { Data WalletInfo `json:"data"` } resp := response{} - err := l.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, localbitcoinsAPIWallet, nil, &resp) + err := l.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, localbitcoinsAPIWallet, nil, &resp) if err != nil { return WalletInfo{}, err @@ -551,12 +554,12 @@ func (l *LocalBitcoins) GetWalletInfo() (WalletInfo, error) { // GetWalletBalance Same as GetWalletInfo(), but only returns the message, // receiving_address and total fields. // Use this instead if you don't care about transactions at the moment. -func (l *LocalBitcoins) GetWalletBalance() (WalletBalanceInfo, error) { +func (l *LocalBitcoins) GetWalletBalance(ctx context.Context) (WalletBalanceInfo, error) { type response struct { Data WalletBalanceInfo `json:"data"` } resp := response{} - err := l.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodGet, localbitcoinsAPIWalletBalance, nil, &resp) + err := l.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, localbitcoinsAPIWalletBalance, nil, &resp) if err != nil { return WalletBalanceInfo{}, err @@ -573,7 +576,7 @@ func (l *LocalBitcoins) GetWalletBalance() (WalletBalanceInfo, error) { // On success, the response returns a message indicating success. It is highly // recommended to minimize the lifetime of access tokens with the money // permission. Use Logout() to make the current token expire instantly. -func (l *LocalBitcoins) WalletSend(address string, amount float64, pin int64) error { +func (l *LocalBitcoins) WalletSend(ctx context.Context, address string, amount float64, pin int64) error { values := url.Values{} values.Set("address", address) values.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) @@ -595,7 +598,7 @@ func (l *LocalBitcoins) WalletSend(address string, amount float64, pin int64) er } `json:"data"` }{} - err := l.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, path, values, &resp) + err := l.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, path, values, &resp) if err != nil { return err } @@ -617,7 +620,7 @@ func (l *LocalBitcoins) WalletSend(address string, amount float64, pin int64) er // GetWalletAddress returns an unused receiving address from the token owner's // wallet. The address is returned in the address key of the response. Note that // this API may keep returning the same (unused) address if requested repeatedly. -func (l *LocalBitcoins) GetWalletAddress() (string, error) { +func (l *LocalBitcoins) GetWalletAddress(ctx context.Context) (string, error) { type response struct { Data struct { Message string `json:"message"` @@ -625,7 +628,7 @@ func (l *LocalBitcoins) GetWalletAddress() (string, error) { } } resp := response{} - err := l.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, localbitcoinsAPIWalletAddress, nil, &resp) + err := l.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, localbitcoinsAPIWalletAddress, nil, &resp) if err != nil { return "", err } @@ -639,25 +642,25 @@ func (l *LocalBitcoins) GetWalletAddress() (string, error) { // GetBitcoinsWithCashAd returns buy or sell as cash local advertisements. // TODO -func (l *LocalBitcoins) GetBitcoinsWithCashAd() error { - return l.SendHTTPRequest(exchange.RestSpot, localbitcoinsAPICashBuy, nil, request.Unset) +func (l *LocalBitcoins) GetBitcoinsWithCashAd(ctx context.Context) error { + return l.SendHTTPRequest(ctx, exchange.RestSpot, localbitcoinsAPICashBuy, nil, request.Unset) } // GetBitcoinsOnlineAd this API returns buy or sell Bitcoin online ads. // TODO -func (l *LocalBitcoins) GetBitcoinsOnlineAd() error { - return l.SendHTTPRequest(exchange.RestSpot, localbitcoinsAPIOnlineBuy, nil, request.Unset) +func (l *LocalBitcoins) GetBitcoinsOnlineAd(ctx context.Context) error { + return l.SendHTTPRequest(ctx, exchange.RestSpot, localbitcoinsAPIOnlineBuy, nil, request.Unset) } // GetTicker returns list of all completed trades. -func (l *LocalBitcoins) GetTicker() (map[string]Ticker, error) { +func (l *LocalBitcoins) GetTicker(ctx context.Context) (map[string]Ticker, error) { result := make(map[string]Ticker) - return result, l.SendHTTPRequest(exchange.RestSpot, localbitcoinsAPITicker, &result, tickerLimiter) + return result, l.SendHTTPRequest(ctx, exchange.RestSpot, localbitcoinsAPITicker, &result, tickerLimiter) } // GetTradableCurrencies returns a list of tradable fiat currencies -func (l *LocalBitcoins) GetTradableCurrencies() ([]string, error) { - resp, err := l.GetTicker() +func (l *LocalBitcoins) GetTradableCurrencies(ctx context.Context) ([]string, error) { + resp, err := l.GetTicker(ctx) if err != nil { return nil, err } @@ -672,18 +675,18 @@ func (l *LocalBitcoins) GetTradableCurrencies() ([]string, error) { // GetTrades returns all closed trades in online buy and online sell categories, // updated every 15 minutes. -func (l *LocalBitcoins) GetTrades(currency string, values url.Values) ([]Trade, error) { +func (l *LocalBitcoins) GetTrades(ctx context.Context, currency string, values url.Values) ([]Trade, error) { endpoint := localbitcoinsAPIBitcoincharts + currency + localbitcoinsAPITrades path := common.EncodeURLValues(endpoint, values) var result []Trade - return result, l.SendHTTPRequest(exchange.RestSpot, path, &result, request.Unset) + return result, l.SendHTTPRequest(ctx, exchange.RestSpot, path, &result, request.Unset) } // GetOrderbook returns buy and sell bitcoin online advertisements. Amount is // the maximum amount available for the trade request. Price is the hourly // updated price. The price is based on the price equation and commission % // entered by the ad author. -func (l *LocalBitcoins) GetOrderbook(currency string) (Orderbook, error) { +func (l *LocalBitcoins) GetOrderbook(ctx context.Context, currency string) (Orderbook, error) { type response struct { Bids [][2]string `json:"bids"` Asks [][2]string `json:"asks"` @@ -692,7 +695,7 @@ func (l *LocalBitcoins) GetOrderbook(currency string) (Orderbook, error) { path := localbitcoinsAPIBitcoincharts + currency + localbitcoinsAPIOrderbook resp := response{} var ob Orderbook - if err := l.SendHTTPRequest(exchange.RestSpot, path, &resp, orderBookLimiter); err != nil { + if err := l.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp, orderBookLimiter); err != nil { return ob, err } @@ -724,7 +727,7 @@ func (l *LocalBitcoins) GetOrderbook(currency string) (Orderbook, error) { } // SendHTTPRequest sends an unauthenticated HTTP request -func (l *LocalBitcoins) SendHTTPRequest(endpoint exchange.URL, path string, result interface{}, ep request.EndpointLimit) error { +func (l *LocalBitcoins) SendHTTPRequest(ctx context.Context, endpoint exchange.URL, path string, result interface{}, ep request.EndpointLimit) error { ePoint, err := l.API.Endpoints.GetURL(endpoint) if err != nil { return err @@ -739,14 +742,14 @@ func (l *LocalBitcoins) SendHTTPRequest(endpoint exchange.URL, path string, resu HTTPRecording: l.HTTPRecording, } - return l.SendPayload(context.Background(), ep, func() (*request.Item, error) { + return l.SendPayload(ctx, ep, func() (*request.Item, error) { return item, nil }) } // SendAuthenticatedHTTPRequest sends an authenticated HTTP request to // localbitcoins -func (l *LocalBitcoins) SendAuthenticatedHTTPRequest(ep exchange.URL, method, path string, params url.Values, result interface{}) (err error) { +func (l *LocalBitcoins) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, method, path string, params url.Values, result interface{}) (err error) { if !l.AllowAuthenticatedRequest() { return fmt.Errorf("%s %w", l.Name, exchange.ErrAuthenticatedRequestWithoutCredentialsSet) } @@ -755,7 +758,7 @@ func (l *LocalBitcoins) SendAuthenticatedHTTPRequest(ep exchange.URL, method, pa return err } - return l.SendPayload(context.Background(), request.Unset, func() (*request.Item, error) { + return l.SendPayload(ctx, request.Unset, func() (*request.Item, error) { n := l.Requester.GetNonce(true).String() fullPath := "/api/" + path diff --git a/exchanges/localbitcoins/localbitcoins_test.go b/exchanges/localbitcoins/localbitcoins_test.go index 996041ce..ff80cfb9 100644 --- a/exchanges/localbitcoins/localbitcoins_test.go +++ b/exchanges/localbitcoins/localbitcoins_test.go @@ -1,6 +1,7 @@ package localbitcoins import ( + "context" "testing" "time" @@ -26,7 +27,7 @@ var l LocalBitcoins func TestGetTicker(t *testing.T) { t.Parallel() - _, err := l.GetTicker() + _, err := l.GetTicker(context.Background()) if err != nil { t.Errorf("GetTicker() returned: %s", err) } @@ -35,7 +36,7 @@ func TestGetTicker(t *testing.T) { func TestGetTradableCurrencies(t *testing.T) { t.Parallel() - _, err := l.GetTradableCurrencies() + _, err := l.GetTradableCurrencies(context.Background()) if err != nil { t.Errorf("GetTradableCurrencies() returned: %s", err) } @@ -43,7 +44,7 @@ func TestGetTradableCurrencies(t *testing.T) { func TestGetAccountInfo(t *testing.T) { t.Parallel() - _, err := l.GetAccountInformation("", true) + _, err := l.GetAccountInformation(context.Background(), "", true) switch { case areTestAPIKeysSet() && err != nil && !mockTests: t.Errorf("Could not get AccountInformation: %s", err) @@ -56,7 +57,7 @@ func TestGetAccountInfo(t *testing.T) { func TestGetads(t *testing.T) { t.Parallel() - _, err := l.Getads("") + _, err := l.Getads(context.Background(), "") switch { case areTestAPIKeysSet() && err != nil && !mockTests: t.Errorf("Could not get ads: %s", err) @@ -71,7 +72,7 @@ func TestEditAd(t *testing.T) { t.Parallel() var edit AdEdit - err := l.EditAd(&edit, "1337") + err := l.EditAd(context.Background(), &edit, "1337") switch { case areTestAPIKeysSet() && err != nil && !mockTests: t.Errorf("Could not edit order: %s", err) @@ -97,7 +98,7 @@ func setFeeBuilder() *exchange.FeeBuilder { func TestGetTrades(t *testing.T) { t.Parallel() - _, err := l.GetTrades("LTC", nil) + _, err := l.GetTrades(context.Background(), "LTC", nil) if err != nil { t.Error(err) } @@ -105,7 +106,7 @@ func TestGetTrades(t *testing.T) { func TestGetOrderbook(t *testing.T) { t.Parallel() - ob, err := l.GetOrderbook("AUD") + ob, err := l.GetOrderbook(context.Background(), "AUD") if err != nil { t.Fatal(err) } @@ -121,7 +122,7 @@ func TestGetOrderbook(t *testing.T) { func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { t.Parallel() var feeBuilder = setFeeBuilder() - _, err := l.GetFeeByType(feeBuilder) + _, err := l.GetFeeByType(context.Background(), feeBuilder) if err != nil { t.Fatal(err) } @@ -222,7 +223,7 @@ func TestGetActiveOrders(t *testing.T) { AssetType: asset.Spot, } - _, err := l.GetActiveOrders(&getOrdersRequest) + _, err := l.GetActiveOrders(context.Background(), &getOrdersRequest) switch { case areTestAPIKeysSet() && err != nil && !mockTests: t.Errorf("Could not get active orders: %s", err) @@ -241,7 +242,7 @@ func TestGetOrderHistory(t *testing.T) { AssetType: asset.Spot, } - _, err := l.GetOrderHistory(&getOrdersRequest) + _, err := l.GetOrderHistory(context.Background(), &getOrdersRequest) switch { case areTestAPIKeysSet() && err != nil && !mockTests: t.Errorf("Could not get order history: %s", err) @@ -277,7 +278,7 @@ func TestSubmitOrder(t *testing.T) { ClientID: "meowOrder", AssetType: asset.Spot, } - response, err := l.SubmitOrder(orderSubmission) + response, err := l.SubmitOrder(context.Background(), orderSubmission) switch { case areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) && !mockTests: t.Errorf("Order failed to be placed: %v", err) @@ -302,7 +303,7 @@ func TestCancelExchangeOrder(t *testing.T) { AssetType: asset.Spot, } - err := l.CancelOrder(orderCancellation) + err := l.CancelOrder(context.Background(), orderCancellation) switch { case !areTestAPIKeysSet() && err == nil && !mockTests: t.Error("Expecting an error when no keys are set") @@ -327,7 +328,7 @@ func TestCancelAllExchangeOrders(t *testing.T) { AssetType: asset.Spot, } - resp, err := l.CancelAllOrders(orderCancellation) + resp, err := l.CancelAllOrders(context.Background(), orderCancellation) switch { case !areTestAPIKeysSet() && err == nil && !mockTests: t.Error("Expecting an error when no keys are set") @@ -345,7 +346,8 @@ func TestCancelAllExchangeOrders(t *testing.T) { func TestModifyOrder(t *testing.T) { t.Parallel() - _, err := l.ModifyOrder(&order.Modify{AssetType: asset.Spot}) + _, err := l.ModifyOrder(context.Background(), + &order.Modify{AssetType: asset.Spot}) if err != common.ErrFunctionNotSupported { t.Error("ModifyOrder() error", err) } @@ -367,7 +369,8 @@ func TestWithdraw(t *testing.T) { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - _, err := l.WithdrawCryptocurrencyFunds(&withdrawCryptoRequest) + _, err := l.WithdrawCryptocurrencyFunds(context.Background(), + &withdrawCryptoRequest) switch { case !areTestAPIKeysSet() && err == nil && !mockTests: t.Error("Expecting an error when no keys are set") @@ -382,7 +385,7 @@ func TestWithdrawFiat(t *testing.T) { t.Parallel() var withdrawFiatRequest = withdraw.Request{} - _, err := l.WithdrawFiatFunds(&withdrawFiatRequest) + _, err := l.WithdrawFiatFunds(context.Background(), &withdrawFiatRequest) if err != common.ErrFunctionNotSupported { t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, @@ -394,7 +397,7 @@ func TestWithdrawInternationalBank(t *testing.T) { t.Parallel() var withdrawFiatRequest = withdraw.Request{} - _, err := l.WithdrawFiatFundsToInternationalBank(&withdrawFiatRequest) + _, err := l.WithdrawFiatFundsToInternationalBank(context.Background(), &withdrawFiatRequest) if err != common.ErrFunctionNotSupported { t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, @@ -405,7 +408,7 @@ func TestWithdrawInternationalBank(t *testing.T) { func TestGetDepositAddress(t *testing.T) { t.Parallel() - _, err := l.GetDepositAddress(currency.BTC, "") + _, err := l.GetDepositAddress(context.Background(), currency.BTC, "") switch { case areTestAPIKeysSet() && err != nil && !mockTests: t.Error("GetDepositAddress() error", err) @@ -422,7 +425,7 @@ func TestGetRecentTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = l.GetRecentTrades(currencyPair, asset.Spot) + _, err = l.GetRecentTrades(context.Background(), currencyPair, asset.Spot) if err != nil { t.Error(err) } @@ -434,7 +437,8 @@ func TestGetHistoricTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = l.GetHistoricTrades(currencyPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) + _, err = l.GetHistoricTrades(context.Background(), + currencyPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) if err != nil && err != common.ErrFunctionNotSupported { t.Error(err) } @@ -446,7 +450,7 @@ func TestUpdateTicker(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = l.UpdateTicker(cp, asset.Spot) + _, err = l.UpdateTicker(context.Background(), cp, asset.Spot) if err != nil { t.Error(err) } @@ -454,7 +458,7 @@ func TestUpdateTicker(t *testing.T) { func TestUpdateTickers(t *testing.T) { t.Parallel() - err := l.UpdateTickers(asset.Spot) + err := l.UpdateTickers(context.Background(), asset.Spot) if err != nil { t.Error(err) } diff --git a/exchanges/localbitcoins/localbitcoins_wrapper.go b/exchanges/localbitcoins/localbitcoins_wrapper.go index d2f8251e..154b2ca4 100644 --- a/exchanges/localbitcoins/localbitcoins_wrapper.go +++ b/exchanges/localbitcoins/localbitcoins_wrapper.go @@ -1,6 +1,7 @@ package localbitcoins import ( + "context" "errors" "fmt" "math" @@ -41,7 +42,7 @@ func (l *LocalBitcoins) GetDefaultConfig() (*config.ExchangeConfig, error) { } if l.Features.Supports.RESTCapabilities.AutoPairUpdates { - err = l.UpdateTradablePairs(true) + err = l.UpdateTradablePairs(context.TODO(), true) if err != nil { return nil, err } @@ -130,15 +131,15 @@ func (l *LocalBitcoins) Run() { return } - err := l.UpdateTradablePairs(false) + err := l.UpdateTradablePairs(context.TODO(), false) if err != nil { log.Errorf(log.ExchangeSys, "%s failed to update tradable pairs. Err: %s", l.Name, err) } } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (l *LocalBitcoins) FetchTradablePairs(asset asset.Item) ([]string, error) { - currencies, err := l.GetTradableCurrencies() +func (l *LocalBitcoins) FetchTradablePairs(ctx context.Context, asset asset.Item) ([]string, error) { + currencies, err := l.GetTradableCurrencies(ctx) if err != nil { return nil, err } @@ -153,8 +154,8 @@ func (l *LocalBitcoins) FetchTradablePairs(asset asset.Item) ([]string, error) { // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (l *LocalBitcoins) UpdateTradablePairs(forceUpdate bool) error { - pairs, err := l.FetchTradablePairs(asset.Spot) +func (l *LocalBitcoins) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { + pairs, err := l.FetchTradablePairs(ctx, asset.Spot) if err != nil { return err } @@ -166,8 +167,8 @@ func (l *LocalBitcoins) UpdateTradablePairs(forceUpdate bool) error { } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (l *LocalBitcoins) UpdateTickers(a asset.Item) error { - tick, err := l.GetTicker() +func (l *LocalBitcoins) UpdateTickers(ctx context.Context, a asset.Item) error { + tick, err := l.GetTicker(ctx) if err != nil { return err } @@ -197,8 +198,8 @@ func (l *LocalBitcoins) UpdateTickers(a asset.Item) error { } // UpdateTicker updates and returns the ticker for a currency pair -func (l *LocalBitcoins) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) { - err := l.UpdateTickers(a) +func (l *LocalBitcoins) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { + err := l.UpdateTickers(ctx, a) if err != nil { return nil, err } @@ -206,25 +207,25 @@ func (l *LocalBitcoins) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Pri } // FetchTicker returns the ticker for a currency pair -func (l *LocalBitcoins) FetchTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) { +func (l *LocalBitcoins) FetchTicker(ctx context.Context, p currency.Pair, assetType asset.Item) (*ticker.Price, error) { tickerNew, err := ticker.GetTicker(l.Name, p, assetType) if err != nil { - return l.UpdateTicker(p, assetType) + return l.UpdateTicker(ctx, p, assetType) } return tickerNew, nil } // FetchOrderbook returns orderbook base on the currency pair -func (l *LocalBitcoins) FetchOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (l *LocalBitcoins) FetchOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { ob, err := orderbook.Get(l.Name, p, assetType) if err != nil { - return l.UpdateOrderbook(p, assetType) + return l.UpdateOrderbook(ctx, p, assetType) } return ob, nil } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (l *LocalBitcoins) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (l *LocalBitcoins) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { book := &orderbook.Base{ Exchange: l.Name, Pair: p, @@ -232,7 +233,7 @@ func (l *LocalBitcoins) UpdateOrderbook(p currency.Pair, assetType asset.Item) ( VerifyOrderbook: l.CanVerifyOrderbook, } - orderbookNew, err := l.GetOrderbook(p.Quote.String()) + orderbookNew, err := l.GetOrderbook(ctx, p.Quote.String()) if err != nil { return book, err } @@ -262,10 +263,10 @@ func (l *LocalBitcoins) UpdateOrderbook(p currency.Pair, assetType asset.Item) ( // UpdateAccountInfo retrieves balances for all enabled currencies for the // LocalBitcoins exchange -func (l *LocalBitcoins) UpdateAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (l *LocalBitcoins) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { var response account.Holdings response.Exchange = l.Name - accountBalance, err := l.GetWalletBalance() + accountBalance, err := l.GetWalletBalance(ctx) if err != nil { return response, err } @@ -286,10 +287,10 @@ func (l *LocalBitcoins) UpdateAccountInfo(assetType asset.Item) (account.Holding } // FetchAccountInfo retrieves balances for all enabled currencies -func (l *LocalBitcoins) FetchAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (l *LocalBitcoins) FetchAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { acc, err := account.GetHoldings(l.Name, assetType) if err != nil { - return l.UpdateAccountInfo(assetType) + return l.UpdateAccountInfo(ctx, assetType) } return acc, nil @@ -297,24 +298,24 @@ func (l *LocalBitcoins) FetchAccountInfo(assetType asset.Item) (account.Holdings // GetFundingHistory returns funding history, deposits and // withdrawals -func (l *LocalBitcoins) GetFundingHistory() ([]exchange.FundHistory, error) { +func (l *LocalBitcoins) GetFundingHistory(ctx context.Context) ([]exchange.FundHistory, error) { return nil, common.ErrFunctionNotSupported } // GetWithdrawalsHistory returns previous withdrawals data -func (l *LocalBitcoins) GetWithdrawalsHistory(c currency.Code) (resp []exchange.WithdrawalHistory, err error) { +func (l *LocalBitcoins) GetWithdrawalsHistory(ctx context.Context, c currency.Code) (resp []exchange.WithdrawalHistory, err error) { return nil, common.ErrNotYetImplemented } // GetRecentTrades returns the most recent trades for a currency and asset -func (l *LocalBitcoins) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade.Data, error) { +func (l *LocalBitcoins) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { var err error p, err = l.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err } var tradeData []Trade - tradeData, err = l.GetTrades(p.Quote.String(), nil) + tradeData, err = l.GetTrades(ctx, p.Quote.String(), nil) if err != nil { return nil, err } @@ -341,12 +342,12 @@ func (l *LocalBitcoins) GetRecentTrades(p currency.Pair, assetType asset.Item) ( } // GetHistoricTrades returns historic trade data within the timeframe provided -func (l *LocalBitcoins) GetHistoricTrades(_ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { +func (l *LocalBitcoins) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { return nil, common.ErrFunctionNotSupported } // SubmitOrder submits a new order -func (l *LocalBitcoins) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { +func (l *LocalBitcoins) SubmitOrder(ctx context.Context, s *order.Submit) (order.SubmitResponse, error) { var submitOrderResponse order.SubmitResponse if err := s.Validate(); err != nil { return submitOrderResponse, err @@ -380,7 +381,7 @@ func (l *LocalBitcoins) SubmitOrder(s *order.Submit) (order.SubmitResponse, erro } // Does not return any orderID, so create the add, then get the order - err = l.CreateAd(¶ms) + err = l.CreateAd(ctx, ¶ms) if err != nil { return submitOrderResponse, err } @@ -390,7 +391,7 @@ func (l *LocalBitcoins) SubmitOrder(s *order.Submit) (order.SubmitResponse, erro // Now to figure out what ad we just submitted // The only details we have are the params above var adID string - ads, err := l.Getads() + ads, err := l.Getads(ctx) for i := range ads.AdList { if ads.AdList[i].Data.PriceEquation == params.PriceEquation && ads.AdList[i].Data.Lat == float64(params.Latitude) && @@ -422,36 +423,36 @@ func (l *LocalBitcoins) SubmitOrder(s *order.Submit) (order.SubmitResponse, erro // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (l *LocalBitcoins) ModifyOrder(action *order.Modify) (order.Modify, error) { +func (l *LocalBitcoins) ModifyOrder(ctx context.Context, action *order.Modify) (order.Modify, error) { return order.Modify{}, common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number -func (l *LocalBitcoins) CancelOrder(o *order.Cancel) error { +func (l *LocalBitcoins) CancelOrder(ctx context.Context, o *order.Cancel) error { if err := o.Validate(o.StandardCancel()); err != nil { return err } - return l.DeleteAd(o.ID) + return l.DeleteAd(ctx, o.ID) } // CancelBatchOrders cancels an orders by their corresponding ID numbers -func (l *LocalBitcoins) CancelBatchOrders(o []order.Cancel) (order.CancelBatchResponse, error) { +func (l *LocalBitcoins) CancelBatchOrders(ctx context.Context, o []order.Cancel) (order.CancelBatchResponse, error) { return order.CancelBatchResponse{}, common.ErrNotYetImplemented } // CancelAllOrders cancels all orders associated with a currency pair -func (l *LocalBitcoins) CancelAllOrders(_ *order.Cancel) (order.CancelAllResponse, error) { +func (l *LocalBitcoins) CancelAllOrders(ctx context.Context, _ *order.Cancel) (order.CancelAllResponse, error) { cancelAllOrdersResponse := order.CancelAllResponse{ Status: make(map[string]string), } - ads, err := l.Getads() + ads, err := l.Getads(ctx) if err != nil { return cancelAllOrdersResponse, err } for i := range ads.AdList { adIDString := strconv.FormatInt(ads.AdList[i].Data.AdID, 10) - err = l.DeleteAd(adIDString) + err = l.DeleteAd(ctx, adIDString) if err != nil { cancelAllOrdersResponse.Status[adIDString] = err.Error() } @@ -461,28 +462,29 @@ func (l *LocalBitcoins) CancelAllOrders(_ *order.Cancel) (order.CancelAllRespons } // GetOrderInfo returns order information based on order ID -func (l *LocalBitcoins) GetOrderInfo(orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { +func (l *LocalBitcoins) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { var orderDetail order.Detail return orderDetail, common.ErrNotYetImplemented } // GetDepositAddress returns a deposit address for a specified currency -func (l *LocalBitcoins) GetDepositAddress(cryptocurrency currency.Code, _ string) (string, error) { +func (l *LocalBitcoins) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _ string) (string, error) { if !strings.EqualFold(currency.BTC.String(), cryptocurrency.String()) { return "", fmt.Errorf("%s does not have support for currency %s, it only supports bitcoin", l.Name, cryptocurrency) } - return l.GetWalletAddress() + return l.GetWalletAddress(ctx) } // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is // submitted -func (l *LocalBitcoins) WithdrawCryptocurrencyFunds(withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (l *LocalBitcoins) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } - err := l.WalletSend(withdrawRequest.Crypto.Address, + err := l.WalletSend(ctx, + withdrawRequest.Crypto.Address, withdrawRequest.Amount, withdrawRequest.PIN) if err != nil { @@ -493,18 +495,18 @@ func (l *LocalBitcoins) WithdrawCryptocurrencyFunds(withdrawRequest *withdraw.Re // WithdrawFiatFunds returns a withdrawal ID when a // withdrawal is submitted -func (l *LocalBitcoins) WithdrawFiatFunds(_ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (l *LocalBitcoins) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a // withdrawal is submitted -func (l *LocalBitcoins) WithdrawFiatFundsToInternationalBank(_ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (l *LocalBitcoins) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // GetFeeByType returns an estimate of fee based on type of transaction -func (l *LocalBitcoins) GetFeeByType(feeBuilder *exchange.FeeBuilder) (float64, error) { +func (l *LocalBitcoins) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { if (!l.AllowAuthenticatedRequest() || l.SkipAuthCheck) && // Todo check connection status feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { feeBuilder.FeeType = exchange.OfflineTradeFee @@ -513,12 +515,12 @@ func (l *LocalBitcoins) GetFeeByType(feeBuilder *exchange.FeeBuilder) (float64, } // GetActiveOrders retrieves any orders that are active/open -func (l *LocalBitcoins) GetActiveOrders(getOrdersRequest *order.GetOrdersRequest) ([]order.Detail, error) { +func (l *LocalBitcoins) GetActiveOrders(ctx context.Context, getOrdersRequest *order.GetOrdersRequest) ([]order.Detail, error) { if err := getOrdersRequest.Validate(); err != nil { return nil, err } - resp, err := l.GetDashboardInfo() + resp, err := l.GetDashboardInfo(ctx) if err != nil { return nil, err } @@ -569,25 +571,25 @@ func (l *LocalBitcoins) GetActiveOrders(getOrdersRequest *order.GetOrdersRequest // GetOrderHistory retrieves account order information // Can Limit response to specific order status -func (l *LocalBitcoins) GetOrderHistory(getOrdersRequest *order.GetOrdersRequest) ([]order.Detail, error) { +func (l *LocalBitcoins) GetOrderHistory(ctx context.Context, getOrdersRequest *order.GetOrdersRequest) ([]order.Detail, error) { if err := getOrdersRequest.Validate(); err != nil { return nil, err } var allTrades []DashBoardInfo - resp, err := l.GetDashboardCancelledTrades() + resp, err := l.GetDashboardCancelledTrades(ctx) if err != nil { return nil, err } allTrades = append(allTrades, resp...) - resp, err = l.GetDashboardClosedTrades() + resp, err = l.GetDashboardClosedTrades(ctx) if err != nil { return nil, err } allTrades = append(allTrades, resp...) - resp, err = l.GetDashboardReleasedTrades() + resp, err = l.GetDashboardReleasedTrades(ctx) if err != nil { return nil, err } @@ -655,17 +657,17 @@ func (l *LocalBitcoins) GetOrderHistory(getOrdersRequest *order.GetOrdersRequest // ValidateCredentials validates current credentials used for wrapper // functionality -func (l *LocalBitcoins) ValidateCredentials(assetType asset.Item) error { - _, err := l.UpdateAccountInfo(assetType) +func (l *LocalBitcoins) ValidateCredentials(ctx context.Context, assetType asset.Item) error { + _, err := l.UpdateAccountInfo(ctx, assetType) return l.CheckTransientError(err) } // GetHistoricCandles returns candles between a time period for a set time interval -func (l *LocalBitcoins) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (l *LocalBitcoins) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { return kline.Item{}, common.ErrFunctionNotSupported } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (l *LocalBitcoins) GetHistoricCandlesExtended(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (l *LocalBitcoins) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { return kline.Item{}, common.ErrFunctionNotSupported } diff --git a/exchanges/mock/server_test.go b/exchanges/mock/server_test.go index 68042057..8cc8ebf4 100644 --- a/exchanges/mock/server_test.go +++ b/exchanges/mock/server_test.go @@ -2,6 +2,7 @@ package mock import ( "bytes" + "context" "encoding/json" "io/ioutil" "net/http" @@ -57,39 +58,45 @@ func TestNewVCRServer(t *testing.T) { t.Error("NewVCRServer error", err) } - common.HTTPClient = client // Set common package global HTTP Client + err = common.SetHTTPClient(client) // Set common package global HTTP Client + if err != nil { + t.Fatal(err) + } - _, err = common.SendHTTPRequest(http.MethodGet, + _, err = common.SendHTTPRequest(context.Background(), + http.MethodGet, "http://localhost:300/somethingElse?"+queryString, nil, - bytes.NewBufferString("")) + bytes.NewBufferString(""), true) if err == nil { t.Error("Sending http request expected an error") } // Expected good outcome - r, err := common.SendHTTPRequest(http.MethodGet, + r, err := common.SendHTTPRequest(context.Background(), + http.MethodGet, deets, nil, - bytes.NewBufferString("")) + bytes.NewBufferString(""), true) if err != nil { t.Error("Sending http request error", err) } - if !strings.Contains(r, "404 page not found") { + if !strings.Contains(string(r), "404 page not found") { t.Error("Was not expecting any value returned:", r) } - r, err = common.SendHTTPRequest(http.MethodGet, + r, err = common.SendHTTPRequest(context.Background(), + http.MethodGet, deets+"/test?"+queryString, nil, - bytes.NewBufferString("")) + bytes.NewBufferString(""), true) if err != nil { t.Error("Sending http request error", err) } var res responsePayload - err = json.Unmarshal([]byte(r), &res) + err = json.Unmarshal(r, &res) if err != nil { t.Error("unmarshal error", err) } diff --git a/exchanges/okcoin/okcoin_test.go b/exchanges/okcoin/okcoin_test.go index ed1797ad..e4cbbc21 100644 --- a/exchanges/okcoin/okcoin_test.go +++ b/exchanges/okcoin/okcoin_test.go @@ -1,6 +1,7 @@ package okcoin import ( + "context" "encoding/json" "log" "net/http" @@ -92,13 +93,13 @@ func testStandardErrorHandling(t *testing.T, err error) { // TestGetAccountCurrencies API endpoint test func TestGetAccountCurrencies(t *testing.T) { - _, err := o.GetAccountCurrencies() + _, err := o.GetAccountCurrencies(context.Background()) testStandardErrorHandling(t, err) } // TestGetAccountWalletInformation API endpoint test func TestGetAccountWalletInformation(t *testing.T) { - resp, err := o.GetAccountWalletInformation("") + resp, err := o.GetAccountWalletInformation(context.Background(), "") if areTestAPIKeysSet() { if err != nil { t.Error(err) @@ -113,7 +114,8 @@ func TestGetAccountWalletInformation(t *testing.T) { // TestGetAccountWalletInformationForCurrency API endpoint test func TestGetAccountWalletInformationForCurrency(t *testing.T) { - resp, err := o.GetAccountWalletInformation(currency.BTC.String()) + resp, err := o.GetAccountWalletInformation(context.Background(), + currency.BTC.String()) if areTestAPIKeysSet() { if err != nil { t.Error(err) @@ -135,7 +137,7 @@ func TestTransferAccountFunds(t *testing.T) { From: 6, To: 1, } - _, err := o.TransferAccountFunds(request) + _, err := o.TransferAccountFunds(context.Background(), request) testStandardErrorHandling(t, err) } @@ -150,13 +152,13 @@ func TestAccountWithdrawRequest(t *testing.T) { ToAddress: core.BitcoinDonationAddress, Fee: 1, } - _, err := o.AccountWithdraw(request) + _, err := o.AccountWithdraw(context.Background(), request) testStandardErrorHandling(t, err) } // TestGetAccountWithdrawalFee API endpoint test func TestGetAccountWithdrawalFee(t *testing.T) { - resp, err := o.GetAccountWithdrawalFee("") + resp, err := o.GetAccountWithdrawalFee(context.Background(), "") if areTestAPIKeysSet() { if err != nil { t.Error(err) @@ -171,7 +173,7 @@ func TestGetAccountWithdrawalFee(t *testing.T) { // TestGetWithdrawalFeeForCurrency API endpoint test func TestGetAccountWithdrawalFeeForCurrency(t *testing.T) { - resp, err := o.GetAccountWithdrawalFee(currency.BTC.String()) + resp, err := o.GetAccountWithdrawalFee(context.Background(), currency.BTC.String()) if areTestAPIKeysSet() { if err != nil { t.Error(err) @@ -186,49 +188,50 @@ func TestGetAccountWithdrawalFeeForCurrency(t *testing.T) { // TestGetAccountWithdrawalHistory API endpoint test func TestGetAccountWithdrawalHistory(t *testing.T) { - _, err := o.GetAccountWithdrawalHistory("") + _, err := o.GetAccountWithdrawalHistory(context.Background(), "") testStandardErrorHandling(t, err) } // TestGetAccountWithdrawalHistoryForCurrency API endpoint test func TestGetAccountWithdrawalHistoryForCurrency(t *testing.T) { - _, err := o.GetAccountWithdrawalHistory(currency.BTC.String()) + _, err := o.GetAccountWithdrawalHistory(context.Background(), currency.BTC.String()) testStandardErrorHandling(t, err) } // TestGetAccountBillDetails API endpoint test func TestGetAccountBillDetails(t *testing.T) { - _, err := o.GetAccountBillDetails(okgroup.GetAccountBillDetailsRequest{}) + _, err := o.GetAccountBillDetails(context.Background(), + okgroup.GetAccountBillDetailsRequest{}) testStandardErrorHandling(t, err) } // TestGetAccountDepositAddressForCurrency API endpoint test func TestGetAccountDepositAddressForCurrency(t *testing.T) { - _, err := o.GetAccountDepositAddressForCurrency(currency.BTC.String()) + _, err := o.GetAccountDepositAddressForCurrency(context.Background(), currency.BTC.String()) testStandardErrorHandling(t, err) } // TestGetAccountDepositHistory API endpoint test func TestGetAccountDepositHistory(t *testing.T) { - _, err := o.GetAccountDepositHistory("") + _, err := o.GetAccountDepositHistory(context.Background(), "") testStandardErrorHandling(t, err) } // TestGetAccountDepositHistoryForCurrency API endpoint test func TestGetAccountDepositHistoryForCurrency(t *testing.T) { - _, err := o.GetAccountDepositHistory(currency.BTC.String()) + _, err := o.GetAccountDepositHistory(context.Background(), currency.BTC.String()) testStandardErrorHandling(t, err) } // TestGetSpotTradingAccounts API endpoint test func TestGetSpotTradingAccounts(t *testing.T) { - _, err := o.GetSpotTradingAccounts() + _, err := o.GetSpotTradingAccounts(context.Background()) testStandardErrorHandling(t, err) } // TestGetSpotTradingAccountsForCurrency API endpoint test func TestGetSpotTradingAccountsForCurrency(t *testing.T) { - _, err := o.GetSpotTradingAccountForCurrency(currency.BTC.String()) + _, err := o.GetSpotTradingAccountForCurrency(context.Background(), currency.BTC.String()) testStandardErrorHandling(t, err) } @@ -238,7 +241,7 @@ func TestGetSpotBillDetailsForCurrency(t *testing.T) { Currency: currency.BTC.String(), Limit: 100, } - _, err := o.GetSpotBillDetailsForCurrency(request) + _, err := o.GetSpotBillDetailsForCurrency(context.Background(), request) testStandardErrorHandling(t, err) } @@ -248,7 +251,7 @@ func TestGetSpotBillDetailsForCurrencyBadLimit(t *testing.T) { Currency: currency.BTC.String(), Limit: -1, } - _, err := o.GetSpotBillDetailsForCurrency(request) + _, err := o.GetSpotBillDetailsForCurrency(context.Background(), request) if areTestAPIKeysSet() && err == nil { t.Errorf("Expecting an error when invalid request sent") } @@ -265,7 +268,7 @@ func TestPlaceSpotOrderLimit(t *testing.T) { Size: "100", } - _, err := o.PlaceSpotOrder(&request) + _, err := o.PlaceSpotOrder(context.Background(), &request) testStandardErrorHandling(t, err) } @@ -280,7 +283,7 @@ func TestPlaceSpotOrderMarket(t *testing.T) { Notional: "100", } - _, err := o.PlaceSpotOrder(&request) + _, err := o.PlaceSpotOrder(context.Background(), &request) testStandardErrorHandling(t, err) } @@ -299,7 +302,7 @@ func TestPlaceMultipleSpotOrders(t *testing.T) { ord, } - _, errs := o.PlaceMultipleSpotOrders(request) + _, errs := o.PlaceMultipleSpotOrders(context.Background(), request) if len(errs) > 0 { testStandardErrorHandling(t, errs[0]) } @@ -323,7 +326,7 @@ func TestPlaceMultipleSpotOrdersOverCurrencyLimits(t *testing.T) { ord, } - _, errs := o.PlaceMultipleSpotOrders(request) + _, errs := o.PlaceMultipleSpotOrders(context.Background(), request) if errs[0].Error() != "maximum 4 orders for each pair" { t.Error("Expecting an error when more than 4 orders for a pair supplied", errs[0]) } @@ -355,7 +358,7 @@ func TestPlaceMultipleSpotOrdersOverPairLimits(t *testing.T) { request = append(request, ord) } - _, errs := o.PlaceMultipleSpotOrders(request) + _, errs := o.PlaceMultipleSpotOrders(context.Background(), request) if errs[0].Error() != "up to 4 trading pairs" { t.Error("Expecting an error when more than 4 trading pairs supplied", errs[0]) } @@ -369,7 +372,7 @@ func TestCancelSpotOrder(t *testing.T) { OrderID: 1234, } - _, err := o.CancelSpotOrder(request) + _, err := o.CancelSpotOrder(context.Background(), request) testStandardErrorHandling(t, err) } @@ -381,7 +384,7 @@ func TestCancelMultipleSpotOrders(t *testing.T) { OrderIDs: []int64{1, 2, 3, 4}, } - cancellations, err := o.CancelMultipleSpotOrders(request) + cancellations, err := o.CancelMultipleSpotOrders(context.Background(), request) testStandardErrorHandling(t, err) for _, cancellationsPerCurrency := range cancellations { for _, cancellation := range cancellationsPerCurrency { @@ -400,7 +403,7 @@ func TestCancelMultipleSpotOrdersOverCurrencyLimits(t *testing.T) { OrderIDs: []int64{1, 2, 3, 4, 5}, } - _, err := o.CancelMultipleSpotOrders(request) + _, err := o.CancelMultipleSpotOrders(context.Background(), request) if err.Error() != "maximum 4 order cancellations for each pair" { t.Error("Expecting an error when more than 4 orders for a pair supplied", err) } @@ -412,14 +415,14 @@ func TestGetSpotOrders(t *testing.T) { InstrumentID: spotCurrency, Status: "all", } - _, err := o.GetSpotOrders(request) + _, err := o.GetSpotOrders(context.Background(), request) testStandardErrorHandling(t, err) } // TestGetSpotOpenOrders API endpoint test func TestGetSpotOpenOrders(t *testing.T) { request := okgroup.GetSpotOpenOrdersRequest{} - _, err := o.GetSpotOpenOrders(request) + _, err := o.GetSpotOpenOrders(context.Background(), request) testStandardErrorHandling(t, err) } @@ -429,7 +432,7 @@ func TestGetSpotOrder(t *testing.T) { OrderID: "-1234", InstrumentID: currency.NewPairWithDelimiter(currency.BTC.String(), currency.USD.String(), "-").Upper().String(), } - _, err := o.GetSpotOrder(request) + _, err := o.GetSpotOrder(context.Background(), request) testStandardErrorHandling(t, err) } @@ -439,13 +442,13 @@ func TestGetSpotTransactionDetails(t *testing.T) { OrderID: 1234, InstrumentID: spotCurrency, } - _, err := o.GetSpotTransactionDetails(request) + _, err := o.GetSpotTransactionDetails(context.Background(), request) testStandardErrorHandling(t, err) } // TestGetSpotTokenPairDetails API endpoint test func TestGetSpotTokenPairDetails(t *testing.T) { - _, err := o.GetSpotTokenPairDetails() + _, err := o.GetSpotTokenPairDetails(context.Background()) if err != nil { t.Error(err) } @@ -453,7 +456,7 @@ func TestGetSpotTokenPairDetails(t *testing.T) { // TestGetSpotAllTokenPairsInformation API endpoint test func TestGetSpotAllTokenPairsInformation(t *testing.T) { - _, err := o.GetSpotAllTokenPairsInformation() + _, err := o.GetSpotAllTokenPairsInformation(context.Background()) if err != nil { t.Error(err) } @@ -461,7 +464,8 @@ func TestGetSpotAllTokenPairsInformation(t *testing.T) { // TestGetSpotAllTokenPairsInformationForCurrency API endpoint test func TestGetSpotAllTokenPairsInformationForCurrency(t *testing.T) { - _, err := o.GetSpotAllTokenPairsInformationForCurrency(spotCurrency) + _, err := o.GetSpotAllTokenPairsInformationForCurrency(context.Background(), + spotCurrency) if err != nil { t.Error(err) } @@ -472,7 +476,7 @@ func TestGetSpotFilledOrdersInformation(t *testing.T) { request := okgroup.GetSpotFilledOrdersInformationRequest{ InstrumentID: spotCurrency, } - _, err := o.GetSpotFilledOrdersInformation(request) + _, err := o.GetSpotFilledOrdersInformation(context.Background(), request) if err != nil { t.Error(err) } @@ -485,7 +489,7 @@ func TestGetSpotMarketData(t *testing.T) { InstrumentID: spotCurrency, Granularity: "604800", } - _, err := o.GetMarketData(request) + _, err := o.GetMarketData(context.Background(), request) if err != nil { t.Error(err) } @@ -493,13 +497,13 @@ func TestGetSpotMarketData(t *testing.T) { // TestGetMarginTradingAccounts API endpoint test func TestGetMarginTradingAccounts(t *testing.T) { - _, err := o.GetMarginTradingAccounts() + _, err := o.GetMarginTradingAccounts(context.Background()) testStandardErrorHandling(t, err) } // TestGetMarginTradingAccountsForCurrency API endpoint test func TestGetMarginTradingAccountsForCurrency(t *testing.T) { - _, err := o.GetMarginTradingAccountsForCurrency(spotCurrency) + _, err := o.GetMarginTradingAccountsForCurrency(context.Background(), spotCurrency) testStandardErrorHandling(t, err) } @@ -509,19 +513,19 @@ func TestGetMarginBillDetails(t *testing.T) { InstrumentID: spotCurrency, Limit: 100, } - _, err := o.GetMarginBillDetails(request) + _, err := o.GetMarginBillDetails(context.Background(), request) testStandardErrorHandling(t, err) } // TestGetMarginAccountSettings API endpoint test func TestGetMarginAccountSettings(t *testing.T) { - _, err := o.GetMarginAccountSettings("") + _, err := o.GetMarginAccountSettings(context.Background(), "") testStandardErrorHandling(t, err) } // TestGetMarginAccountSettingsForCurrency API endpoint test func TestGetMarginAccountSettingsForCurrency(t *testing.T) { - _, err := o.GetMarginAccountSettings(spotCurrency) + _, err := o.GetMarginAccountSettings(context.Background(), spotCurrency) testStandardErrorHandling(t, err) } @@ -534,7 +538,7 @@ func TestOpenMarginLoan(t *testing.T) { QuoteCurrency: currency.USD.String(), } - _, err := o.OpenMarginLoan(request) + _, err := o.OpenMarginLoan(context.Background(), request) testStandardErrorHandling(t, err) } @@ -548,7 +552,7 @@ func TestRepayMarginLoan(t *testing.T) { BorrowID: 1, } - _, err := o.RepayMarginLoan(request) + _, err := o.RepayMarginLoan(context.Background(), request) testStandardErrorHandling(t, err) } @@ -564,7 +568,7 @@ func TestPlaceMarginOrderLimit(t *testing.T) { Size: "100", } - _, err := o.PlaceMarginOrder(&request) + _, err := o.PlaceMarginOrder(context.Background(), &request) testStandardErrorHandling(t, err) } @@ -580,7 +584,7 @@ func TestPlaceMarginOrderMarket(t *testing.T) { Notional: "100", } - _, err := o.PlaceMarginOrder(&request) + _, err := o.PlaceMarginOrder(context.Background(), &request) testStandardErrorHandling(t, err) } @@ -600,7 +604,7 @@ func TestPlaceMultipleMarginOrders(t *testing.T) { ord, } - _, errs := o.PlaceMultipleMarginOrders(request) + _, errs := o.PlaceMultipleMarginOrders(context.Background(), request) if len(errs) > 0 { testStandardErrorHandling(t, errs[0]) } @@ -625,7 +629,7 @@ func TestPlaceMultipleMarginOrdersOverCurrencyLimits(t *testing.T) { ord, } - _, errs := o.PlaceMultipleMarginOrders(request) + _, errs := o.PlaceMultipleMarginOrders(context.Background(), request) if errs[0].Error() != "maximum 4 orders for each pair" { t.Error("Expecting an error when more than 4 orders for a pair supplied", errs[0]) } @@ -658,7 +662,7 @@ func TestPlaceMultipleMarginOrdersOverPairLimits(t *testing.T) { request = append(request, ord) } - _, errs := o.PlaceMultipleMarginOrders(request) + _, errs := o.PlaceMultipleMarginOrders(context.Background(), request) if errs[0].Error() != "up to 4 trading pairs" { t.Error("Expecting an error when more than 4 trading pairs supplied", errs[0]) } @@ -672,7 +676,7 @@ func TestCancelMarginOrder(t *testing.T) { OrderID: 1234, } - _, err := o.CancelMarginOrder(request) + _, err := o.CancelMarginOrder(context.Background(), request) testStandardErrorHandling(t, err) } @@ -684,7 +688,7 @@ func TestCancelMultipleMarginOrders(t *testing.T) { OrderIDs: []int64{1, 2, 3, 4}, } - _, errs := o.CancelMultipleMarginOrders(request) + _, errs := o.CancelMultipleMarginOrders(context.Background(), request) if len(errs) > 0 { testStandardErrorHandling(t, errs[0]) } @@ -698,7 +702,7 @@ func TestCancelMultipleMarginOrdersOverCurrencyLimits(t *testing.T) { OrderIDs: []int64{1, 2, 3, 4, 5}, } - _, errs := o.CancelMultipleMarginOrders(request) + _, errs := o.CancelMultipleMarginOrders(context.Background(), request) if errs[0].Error() != "maximum 4 order cancellations for each pair" { t.Error("Expecting an error when more than 4 orders for a pair supplied", errs[0]) } @@ -710,14 +714,14 @@ func TestGetMarginOrders(t *testing.T) { InstrumentID: spotCurrency, Status: "all", } - _, err := o.GetMarginOrders(request) + _, err := o.GetMarginOrders(context.Background(), request) testStandardErrorHandling(t, err) } // TestGetMarginOpenOrders API endpoint test func TestGetMarginOpenOrders(t *testing.T) { request := okgroup.GetSpotOpenOrdersRequest{} - _, err := o.GetMarginOpenOrders(request) + _, err := o.GetMarginOpenOrders(context.Background(), request) testStandardErrorHandling(t, err) } @@ -727,7 +731,7 @@ func TestGetMarginOrder(t *testing.T) { OrderID: "1234", InstrumentID: currency.NewPairWithDelimiter(currency.BTC.String(), currency.USD.String(), "-").Upper().String(), } - _, err := o.GetMarginOrder(request) + _, err := o.GetMarginOrder(context.Background(), request) testStandardErrorHandling(t, err) } @@ -737,7 +741,7 @@ func TestGetMarginTransactionDetails(t *testing.T) { OrderID: 1234, InstrumentID: spotCurrency, } - _, err := o.GetMarginTransactionDetails(request) + _, err := o.GetMarginTransactionDetails(context.Background(), request) testStandardErrorHandling(t, err) } @@ -879,7 +883,7 @@ func setFeeBuilder() *exchange.FeeBuilder { // TestGetFeeByTypeOfflineTradeFee logic test func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { var feeBuilder = setFeeBuilder() - _, err := o.GetFeeByType(feeBuilder) + _, err := o.GetFeeByType(context.Background(), feeBuilder) if err != nil { t.Fatal(err) } @@ -897,45 +901,45 @@ func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { func TestGetFee(t *testing.T) { var feeBuilder = setFeeBuilder() // CryptocurrencyTradeFee Basic - if _, err := o.GetFee(feeBuilder); err != nil { + if _, err := o.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyTradeFee High quantity feeBuilder = setFeeBuilder() feeBuilder.Amount = 1000 feeBuilder.PurchasePrice = 1000 - if _, err := o.GetFee(feeBuilder); err != nil { + if _, err := o.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyTradeFee IsMaker feeBuilder = setFeeBuilder() feeBuilder.IsMaker = true - if _, err := o.GetFee(feeBuilder); err != nil { + if _, err := o.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyTradeFee Negative purchase price feeBuilder = setFeeBuilder() feeBuilder.PurchasePrice = -1000 - if _, err := o.GetFee(feeBuilder); err != nil { + if _, err := o.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyDepositFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.CryptocurrencyDepositFee - if _, err := o.GetFee(feeBuilder); err != nil { + if _, err := o.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } // InternationalBankDepositFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankDepositFee - if _, err := o.GetFee(feeBuilder); err != nil { + if _, err := o.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } // InternationalBankWithdrawalFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee feeBuilder.FiatCurrency = currency.USD - if _, err := o.GetFee(feeBuilder); err != nil { + if _, err := o.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } } @@ -966,7 +970,7 @@ func TestSubmitOrder(t *testing.T) { ClientID: "meowOrder", AssetType: asset.Spot, } - response, err := o.SubmitOrder(orderSubmission) + response, err := o.SubmitOrder(context.Background(), orderSubmission) if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) { t.Errorf("Order failed to be placed: %v", err) } else if !areTestAPIKeysSet() && err == nil { @@ -985,7 +989,7 @@ func TestCancelExchangeOrder(t *testing.T) { Pair: currencyPair, } - err := o.CancelOrder(&orderCancellation) + err := o.CancelOrder(context.Background(), &orderCancellation) testStandardErrorHandling(t, err) } @@ -1000,7 +1004,7 @@ func TestCancelAllExchangeOrders(t *testing.T) { Pair: currencyPair, } - resp, err := o.CancelAllOrders(&orderCancellation) + resp, err := o.CancelAllOrders(context.Background(), &orderCancellation) testStandardErrorHandling(t, err) if len(resp.Status) > 0 { t.Errorf("%v orders failed to cancel", len(resp.Status)) @@ -1009,14 +1013,15 @@ func TestCancelAllExchangeOrders(t *testing.T) { // TestGetAccountInfo Wrapper test func TestGetAccountInfo(t *testing.T) { - _, err := o.UpdateAccountInfo(asset.Spot) + _, err := o.UpdateAccountInfo(context.Background(), asset.Spot) testStandardErrorHandling(t, err) } // TestModifyOrder Wrapper test func TestModifyOrder(t *testing.T) { TestSetRealOrderDefaults(t) - _, err := o.ModifyOrder(&order.Modify{AssetType: asset.Spot}) + _, err := o.ModifyOrder(context.Background(), + &order.Modify{AssetType: asset.Spot}) if err != common.ErrFunctionNotSupported { t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err) } @@ -1037,7 +1042,8 @@ func TestWithdraw(t *testing.T) { TradePassword: "Password", } - _, err := o.WithdrawCryptocurrencyFunds(&withdrawCryptoRequest) + _, err := o.WithdrawCryptocurrencyFunds(context.Background(), + &withdrawCryptoRequest) testStandardErrorHandling(t, err) } @@ -1045,7 +1051,7 @@ func TestWithdraw(t *testing.T) { func TestWithdrawFiat(t *testing.T) { TestSetRealOrderDefaults(t) var withdrawFiatRequest = withdraw.Request{} - _, err := o.WithdrawFiatFunds(&withdrawFiatRequest) + _, err := o.WithdrawFiatFunds(context.Background(), &withdrawFiatRequest) if err != common.ErrFunctionNotSupported { t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err) } @@ -1055,7 +1061,8 @@ func TestWithdrawFiat(t *testing.T) { func TestWithdrawInternationalBank(t *testing.T) { TestSetRealOrderDefaults(t) var withdrawFiatRequest = withdraw.Request{} - _, err := o.WithdrawFiatFundsToInternationalBank(&withdrawFiatRequest) + _, err := o.WithdrawFiatFundsToInternationalBank(context.Background(), + &withdrawFiatRequest) if err != common.ErrFunctionNotSupported { t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err) } @@ -1064,19 +1071,22 @@ func TestWithdrawInternationalBank(t *testing.T) { // TestGetOrderbook logic test func TestGetOrderbook(t *testing.T) { t.Parallel() - _, err := o.GetOrderBook(okgroup.GetOrderBookRequest{InstrumentID: "BTC-USDT"}, + _, err := o.GetOrderBook(context.Background(), + okgroup.GetOrderBookRequest{InstrumentID: "BTC-USDT"}, asset.Spot) if err != nil { t.Error(err) } - _, err = o.GetOrderBook(okgroup.GetOrderBookRequest{InstrumentID: "Payload"}, + _, err = o.GetOrderBook(context.Background(), + okgroup.GetOrderBookRequest{InstrumentID: "Payload"}, asset.Futures) if err == nil { t.Error("error cannot be nil") } - _, err = o.GetOrderBook(okgroup.GetOrderBookRequest{InstrumentID: "BTC-USD-SWAP"}, + _, err = o.GetOrderBook(context.Background(), + okgroup.GetOrderBookRequest{InstrumentID: "BTC-USD-SWAP"}, asset.PerpetualSwap) if err == nil { t.Error("error cannot be nil") @@ -1089,7 +1099,8 @@ func TestGetHistoricCandles(t *testing.T) { t.Fatal(err) } startTime := time.Unix(1588636800, 0) - _, err = o.GetHistoricCandles(currencyPair, asset.Spot, startTime, time.Now(), kline.OneMin) + _, err = o.GetHistoricCandles(context.Background(), + currencyPair, asset.Spot, startTime, time.Now(), kline.OneMin) if err != nil { t.Fatal(err) } @@ -1101,12 +1112,14 @@ func TestGetHistoricCandlesExtended(t *testing.T) { t.Fatal(err) } startTime := time.Unix(1588636800, 0) - _, err = o.GetHistoricCandlesExtended(currencyPair, asset.Spot, startTime, time.Now(), kline.OneWeek) + _, err = o.GetHistoricCandlesExtended(context.Background(), + currencyPair, asset.Spot, startTime, time.Now(), kline.OneWeek) if err != nil { t.Fatal(err) } - _, err = o.GetHistoricCandles(currencyPair, asset.Spot, startTime, time.Now(), kline.Interval(time.Hour*7)) + _, err = o.GetHistoricCandles(context.Background(), + currencyPair, asset.Spot, startTime, time.Now(), kline.Interval(time.Hour*7)) if err == nil { t.Fatal("unexpected result") } @@ -1118,7 +1131,7 @@ func TestGetRecentTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = o.GetRecentTrades(currencyPair, asset.Spot) + _, err = o.GetRecentTrades(context.Background(), currencyPair, asset.Spot) if err != nil { t.Error(err) } @@ -1130,7 +1143,8 @@ func TestGetHistoricTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = o.GetHistoricTrades(currencyPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) + _, err = o.GetHistoricTrades(context.Background(), + currencyPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) if err != nil && err != common.ErrFunctionNotSupported { t.Error(err) } @@ -1142,7 +1156,7 @@ func TestUpdateTicker(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = o.UpdateTicker(cp, asset.Spot) + _, err = o.UpdateTicker(context.Background(), cp, asset.Spot) if err != nil { t.Error(err) } @@ -1150,7 +1164,7 @@ func TestUpdateTicker(t *testing.T) { func TestUpdateTickers(t *testing.T) { t.Parallel() - err := o.UpdateTickers(asset.Spot) + err := o.UpdateTickers(context.Background(), asset.Spot) if err != nil { t.Error(err) } diff --git a/exchanges/okcoin/okcoin_wrapper.go b/exchanges/okcoin/okcoin_wrapper.go index f68962c5..4db5a447 100644 --- a/exchanges/okcoin/okcoin_wrapper.go +++ b/exchanges/okcoin/okcoin_wrapper.go @@ -1,6 +1,7 @@ package okcoin import ( + "context" "fmt" "sort" "sync" @@ -35,7 +36,7 @@ func (o *OKCoin) GetDefaultConfig() (*config.ExchangeConfig, error) { } if o.Features.Supports.RESTCapabilities.AutoPairUpdates { - err = o.UpdateTradablePairs(true) + err = o.UpdateTradablePairs(context.TODO(), true) if err != nil { return nil, err } @@ -229,7 +230,7 @@ func (o *OKCoin) Run() { return } - err = o.UpdateTradablePairs(forceUpdate) + err = o.UpdateTradablePairs(context.TODO(), forceUpdate) if err != nil { log.Errorf(log.ExchangeSys, "%s failed to update tradable pairs. Err: %s", @@ -239,8 +240,8 @@ func (o *OKCoin) Run() { } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (o *OKCoin) FetchTradablePairs(asset asset.Item) ([]string, error) { - prods, err := o.GetSpotTokenPairDetails() +func (o *OKCoin) FetchTradablePairs(ctx context.Context, asset asset.Item) ([]string, error) { + prods, err := o.GetSpotTokenPairDetails(ctx) if err != nil { return nil, err } @@ -262,8 +263,8 @@ func (o *OKCoin) FetchTradablePairs(asset asset.Item) ([]string, error) { // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (o *OKCoin) UpdateTradablePairs(forceUpdate bool) error { - pairs, err := o.FetchTradablePairs(asset.Spot) +func (o *OKCoin) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { + pairs, err := o.FetchTradablePairs(ctx, asset.Spot) if err != nil { return err } @@ -275,9 +276,9 @@ func (o *OKCoin) UpdateTradablePairs(forceUpdate bool) error { } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (o *OKCoin) UpdateTickers(a asset.Item) error { +func (o *OKCoin) UpdateTickers(ctx context.Context, a asset.Item) error { if a == asset.Spot { - resp, err := o.GetSpotAllTokenPairsInformation() + resp, err := o.GetSpotAllTokenPairsInformation(ctx) if err != nil { return err } @@ -314,8 +315,8 @@ func (o *OKCoin) UpdateTickers(a asset.Item) error { } // UpdateTicker updates and returns the ticker for a currency pair -func (o *OKCoin) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) { - err := o.UpdateTickers(a) +func (o *OKCoin) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { + err := o.UpdateTickers(ctx, a) if err != nil { return nil, err } @@ -323,16 +324,16 @@ func (o *OKCoin) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, err } // FetchTicker returns the ticker for a currency pair -func (o *OKCoin) FetchTicker(p currency.Pair, assetType asset.Item) (tickerData *ticker.Price, err error) { +func (o *OKCoin) FetchTicker(ctx context.Context, p currency.Pair, assetType asset.Item) (tickerData *ticker.Price, err error) { tickerData, err = ticker.GetTicker(o.Name, p, assetType) if err != nil { - return o.UpdateTicker(p, assetType) + return o.UpdateTicker(ctx, p, assetType) } return } // GetRecentTrades returns the most recent trades for a currency and asset -func (o *OKCoin) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade.Data, error) { +func (o *OKCoin) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { var err error p, err = o.FormatExchangeCurrency(p, assetType) if err != nil { @@ -342,9 +343,10 @@ func (o *OKCoin) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade switch assetType { case asset.Spot: var tradeData []okgroup.GetSpotFilledOrdersInformationResponse - tradeData, err = o.GetSpotFilledOrdersInformation(okgroup.GetSpotFilledOrdersInformationRequest{ - InstrumentID: p.String(), - }) + tradeData, err = o.GetSpotFilledOrdersInformation(ctx, + okgroup.GetSpotFilledOrdersInformationRequest{ + InstrumentID: p.String(), + }) if err != nil { return nil, err } @@ -378,6 +380,6 @@ func (o *OKCoin) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade } // CancelBatchOrders cancels an orders by their corresponding ID numbers -func (o *OKCoin) CancelBatchOrders(orders []order.Cancel) (order.CancelBatchResponse, error) { +func (o *OKCoin) CancelBatchOrders(ctx context.Context, orders []order.Cancel) (order.CancelBatchResponse, error) { return order.CancelBatchResponse{}, common.ErrNotYetImplemented } diff --git a/exchanges/okex/okex.go b/exchanges/okex/okex.go index d04a7f6f..cc173527 100644 --- a/exchanges/okex/okex.go +++ b/exchanges/okex/okex.go @@ -1,6 +1,7 @@ package okex import ( + "context" "encoding/json" "errors" "fmt" @@ -61,28 +62,28 @@ type OKEX struct { } // GetSwapMarkets gets perpetual swap markets -func (o *OKEX) GetSwapMarkets() ([]okgroup.SwapInstrumentsData, error) { +func (o *OKEX) GetSwapMarkets(ctx context.Context) ([]okgroup.SwapInstrumentsData, error) { var resp []okgroup.SwapInstrumentsData - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, okGroupSwapInstruments, nil, &resp, false) } // GetSwapInstruments gets perpetual swap instruments data -func (o *OKEX) GetSwapInstruments() ([]okgroup.PerpSwapInstrumentData, error) { +func (o *OKEX) GetSwapInstruments(ctx context.Context) ([]okgroup.PerpSwapInstrumentData, error) { var resp []okgroup.PerpSwapInstrumentData - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, okGroupInstruments, nil, &resp, false) } // GetAllMarginRates gets interest rates for all margin currencies on OKEX -func (o *OKEX) GetAllMarginRates() ([]okgroup.MarginCurrencyData, error) { +func (o *OKEX) GetAllMarginRates(ctx context.Context) ([]okgroup.MarginCurrencyData, error) { var resp []okgroup.MarginCurrencyData var result []map[string]interface{} var tempResp okgroup.MarginCurrencyData tempResp.Data = make(map[string]okgroup.MarginData) - err := o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, + err := o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupMarginSubsection, okGroupMarginPairsData, nil, @@ -126,11 +127,11 @@ func (o *OKEX) GetAllMarginRates() ([]okgroup.MarginCurrencyData, error) { } // GetMarginRates gets interest rates for margin currencies -func (o *OKEX) GetMarginRates(instrumentID currency.Pair) (okgroup.MarginCurrencyData, error) { +func (o *OKEX) GetMarginRates(ctx context.Context, instrumentID currency.Pair) (okgroup.MarginCurrencyData, error) { var resp okgroup.MarginCurrencyData resp.Data = make(map[string]okgroup.MarginData) var result []map[string]interface{} - err := o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, + err := o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupMarginSubsection, fmt.Sprintf(okGroupMarginPairData, instrumentID), nil, @@ -178,410 +179,410 @@ func (o *OKEX) GetMarginRates(instrumentID currency.Pair) (okgroup.MarginCurrenc } // GetSpotMarkets gets perpetual swap markets' data -func (o *OKEX) GetSpotMarkets() ([]okgroup.TradingPairData, error) { +func (o *OKEX) GetSpotMarkets(ctx context.Context) ([]okgroup.TradingPairData, error) { var resp []okgroup.TradingPairData - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupSpotSubsection, okGroupInstruments, nil, &resp, false) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupSpotSubsection, okGroupInstruments, nil, &resp, false) } // GetFundingRate gets funding rate of a given currency -func (o *OKEX) GetFundingRate(marketName, limit string) ([]okgroup.PerpSwapFundingRates, error) { +func (o *OKEX) GetFundingRate(ctx context.Context, marketName, limit string) ([]okgroup.PerpSwapFundingRates, error) { params := url.Values{} params.Set("limit", limit) var resp []okgroup.PerpSwapFundingRates - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, fmt.Sprintf(okGroupPerpSwapRates, marketName)+params.Encode(), nil, &resp, false) } // GetPerpSwapMarkets gets perpetual swap markets' data -func (o *OKEX) GetPerpSwapMarkets() ([]okgroup.TickerData, error) { +func (o *OKEX) GetPerpSwapMarkets(ctx context.Context) ([]okgroup.TickerData, error) { var resp []okgroup.TickerData - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, okGroupPerpTickers, nil, &resp, false) } // GetFuturesPostions Get the information of all holding positions in futures trading. // Due to high energy consumption, you are advised to capture data with the "Futures Account of a Currency" API instead. -func (o *OKEX) GetFuturesPostions() (resp okgroup.GetFuturesPositionsResponse, _ error) { - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupFuturesSubsection, okGroupFuturePosition, nil, &resp, true) +func (o *OKEX) GetFuturesPostions(ctx context.Context) (resp okgroup.GetFuturesPositionsResponse, _ error) { + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupFuturesSubsection, okGroupFuturePosition, nil, &resp, true) } // GetFuturesPostionsForCurrency Get the information of holding positions of a contract. -func (o *OKEX) GetFuturesPostionsForCurrency(instrumentID string) (resp okgroup.GetFuturesPositionsForCurrencyResponse, _ error) { +func (o *OKEX) GetFuturesPostionsForCurrency(ctx context.Context, instrumentID string) (resp okgroup.GetFuturesPositionsForCurrencyResponse, _ error) { requestURL := fmt.Sprintf("%v/%v", instrumentID, okGroupFuturePosition) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupFuturesSubsection, requestURL, nil, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupFuturesSubsection, requestURL, nil, &resp, true) } // GetFuturesAccountOfAllCurrencies Get the futures account info of all token. // Due to high energy consumption, you are advised to capture data with the "Futures Account of a Currency" API instead. -func (o *OKEX) GetFuturesAccountOfAllCurrencies() (resp okgroup.FuturesAccountForAllCurrenciesResponse, _ error) { - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupFuturesSubsection, okgroup.OKGroupAccounts, nil, &resp, true) +func (o *OKEX) GetFuturesAccountOfAllCurrencies(ctx context.Context) (resp okgroup.FuturesAccountForAllCurrenciesResponse, _ error) { + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupFuturesSubsection, okgroup.OKGroupAccounts, nil, &resp, true) } // GetFuturesAccountOfACurrency Get the futures account info of a token. -func (o *OKEX) GetFuturesAccountOfACurrency(instrumentID string) (resp okgroup.FuturesCurrencyData, _ error) { +func (o *OKEX) GetFuturesAccountOfACurrency(ctx context.Context, instrumentID string) (resp okgroup.FuturesCurrencyData, _ error) { requestURL := fmt.Sprintf("%v/%v", okgroup.OKGroupAccounts, instrumentID) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupFuturesSubsection, requestURL, nil, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupFuturesSubsection, requestURL, nil, &resp, true) } // GetFuturesLeverage Get the leverage of the futures account -func (o *OKEX) GetFuturesLeverage(instrumentID string) (resp okgroup.GetFuturesLeverageResponse, _ error) { +func (o *OKEX) GetFuturesLeverage(ctx context.Context, instrumentID string) (resp okgroup.GetFuturesLeverageResponse, _ error) { requestURL := fmt.Sprintf("%v/%v/%v", okgroup.OKGroupAccounts, instrumentID, okGroupFutureLeverage) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupFuturesSubsection, requestURL, nil, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupFuturesSubsection, requestURL, nil, &resp, true) } // SetFuturesLeverage Adjusting the leverage for futures account。 // Cross margin request requirements: {"leverage":"10"} // Fixed margin request requirements: {"instrument_id":"BTC-USD-180213","direction":"long","leverage":"10"} -func (o *OKEX) SetFuturesLeverage(request okgroup.SetFuturesLeverageRequest) (resp okgroup.SetFuturesLeverageResponse, _ error) { +func (o *OKEX) SetFuturesLeverage(ctx context.Context, request okgroup.SetFuturesLeverageRequest) (resp okgroup.SetFuturesLeverageResponse, _ error) { requestURL := fmt.Sprintf("%v/%v/%v", okgroup.OKGroupAccounts, request.Currency, okGroupFutureLeverage) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodPost, okGroupFuturesSubsection, requestURL, request, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, okGroupFuturesSubsection, requestURL, request, &resp, true) } // GetFuturesBillDetails Shows the account’s historical coin in flow and out flow. // All paginated requests return the latest information (newest) as the first page sorted by newest (in chronological time) first. -func (o *OKEX) GetFuturesBillDetails(request okgroup.GetSpotBillDetailsForCurrencyRequest) (resp []okgroup.GetSpotBillDetailsForCurrencyResponse, _ error) { +func (o *OKEX) GetFuturesBillDetails(ctx context.Context, request okgroup.GetSpotBillDetailsForCurrencyRequest) (resp []okgroup.GetSpotBillDetailsForCurrencyResponse, _ error) { requestURL := fmt.Sprintf("%v/%v/%v%v", okgroup.OKGroupAccounts, request.Currency, okgroup.OKGroupLedger, okgroup.FormatParameters(request)) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupFuturesSubsection, requestURL, nil, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupFuturesSubsection, requestURL, nil, &resp, true) } // PlaceFuturesOrder OKEx futures trading only supports limit orders. // You can place an order only if you have enough funds. Once your order is placed, the amount will be put on hold in the order lifecycle. // The assets and amount on hold depends on the order's specific type and parameters. -func (o *OKEX) PlaceFuturesOrder(request okgroup.PlaceFuturesOrderRequest) (resp okgroup.PlaceFuturesOrderResponse, _ error) { - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodPost, okGroupFuturesSubsection, okGroupFutureOrder, request, &resp, true) +func (o *OKEX) PlaceFuturesOrder(ctx context.Context, request okgroup.PlaceFuturesOrderRequest) (resp okgroup.PlaceFuturesOrderResponse, _ error) { + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, okGroupFuturesSubsection, okGroupFutureOrder, request, &resp, true) } // PlaceFuturesOrderBatch Batch contract placing order operation. -func (o *OKEX) PlaceFuturesOrderBatch(request okgroup.PlaceFuturesOrderBatchRequest) (resp okgroup.PlaceFuturesOrderBatchResponse, _ error) { - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodPost, okGroupFuturesSubsection, okgroup.OKGroupOrders, request, &resp, true) +func (o *OKEX) PlaceFuturesOrderBatch(ctx context.Context, request okgroup.PlaceFuturesOrderBatchRequest) (resp okgroup.PlaceFuturesOrderBatchResponse, _ error) { + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, okGroupFuturesSubsection, okgroup.OKGroupOrders, request, &resp, true) } // CancelFuturesOrder Cancelling an unfilled order. -func (o *OKEX) CancelFuturesOrder(request okgroup.CancelFuturesOrderRequest) (resp okgroup.CancelFuturesOrderResponse, _ error) { +func (o *OKEX) CancelFuturesOrder(ctx context.Context, request okgroup.CancelFuturesOrderRequest) (resp okgroup.CancelFuturesOrderResponse, _ error) { requestURL := fmt.Sprintf("%v/%v/%v", okgroup.OKGroupCancelOrder, request.InstrumentID, request.OrderID) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodPost, okGroupFuturesSubsection, requestURL, request, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, okGroupFuturesSubsection, requestURL, request, &resp, true) } // CancelFuturesOrderBatch With best effort, cancel all open orders. -func (o *OKEX) CancelFuturesOrderBatch(request okgroup.CancelMultipleSpotOrdersRequest) (resp okgroup.CancelMultipleSpotOrdersResponse, _ error) { +func (o *OKEX) CancelFuturesOrderBatch(ctx context.Context, request okgroup.CancelMultipleSpotOrdersRequest) (resp okgroup.CancelMultipleSpotOrdersResponse, _ error) { requestURL := fmt.Sprintf("%v/%v", okgroup.OKGroupCancelBatchOrders, request.InstrumentID) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodPost, okGroupFuturesSubsection, requestURL, request, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, okGroupFuturesSubsection, requestURL, request, &resp, true) } // GetFuturesOrderList List your orders. Cursor pagination is used. // All paginated requests return the latest information (newest) as the first page sorted by newest (in chronological time) first. -func (o *OKEX) GetFuturesOrderList(request okgroup.GetFuturesOrdersListRequest) (resp okgroup.GetFuturesOrderListResponse, _ error) { +func (o *OKEX) GetFuturesOrderList(ctx context.Context, request okgroup.GetFuturesOrdersListRequest) (resp okgroup.GetFuturesOrderListResponse, _ error) { requestURL := fmt.Sprintf("%v/%v%v", okgroup.OKGroupOrders, request.InstrumentID, okgroup.FormatParameters(request)) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupFuturesSubsection, requestURL, nil, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupFuturesSubsection, requestURL, nil, &resp, true) } // GetFuturesOrderDetails Get order details by order ID. -func (o *OKEX) GetFuturesOrderDetails(request okgroup.GetFuturesOrderDetailsRequest) (resp okgroup.GetFuturesOrderDetailsResponseData, _ error) { +func (o *OKEX) GetFuturesOrderDetails(ctx context.Context, request okgroup.GetFuturesOrderDetailsRequest) (resp okgroup.GetFuturesOrderDetailsResponseData, _ error) { requestURL := fmt.Sprintf("%v/%v/%v", okgroup.OKGroupOrders, request.InstrumentID, request.OrderID) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupFuturesSubsection, requestURL, nil, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupFuturesSubsection, requestURL, nil, &resp, true) } // GetFuturesTransactionDetails Get details of the recent filled orders. Cursor pagination is used. // All paginated requests return the latest information (newest) as the first page sorted by newest (in chronological time) first. -func (o *OKEX) GetFuturesTransactionDetails(request okgroup.GetFuturesTransactionDetailsRequest) (resp []okgroup.GetFuturesTransactionDetailsResponse, _ error) { +func (o *OKEX) GetFuturesTransactionDetails(ctx context.Context, request okgroup.GetFuturesTransactionDetailsRequest) (resp []okgroup.GetFuturesTransactionDetailsResponse, _ error) { requestURL := fmt.Sprintf("%v%v", okgroup.OKGroupGetSpotTransactionDetails, okgroup.FormatParameters(request)) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupFuturesSubsection, requestURL, nil, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupFuturesSubsection, requestURL, nil, &resp, true) } // GetFuturesContractInformation Get market data. This endpoint provides the snapshots of market data and can be used without verifications. -func (o *OKEX) GetFuturesContractInformation() (resp []okgroup.GetFuturesContractInformationResponse, _ error) { - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupFuturesSubsection, okgroup.OKGroupInstruments, nil, &resp, false) +func (o *OKEX) GetFuturesContractInformation(ctx context.Context) (resp []okgroup.GetFuturesContractInformationResponse, _ error) { + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupFuturesSubsection, okgroup.OKGroupInstruments, nil, &resp, false) } // GetAllFuturesTokenInfo Get the last traded price, best bid/ask price, 24 hour trading volume and more info of all contracts. -func (o *OKEX) GetAllFuturesTokenInfo() (resp []okgroup.GetFuturesTokenInfoResponse, _ error) { +func (o *OKEX) GetAllFuturesTokenInfo(ctx context.Context) (resp []okgroup.GetFuturesTokenInfoResponse, _ error) { requestURL := fmt.Sprintf("%v/%v", okgroup.OKGroupInstruments, okgroup.OKGroupTicker) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupFuturesSubsection, requestURL, nil, &resp, false) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupFuturesSubsection, requestURL, nil, &resp, false) } // GetFuturesTokenInfoForCurrency Get the last traded price, best bid/ask price, 24 hour trading volume and more info of a contract. -func (o *OKEX) GetFuturesTokenInfoForCurrency(instrumentID string) (resp okgroup.GetFuturesTokenInfoResponse, _ error) { +func (o *OKEX) GetFuturesTokenInfoForCurrency(ctx context.Context, instrumentID string) (resp okgroup.GetFuturesTokenInfoResponse, _ error) { requestURL := fmt.Sprintf("%v/%v/%v", okgroup.OKGroupInstruments, instrumentID, okgroup.OKGroupTicker) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupFuturesSubsection, requestURL, nil, &resp, false) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupFuturesSubsection, requestURL, nil, &resp, false) } // GetFuturesFilledOrder Get the recent 300 transactions of all contracts. Pagination is not supported here. // The whole book will be returned for one request. Websocket is recommended here. -func (o *OKEX) GetFuturesFilledOrder(request okgroup.GetFuturesFilledOrderRequest) (resp []okgroup.GetFuturesFilledOrdersResponse, _ error) { +func (o *OKEX) GetFuturesFilledOrder(ctx context.Context, request okgroup.GetFuturesFilledOrderRequest) (resp []okgroup.GetFuturesFilledOrdersResponse, _ error) { requestURL := fmt.Sprintf("%v/%v/%v%v", okgroup.OKGroupInstruments, request.InstrumentID, okgroup.OKGroupTrades, okgroup.FormatParameters(request)) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupFuturesSubsection, requestURL, nil, &resp, false) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupFuturesSubsection, requestURL, nil, &resp, false) } // GetFuturesHoldAmount Get the number of futures with hold. -func (o *OKEX) GetFuturesHoldAmount(instrumentID string) (resp okgroup.GetFuturesHoldAmountResponse, _ error) { +func (o *OKEX) GetFuturesHoldAmount(ctx context.Context, instrumentID string) (resp okgroup.GetFuturesHoldAmountResponse, _ error) { requestURL := fmt.Sprintf("%v/%v/%v", okgroup.OKGroupAccounts, instrumentID, okGroupFutureHolds) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupFuturesSubsection, requestURL, nil, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupFuturesSubsection, requestURL, nil, &resp, true) } // GetFuturesIndices Get Indices of tokens. This is a public endpoint, no identity verification is needed. -func (o *OKEX) GetFuturesIndices(instrumentID string) (resp okgroup.GetFuturesIndicesResponse, _ error) { +func (o *OKEX) GetFuturesIndices(ctx context.Context, instrumentID string) (resp okgroup.GetFuturesIndicesResponse, _ error) { requestURL := fmt.Sprintf("%v/%v/%v", okgroup.OKGroupInstruments, instrumentID, okGroupIndices) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupFuturesSubsection, requestURL, nil, &resp, false) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupFuturesSubsection, requestURL, nil, &resp, false) } // GetFuturesExchangeRates Get the fiat exchange rates. This is a public endpoint, no identity verification is needed. -func (o *OKEX) GetFuturesExchangeRates() (resp okgroup.GetFuturesExchangeRatesResponse, _ error) { - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupFuturesSubsection, okGroupRate, nil, &resp, false) +func (o *OKEX) GetFuturesExchangeRates(ctx context.Context) (resp okgroup.GetFuturesExchangeRatesResponse, _ error) { + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupFuturesSubsection, okGroupRate, nil, &resp, false) } // GetFuturesEstimatedDeliveryPrice the estimated delivery price. It is available 3 hours before delivery. // This is a public endpoint, no identity verification is needed. -func (o *OKEX) GetFuturesEstimatedDeliveryPrice(instrumentID string) (resp okgroup.GetFuturesEstimatedDeliveryPriceResponse, _ error) { +func (o *OKEX) GetFuturesEstimatedDeliveryPrice(ctx context.Context, instrumentID string) (resp okgroup.GetFuturesEstimatedDeliveryPriceResponse, _ error) { requestURL := fmt.Sprintf("%v/%v/%v", okgroup.OKGroupInstruments, instrumentID, okGroupEsimtatedPrice) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupFuturesSubsection, requestURL, nil, &resp, false) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupFuturesSubsection, requestURL, nil, &resp, false) } // GetFuturesOpenInterests Get the open interest of a contract. This is a public endpoint, no identity verification is needed. -func (o *OKEX) GetFuturesOpenInterests(instrumentID string) (resp okgroup.GetFuturesOpenInterestsResponse, _ error) { +func (o *OKEX) GetFuturesOpenInterests(ctx context.Context, instrumentID string) (resp okgroup.GetFuturesOpenInterestsResponse, _ error) { requestURL := fmt.Sprintf("%v/%v/%v", okgroup.OKGroupInstruments, instrumentID, okGroupOpenInterest) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupFuturesSubsection, requestURL, nil, &resp, false) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupFuturesSubsection, requestURL, nil, &resp, false) } // GetFuturesCurrentPriceLimit The maximum buying price and the minimum selling price of the contract. // This is a public endpoint, no identity verification is needed. -func (o *OKEX) GetFuturesCurrentPriceLimit(instrumentID string) (resp okgroup.GetFuturesCurrentPriceLimitResponse, _ error) { +func (o *OKEX) GetFuturesCurrentPriceLimit(ctx context.Context, instrumentID string) (resp okgroup.GetFuturesCurrentPriceLimitResponse, _ error) { requestURL := fmt.Sprintf("%v/%v/%v", okgroup.OKGroupInstruments, instrumentID, okgroup.OKGroupPriceLimit) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupFuturesSubsection, requestURL, nil, &resp, false) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupFuturesSubsection, requestURL, nil, &resp, false) } // GetFuturesCurrentMarkPrice The maximum buying price and the minimum selling price of the contract. // This is a public endpoint, no identity verification is needed. -func (o *OKEX) GetFuturesCurrentMarkPrice(instrumentID string) (resp okgroup.GetFuturesCurrentMarkPriceResponse, _ error) { +func (o *OKEX) GetFuturesCurrentMarkPrice(ctx context.Context, instrumentID string) (resp okgroup.GetFuturesCurrentMarkPriceResponse, _ error) { requestURL := fmt.Sprintf("%v/%v/%v", okgroup.OKGroupInstruments, instrumentID, okgroup.OKGroupMarkPrice) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupFuturesSubsection, requestURL, nil, &resp, false) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupFuturesSubsection, requestURL, nil, &resp, false) } // GetFuturesForceLiquidatedOrders Get force liquidated orders. This is a public endpoint, no identity verification is needed. -func (o *OKEX) GetFuturesForceLiquidatedOrders(request okgroup.GetFuturesForceLiquidatedOrdersRequest) (resp []okgroup.GetFuturesForceLiquidatedOrdersResponse, _ error) { +func (o *OKEX) GetFuturesForceLiquidatedOrders(ctx context.Context, request okgroup.GetFuturesForceLiquidatedOrdersRequest) (resp []okgroup.GetFuturesForceLiquidatedOrdersResponse, _ error) { requestURL := fmt.Sprintf("%v/%v/%v%v", okgroup.OKGroupInstruments, request.InstrumentID, okgroup.OKGroupLiquidation, okgroup.FormatParameters(request)) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupFuturesSubsection, requestURL, nil, &resp, false) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupFuturesSubsection, requestURL, nil, &resp, false) } // GetFuturesTagPrice Get the tag price. This is a public endpoint, no identity verification is needed. -func (o *OKEX) GetFuturesTagPrice(instrumentID string) (resp okgroup.GetFuturesTagPriceResponse, _ error) { +func (o *OKEX) GetFuturesTagPrice(ctx context.Context, instrumentID string) (resp okgroup.GetFuturesTagPriceResponse, _ error) { // OKEX documentation is missing for this endpoint. Guessing "tag_price" for the URL results in 404 return okgroup.GetFuturesTagPriceResponse{}, common.ErrNotYetImplemented } // GetSwapPostions Get the information of all holding positions in swap trading. // Due to high energy consumption, you are advised to capture data with the "Swap Account of a Currency" API instead. -func (o *OKEX) GetSwapPostions() (resp []okgroup.GetSwapPostionsResponse, _ error) { - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, okGroupFuturePosition, nil, &resp, true) +func (o *OKEX) GetSwapPostions(ctx context.Context) (resp []okgroup.GetSwapPostionsResponse, _ error) { + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, okGroupFuturePosition, nil, &resp, true) } // GetSwapPostionsForContract Get the information of holding positions of a contract. -func (o *OKEX) GetSwapPostionsForContract(instrumentID string) (resp okgroup.GetSwapPostionsResponse, _ error) { +func (o *OKEX) GetSwapPostionsForContract(ctx context.Context, instrumentID string) (resp okgroup.GetSwapPostionsResponse, _ error) { requestURL := fmt.Sprintf("%v/%v", instrumentID, okGroupFuturePosition) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, requestURL, nil, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, requestURL, nil, &resp, true) } // GetSwapAccountOfAllCurrency Get the perpetual swap account info of a token. // Margin ratio set as 10,000 when users have no open position. -func (o *OKEX) GetSwapAccountOfAllCurrency() (resp okgroup.GetSwapAccountOfAllCurrencyResponse, _ error) { - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, okgroup.OKGroupAccounts, nil, &resp, true) +func (o *OKEX) GetSwapAccountOfAllCurrency(ctx context.Context) (resp okgroup.GetSwapAccountOfAllCurrencyResponse, _ error) { + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, okgroup.OKGroupAccounts, nil, &resp, true) } // GetSwapAccountSettingsOfAContract Get leverage level and margin mode of a contract. -func (o *OKEX) GetSwapAccountSettingsOfAContract(instrumentID string) (resp okgroup.GetSwapAccountSettingsOfAContractResponse, _ error) { +func (o *OKEX) GetSwapAccountSettingsOfAContract(ctx context.Context, instrumentID string) (resp okgroup.GetSwapAccountSettingsOfAContractResponse, _ error) { requestURL := fmt.Sprintf("%v/%v/%v", okgroup.OKGroupAccounts, instrumentID, okGroupSettings) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, requestURL, nil, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, requestURL, nil, &resp, true) } // SetSwapLeverageLevelOfAContract Setting the leverage level of a contract // TODO this returns invalid parameters, but matches spec. Unsure how to fix -func (o *OKEX) SetSwapLeverageLevelOfAContract(request okgroup.SetSwapLeverageLevelOfAContractRequest) (resp okgroup.SetSwapLeverageLevelOfAContractResponse, _ error) { +func (o *OKEX) SetSwapLeverageLevelOfAContract(ctx context.Context, request okgroup.SetSwapLeverageLevelOfAContractRequest) (resp okgroup.SetSwapLeverageLevelOfAContractResponse, _ error) { requestURL := fmt.Sprintf("%v/%v/%v", okgroup.OKGroupAccounts, request.InstrumentID, okGroupFutureLeverage) request.InstrumentID = "" - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodPost, okGroupSwapSubsection, requestURL, request, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, okGroupSwapSubsection, requestURL, request, &resp, true) } // GetSwapBillDetails Shows the account’s historical coin in flow and out flow. // All paginated requests return the latest information (newest) as the first page sorted by newest (in chronological time) first. -func (o *OKEX) GetSwapBillDetails(request okgroup.GetSpotBillDetailsForCurrencyRequest) (resp []okgroup.GetSwapBillDetailsResponse, _ error) { +func (o *OKEX) GetSwapBillDetails(ctx context.Context, request okgroup.GetSpotBillDetailsForCurrencyRequest) (resp []okgroup.GetSwapBillDetailsResponse, _ error) { requestURL := fmt.Sprintf("%v/%v/%v%v", okgroup.OKGroupAccounts, request.Currency, okgroup.OKGroupLedger, okgroup.FormatParameters(request)) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, requestURL, nil, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, requestURL, nil, &resp, true) } // PlaceSwapOrder OKEx perpetual swap trading only supports limit orders,USD as quote currency for orders. // You can place an order only if you have enough funds. Once your order is placed, the amount will be put on hold in the order lifecycle. // The assets and amount on hold depends on the order's specific type and parameters. -func (o *OKEX) PlaceSwapOrder(request okgroup.PlaceSwapOrderRequest) (resp okgroup.PlaceSwapOrderResponse, _ error) { - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodPost, okGroupSwapSubsection, okGroupFutureOrder, request, &resp, true) +func (o *OKEX) PlaceSwapOrder(ctx context.Context, request okgroup.PlaceSwapOrderRequest) (resp okgroup.PlaceSwapOrderResponse, _ error) { + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, okGroupSwapSubsection, okGroupFutureOrder, request, &resp, true) } // PlaceMultipleSwapOrders Batch contract placing order operation. -func (o *OKEX) PlaceMultipleSwapOrders(request okgroup.PlaceMultipleSwapOrdersRequest) (resp okgroup.PlaceMultipleSwapOrdersResponse, _ error) { - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodPost, okGroupSwapSubsection, okgroup.OKGroupOrders, request, &resp, true) +func (o *OKEX) PlaceMultipleSwapOrders(ctx context.Context, request okgroup.PlaceMultipleSwapOrdersRequest) (resp okgroup.PlaceMultipleSwapOrdersResponse, _ error) { + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, okGroupSwapSubsection, okgroup.OKGroupOrders, request, &resp, true) } // CancelSwapOrder Cancelling an unfilled order -func (o *OKEX) CancelSwapOrder(request okgroup.CancelSwapOrderRequest) (resp okgroup.CancelSwapOrderResponse, _ error) { +func (o *OKEX) CancelSwapOrder(ctx context.Context, request okgroup.CancelSwapOrderRequest) (resp okgroup.CancelSwapOrderResponse, _ error) { requestURL := fmt.Sprintf("%v/%v/%v", okgroup.OKGroupCancelOrder, request.InstrumentID, request.OrderID) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodPost, okGroupSwapSubsection, requestURL, nil, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, okGroupSwapSubsection, requestURL, nil, &resp, true) } // CancelMultipleSwapOrders With best effort, cancel all open orders. -func (o *OKEX) CancelMultipleSwapOrders(request okgroup.CancelMultipleSwapOrdersRequest) (resp okgroup.CancelMultipleSwapOrdersResponse, _ error) { +func (o *OKEX) CancelMultipleSwapOrders(ctx context.Context, request okgroup.CancelMultipleSwapOrdersRequest) (resp okgroup.CancelMultipleSwapOrdersResponse, _ error) { requestURL := fmt.Sprintf("%v/%v", okgroup.OKGroupCancelBatchOrders, request.InstrumentID) request.InstrumentID = "" - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodPost, okGroupSwapSubsection, requestURL, request, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, okGroupSwapSubsection, requestURL, request, &resp, true) } // GetSwapOrderList List your orders. Cursor pagination is used. // All paginated requests return the latest information (newest) as the first page sorted by newest (in chronological time) first. -func (o *OKEX) GetSwapOrderList(request okgroup.GetSwapOrderListRequest) (resp okgroup.GetSwapOrderListResponse, _ error) { +func (o *OKEX) GetSwapOrderList(ctx context.Context, request okgroup.GetSwapOrderListRequest) (resp okgroup.GetSwapOrderListResponse, _ error) { requestURL := fmt.Sprintf("%v/%v%v", okgroup.OKGroupOrders, request.InstrumentID, okgroup.FormatParameters(request)) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, requestURL, nil, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, requestURL, nil, &resp, true) } // GetSwapOrderDetails Get order details by order ID. -func (o *OKEX) GetSwapOrderDetails(request okgroup.GetSwapOrderDetailsRequest) (resp okgroup.GetSwapOrderListResponseData, _ error) { +func (o *OKEX) GetSwapOrderDetails(ctx context.Context, request okgroup.GetSwapOrderDetailsRequest) (resp okgroup.GetSwapOrderListResponseData, _ error) { requestURL := fmt.Sprintf("%v/%v/%v", okgroup.OKGroupOrders, request.InstrumentID, request.OrderID) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, requestURL, nil, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, requestURL, nil, &resp, true) } // GetSwapTransactionDetails Get details of the recent filled orders -func (o *OKEX) GetSwapTransactionDetails(request okgroup.GetSwapTransactionDetailsRequest) (resp []okgroup.GetSwapTransactionDetailsResponse, _ error) { +func (o *OKEX) GetSwapTransactionDetails(ctx context.Context, request okgroup.GetSwapTransactionDetailsRequest) (resp []okgroup.GetSwapTransactionDetailsResponse, _ error) { requestURL := fmt.Sprintf("%v%v", okgroup.OKGroupGetSpotTransactionDetails, okgroup.FormatParameters(request)) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, requestURL, nil, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, requestURL, nil, &resp, true) } // GetSwapContractInformation Get market data. -func (o *OKEX) GetSwapContractInformation() (resp []okgroup.GetSwapContractInformationResponse, _ error) { - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, okgroup.OKGroupInstruments, nil, &resp, false) +func (o *OKEX) GetSwapContractInformation(ctx context.Context) (resp []okgroup.GetSwapContractInformationResponse, _ error) { + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, okgroup.OKGroupInstruments, nil, &resp, false) } // GetAllSwapTokensInformation Get the last traded price, best bid/ask price, 24 hour trading volume and more info of all contracts. -func (o *OKEX) GetAllSwapTokensInformation() (resp []okgroup.GetAllSwapTokensInformationResponse, _ error) { +func (o *OKEX) GetAllSwapTokensInformation(ctx context.Context) (resp []okgroup.GetAllSwapTokensInformationResponse, _ error) { requestURL := fmt.Sprintf("%v/%v", okgroup.OKGroupInstruments, okgroup.OKGroupTicker) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, requestURL, nil, &resp, false) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, requestURL, nil, &resp, false) } // GetSwapTokensInformationForCurrency Get the last traded price, best bid/ask price, 24 hour trading volume and more info of all contracts. -func (o *OKEX) GetSwapTokensInformationForCurrency(instrumentID string) (resp okgroup.GetAllSwapTokensInformationResponse, _ error) { +func (o *OKEX) GetSwapTokensInformationForCurrency(ctx context.Context, instrumentID string) (resp okgroup.GetAllSwapTokensInformationResponse, _ error) { requestURL := fmt.Sprintf("%v/%v/%v", okgroup.OKGroupInstruments, instrumentID, okgroup.OKGroupTicker) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, requestURL, nil, &resp, false) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, requestURL, nil, &resp, false) } // GetSwapFilledOrdersData Get details of the recent filled orders -func (o *OKEX) GetSwapFilledOrdersData(request *okgroup.GetSwapFilledOrdersDataRequest) (resp []okgroup.GetSwapFilledOrdersDataResponse, _ error) { +func (o *OKEX) GetSwapFilledOrdersData(ctx context.Context, request *okgroup.GetSwapFilledOrdersDataRequest) (resp []okgroup.GetSwapFilledOrdersDataResponse, _ error) { requestURL := fmt.Sprintf("%v/%v/%v%v", okgroup.OKGroupInstruments, request.InstrumentID, okgroup.OKGroupTrades, okgroup.FormatParameters(request)) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, requestURL, nil, &resp, false) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, requestURL, nil, &resp, false) } // GetSwapIndices Get Indices of tokens. -func (o *OKEX) GetSwapIndices(instrumentID string) (resp okgroup.GetSwapIndecesResponse, _ error) { +func (o *OKEX) GetSwapIndices(ctx context.Context, instrumentID string) (resp okgroup.GetSwapIndecesResponse, _ error) { requestURL := fmt.Sprintf("%v/%v/%v", okgroup.OKGroupInstruments, instrumentID, okGroupIndices) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, requestURL, nil, &resp, false) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, requestURL, nil, &resp, false) } // GetSwapExchangeRates Get the fiat exchange rates. -func (o *OKEX) GetSwapExchangeRates() (resp okgroup.GetSwapExchangeRatesResponse, _ error) { - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, okGroupRate, nil, &resp, false) +func (o *OKEX) GetSwapExchangeRates(ctx context.Context) (resp okgroup.GetSwapExchangeRatesResponse, _ error) { + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, okGroupRate, nil, &resp, false) } // GetSwapOpenInterest Get the open interest of a contract. -func (o *OKEX) GetSwapOpenInterest(instrumentID string) (resp okgroup.GetSwapExchangeRatesResponse, _ error) { +func (o *OKEX) GetSwapOpenInterest(ctx context.Context, instrumentID string) (resp okgroup.GetSwapExchangeRatesResponse, _ error) { requestURL := fmt.Sprintf("%v/%v/%v", okgroup.OKGroupInstruments, instrumentID, okGroupOpenInterest) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, requestURL, nil, &resp, false) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, requestURL, nil, &resp, false) } // GetSwapCurrentPriceLimits Get the open interest of a contract. -func (o *OKEX) GetSwapCurrentPriceLimits(instrumentID string) (resp okgroup.GetSwapCurrentPriceLimitsResponse, _ error) { +func (o *OKEX) GetSwapCurrentPriceLimits(ctx context.Context, instrumentID string) (resp okgroup.GetSwapCurrentPriceLimitsResponse, _ error) { requestURL := fmt.Sprintf("%v/%v/%v", okgroup.OKGroupInstruments, instrumentID, okgroup.OKGroupPriceLimit) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, requestURL, nil, &resp, false) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, requestURL, nil, &resp, false) } // GetSwapForceLiquidatedOrders Get force liquidated orders. -func (o *OKEX) GetSwapForceLiquidatedOrders(request okgroup.GetSwapForceLiquidatedOrdersRequest) (resp []okgroup.GetSwapForceLiquidatedOrdersResponse, _ error) { +func (o *OKEX) GetSwapForceLiquidatedOrders(ctx context.Context, request okgroup.GetSwapForceLiquidatedOrdersRequest) (resp []okgroup.GetSwapForceLiquidatedOrdersResponse, _ error) { requestURL := fmt.Sprintf("%v/%v/%v%v", okgroup.OKGroupInstruments, request.InstrumentID, okgroup.OKGroupLiquidation, okgroup.FormatParameters(request)) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, requestURL, nil, &resp, false) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, requestURL, nil, &resp, false) } // GetSwapOnHoldAmountForOpenOrders Get On Hold Amount for Open Orders. -func (o *OKEX) GetSwapOnHoldAmountForOpenOrders(instrumentID string) (resp okgroup.GetSwapOnHoldAmountForOpenOrdersResponse, _ error) { +func (o *OKEX) GetSwapOnHoldAmountForOpenOrders(ctx context.Context, instrumentID string) (resp okgroup.GetSwapOnHoldAmountForOpenOrdersResponse, _ error) { requestURL := fmt.Sprintf("%v/%v/%v", okgroup.OKGroupAccounts, instrumentID, okGroupFutureHolds) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, requestURL, nil, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, requestURL, nil, &resp, true) } // GetSwapNextSettlementTime Get the time of next settlement. -func (o *OKEX) GetSwapNextSettlementTime(instrumentID string) (resp okgroup.GetSwapNextSettlementTimeResponse, _ error) { +func (o *OKEX) GetSwapNextSettlementTime(ctx context.Context, instrumentID string) (resp okgroup.GetSwapNextSettlementTimeResponse, _ error) { requestURL := fmt.Sprintf("%v/%v/%v", okgroup.OKGroupInstruments, instrumentID, okGroupFundingTime) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, requestURL, nil, &resp, false) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, requestURL, nil, &resp, false) } // GetSwapMarkPrice Get the time of next settlement. -func (o *OKEX) GetSwapMarkPrice(instrumentID string) (resp okgroup.GetSwapMarkPriceResponse, _ error) { +func (o *OKEX) GetSwapMarkPrice(ctx context.Context, instrumentID string) (resp okgroup.GetSwapMarkPriceResponse, _ error) { requestURL := fmt.Sprintf("%v/%v/%v", okgroup.OKGroupInstruments, instrumentID, okgroup.OKGroupMarkPrice) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, requestURL, nil, &resp, false) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, requestURL, nil, &resp, false) } // GetSwapFundingRateHistory Get Funding Rate History. -func (o *OKEX) GetSwapFundingRateHistory(request okgroup.GetSwapFundingRateHistoryRequest) (resp []okgroup.GetSwapFundingRateHistoryResponse, _ error) { +func (o *OKEX) GetSwapFundingRateHistory(ctx context.Context, request okgroup.GetSwapFundingRateHistoryRequest) (resp []okgroup.GetSwapFundingRateHistoryResponse, _ error) { requestURL := fmt.Sprintf("%v/%v/%v%v", okgroup.OKGroupInstruments, request.InstrumentID, okGroupHistoricalFundingRate, okgroup.FormatParameters(request)) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, requestURL, nil, &resp, false) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupSwapSubsection, requestURL, nil, &resp, false) } // GetETT List the assets in ETT account. Get information such as balance, amount on hold/ available. -func (o *OKEX) GetETT() (resp []okgroup.GetETTResponse, _ error) { - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupETTSubsection, okgroup.OKGroupAccounts, nil, &resp, true) +func (o *OKEX) GetETT(ctx context.Context) (resp []okgroup.GetETTResponse, _ error) { + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupETTSubsection, okgroup.OKGroupAccounts, nil, &resp, true) } // GetETTAccountInformationForCurrency Getting the balance, amount available/on hold of a token in ETT account. -func (o *OKEX) GetETTAccountInformationForCurrency(currency string) (resp okgroup.GetETTResponse, _ error) { +func (o *OKEX) GetETTAccountInformationForCurrency(ctx context.Context, currency string) (resp okgroup.GetETTResponse, _ error) { requestURL := fmt.Sprintf("%v/%v", okgroup.OKGroupAccounts, currency) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupETTSubsection, requestURL, nil, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupETTSubsection, requestURL, nil, &resp, true) } // GetETTBillsDetails Bills details. All paginated requests return the latest information (newest) // as the first page sorted by newest (in chronological time) first -func (o *OKEX) GetETTBillsDetails(currency string) (resp []okgroup.GetETTBillsDetailsResponse, _ error) { +func (o *OKEX) GetETTBillsDetails(ctx context.Context, currency string) (resp []okgroup.GetETTBillsDetailsResponse, _ error) { requestURL := fmt.Sprintf("%v/%v/%v", okgroup.OKGroupAccounts, currency, okgroup.OKGroupLedger) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupETTSubsection, requestURL, nil, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupETTSubsection, requestURL, nil, &resp, true) } // PlaceETTOrder You can place subscription or redemption orders under ETT trading. // You can place an order only if you have enough funds. Once your order is placed, // the amount will be put on hold in the order lifecycle. // The assets and amount on hold depends on the order's specific type and parameters. -func (o *OKEX) PlaceETTOrder(request *okgroup.PlaceETTOrderRequest) (resp okgroup.PlaceETTOrderResponse, _ error) { - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodPost, okGroupETTSubsection, okgroup.OKGroupOrders, nil, &resp, true) +func (o *OKEX) PlaceETTOrder(ctx context.Context, request *okgroup.PlaceETTOrderRequest) (resp okgroup.PlaceETTOrderResponse, _ error) { + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, okGroupETTSubsection, okgroup.OKGroupOrders, nil, &resp, true) } // CancelETTOrder Cancel an unfilled order. -func (o *OKEX) CancelETTOrder(orderID string) (resp okgroup.PlaceETTOrderResponse, _ error) { +func (o *OKEX) CancelETTOrder(ctx context.Context, orderID string) (resp okgroup.PlaceETTOrderResponse, _ error) { requestURL := fmt.Sprintf("%v/%v", okgroup.OKGroupOrders, orderID) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodDelete, okGroupETTSubsection, requestURL, nil, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodDelete, okGroupETTSubsection, requestURL, nil, &resp, true) } // GetETTOrderList List your orders. Cursor pagination is used. All paginated requests return the latest information // (newest) as the first page sorted by newest (in chronological time) first. -func (o *OKEX) GetETTOrderList(request okgroup.GetETTOrderListRequest) (resp []okgroup.GetETTOrderListResponse, _ error) { +func (o *OKEX) GetETTOrderList(ctx context.Context, request okgroup.GetETTOrderListRequest) (resp []okgroup.GetETTOrderListResponse, _ error) { requestURL := fmt.Sprintf("%v%v", okgroup.OKGroupOrders, okgroup.FormatParameters(request)) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupETTSubsection, requestURL, nil, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupETTSubsection, requestURL, nil, &resp, true) } // GetETTOrderDetails Get order details by order ID. -func (o *OKEX) GetETTOrderDetails(orderID string) (resp okgroup.GetETTOrderListResponse, _ error) { +func (o *OKEX) GetETTOrderDetails(ctx context.Context, orderID string) (resp okgroup.GetETTOrderListResponse, _ error) { requestURL := fmt.Sprintf("%v/%v", okgroup.OKGroupOrders, orderID) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupETTSubsection, requestURL, nil, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupETTSubsection, requestURL, nil, &resp, true) } // GetETTConstituents Get ETT Constituents.This is a public endpoint, no identity verification is needed. -func (o *OKEX) GetETTConstituents(ett string) (resp okgroup.GetETTConstituentsResponse, _ error) { +func (o *OKEX) GetETTConstituents(ctx context.Context, ett string) (resp okgroup.GetETTConstituentsResponse, _ error) { requestURL := fmt.Sprintf("%v/%v", okGroupConstituents, ett) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupETTSubsection, requestURL, nil, &resp, false) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupETTSubsection, requestURL, nil, &resp, false) } // GetETTSettlementPriceHistory Get ETT settlement price history. This is a public endpoint, no identity verification is needed. -func (o *OKEX) GetETTSettlementPriceHistory(ett string) (resp []okgroup.GetETTSettlementPriceHistoryResponse, _ error) { +func (o *OKEX) GetETTSettlementPriceHistory(ctx context.Context, ett string) (resp []okgroup.GetETTSettlementPriceHistoryResponse, _ error) { requestURL := fmt.Sprintf("%v/%v", okGroupDefinePrice, ett) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupETTSubsection, requestURL, nil, &resp, false) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupETTSubsection, requestURL, nil, &resp, false) } diff --git a/exchanges/okex/okex_test.go b/exchanges/okex/okex_test.go index 474a298f..46520ba2 100644 --- a/exchanges/okex/okex_test.go +++ b/exchanges/okex/okex_test.go @@ -1,6 +1,7 @@ package okex import ( + "context" "encoding/json" "fmt" "log" @@ -81,7 +82,7 @@ func areTestAPIKeysSet() bool { } func TestUpdateOrderbook(t *testing.T) { - tradablePairs, err := o.FetchTradablePairs(asset.Futures) + tradablePairs, err := o.FetchTradablePairs(context.Background(), asset.Futures) if err != nil { t.Error(err) } @@ -100,7 +101,7 @@ func TestUpdateOrderbook(t *testing.T) { if err != nil { t.Error(err) } - _, err = o.UpdateOrderbook(cp, asset.Futures) + _, err = o.UpdateOrderbook(context.Background(), cp, asset.Futures) if err != nil { t.Error(err) } @@ -108,7 +109,7 @@ func TestUpdateOrderbook(t *testing.T) { if err != nil { t.Error(err) } - _, err = o.UpdateOrderbook(cp, asset.PerpetualSwap) + _, err = o.UpdateOrderbook(context.Background(), cp, asset.PerpetualSwap) if err != nil { t.Error(err) } @@ -116,7 +117,7 @@ func TestUpdateOrderbook(t *testing.T) { if err != nil { t.Error(err) } - _, err = o.UpdateOrderbook(cp, asset.Spot) + _, err = o.UpdateOrderbook(context.Background(), cp, asset.Spot) if err != nil { t.Error(err) } @@ -126,7 +127,7 @@ func TestGetAllMarginRates(t *testing.T) { if !areTestAPIKeysSet() { t.Skip("skipping test: api keys not set") } - _, err := o.GetAllMarginRates() + _, err := o.GetAllMarginRates(context.Background()) if err != nil { t.Error(err) } @@ -140,7 +141,7 @@ func TestGetMarginRates(t *testing.T) { if err != nil { t.Error(err) } - _, err = o.GetMarginRates(cp) + _, err = o.GetMarginRates(context.Background(), cp) if err != nil { t.Error(err) } @@ -148,7 +149,7 @@ func TestGetMarginRates(t *testing.T) { func TestGetSpotMarkets(t *testing.T) { t.Parallel() - _, err := o.GetSpotMarkets() + _, err := o.GetSpotMarkets(context.Background()) if err != nil { t.Error(err) } @@ -156,7 +157,7 @@ func TestGetSpotMarkets(t *testing.T) { func TestGetSwapInstruments(t *testing.T) { t.Parallel() - _, err := o.GetSwapInstruments() + _, err := o.GetSwapInstruments(context.Background()) if err != nil { t.Error(err) } @@ -164,7 +165,7 @@ func TestGetSwapInstruments(t *testing.T) { func TestGetSwapMarkets(t *testing.T) { t.Parallel() - _, err := o.GetSwapMarkets() + _, err := o.GetSwapMarkets(context.Background()) if err != nil { t.Error(err) } @@ -172,14 +173,14 @@ func TestGetSwapMarkets(t *testing.T) { func TestGetFundingRate(t *testing.T) { t.Parallel() - _, err := o.GetFundingRate("BTC-USD-SWAP", "1") + _, err := o.GetFundingRate(context.Background(), "BTC-USD-SWAP", "1") if err != nil { t.Error(err) } } func TestGetPerpSwapMarkets(t *testing.T) { - _, err := o.GetPerpSwapMarkets() + _, err := o.GetPerpSwapMarkets(context.Background()) if err != nil { t.Error(err) } @@ -197,14 +198,14 @@ func testStandardErrorHandling(t *testing.T, err error) { // TestGetAccountCurrencies API endpoint test func TestGetAccountCurrencies(t *testing.T) { t.Parallel() - _, err := o.GetAccountCurrencies() + _, err := o.GetAccountCurrencies(context.Background()) testStandardErrorHandling(t, err) } // TestGetAccountWalletInformation API endpoint test func TestGetAccountWalletInformation(t *testing.T) { t.Parallel() - resp, err := o.GetAccountWalletInformation("") + resp, err := o.GetAccountWalletInformation(context.Background(), "") if areTestAPIKeysSet() { if err != nil { t.Error(err) @@ -220,7 +221,7 @@ func TestGetAccountWalletInformation(t *testing.T) { // TestGetAccountWalletInformationForCurrency API endpoint test func TestGetAccountWalletInformationForCurrency(t *testing.T) { t.Parallel() - resp, err := o.GetAccountWalletInformation(currency.BTC.String()) + resp, err := o.GetAccountWalletInformation(context.Background(), currency.BTC.String()) if areTestAPIKeysSet() { if err != nil { t.Error(err) @@ -244,7 +245,7 @@ func TestTransferAccountFunds(t *testing.T) { To: -1, } - _, err := o.TransferAccountFunds(request) + _, err := o.TransferAccountFunds(context.Background(), request) testStandardErrorHandling(t, err) } @@ -261,14 +262,14 @@ func TestAccountWithdrawRequest(t *testing.T) { Fee: 1, } - _, err := o.AccountWithdraw(request) + _, err := o.AccountWithdraw(context.Background(), request) testStandardErrorHandling(t, err) } // TestGetAccountWithdrawalFee API endpoint test func TestGetAccountWithdrawalFee(t *testing.T) { t.Parallel() - resp, err := o.GetAccountWithdrawalFee("") + resp, err := o.GetAccountWithdrawalFee(context.Background(), "") if areTestAPIKeysSet() { if err != nil { t.Error(err) @@ -284,7 +285,7 @@ func TestGetAccountWithdrawalFee(t *testing.T) { // TestGetWithdrawalFeeForCurrency API endpoint test func TestGetAccountWithdrawalFeeForCurrency(t *testing.T) { t.Parallel() - resp, err := o.GetAccountWithdrawalFee(currency.BTC.String()) + resp, err := o.GetAccountWithdrawalFee(context.Background(), currency.BTC.String()) if areTestAPIKeysSet() { if err != nil { t.Error(err) @@ -300,56 +301,59 @@ func TestGetAccountWithdrawalFeeForCurrency(t *testing.T) { // TestGetAccountWithdrawalHistory API endpoint test func TestGetAccountWithdrawalHistory(t *testing.T) { t.Parallel() - _, err := o.GetAccountWithdrawalHistory("") + _, err := o.GetAccountWithdrawalHistory(context.Background(), "") testStandardErrorHandling(t, err) } // TestGetAccountWithdrawalHistoryForCurrency API endpoint test func TestGetAccountWithdrawalHistoryForCurrency(t *testing.T) { t.Parallel() - _, err := o.GetAccountWithdrawalHistory(currency.BTC.String()) + _, err := o.GetAccountWithdrawalHistory(context.Background(), currency.BTC.String()) testStandardErrorHandling(t, err) } // TestGetAccountBillDetails API endpoint test func TestGetAccountBillDetails(t *testing.T) { t.Parallel() - _, err := o.GetAccountBillDetails(okgroup.GetAccountBillDetailsRequest{}) + _, err := o.GetAccountBillDetails(context.Background(), + okgroup.GetAccountBillDetailsRequest{}) testStandardErrorHandling(t, err) } // TestGetAccountDepositAddressForCurrency API endpoint test func TestGetAccountDepositAddressForCurrency(t *testing.T) { t.Parallel() - _, err := o.GetAccountDepositAddressForCurrency(currency.BTC.String()) + _, err := o.GetAccountDepositAddressForCurrency(context.Background(), + currency.BTC.String()) testStandardErrorHandling(t, err) } // TestGetAccountDepositHistory API endpoint test func TestGetAccountDepositHistory(t *testing.T) { t.Parallel() - _, err := o.GetAccountDepositHistory("") + _, err := o.GetAccountDepositHistory(context.Background(), "") testStandardErrorHandling(t, err) } // TestGetAccountDepositHistoryForCurrency API endpoint test func TestGetAccountDepositHistoryForCurrency(t *testing.T) { t.Parallel() - _, err := o.GetAccountDepositHistory(currency.BTC.String()) + _, err := o.GetAccountDepositHistory(context.Background(), currency.BTC.String()) testStandardErrorHandling(t, err) } // TestGetSpotTradingAccounts API endpoint test func TestGetSpotTradingAccounts(t *testing.T) { t.Parallel() - _, err := o.GetSpotTradingAccounts() + _, err := o.GetSpotTradingAccounts(context.Background()) testStandardErrorHandling(t, err) } // TestGetSpotTradingAccountsForCurrency API endpoint test func TestGetSpotTradingAccountsForCurrency(t *testing.T) { t.Parallel() - _, err := o.GetSpotTradingAccountForCurrency(currency.BTC.String()) + _, err := o.GetSpotTradingAccountForCurrency(context.Background(), + currency.BTC.String()) testStandardErrorHandling(t, err) } @@ -360,7 +364,7 @@ func TestGetSpotBillDetailsForCurrency(t *testing.T) { Currency: currency.BTC.String(), Limit: 100, } - _, err := o.GetSpotBillDetailsForCurrency(request) + _, err := o.GetSpotBillDetailsForCurrency(context.Background(), request) testStandardErrorHandling(t, err) } @@ -371,7 +375,7 @@ func TestGetSpotBillDetailsForCurrencyBadLimit(t *testing.T) { Currency: currency.BTC.String(), Limit: -1, } - _, err := o.GetSpotBillDetailsForCurrency(request) + _, err := o.GetSpotBillDetailsForCurrency(context.Background(), request) if areTestAPIKeysSet() && err == nil { t.Errorf("Expecting an error when invalid request sent") } @@ -389,7 +393,7 @@ func TestPlaceSpotOrderLimit(t *testing.T) { Size: "0.001", } - _, err := o.PlaceSpotOrder(&request) + _, err := o.PlaceSpotOrder(context.Background(), &request) testStandardErrorHandling(t, err) } @@ -405,7 +409,7 @@ func TestPlaceSpotOrderMarket(t *testing.T) { Notional: "100", } - _, err := o.PlaceSpotOrder(&request) + _, err := o.PlaceSpotOrder(context.Background(), &request) testStandardErrorHandling(t, err) } @@ -425,7 +429,7 @@ func TestPlaceMultipleSpotOrders(t *testing.T) { ord, } - _, errs := o.PlaceMultipleSpotOrders(request) + _, errs := o.PlaceMultipleSpotOrders(context.Background(), request) if len(errs) > 0 { testStandardErrorHandling(t, errs[0]) } @@ -450,7 +454,7 @@ func TestPlaceMultipleSpotOrdersOverCurrencyLimits(t *testing.T) { ord, } - _, errs := o.PlaceMultipleSpotOrders(request) + _, errs := o.PlaceMultipleSpotOrders(context.Background(), request) if errs[0].Error() != "maximum 4 orders for each pair" { t.Error("Expecting an error when more than 4 orders for a pair supplied", errs[0]) } @@ -483,7 +487,7 @@ func TestPlaceMultipleSpotOrdersOverPairLimits(t *testing.T) { request = append(request, ord) } - _, errs := o.PlaceMultipleSpotOrders(request) + _, errs := o.PlaceMultipleSpotOrders(context.Background(), request) if errs[0].Error() != "up to 4 trading pairs" { t.Error("Expecting an error when more than 4 trading pairs supplied", errs[0]) } @@ -498,7 +502,7 @@ func TestCancelSpotOrder(t *testing.T) { OrderID: 1234, } - _, err := o.CancelSpotOrder(request) + _, err := o.CancelSpotOrder(context.Background(), request) testStandardErrorHandling(t, err) } @@ -511,7 +515,7 @@ func TestCancelMultipleSpotOrders(t *testing.T) { OrderIDs: []int64{1, 2, 3, 4}, } - cancellations, err := o.CancelMultipleSpotOrders(request) + cancellations, err := o.CancelMultipleSpotOrders(context.Background(), request) testStandardErrorHandling(t, err) for _, cancellationsPerCurrency := range cancellations { for _, cancellation := range cancellationsPerCurrency { @@ -531,7 +535,7 @@ func TestCancelMultipleSpotOrdersOverCurrencyLimits(t *testing.T) { OrderIDs: []int64{1, 2, 3, 4, 5}, } - _, err := o.CancelMultipleSpotOrders(request) + _, err := o.CancelMultipleSpotOrders(context.Background(), request) if err.Error() != "maximum 4 order cancellations for each pair" { t.Error("Expecting an error when more than 4 orders for a pair supplied", err) } @@ -545,7 +549,7 @@ func TestGetSpotOrders(t *testing.T) { Status: "all", Limit: 1, } - _, err := o.GetSpotOrders(request) + _, err := o.GetSpotOrders(context.Background(), request) testStandardErrorHandling(t, err) } @@ -553,7 +557,7 @@ func TestGetSpotOrders(t *testing.T) { func TestGetSpotOpenOrders(t *testing.T) { t.Parallel() request := okgroup.GetSpotOpenOrdersRequest{} - _, err := o.GetSpotOpenOrders(request) + _, err := o.GetSpotOpenOrders(context.Background(), request) testStandardErrorHandling(t, err) } @@ -564,7 +568,7 @@ func TestGetSpotOrder(t *testing.T) { OrderID: "-1234", InstrumentID: currency.NewPairWithDelimiter(currency.BTC.String(), currency.USDT.String(), "-").Upper().String(), } - _, err := o.GetSpotOrder(request) + _, err := o.GetSpotOrder(context.Background(), request) testStandardErrorHandling(t, err) } @@ -575,14 +579,14 @@ func TestGetSpotTransactionDetails(t *testing.T) { OrderID: 1234, InstrumentID: spotCurrency, } - _, err := o.GetSpotTransactionDetails(request) + _, err := o.GetSpotTransactionDetails(context.Background(), request) testStandardErrorHandling(t, err) } // TestGetSpotTokenPairDetails API endpoint test func TestGetSpotTokenPairDetails(t *testing.T) { t.Parallel() - _, err := o.GetSpotTokenPairDetails() + _, err := o.GetSpotTokenPairDetails(context.Background()) if err != nil { t.Error(err) } @@ -591,7 +595,7 @@ func TestGetSpotTokenPairDetails(t *testing.T) { // TestGetSpotAllTokenPairsInformation API endpoint test func TestGetSpotAllTokenPairsInformation(t *testing.T) { t.Parallel() - _, err := o.GetSpotAllTokenPairsInformation() + _, err := o.GetSpotAllTokenPairsInformation(context.Background()) if err != nil { t.Error(err) } @@ -600,7 +604,7 @@ func TestGetSpotAllTokenPairsInformation(t *testing.T) { // TestGetSpotAllTokenPairsInformationForCurrency API endpoint test func TestGetSpotAllTokenPairsInformationForCurrency(t *testing.T) { t.Parallel() - _, err := o.GetSpotAllTokenPairsInformationForCurrency(spotCurrency) + _, err := o.GetSpotAllTokenPairsInformationForCurrency(context.Background(), spotCurrency) if err != nil { t.Error(err) } @@ -612,7 +616,7 @@ func TestGetSpotFilledOrdersInformation(t *testing.T) { request := okgroup.GetSpotFilledOrdersInformationRequest{ InstrumentID: spotCurrency, } - _, err := o.GetSpotFilledOrdersInformation(request) + _, err := o.GetSpotFilledOrdersInformation(context.Background(), request) if err != nil { t.Error(err) } @@ -626,7 +630,7 @@ func TestGetSpotMarketData(t *testing.T) { InstrumentID: spotCurrency, Granularity: "604800", } - _, err := o.GetMarketData(request) + _, err := o.GetMarketData(context.Background(), request) if err != nil { t.Error(err) } @@ -638,17 +642,20 @@ func TestGetHistoricCandles(t *testing.T) { t.Fatal(err) } startTime := time.Unix(1588636800, 0) - _, err = o.GetHistoricCandles(currencyPair, asset.Spot, startTime, time.Now(), kline.OneMin) + _, err = o.GetHistoricCandles(context.Background(), + currencyPair, asset.Spot, startTime, time.Now(), kline.OneMin) if err != nil { t.Fatal(err) } - _, err = o.GetHistoricCandles(currencyPair, asset.Spot, startTime, time.Now(), kline.Interval(time.Hour*7)) + _, err = o.GetHistoricCandles(context.Background(), + currencyPair, asset.Spot, startTime, time.Now(), kline.Interval(time.Hour*7)) if err == nil { t.Fatal("unexpected result") } - _, err = o.GetHistoricCandles(currencyPair, asset.Margin, startTime, time.Now(), kline.Interval(time.Hour*7)) + _, err = o.GetHistoricCandles(context.Background(), + currencyPair, asset.Margin, startTime, time.Now(), kline.Interval(time.Hour*7)) if err == nil { t.Fatal("unexpected result") } @@ -657,7 +664,8 @@ func TestGetHistoricCandles(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = o.GetHistoricCandles(swapPair, asset.PerpetualSwap, startTime, time.Now(), kline.OneDay) + _, err = o.GetHistoricCandles(context.Background(), + swapPair, asset.PerpetualSwap, startTime, time.Now(), kline.OneDay) if err != nil { t.Fatal(err) } @@ -670,12 +678,14 @@ func TestGetHistoricCandlesExtended(t *testing.T) { } startTime := time.Unix(1607494054, 0) endTime := time.Unix(1607594054, 0) - _, err = o.GetHistoricCandlesExtended(currencyPair, asset.Spot, startTime, endTime, kline.OneMin) + _, err = o.GetHistoricCandlesExtended(context.Background(), + currencyPair, asset.Spot, startTime, endTime, kline.OneMin) if err != nil { t.Fatal(err) } - _, err = o.GetHistoricCandles(currencyPair, asset.Spot, startTime, endTime, kline.Interval(time.Hour*15)) + _, err = o.GetHistoricCandles(context.Background(), + currencyPair, asset.Spot, startTime, endTime, kline.Interval(time.Hour*15)) if err == nil { t.Fatal("unexpected result") } @@ -684,14 +694,14 @@ func TestGetHistoricCandlesExtended(t *testing.T) { // TestGetMarginTradingAccounts API endpoint test func TestGetMarginTradingAccounts(t *testing.T) { t.Parallel() - _, err := o.GetMarginTradingAccounts() + _, err := o.GetMarginTradingAccounts(context.Background()) testStandardErrorHandling(t, err) } // TestGetMarginTradingAccountsForCurrency API endpoint test func TestGetMarginTradingAccountsForCurrency(t *testing.T) { t.Parallel() - _, err := o.GetMarginTradingAccountsForCurrency(spotCurrency) + _, err := o.GetMarginTradingAccountsForCurrency(context.Background(), spotCurrency) testStandardErrorHandling(t, err) } @@ -703,21 +713,21 @@ func TestGetMarginBillDetails(t *testing.T) { Limit: 100, } - _, err := o.GetMarginBillDetails(request) + _, err := o.GetMarginBillDetails(context.Background(), request) testStandardErrorHandling(t, err) } // TestGetMarginAccountSettings API endpoint test func TestGetMarginAccountSettings(t *testing.T) { t.Parallel() - _, err := o.GetMarginAccountSettings("") + _, err := o.GetMarginAccountSettings(context.Background(), "") testStandardErrorHandling(t, err) } // TestGetMarginAccountSettingsForCurrency API endpoint test func TestGetMarginAccountSettingsForCurrency(t *testing.T) { t.Parallel() - _, err := o.GetMarginAccountSettings(spotCurrency) + _, err := o.GetMarginAccountSettings(context.Background(), spotCurrency) testStandardErrorHandling(t, err) } @@ -731,7 +741,7 @@ func TestOpenMarginLoan(t *testing.T) { QuoteCurrency: currency.USDT.String(), } - _, err := o.OpenMarginLoan(request) + _, err := o.OpenMarginLoan(context.Background(), request) testStandardErrorHandling(t, err) } @@ -746,7 +756,7 @@ func TestRepayMarginLoan(t *testing.T) { BorrowID: 1, } - _, err := o.RepayMarginLoan(request) + _, err := o.RepayMarginLoan(context.Background(), request) testStandardErrorHandling(t, err) } @@ -763,7 +773,7 @@ func TestPlaceMarginOrderLimit(t *testing.T) { Size: "100", } - _, err := o.PlaceMarginOrder(&request) + _, err := o.PlaceMarginOrder(context.Background(), &request) testStandardErrorHandling(t, err) } @@ -780,7 +790,7 @@ func TestPlaceMarginOrderMarket(t *testing.T) { Notional: "100", } - _, err := o.PlaceMarginOrder(&request) + _, err := o.PlaceMarginOrder(context.Background(), &request) testStandardErrorHandling(t, err) } @@ -801,7 +811,7 @@ func TestPlaceMultipleMarginOrders(t *testing.T) { ord, } - _, errs := o.PlaceMultipleMarginOrders(request) + _, errs := o.PlaceMultipleMarginOrders(context.Background(), request) if len(errs) > 0 { testStandardErrorHandling(t, errs[0]) } @@ -827,7 +837,7 @@ func TestPlaceMultipleMarginOrdersOverCurrencyLimits(t *testing.T) { ord, } - _, errs := o.PlaceMultipleMarginOrders(request) + _, errs := o.PlaceMultipleMarginOrders(context.Background(), request) if errs[0].Error() != "maximum 4 orders for each pair" { t.Error("Expecting an error when more than 4 orders for a pair supplied", errs[0]) } @@ -861,7 +871,7 @@ func TestPlaceMultipleMarginOrdersOverPairLimits(t *testing.T) { request = append(request, ord) } - _, errs := o.PlaceMultipleMarginOrders(request) + _, errs := o.PlaceMultipleMarginOrders(context.Background(), request) if errs[0].Error() != "up to 4 trading pairs" { t.Error("Expecting an error when more than 4 trading pairs supplied", errs[0]) } @@ -876,7 +886,7 @@ func TestCancelMarginOrder(t *testing.T) { OrderID: 1234, } - _, err := o.CancelMarginOrder(request) + _, err := o.CancelMarginOrder(context.Background(), request) testStandardErrorHandling(t, err) } @@ -889,7 +899,7 @@ func TestCancelMultipleMarginOrders(t *testing.T) { OrderIDs: []int64{1, 2, 3, 4}, } - _, errs := o.CancelMultipleMarginOrders(request) + _, errs := o.CancelMultipleMarginOrders(context.Background(), request) if len(errs) > 0 { testStandardErrorHandling(t, errs[0]) } @@ -904,7 +914,7 @@ func TestCancelMultipleMarginOrdersOverCurrencyLimits(t *testing.T) { OrderIDs: []int64{1, 2, 3, 4, 5}, } - _, errs := o.CancelMultipleMarginOrders(request) + _, errs := o.CancelMultipleMarginOrders(context.Background(), request) if errs[0].Error() != "maximum 4 order cancellations for each pair" { t.Error("Expecting an error when more than 4 orders for a pair supplied", errs[0]) } @@ -917,7 +927,7 @@ func TestGetMarginOrders(t *testing.T) { InstrumentID: spotCurrency, Status: "all", } - _, err := o.GetMarginOrders(request) + _, err := o.GetMarginOrders(context.Background(), request) testStandardErrorHandling(t, err) } @@ -925,7 +935,7 @@ func TestGetMarginOrders(t *testing.T) { func TestGetMarginOpenOrders(t *testing.T) { t.Parallel() request := okgroup.GetSpotOpenOrdersRequest{} - _, err := o.GetMarginOpenOrders(request) + _, err := o.GetMarginOpenOrders(context.Background(), request) testStandardErrorHandling(t, err) } @@ -936,7 +946,7 @@ func TestGetMarginOrder(t *testing.T) { OrderID: "1234", InstrumentID: currency.NewPairWithDelimiter(currency.BTC.String(), currency.USDT.String(), "-").Upper().String(), } - _, err := o.GetMarginOrder(request) + _, err := o.GetMarginOrder(context.Background(), request) testStandardErrorHandling(t, err) } @@ -947,7 +957,7 @@ func TestGetMarginTransactionDetails(t *testing.T) { OrderID: 1234, InstrumentID: spotCurrency, } - _, err := o.GetMarginTransactionDetails(request) + _, err := o.GetMarginTransactionDetails(context.Background(), request) testStandardErrorHandling(t, err) } @@ -959,7 +969,7 @@ func getFutureInstrumentID() string { if genericFutureInstrumentID != "" { return genericFutureInstrumentID } - resp, err := o.GetFuturesContractInformation() + resp, err := o.GetFuturesContractInformation(context.Background()) if err != nil { // No error handling here because we're not testing this return err.Error() @@ -971,35 +981,35 @@ func getFutureInstrumentID() string { // TestGetFuturesPostions API endpoint test func TestGetFuturesPostions(t *testing.T) { t.Parallel() - _, err := o.GetFuturesPostions() + _, err := o.GetFuturesPostions(context.Background()) testStandardErrorHandling(t, err) } // TestGetFuturesPostionsForCurrency API endpoint test func TestGetFuturesPostionsForCurrency(t *testing.T) { currencyContract := getFutureInstrumentID() - _, err := o.GetFuturesPostionsForCurrency(currencyContract) + _, err := o.GetFuturesPostionsForCurrency(context.Background(), currencyContract) testStandardErrorHandling(t, err) } // TestGetFuturesAccountOfAllCurrencies API endpoint test func TestGetFuturesAccountOfAllCurrencies(t *testing.T) { t.Parallel() - _, err := o.GetFuturesAccountOfAllCurrencies() + _, err := o.GetFuturesAccountOfAllCurrencies(context.Background()) testStandardErrorHandling(t, err) } // TestGetFuturesAccountOfACurrency API endpoint test func TestGetFuturesAccountOfACurrency(t *testing.T) { t.Parallel() - _, err := o.GetFuturesAccountOfACurrency(currency.BTC.String()) + _, err := o.GetFuturesAccountOfACurrency(context.Background(), currency.BTC.String()) testStandardErrorHandling(t, err) } // TestGetFuturesLeverage API endpoint test func TestGetFuturesLeverage(t *testing.T) { t.Parallel() - _, err := o.GetFuturesLeverage(currency.BTC.String()) + _, err := o.GetFuturesLeverage(context.Background(), currency.BTC.String()) testStandardErrorHandling(t, err) } @@ -1012,59 +1022,63 @@ func TestSetFuturesLeverage(t *testing.T) { Leverage: 10, Direction: "Long", } - _, err := o.SetFuturesLeverage(request) + _, err := o.SetFuturesLeverage(context.Background(), request) testStandardErrorHandling(t, err) } // TestGetFuturesBillDetails API endpoint test func TestGetFuturesBillDetails(t *testing.T) { t.Parallel() - _, err := o.GetFuturesBillDetails(okgroup.GetSpotBillDetailsForCurrencyRequest{ - Currency: currency.BTC.String(), - }) + _, err := o.GetFuturesBillDetails(context.Background(), + okgroup.GetSpotBillDetailsForCurrencyRequest{ + Currency: currency.BTC.String(), + }) testStandardErrorHandling(t, err) } // TestPlaceFuturesOrder API endpoint test func TestPlaceFuturesOrder(t *testing.T) { TestSetRealOrderDefaults(t) - _, err := o.PlaceFuturesOrder(okgroup.PlaceFuturesOrderRequest{ - InstrumentID: getFutureInstrumentID(), - Leverage: 10, - Type: 1, - Size: 2, - Price: -432.11, - ClientOid: "12233456", - }) + _, err := o.PlaceFuturesOrder(context.Background(), + okgroup.PlaceFuturesOrderRequest{ + InstrumentID: getFutureInstrumentID(), + Leverage: 10, + Type: 1, + Size: 2, + Price: -432.11, + ClientOid: "12233456", + }) testStandardErrorHandling(t, err) } // TestPlaceFuturesOrderBatch API endpoint test func TestPlaceFuturesOrderBatch(t *testing.T) { TestSetRealOrderDefaults(t) - _, err := o.PlaceFuturesOrderBatch(okgroup.PlaceFuturesOrderBatchRequest{ - InstrumentID: getFutureInstrumentID(), - Leverage: 10, - OrdersData: []okgroup.PlaceFuturesOrderBatchRequestDetails{ - { - ClientOid: "1", - MatchPrice: "0", - Price: "-100", - Size: "100", - Type: "1", + _, err := o.PlaceFuturesOrderBatch(context.Background(), + okgroup.PlaceFuturesOrderBatchRequest{ + InstrumentID: getFutureInstrumentID(), + Leverage: 10, + OrdersData: []okgroup.PlaceFuturesOrderBatchRequestDetails{ + { + ClientOid: "1", + MatchPrice: "0", + Price: "-100", + Size: "100", + Type: "1", + }, }, - }, - }) + }) testStandardErrorHandling(t, err) } // TestCancelFuturesOrder API endpoint test func TestCancelFuturesOrder(t *testing.T) { TestSetRealOrderDefaults(t) - _, err := o.CancelFuturesOrder(okgroup.CancelFuturesOrderRequest{ - InstrumentID: getFutureInstrumentID(), - OrderID: "1", - }) + _, err := o.CancelFuturesOrder(context.Background(), + okgroup.CancelFuturesOrderRequest{ + InstrumentID: getFutureInstrumentID(), + OrderID: "1", + }) testStandardErrorHandling(t, err) } @@ -1076,41 +1090,44 @@ func TestCancelMultipleFuturesOrders(t *testing.T) { OrderIDs: []int64{1, 2, 3, 4}, } - _, err := o.CancelFuturesOrderBatch(request) + _, err := o.CancelFuturesOrderBatch(context.Background(), request) testStandardErrorHandling(t, err) } // TestGetFuturesOrderList API endpoint test func TestGetFuturesOrderList(t *testing.T) { - _, err := o.GetFuturesOrderList(okgroup.GetFuturesOrdersListRequest{ - InstrumentID: getFutureInstrumentID(), - Status: 6, - }) + _, err := o.GetFuturesOrderList(context.Background(), + okgroup.GetFuturesOrdersListRequest{ + InstrumentID: getFutureInstrumentID(), + Status: 6, + }) testStandardErrorHandling(t, err) } // TestGetFuturesOrderDetails API endpoint test func TestGetFuturesOrderDetails(t *testing.T) { - _, err := o.GetFuturesOrderDetails(okgroup.GetFuturesOrderDetailsRequest{ - InstrumentID: getFutureInstrumentID(), - OrderID: 1, - }) + _, err := o.GetFuturesOrderDetails(context.Background(), + okgroup.GetFuturesOrderDetailsRequest{ + InstrumentID: getFutureInstrumentID(), + OrderID: 1, + }) testStandardErrorHandling(t, err) } // TestGetFuturesTransactionDetails API endpoint test func TestGetFuturesTransactionDetails(t *testing.T) { - _, err := o.GetFuturesTransactionDetails(okgroup.GetFuturesTransactionDetailsRequest{ - InstrumentID: getFutureInstrumentID(), - OrderID: 1, - }) + _, err := o.GetFuturesTransactionDetails(context.Background(), + okgroup.GetFuturesTransactionDetailsRequest{ + InstrumentID: getFutureInstrumentID(), + OrderID: 1, + }) testStandardErrorHandling(t, err) } // TestGetFuturesContractInformation API endpoint test func TestGetFuturesContractInformation(t *testing.T) { t.Parallel() - _, err := o.GetFuturesContractInformation() + _, err := o.GetFuturesContractInformation(context.Background()) if err != nil { t.Error(err) } @@ -1119,7 +1136,7 @@ func TestGetFuturesContractInformation(t *testing.T) { // TestGetAllFuturesTokenInfo API endpoint test func TestGetAllFuturesTokenInfo(t *testing.T) { t.Parallel() - _, err := o.GetAllFuturesTokenInfo() + _, err := o.GetAllFuturesTokenInfo(context.Background()) if err != nil { t.Error(err) } @@ -1127,7 +1144,8 @@ func TestGetAllFuturesTokenInfo(t *testing.T) { // TestGetAllFuturesTokenInfo API endpoint test func TestGetFuturesTokenInfoForCurrency(t *testing.T) { - _, err := o.GetFuturesTokenInfoForCurrency(getFutureInstrumentID()) + _, err := o.GetFuturesTokenInfoForCurrency(context.Background(), + getFutureInstrumentID()) if err != nil { t.Error(err) } @@ -1135,9 +1153,10 @@ func TestGetFuturesTokenInfoForCurrency(t *testing.T) { // TestGetFuturesFilledOrder API endpoint test func TestGetFuturesFilledOrder(t *testing.T) { - _, err := o.GetFuturesFilledOrder(okgroup.GetFuturesFilledOrderRequest{ - InstrumentID: getFutureInstrumentID(), - }) + _, err := o.GetFuturesFilledOrder(context.Background(), + okgroup.GetFuturesFilledOrderRequest{ + InstrumentID: getFutureInstrumentID(), + }) if err != nil { t.Error(err) } @@ -1145,13 +1164,14 @@ func TestGetFuturesFilledOrder(t *testing.T) { // TestGetFuturesHoldAmount API endpoint test func TestGetFuturesHoldAmount(t *testing.T) { - _, err := o.GetFuturesHoldAmount(getFutureInstrumentID()) + _, err := o.GetFuturesHoldAmount(context.Background(), + getFutureInstrumentID()) testStandardErrorHandling(t, err) } // TestGetFuturesHoldAmount API endpoint test func TestGetFuturesIndices(t *testing.T) { - _, err := o.GetFuturesIndices(getFutureInstrumentID()) + _, err := o.GetFuturesIndices(context.Background(), getFutureInstrumentID()) if err != nil { t.Error(err) } @@ -1160,7 +1180,7 @@ func TestGetFuturesIndices(t *testing.T) { // TestGetFuturesHoldAmount API endpoint test func TestGetFuturesExchangeRates(t *testing.T) { t.Parallel() - _, err := o.GetFuturesExchangeRates() + _, err := o.GetFuturesExchangeRates(context.Background()) if err != nil { t.Errorf("Encountered error: %v", err) } @@ -1168,7 +1188,8 @@ func TestGetFuturesExchangeRates(t *testing.T) { // TestGetFuturesHoldAmount API endpoint test func TestGetFuturesEstimatedDeliveryPrice(t *testing.T) { - _, err := o.GetFuturesEstimatedDeliveryPrice(getFutureInstrumentID()) + _, err := o.GetFuturesEstimatedDeliveryPrice(context.Background(), + getFutureInstrumentID()) if err != nil { t.Error(err) } @@ -1176,7 +1197,7 @@ func TestGetFuturesEstimatedDeliveryPrice(t *testing.T) { // TestGetFuturesOpenInterests API endpoint test func TestGetFuturesOpenInterests(t *testing.T) { - _, err := o.GetFuturesOpenInterests(getFutureInstrumentID()) + _, err := o.GetFuturesOpenInterests(context.Background(), getFutureInstrumentID()) if err != nil { t.Error(err) } @@ -1184,7 +1205,8 @@ func TestGetFuturesOpenInterests(t *testing.T) { // TestGetFuturesOpenInterests API endpoint test func TestGetFuturesCurrentPriceLimit(t *testing.T) { - _, err := o.GetFuturesCurrentPriceLimit(getFutureInstrumentID()) + _, err := o.GetFuturesCurrentPriceLimit(context.Background(), + getFutureInstrumentID()) if err != nil { t.Error(err) } @@ -1192,7 +1214,8 @@ func TestGetFuturesCurrentPriceLimit(t *testing.T) { // TestGetFuturesCurrentMarkPrice API endpoint test func TestGetFuturesCurrentMarkPrice(t *testing.T) { - _, err := o.GetFuturesCurrentMarkPrice(getFutureInstrumentID()) + _, err := o.GetFuturesCurrentMarkPrice(context.Background(), + getFutureInstrumentID()) if err != nil { t.Error(err) } @@ -1200,10 +1223,11 @@ func TestGetFuturesCurrentMarkPrice(t *testing.T) { // TestGetFuturesForceLiquidatedOrders API endpoint test func TestGetFuturesForceLiquidatedOrders(t *testing.T) { - _, err := o.GetFuturesForceLiquidatedOrders(okgroup.GetFuturesForceLiquidatedOrdersRequest{ - InstrumentID: getFutureInstrumentID(), - Status: "1", - }) + _, err := o.GetFuturesForceLiquidatedOrders(context.Background(), + okgroup.GetFuturesForceLiquidatedOrdersRequest{ + InstrumentID: getFutureInstrumentID(), + Status: "1", + }) if err != nil { t.Error(err) } @@ -1211,46 +1235,49 @@ func TestGetFuturesForceLiquidatedOrders(t *testing.T) { // TestGetFuturesTagPrice API endpoint test func TestGetFuturesTagPrice(t *testing.T) { - _, err := o.GetFuturesTagPrice(getFutureInstrumentID()) + _, err := o.GetFuturesTagPrice(context.Background(), getFutureInstrumentID()) testStandardErrorHandling(t, err) } // TestGetSwapPostions API endpoint test func TestGetSwapPostions(t *testing.T) { t.Parallel() - _, err := o.GetSwapPostions() + _, err := o.GetSwapPostions(context.Background()) testStandardErrorHandling(t, err) } // TestGetSwapPostionsForContract API endpoint test func TestGetSwapPostionsForContract(t *testing.T) { t.Parallel() - _, err := o.GetSwapPostionsForContract(fmt.Sprintf("%v-%v-SWAP", currency.BTC, currency.USD)) + _, err := o.GetSwapPostionsForContract(context.Background(), + fmt.Sprintf("%v-%v-SWAP", currency.BTC, currency.USD)) testStandardErrorHandling(t, err) } // TestGetSwapAccountOfAllCurrency API endpoint test func TestGetSwapAccountOfAllCurrency(t *testing.T) { t.Parallel() - _, err := o.GetSwapAccountOfAllCurrency() + _, err := o.GetSwapAccountOfAllCurrency(context.Background()) testStandardErrorHandling(t, err) } // TestGetSwapAccountSettingsOfAContract API endpoint test func TestGetSwapAccountSettingsOfAContract(t *testing.T) { t.Parallel() - _, err := o.GetSwapAccountSettingsOfAContract(fmt.Sprintf("%v-%v-SWAP", currency.BTC, currency.USD)) + _, err := o.GetSwapAccountSettingsOfAContract(context.Background(), + fmt.Sprintf("%v-%v-SWAP", currency.BTC, currency.USD)) testStandardErrorHandling(t, err) } // TestSetSwapLeverageLevelOfAContract API endpoint test func TestSetSwapLeverageLevelOfAContract(t *testing.T) { t.Parallel() - _, err := o.SetSwapLeverageLevelOfAContract(okgroup.SetSwapLeverageLevelOfAContractRequest{ - InstrumentID: fmt.Sprintf("%v-%v-SWAP", currency.BTC, currency.USD), - Leverage: 10, - Side: 1, - }) + _, err := o.SetSwapLeverageLevelOfAContract(context.Background(), + okgroup.SetSwapLeverageLevelOfAContractRequest{ + InstrumentID: fmt.Sprintf("%v-%v-SWAP", currency.BTC, currency.USD), + Leverage: 10, + Side: 1, + }) testStandardErrorHandling(t, err) } @@ -1258,10 +1285,11 @@ func TestSetSwapLeverageLevelOfAContract(t *testing.T) { // TestGetSwapAccountSettingsOfAContract API endpoint test func TestGetSwapBillDetails(t *testing.T) { t.Parallel() - _, err := o.GetSwapBillDetails(okgroup.GetSpotBillDetailsForCurrencyRequest{ - Currency: fmt.Sprintf("%v-%v-SWAP", currency.BTC, currency.USD), - Limit: 100, - }) + _, err := o.GetSwapBillDetails(context.Background(), + okgroup.GetSpotBillDetailsForCurrencyRequest{ + Currency: fmt.Sprintf("%v-%v-SWAP", currency.BTC, currency.USD), + Limit: 100, + }) testStandardErrorHandling(t, err) } @@ -1269,12 +1297,13 @@ func TestGetSwapBillDetails(t *testing.T) { func TestPlaceSwapOrder(t *testing.T) { TestSetRealOrderDefaults(t) t.Parallel() - _, err := o.PlaceSwapOrder(okgroup.PlaceSwapOrderRequest{ - InstrumentID: fmt.Sprintf("%v-%v-SWAP", currency.BTC, currency.USD), - Size: 1, - Type: 1, - Price: 1, - }) + _, err := o.PlaceSwapOrder(context.Background(), + okgroup.PlaceSwapOrderRequest{ + InstrumentID: fmt.Sprintf("%v-%v-SWAP", currency.BTC, currency.USD), + Size: 1, + Type: 1, + Price: 1, + }) testStandardErrorHandling(t, err) } @@ -1282,24 +1311,25 @@ func TestPlaceSwapOrder(t *testing.T) { func TestPlaceMultipleSwapOrders(t *testing.T) { TestSetRealOrderDefaults(t) t.Parallel() - _, err := o.PlaceMultipleSwapOrders(okgroup.PlaceMultipleSwapOrdersRequest{ - InstrumentID: fmt.Sprintf("%v-%v-SWAP", currency.BTC, currency.USD), - Leverage: 10, - OrdersData: []okgroup.PlaceMultipleSwapOrderData{ - { - ClientOID: "hello", - MatchPrice: "0", - Price: "10", - Size: "-1", - Type: "1", - }, { - ClientOID: "hello2", - MatchPrice: "0", - Price: "10", - Size: "-1", - Type: "1", - }}, - }) + _, err := o.PlaceMultipleSwapOrders(context.Background(), + okgroup.PlaceMultipleSwapOrdersRequest{ + InstrumentID: fmt.Sprintf("%v-%v-SWAP", currency.BTC, currency.USD), + Leverage: 10, + OrdersData: []okgroup.PlaceMultipleSwapOrderData{ + { + ClientOID: "hello", + MatchPrice: "0", + Price: "10", + Size: "-1", + Type: "1", + }, { + ClientOID: "hello2", + MatchPrice: "0", + Price: "10", + Size: "-1", + Type: "1", + }}, + }) testStandardErrorHandling(t, err) } @@ -1307,10 +1337,11 @@ func TestPlaceMultipleSwapOrders(t *testing.T) { func TestCancelSwapOrder(t *testing.T) { TestSetRealOrderDefaults(t) t.Parallel() - _, err := o.CancelSwapOrder(okgroup.CancelSwapOrderRequest{ - InstrumentID: fmt.Sprintf("%v-%v-SWAP", currency.BTC, currency.USD), - OrderID: "64-2a-26132f931-3", - }) + _, err := o.CancelSwapOrder(context.Background(), + okgroup.CancelSwapOrderRequest{ + InstrumentID: fmt.Sprintf("%v-%v-SWAP", currency.BTC, currency.USD), + OrderID: "64-2a-26132f931-3", + }) testStandardErrorHandling(t, err) } @@ -1318,47 +1349,51 @@ func TestCancelSwapOrder(t *testing.T) { func TestCancelMultipleSwapOrders(t *testing.T) { TestSetRealOrderDefaults(t) t.Parallel() - _, err := o.CancelMultipleSwapOrders(okgroup.CancelMultipleSwapOrdersRequest{ - InstrumentID: fmt.Sprintf("%v-%v-SWAP", currency.BTC, currency.USD), - OrderIDs: []int64{1, 2, 3, 4}, - }) + _, err := o.CancelMultipleSwapOrders(context.Background(), + okgroup.CancelMultipleSwapOrdersRequest{ + InstrumentID: fmt.Sprintf("%v-%v-SWAP", currency.BTC, currency.USD), + OrderIDs: []int64{1, 2, 3, 4}, + }) testStandardErrorHandling(t, err) } // TestGetSwapOrderList API endpoint test func TestGetSwapOrderList(t *testing.T) { t.Parallel() - _, err := o.GetSwapOrderList(okgroup.GetSwapOrderListRequest{ - InstrumentID: fmt.Sprintf("%v-%v-SWAP", currency.BTC, currency.USD), - Status: 6, - }) + _, err := o.GetSwapOrderList(context.Background(), + okgroup.GetSwapOrderListRequest{ + InstrumentID: fmt.Sprintf("%v-%v-SWAP", currency.BTC, currency.USD), + Status: 6, + }) testStandardErrorHandling(t, err) } // TestGetSwapOrderDetails API endpoint test func TestGetSwapOrderDetails(t *testing.T) { t.Parallel() - _, err := o.GetSwapOrderDetails(okgroup.GetSwapOrderDetailsRequest{ - InstrumentID: fmt.Sprintf("%v-%v-SWAP", currency.BTC, currency.USD), - OrderID: "64-2a-26132f931-3", - }) + _, err := o.GetSwapOrderDetails(context.Background(), + okgroup.GetSwapOrderDetailsRequest{ + InstrumentID: fmt.Sprintf("%v-%v-SWAP", currency.BTC, currency.USD), + OrderID: "64-2a-26132f931-3", + }) testStandardErrorHandling(t, err) } // TestGetSwapTransactionDetails API endpoint test func TestGetSwapTransactionDetails(t *testing.T) { t.Parallel() - _, err := o.GetSwapTransactionDetails(okgroup.GetSwapTransactionDetailsRequest{ - InstrumentID: fmt.Sprintf("%v-%v-SWAP", currency.BTC, currency.USD), - OrderID: "64-2a-26132f931-3", - }) + _, err := o.GetSwapTransactionDetails(context.Background(), + okgroup.GetSwapTransactionDetailsRequest{ + InstrumentID: fmt.Sprintf("%v-%v-SWAP", currency.BTC, currency.USD), + OrderID: "64-2a-26132f931-3", + }) testStandardErrorHandling(t, err) } // TestGetSwapContractInformation API endpoint test func TestGetSwapContractInformation(t *testing.T) { t.Parallel() - _, err := o.GetSwapContractInformation() + _, err := o.GetSwapContractInformation(context.Background()) if err != nil { t.Error(err) } @@ -1367,7 +1402,7 @@ func TestGetSwapContractInformation(t *testing.T) { // TestGetAllSwapTokensInformation API endpoint test func TestGetAllSwapTokensInformation(t *testing.T) { t.Parallel() - _, err := o.GetAllSwapTokensInformation() + _, err := o.GetAllSwapTokensInformation(context.Background()) if err != nil { t.Error(err) } @@ -1376,7 +1411,8 @@ func TestGetAllSwapTokensInformation(t *testing.T) { // TestGetSwapTokensInformationForCurrency API endpoint test func TestGetSwapTokensInformationForCurrency(t *testing.T) { t.Parallel() - _, err := o.GetSwapTokensInformationForCurrency(fmt.Sprintf("%v-%v-SWAP", currency.BTC, currency.USD)) + _, err := o.GetSwapTokensInformationForCurrency(context.Background(), + fmt.Sprintf("%v-%v-SWAP", currency.BTC, currency.USD)) if err != nil { t.Error(err) } @@ -1385,10 +1421,11 @@ func TestGetSwapTokensInformationForCurrency(t *testing.T) { // TestGetSwapFilledOrdersData API endpoint test func TestGetSwapFilledOrdersData(t *testing.T) { t.Parallel() - _, err := o.GetSwapFilledOrdersData(&okgroup.GetSwapFilledOrdersDataRequest{ - InstrumentID: fmt.Sprintf("%v-%v-SWAP", currency.BTC, currency.USD), - Limit: 100, - }) + _, err := o.GetSwapFilledOrdersData(context.Background(), + &okgroup.GetSwapFilledOrdersDataRequest{ + InstrumentID: fmt.Sprintf("%v-%v-SWAP", currency.BTC, currency.USD), + Limit: 100, + }) if err != nil { t.Error(err) } @@ -1397,7 +1434,8 @@ func TestGetSwapFilledOrdersData(t *testing.T) { // TestGetSwapIndeces API endpoint test func TestGetSwapIndeces(t *testing.T) { t.Parallel() - _, err := o.GetSwapIndices(fmt.Sprintf("%v-%v-SWAP", currency.BTC, currency.USD)) + _, err := o.GetSwapIndices(context.Background(), + fmt.Sprintf("%v-%v-SWAP", currency.BTC, currency.USD)) if err != nil { t.Error(err) } @@ -1406,7 +1444,7 @@ func TestGetSwapIndeces(t *testing.T) { // TestGetSwapExchangeRates API endpoint test func TestGetSwapExchangeRates(t *testing.T) { t.Parallel() - _, err := o.GetSwapExchangeRates() + _, err := o.GetSwapExchangeRates(context.Background()) if err != nil { t.Error(err) } @@ -1415,7 +1453,8 @@ func TestGetSwapExchangeRates(t *testing.T) { // TestGetSwapOpenInterest API endpoint test func TestGetSwapOpenInterest(t *testing.T) { t.Parallel() - _, err := o.GetSwapOpenInterest(fmt.Sprintf("%v-%v-SWAP", currency.BTC, currency.USD)) + _, err := o.GetSwapOpenInterest(context.Background(), + fmt.Sprintf("%v-%v-SWAP", currency.BTC, currency.USD)) if err != nil { t.Error(err) } @@ -1424,7 +1463,8 @@ func TestGetSwapOpenInterest(t *testing.T) { // TestGetSwapCurrentPriceLimits API endpoint test func TestGetSwapCurrentPriceLimits(t *testing.T) { t.Parallel() - _, err := o.GetSwapCurrentPriceLimits(fmt.Sprintf("%v-%v-SWAP", currency.BTC, currency.USD)) + _, err := o.GetSwapCurrentPriceLimits(context.Background(), + fmt.Sprintf("%v-%v-SWAP", currency.BTC, currency.USD)) if err != nil { t.Error(err) } @@ -1433,10 +1473,11 @@ func TestGetSwapCurrentPriceLimits(t *testing.T) { // TestGetSwapForceLiquidatedOrders API endpoint test func TestGetSwapForceLiquidatedOrders(t *testing.T) { t.Parallel() - _, err := o.GetSwapForceLiquidatedOrders(okgroup.GetSwapForceLiquidatedOrdersRequest{ - InstrumentID: fmt.Sprintf("%v-%v-SWAP", currency.BTC, currency.USD), - Status: "0", - }) + _, err := o.GetSwapForceLiquidatedOrders(context.Background(), + okgroup.GetSwapForceLiquidatedOrdersRequest{ + InstrumentID: fmt.Sprintf("%v-%v-SWAP", currency.BTC, currency.USD), + Status: "0", + }) if err != nil { t.Error(err) } @@ -1445,14 +1486,17 @@ func TestGetSwapForceLiquidatedOrders(t *testing.T) { // TestGetSwapOnHoldAmountForOpenOrders API endpoint test func TestGetSwapOnHoldAmountForOpenOrders(t *testing.T) { t.Parallel() - _, err := o.GetSwapOnHoldAmountForOpenOrders(fmt.Sprintf("%v-%v-SWAP", currency.BTC, currency.USD)) + _, err := o.GetSwapOnHoldAmountForOpenOrders( + context.Background(), + fmt.Sprintf("%v-%v-SWAP", currency.BTC, currency.USD)) testStandardErrorHandling(t, err) } // TestGetSwapNextSettlementTime API endpoint test func TestGetSwapNextSettlementTime(t *testing.T) { t.Parallel() - _, err := o.GetSwapNextSettlementTime(fmt.Sprintf("%v-%v-SWAP", currency.BTC, currency.USD)) + _, err := o.GetSwapNextSettlementTime(context.Background(), + fmt.Sprintf("%v-%v-SWAP", currency.BTC, currency.USD)) if err != nil { t.Error(err) } @@ -1461,7 +1505,8 @@ func TestGetSwapNextSettlementTime(t *testing.T) { // TestGetSwapMarkPrice API endpoint test func TestGetSwapMarkPrice(t *testing.T) { t.Parallel() - _, err := o.GetSwapMarkPrice(fmt.Sprintf("%v-%v-SWAP", currency.BTC, currency.USD)) + _, err := o.GetSwapMarkPrice(context.Background(), + fmt.Sprintf("%v-%v-SWAP", currency.BTC, currency.USD)) if err != nil { t.Error(err) } @@ -1470,10 +1515,11 @@ func TestGetSwapMarkPrice(t *testing.T) { // TestGetSwapFundingRateHistory API endpoint test func TestGetSwapFundingRateHistory(t *testing.T) { t.Parallel() - _, err := o.GetSwapFundingRateHistory(okgroup.GetSwapFundingRateHistoryRequest{ - InstrumentID: fmt.Sprintf("%v-%v-SWAP", currency.BTC, currency.USD), - Limit: 100, - }) + _, err := o.GetSwapFundingRateHistory(context.Background(), + okgroup.GetSwapFundingRateHistoryRequest{ + InstrumentID: fmt.Sprintf("%v-%v-SWAP", currency.BTC, currency.USD), + Limit: 100, + }) if err != nil { t.Error(err) } @@ -1482,21 +1528,21 @@ func TestGetSwapFundingRateHistory(t *testing.T) { // TestGetETT API endpoint test func TestGetETT(t *testing.T) { t.Parallel() - _, err := o.GetETT() + _, err := o.GetETT(context.Background()) testStandardErrorHandling(t, err) } // TestGetETTAccountInformationForCurrency API endpoint test func TestGetETTAccountInformationForCurrency(t *testing.T) { t.Parallel() - _, err := o.GetETTBillsDetails(currency.BTC.String()) + _, err := o.GetETTBillsDetails(context.Background(), currency.BTC.String()) testStandardErrorHandling(t, err) } // TestGetETTBillsDetails API endpoint test func TestGetETTBillsDetails(t *testing.T) { t.Parallel() - _, err := o.GetETTBillsDetails(currency.BTC.String()) + _, err := o.GetETTBillsDetails(context.Background(), currency.BTC.String()) testStandardErrorHandling(t, err) } @@ -1512,7 +1558,7 @@ func TestPlaceETTOrder(t *testing.T) { ETT: "OK06", } - _, err := o.PlaceETTOrder(&request) + _, err := o.PlaceETTOrder(context.Background(), &request) testStandardErrorHandling(t, err) } @@ -1520,7 +1566,7 @@ func TestPlaceETTOrder(t *testing.T) { func TestCancelETTOrder(t *testing.T) { TestSetRealOrderDefaults(t) t.Parallel() - _, err := o.CancelETTOrder("888845120785408") + _, err := o.CancelETTOrder(context.Background(), "888845120785408") testStandardErrorHandling(t, err) } @@ -1536,14 +1582,14 @@ func TestGetETTOrderList(t *testing.T) { Status: 0, } - _, err := o.GetETTOrderList(request) + _, err := o.GetETTOrderList(context.Background(), request) testStandardErrorHandling(t, err) } // TestGetETTOrderDetails API endpoint test func TestGetETTOrderDetails(t *testing.T) { t.Parallel() - _, err := o.GetETTOrderDetails("888845020785408") + _, err := o.GetETTOrderDetails(context.Background(), "888845020785408") testStandardErrorHandling(t, err) } @@ -1551,7 +1597,7 @@ func TestGetETTOrderDetails(t *testing.T) { func TestGetETTConstituents(t *testing.T) { t.Skip("ETT currently unavailable") t.Parallel() - _, err := o.GetETTConstituents("OK06ETT") + _, err := o.GetETTConstituents(context.Background(), "OK06ETT") if err != nil { t.Error(err) } @@ -1561,7 +1607,7 @@ func TestGetETTConstituents(t *testing.T) { func TestGetETTSettlementPriceHistory(t *testing.T) { t.Skip("ETT currently unavailable") t.Parallel() - _, err := o.GetETTSettlementPriceHistory("OK06ETT") + _, err := o.GetETTSettlementPriceHistory(context.Background(), "OK06ETT") if err != nil { t.Error(err) } @@ -1699,7 +1745,7 @@ func setFeeBuilder() *exchange.FeeBuilder { // TestGetFeeByTypeOfflineTradeFee logic test func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { var feeBuilder = setFeeBuilder() - _, err := o.GetFeeByType(feeBuilder) + _, err := o.GetFeeByType(context.Background(), feeBuilder) if err != nil { t.Fatal(err) } @@ -1718,7 +1764,7 @@ func TestGetFee(t *testing.T) { t.Parallel() var feeBuilder = setFeeBuilder() // CryptocurrencyTradeFee Basic - if _, err := o.GetFee(feeBuilder); err != nil { + if _, err := o.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } @@ -1726,39 +1772,39 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.Amount = 1000 feeBuilder.PurchasePrice = 1000 - if _, err := o.GetFee(feeBuilder); err != nil { + if _, err := o.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyTradeFee IsMaker feeBuilder = setFeeBuilder() feeBuilder.IsMaker = true - if _, err := o.GetFee(feeBuilder); err != nil { + if _, err := o.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyTradeFee Negative purchase price feeBuilder = setFeeBuilder() feeBuilder.PurchasePrice = -1000 - if _, err := o.GetFee(feeBuilder); err != nil { + if _, err := o.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyDepositFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.CryptocurrencyDepositFee - if _, err := o.GetFee(feeBuilder); err != nil { + if _, err := o.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } // InternationalBankDepositFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankDepositFee - if _, err := o.GetFee(feeBuilder); err != nil { + if _, err := o.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } // InternationalBankWithdrawalFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee feeBuilder.FiatCurrency = currency.USD - if _, err := o.GetFee(feeBuilder); err != nil { + if _, err := o.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } } @@ -1791,7 +1837,7 @@ func TestSubmitOrder(t *testing.T) { ClientID: "meowOrder", AssetType: asset.Spot, } - response, err := o.SubmitOrder(orderSubmission) + response, err := o.SubmitOrder(context.Background(), orderSubmission) if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) { t.Errorf("Order failed to be placed: %v", err) } else if !areTestAPIKeysSet() && err == nil { @@ -1811,7 +1857,7 @@ func TestCancelExchangeOrder(t *testing.T) { Pair: currencyPair, } - err := o.CancelOrder(&orderCancellation) + err := o.CancelOrder(context.Background(), &orderCancellation) testStandardErrorHandling(t, err) } @@ -1827,7 +1873,7 @@ func TestCancelAllExchangeOrders(t *testing.T) { Pair: currencyPair, } - resp, err := o.CancelAllOrders(&orderCancellation) + resp, err := o.CancelAllOrders(context.Background(), &orderCancellation) testStandardErrorHandling(t, err) if len(resp.Status) > 0 { @@ -1837,7 +1883,7 @@ func TestCancelAllExchangeOrders(t *testing.T) { // TestGetAccountInfo Wrapper test func TestGetAccountInfo(t *testing.T) { - _, err := o.UpdateAccountInfo(asset.Spot) + _, err := o.UpdateAccountInfo(context.Background(), asset.Spot) testStandardErrorHandling(t, err) } @@ -1845,7 +1891,7 @@ func TestGetAccountInfo(t *testing.T) { func TestModifyOrder(t *testing.T) { TestSetRealOrderDefaults(t) t.Parallel() - _, err := o.ModifyOrder(&order.Modify{AssetType: asset.Spot}) + _, err := o.ModifyOrder(context.Background(), &order.Modify{AssetType: asset.Spot}) if err != common.ErrFunctionNotSupported { t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, @@ -1867,7 +1913,8 @@ func TestWithdraw(t *testing.T) { Description: "WITHDRAW IT ALL", TradePassword: "Password", } - _, err := o.WithdrawCryptocurrencyFunds(&withdrawCryptoRequest) + _, err := o.WithdrawCryptocurrencyFunds(context.Background(), + &withdrawCryptoRequest) testStandardErrorHandling(t, err) } @@ -1876,7 +1923,7 @@ func TestWithdrawFiat(t *testing.T) { TestSetRealOrderDefaults(t) t.Parallel() var withdrawFiatRequest = withdraw.Request{} - _, err := o.WithdrawFiatFunds(&withdrawFiatRequest) + _, err := o.WithdrawFiatFunds(context.Background(), &withdrawFiatRequest) if err != common.ErrFunctionNotSupported { t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, @@ -1889,7 +1936,8 @@ func TestWithdrawInternationalBank(t *testing.T) { TestSetRealOrderDefaults(t) t.Parallel() var withdrawFiatRequest = withdraw.Request{} - _, err := o.WithdrawFiatFundsToInternationalBank(&withdrawFiatRequest) + _, err := o.WithdrawFiatFundsToInternationalBank(context.Background(), + &withdrawFiatRequest) if err != common.ErrFunctionNotSupported { t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, @@ -1900,19 +1948,22 @@ func TestWithdrawInternationalBank(t *testing.T) { // TestGetOrderbook logic test func TestGetOrderbook(t *testing.T) { t.Parallel() - _, err := o.GetOrderBook(okgroup.GetOrderBookRequest{InstrumentID: "BTC-USDT"}, + _, err := o.GetOrderBook(context.Background(), + okgroup.GetOrderBookRequest{InstrumentID: "BTC-USDT"}, asset.Spot) if err != nil { t.Error(err) } contract := getFutureInstrumentID() - _, err = o.GetOrderBook(okgroup.GetOrderBookRequest{InstrumentID: contract}, + _, err = o.GetOrderBook(context.Background(), + okgroup.GetOrderBookRequest{InstrumentID: contract}, asset.Futures) if err != nil { t.Error(err) } - _, err = o.GetOrderBook(okgroup.GetOrderBookRequest{InstrumentID: "BTC-USD-SWAP"}, + _, err = o.GetOrderBook(context.Background(), + okgroup.GetOrderBookRequest{InstrumentID: "BTC-USD-SWAP"}, asset.PerpetualSwap) if err != nil { t.Error(err) @@ -1920,7 +1971,7 @@ func TestGetOrderbook(t *testing.T) { } func TestUpdateTradablePairs(t *testing.T) { - err := o.UpdateTradablePairs(true) + err := o.UpdateTradablePairs(context.Background(), true) if err != nil { t.Fatal(err) } @@ -2236,7 +2287,7 @@ func TestGetRecentTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = o.GetRecentTrades(currencyPair, asset.PerpetualSwap) + _, err = o.GetRecentTrades(context.Background(), currencyPair, asset.PerpetualSwap) if err != nil { t.Error(err) } @@ -2248,7 +2299,8 @@ func TestGetHistoricTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = o.GetHistoricTrades(currencyPair, asset.PerpetualSwap, time.Now().Add(-time.Minute*15), time.Now()) + _, err = o.GetHistoricTrades(context.Background(), + currencyPair, asset.PerpetualSwap, time.Now().Add(-time.Minute*15), time.Now()) if err != nil && err != common.ErrFunctionNotSupported { t.Error(err) } @@ -2260,7 +2312,7 @@ func TestUpdateTicker(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = o.UpdateTicker(cp, asset.Spot) + _, err = o.UpdateTicker(context.Background(), cp, asset.Spot) if err != nil { t.Error(err) } @@ -2268,7 +2320,7 @@ func TestUpdateTicker(t *testing.T) { func TestUpdateTickers(t *testing.T) { t.Parallel() - err := o.UpdateTickers(asset.Spot) + err := o.UpdateTickers(context.Background(), asset.Spot) if err != nil { t.Error(err) } diff --git a/exchanges/okex/okex_wrapper.go b/exchanges/okex/okex_wrapper.go index 241b5de0..00ab4549 100644 --- a/exchanges/okex/okex_wrapper.go +++ b/exchanges/okex/okex_wrapper.go @@ -1,6 +1,7 @@ package okex import ( + "context" "errors" "fmt" "sort" @@ -37,7 +38,7 @@ func (o *OKEX) GetDefaultConfig() (*config.ExchangeConfig, error) { } if o.Features.Supports.RESTCapabilities.AutoPairUpdates { - err = o.UpdateTradablePairs(true) + err = o.UpdateTradablePairs(context.TODO(), true) if err != nil { return nil, err } @@ -291,7 +292,7 @@ func (o *OKEX) Run() { return } - err = o.UpdateTradablePairs(forceUpdate) + err = o.UpdateTradablePairs(context.TODO(), forceUpdate) if err != nil { log.Errorf(log.ExchangeSys, "%s failed to update tradable pairs. Err: %s", @@ -301,7 +302,7 @@ func (o *OKEX) Run() { } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (o *OKEX) FetchTradablePairs(i asset.Item) ([]string, error) { +func (o *OKEX) FetchTradablePairs(ctx context.Context, i asset.Item) ([]string, error) { var pairs []string format, err := o.GetPairFormat(i, false) @@ -311,7 +312,7 @@ func (o *OKEX) FetchTradablePairs(i asset.Item) ([]string, error) { switch i { case asset.Spot: - prods, err := o.GetSpotTokenPairDetails() + prods, err := o.GetSpotTokenPairDetails(ctx) if err != nil { return nil, err } @@ -324,7 +325,7 @@ func (o *OKEX) FetchTradablePairs(i asset.Item) ([]string, error) { } return pairs, nil case asset.Futures: - prods, err := o.GetFuturesContractInformation() + prods, err := o.GetFuturesContractInformation(ctx) if err != nil { return nil, err } @@ -336,7 +337,7 @@ func (o *OKEX) FetchTradablePairs(i asset.Item) ([]string, error) { return pairs, nil case asset.PerpetualSwap: - prods, err := o.GetSwapContractInformation() + prods, err := o.GetSwapContractInformation(ctx) if err != nil { return nil, err } @@ -360,7 +361,7 @@ func (o *OKEX) FetchTradablePairs(i asset.Item) ([]string, error) { // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (o *OKEX) UpdateTradablePairs(forceUpdate bool) error { +func (o *OKEX) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { assets := o.CurrencyPairs.GetAssetTypes(false) for x := range assets { if assets[x] == asset.Index { @@ -368,7 +369,7 @@ func (o *OKEX) UpdateTradablePairs(forceUpdate bool) error { continue } - pairs, err := o.FetchTradablePairs(assets[x]) + pairs, err := o.FetchTradablePairs(ctx, assets[x]) if err != nil { return err } @@ -425,10 +426,10 @@ func (o *OKEX) UpdateTradablePairs(forceUpdate bool) error { } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (o *OKEX) UpdateTickers(a asset.Item) error { +func (o *OKEX) UpdateTickers(ctx context.Context, a asset.Item) error { switch a { case asset.Spot: - resp, err := o.GetSpotAllTokenPairsInformation() + resp, err := o.GetSpotAllTokenPairsInformation(ctx) if err != nil { return err } @@ -462,7 +463,7 @@ func (o *OKEX) UpdateTickers(a asset.Item) error { } case asset.PerpetualSwap: - resp, err := o.GetAllSwapTokensInformation() + resp, err := o.GetAllSwapTokensInformation(ctx) if err != nil { return err } @@ -498,7 +499,7 @@ func (o *OKEX) UpdateTickers(a asset.Item) error { } case asset.Futures: - resp, err := o.GetAllFuturesTokenInfo() + resp, err := o.GetAllFuturesTokenInfo(ctx) if err != nil { return err } @@ -538,8 +539,8 @@ func (o *OKEX) UpdateTickers(a asset.Item) error { } // UpdateTicker updates and returns the ticker for a currency pair -func (o *OKEX) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) { - err := o.UpdateTickers(a) +func (o *OKEX) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { + err := o.UpdateTickers(ctx, a) if err != nil { return nil, err } @@ -547,7 +548,7 @@ func (o *OKEX) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error } // FetchTicker returns the ticker for a currency pair -func (o *OKEX) FetchTicker(p currency.Pair, assetType asset.Item) (tickerData *ticker.Price, err error) { +func (o *OKEX) FetchTicker(ctx context.Context, p currency.Pair, assetType asset.Item) (tickerData *ticker.Price, err error) { if assetType == asset.Index { return tickerData, errors.New("ticker fetching not supported for index") } @@ -558,13 +559,13 @@ func (o *OKEX) FetchTicker(p currency.Pair, assetType asset.Item) (tickerData *t tickerData, err = ticker.GetTicker(o.Name, fPair, assetType) if err != nil { - return o.UpdateTicker(fPair, assetType) + return o.UpdateTicker(ctx, fPair, assetType) } return } // GetRecentTrades returns recent trade data -func (o *OKEX) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade.Data, error) { +func (o *OKEX) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { var err error p, err = o.FormatExchangeCurrency(p, assetType) if err != nil { @@ -575,9 +576,10 @@ func (o *OKEX) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade.D switch assetType { case asset.Spot: var tradeData []okgroup.GetSpotFilledOrdersInformationResponse - tradeData, err = o.GetSpotFilledOrdersInformation(okgroup.GetSpotFilledOrdersInformationRequest{ - InstrumentID: p.String(), - }) + tradeData, err = o.GetSpotFilledOrdersInformation(ctx, + okgroup.GetSpotFilledOrdersInformationRequest{ + InstrumentID: p.String(), + }) if err != nil { return nil, err } @@ -599,9 +601,10 @@ func (o *OKEX) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade.D } case asset.Futures: var tradeData []okgroup.GetFuturesFilledOrdersResponse - tradeData, err = o.GetFuturesFilledOrder(okgroup.GetFuturesFilledOrderRequest{ - InstrumentID: p.String(), - }) + tradeData, err = o.GetFuturesFilledOrder(ctx, + okgroup.GetFuturesFilledOrderRequest{ + InstrumentID: p.String(), + }) if err != nil { return nil, err } @@ -623,9 +626,10 @@ func (o *OKEX) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade.D } case asset.PerpetualSwap: var tradeData []okgroup.GetSwapFilledOrdersDataResponse - tradeData, err = o.GetSwapFilledOrdersData(&okgroup.GetSwapFilledOrdersDataRequest{ - InstrumentID: p.String(), - }) + tradeData, err = o.GetSwapFilledOrdersData(ctx, + &okgroup.GetSwapFilledOrdersDataRequest{ + InstrumentID: p.String(), + }) if err != nil { return nil, err } @@ -659,6 +663,6 @@ func (o *OKEX) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade.D } // CancelBatchOrders cancels an orders by their corresponding ID numbers -func (o *OKEX) CancelBatchOrders(_ []order.Cancel) (order.CancelBatchResponse, error) { +func (o *OKEX) CancelBatchOrders(_ context.Context, _ []order.Cancel) (order.CancelBatchResponse, error) { return order.CancelBatchResponse{}, common.ErrNotYetImplemented } diff --git a/exchanges/okgroup/okgroup.go b/exchanges/okgroup/okgroup.go index d023132c..28e0f0f1 100644 --- a/exchanges/okgroup/okgroup.go +++ b/exchanges/okgroup/okgroup.go @@ -99,12 +99,12 @@ type OKGroup struct { } // GetAccountCurrencies returns a list of tradable spot instruments and their properties -func (o *OKGroup) GetAccountCurrencies() (resp []GetAccountCurrenciesResponse, _ error) { - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupAccountSubsection, okGroupGetAccountCurrencies, nil, &resp, true) +func (o *OKGroup) GetAccountCurrencies(ctx context.Context) (resp []GetAccountCurrenciesResponse, _ error) { + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupAccountSubsection, okGroupGetAccountCurrencies, nil, &resp, true) } // GetAccountWalletInformation returns a list of wallets and their properties -func (o *OKGroup) GetAccountWalletInformation(currency string) (resp []WalletInformationResponse, _ error) { +func (o *OKGroup) GetAccountWalletInformation(ctx context.Context, currency string) (resp []WalletInformationResponse, _ error) { var requestURL string if currency != "" { requestURL = fmt.Sprintf("%v/%v", okGroupGetAccountWalletInformation, currency) @@ -112,21 +112,21 @@ func (o *OKGroup) GetAccountWalletInformation(currency string) (resp []WalletInf requestURL = okGroupGetAccountWalletInformation } - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupAccountSubsection, requestURL, nil, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupAccountSubsection, requestURL, nil, &resp, true) } // TransferAccountFunds the transfer of funds between wallet, trading accounts, main account and sub accounts. -func (o *OKGroup) TransferAccountFunds(request TransferAccountFundsRequest) (resp TransferAccountFundsResponse, _ error) { - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodPost, okGroupAccountSubsection, okGroupFundsTransfer, request, &resp, true) +func (o *OKGroup) TransferAccountFunds(ctx context.Context, request TransferAccountFundsRequest) (resp TransferAccountFundsResponse, _ error) { + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, okGroupAccountSubsection, okGroupFundsTransfer, request, &resp, true) } // AccountWithdraw withdrawal of tokens to OKCoin International, other OKEx accounts or other addresses. -func (o *OKGroup) AccountWithdraw(request AccountWithdrawRequest) (resp AccountWithdrawResponse, _ error) { - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodPost, okGroupAccountSubsection, okGroupWithdraw, request, &resp, true) +func (o *OKGroup) AccountWithdraw(ctx context.Context, request AccountWithdrawRequest) (resp AccountWithdrawResponse, _ error) { + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, okGroupAccountSubsection, okGroupWithdraw, request, &resp, true) } // GetAccountWithdrawalFee retrieves the information about the recommended network transaction fee for withdrawals to digital asset addresses. The higher the fees are, the sooner the confirmations you will get. -func (o *OKGroup) GetAccountWithdrawalFee(currency string) (resp []GetAccountWithdrawalFeeResponse, _ error) { +func (o *OKGroup) GetAccountWithdrawalFee(ctx context.Context, currency string) (resp []GetAccountWithdrawalFeeResponse, _ error) { var requestURL string if currency != "" { requestURL = fmt.Sprintf("%v?currency=%v", okGroupGetWithdrawalFees, currency) @@ -134,77 +134,77 @@ func (o *OKGroup) GetAccountWithdrawalFee(currency string) (resp []GetAccountWit requestURL = okGroupGetAccountWalletInformation } - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupAccountSubsection, requestURL, nil, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupAccountSubsection, requestURL, nil, &resp, true) } // GetAccountWithdrawalHistory retrieves all recent withdrawal records. -func (o *OKGroup) GetAccountWithdrawalHistory(currency string) (resp []WithdrawalHistoryResponse, _ error) { +func (o *OKGroup) GetAccountWithdrawalHistory(ctx context.Context, currency string) (resp []WithdrawalHistoryResponse, _ error) { var requestURL string if currency != "" { requestURL = fmt.Sprintf("%v/%v", okGroupGetWithdrawalHistory, currency) } else { requestURL = okGroupGetWithdrawalHistory } - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupAccountSubsection, requestURL, nil, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupAccountSubsection, requestURL, nil, &resp, true) } // GetAccountBillDetails retrieves the bill details of the wallet. All the information will be paged and sorted in reverse chronological order, // which means the latest will be at the top. Please refer to the pagination section for additional records after the first page. // 3 months recent records will be returned at maximum -func (o *OKGroup) GetAccountBillDetails(request GetAccountBillDetailsRequest) (resp []GetAccountBillDetailsResponse, _ error) { +func (o *OKGroup) GetAccountBillDetails(ctx context.Context, request GetAccountBillDetailsRequest) (resp []GetAccountBillDetailsResponse, _ error) { requestURL := fmt.Sprintf("%v%v", OKGroupLedger, FormatParameters(request)) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupAccountSubsection, requestURL, nil, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupAccountSubsection, requestURL, nil, &resp, true) } // GetAccountDepositAddressForCurrency retrieves the deposit addresses of different tokens, including previously used addresses. -func (o *OKGroup) GetAccountDepositAddressForCurrency(currency string) (resp []GetDepositAddressResponse, _ error) { +func (o *OKGroup) GetAccountDepositAddressForCurrency(ctx context.Context, currency string) (resp []GetDepositAddressResponse, _ error) { urlValues := url.Values{} urlValues.Set("currency", currency) requestURL := fmt.Sprintf("%v?%v", okGroupGetDepositAddress, urlValues.Encode()) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupAccountSubsection, requestURL, nil, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupAccountSubsection, requestURL, nil, &resp, true) } // GetAccountDepositHistory retrieves the deposit history of all tokens.100 recent records will be returned at maximum -func (o *OKGroup) GetAccountDepositHistory(currency string) (resp []GetAccountDepositHistoryResponse, _ error) { +func (o *OKGroup) GetAccountDepositHistory(ctx context.Context, currency string) (resp []GetAccountDepositHistoryResponse, _ error) { var requestURL string if currency != "" { requestURL = fmt.Sprintf("%v/%v", OKGroupGetAccountDepositHistory, currency) } else { requestURL = OKGroupGetAccountDepositHistory } - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupAccountSubsection, requestURL, nil, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupAccountSubsection, requestURL, nil, &resp, true) } // GetSpotTradingAccounts retrieves the list of assets(only show pairs with balance larger than 0), the balances, amount available/on hold in spot accounts. -func (o *OKGroup) GetSpotTradingAccounts() (resp []GetSpotTradingAccountResponse, _ error) { - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupTokenSubsection, OKGroupAccounts, nil, &resp, true) +func (o *OKGroup) GetSpotTradingAccounts(ctx context.Context) (resp []GetSpotTradingAccountResponse, _ error) { + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupTokenSubsection, OKGroupAccounts, nil, &resp, true) } // GetSpotTradingAccountForCurrency This endpoint supports getting the balance, amount available/on hold of a token in spot account. -func (o *OKGroup) GetSpotTradingAccountForCurrency(currency string) (resp GetSpotTradingAccountResponse, _ error) { +func (o *OKGroup) GetSpotTradingAccountForCurrency(ctx context.Context, currency string) (resp GetSpotTradingAccountResponse, _ error) { requestURL := fmt.Sprintf("%v/%v", OKGroupAccounts, currency) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupTokenSubsection, requestURL, nil, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupTokenSubsection, requestURL, nil, &resp, true) } // GetSpotBillDetailsForCurrency This endpoint supports getting the balance, amount available/on hold of a token in spot account. -func (o *OKGroup) GetSpotBillDetailsForCurrency(request GetSpotBillDetailsForCurrencyRequest) (resp []GetSpotBillDetailsForCurrencyResponse, _ error) { +func (o *OKGroup) GetSpotBillDetailsForCurrency(ctx context.Context, request GetSpotBillDetailsForCurrencyRequest) (resp []GetSpotBillDetailsForCurrencyResponse, _ error) { requestURL := fmt.Sprintf("%v/%v/%v%v", OKGroupAccounts, request.Currency, OKGroupLedger, FormatParameters(request)) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupTokenSubsection, requestURL, nil, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupTokenSubsection, requestURL, nil, &resp, true) } // PlaceSpotOrder token trading only supports limit and market orders (more order types will become available in the future). // You can place an order only if you have enough funds. // Once your order is placed, the amount will be put on hold. -func (o *OKGroup) PlaceSpotOrder(request *PlaceOrderRequest) (resp PlaceOrderResponse, _ error) { +func (o *OKGroup) PlaceSpotOrder(ctx context.Context, request *PlaceOrderRequest) (resp PlaceOrderResponse, _ error) { if request.OrderType == "" { request.OrderType = strconv.Itoa(NormalOrder) } - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodPost, okGroupTokenSubsection, OKGroupOrders, request, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, okGroupTokenSubsection, OKGroupOrders, request, &resp, true) } // PlaceMultipleSpotOrders supports placing multiple orders for specific trading pairs // up to 4 trading pairs, maximum 4 orders for each pair -func (o *OKGroup) PlaceMultipleSpotOrders(request []PlaceOrderRequest) (map[string][]PlaceOrderResponse, []error) { +func (o *OKGroup) PlaceMultipleSpotOrders(ctx context.Context, request []PlaceOrderRequest) (map[string][]PlaceOrderResponse, []error) { currencyPairOrders := make(map[string]int) resp := make(map[string][]PlaceOrderResponse) @@ -224,7 +224,7 @@ func (o *OKGroup) PlaceMultipleSpotOrders(request []PlaceOrderRequest) (map[stri } } - err := o.SendHTTPRequest(exchange.RestSpot, http.MethodPost, okGroupTokenSubsection, OKGroupBatchOrders, request, &resp, true) + err := o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, okGroupTokenSubsection, OKGroupBatchOrders, request, &resp, true) if err != nil { return resp, []error{err} } @@ -242,19 +242,19 @@ func (o *OKGroup) PlaceMultipleSpotOrders(request []PlaceOrderRequest) (map[stri } // CancelSpotOrder Cancelling an unfilled order. -func (o *OKGroup) CancelSpotOrder(request CancelSpotOrderRequest) (resp CancelSpotOrderResponse, _ error) { +func (o *OKGroup) CancelSpotOrder(ctx context.Context, request CancelSpotOrderRequest) (resp CancelSpotOrderResponse, _ error) { requestURL := fmt.Sprintf("%v/%v", OKGroupCancelOrders, request.OrderID) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodPost, okGroupTokenSubsection, requestURL, request, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, okGroupTokenSubsection, requestURL, request, &resp, true) } // CancelMultipleSpotOrders Cancelling multiple unfilled orders. -func (o *OKGroup) CancelMultipleSpotOrders(request CancelMultipleSpotOrdersRequest) (resp map[string][]CancelMultipleSpotOrdersResponse, err error) { +func (o *OKGroup) CancelMultipleSpotOrders(ctx context.Context, request CancelMultipleSpotOrdersRequest) (resp map[string][]CancelMultipleSpotOrdersResponse, err error) { resp = make(map[string][]CancelMultipleSpotOrdersResponse) if len(request.OrderIDs) > 4 { return resp, errors.New("maximum 4 order cancellations for each pair") } - err = o.SendHTTPRequest(exchange.RestSpot, http.MethodPost, okGroupTokenSubsection, OKGroupCancelBatchOrders, []CancelMultipleSpotOrdersRequest{request}, &resp, true) + err = o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, okGroupTokenSubsection, OKGroupCancelBatchOrders, []CancelMultipleSpotOrdersRequest{request}, &resp, true) if err != nil { return } @@ -280,41 +280,41 @@ func (o *OKGroup) CancelMultipleSpotOrders(request CancelMultipleSpotOrdersReque // GetSpotOrders List your orders. Cursor pagination is used. // All paginated requests return the latest information (newest) as the first page sorted by newest (in chronological time) first. -func (o *OKGroup) GetSpotOrders(request GetSpotOrdersRequest) (resp []GetSpotOrderResponse, _ error) { +func (o *OKGroup) GetSpotOrders(ctx context.Context, request GetSpotOrdersRequest) (resp []GetSpotOrderResponse, _ error) { requestURL := fmt.Sprintf("%v%v", OKGroupOrders, FormatParameters(request)) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupTokenSubsection, requestURL, nil, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupTokenSubsection, requestURL, nil, &resp, true) } // GetSpotOpenOrders List all your current open orders. Cursor pagination is used. // All paginated requests return the latest information (newest) as the first page sorted by newest (in chronological time) first. -func (o *OKGroup) GetSpotOpenOrders(request GetSpotOpenOrdersRequest) (resp []GetSpotOrderResponse, _ error) { +func (o *OKGroup) GetSpotOpenOrders(ctx context.Context, request GetSpotOpenOrdersRequest) (resp []GetSpotOrderResponse, _ error) { requestURL := fmt.Sprintf("%v%v", OKGroupPendingOrders, FormatParameters(request)) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupTokenSubsection, requestURL, nil, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupTokenSubsection, requestURL, nil, &resp, true) } // GetSpotOrder Get order details by order ID. -func (o *OKGroup) GetSpotOrder(request GetSpotOrderRequest) (resp GetSpotOrderResponse, _ error) { +func (o *OKGroup) GetSpotOrder(ctx context.Context, request GetSpotOrderRequest) (resp GetSpotOrderResponse, _ error) { requestURL := fmt.Sprintf("%v/%v%v", OKGroupOrders, request.OrderID, FormatParameters(request)) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupTokenSubsection, requestURL, request, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupTokenSubsection, requestURL, request, &resp, true) } // GetSpotTransactionDetails Get details of the recent filled orders. Cursor pagination is used. // All paginated requests return the latest information (newest) as the first page sorted by newest (in chronological time) first. -func (o *OKGroup) GetSpotTransactionDetails(request GetSpotTransactionDetailsRequest) (resp []GetSpotTransactionDetailsResponse, _ error) { +func (o *OKGroup) GetSpotTransactionDetails(ctx context.Context, request GetSpotTransactionDetailsRequest) (resp []GetSpotTransactionDetailsResponse, _ error) { requestURL := fmt.Sprintf("%v%v", OKGroupGetSpotTransactionDetails, FormatParameters(request)) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupTokenSubsection, requestURL, nil, &resp, false) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupTokenSubsection, requestURL, nil, &resp, false) } // GetSpotTokenPairDetails Get market data. This endpoint provides the snapshots of market data and can be used without verifications. // List trading pairs and get the trading limit, price, and more information of different trading pairs. -func (o *OKGroup) GetSpotTokenPairDetails() (resp []GetSpotTokenPairDetailsResponse, _ error) { - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupTokenSubsection, OKGroupInstruments, nil, &resp, false) +func (o *OKGroup) GetSpotTokenPairDetails(ctx context.Context) (resp []GetSpotTokenPairDetailsResponse, _ error) { + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupTokenSubsection, OKGroupInstruments, nil, &resp, false) } // GetOrderBook Getting the order book of a trading pair. Pagination is not // supported here. The whole book will be returned for one request. Websocket is // recommended here. -func (o *OKGroup) GetOrderBook(request GetOrderBookRequest, a asset.Item) (resp GetOrderBookResponse, _ error) { +func (o *OKGroup) GetOrderBook(ctx context.Context, request GetOrderBookRequest, a asset.Item) (resp GetOrderBookResponse, _ error) { var requestType, endpoint string switch a { case asset.Spot: @@ -334,7 +334,7 @@ func (o *OKGroup) GetOrderBook(request GetOrderBookRequest, a asset.Item) (resp request.InstrumentID, endpoint, FormatParameters(request)) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, requestType, requestURL, nil, @@ -343,26 +343,26 @@ func (o *OKGroup) GetOrderBook(request GetOrderBookRequest, a asset.Item) (resp } // GetSpotAllTokenPairsInformation Get the last traded price, best bid/ask price, 24 hour trading volume and more info of all trading pairs. -func (o *OKGroup) GetSpotAllTokenPairsInformation() (resp []GetSpotTokenPairsInformationResponse, _ error) { +func (o *OKGroup) GetSpotAllTokenPairsInformation(ctx context.Context) (resp []GetSpotTokenPairsInformationResponse, _ error) { requestURL := fmt.Sprintf("%v/%v", OKGroupInstruments, OKGroupTicker) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupTokenSubsection, requestURL, nil, &resp, false) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupTokenSubsection, requestURL, nil, &resp, false) } // GetSpotAllTokenPairsInformationForCurrency Get the last traded price, best bid/ask price, 24 hour trading volume and more info of a currency -func (o *OKGroup) GetSpotAllTokenPairsInformationForCurrency(currency string) (resp GetSpotTokenPairsInformationResponse, _ error) { +func (o *OKGroup) GetSpotAllTokenPairsInformationForCurrency(ctx context.Context, currency string) (resp GetSpotTokenPairsInformationResponse, _ error) { requestURL := fmt.Sprintf("%v/%v/%v", OKGroupInstruments, currency, OKGroupTicker) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupTokenSubsection, requestURL, nil, &resp, false) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupTokenSubsection, requestURL, nil, &resp, false) } // GetSpotFilledOrdersInformation Get the recent 60 transactions of all trading pairs. // Cursor pagination is used. All paginated requests return the latest information (newest) as the first page sorted by newest (in chronological time) first. -func (o *OKGroup) GetSpotFilledOrdersInformation(request GetSpotFilledOrdersInformationRequest) (resp []GetSpotFilledOrdersInformationResponse, _ error) { +func (o *OKGroup) GetSpotFilledOrdersInformation(ctx context.Context, request GetSpotFilledOrdersInformationRequest) (resp []GetSpotFilledOrdersInformationResponse, _ error) { requestURL := fmt.Sprintf("%v/%v/%v%v", OKGroupInstruments, request.InstrumentID, OKGroupTrades, FormatParameters(request)) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupTokenSubsection, requestURL, nil, &resp, false) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupTokenSubsection, requestURL, nil, &resp, false) } // GetMarketData Get the charts of the trading pairs. Charts are returned in grouped buckets based on requested granularity. -func (o *OKGroup) GetMarketData(request *GetMarketDataRequest) (resp GetMarketDataResponse, err error) { +func (o *OKGroup) GetMarketData(ctx context.Context, request *GetMarketDataRequest) (resp GetMarketDataResponse, err error) { requestURL := fmt.Sprintf("%v/%v/%v%v", OKGroupInstruments, request.InstrumentID, OKGroupGetSpotMarketData, FormatParameters(request)) var requestType string switch request.Asset { @@ -375,73 +375,73 @@ func (o *OKGroup) GetMarketData(request *GetMarketDataRequest) (resp GetMarketDa default: return nil, errors.New("asset not supported") } - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, requestType, requestURL, nil, &resp, false) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, requestType, requestURL, nil, &resp, false) } // GetMarginTradingAccounts List all assets under token margin trading account, including information such as balance, amount on hold and more. -func (o *OKGroup) GetMarginTradingAccounts() (resp []GetMarginAccountsResponse, _ error) { - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupMarginTradingSubsection, OKGroupAccounts, nil, &resp, true) +func (o *OKGroup) GetMarginTradingAccounts(ctx context.Context) (resp []GetMarginAccountsResponse, _ error) { + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupMarginTradingSubsection, OKGroupAccounts, nil, &resp, true) } // GetMarginTradingAccountsForCurrency Get the balance, amount on hold and more useful information. -func (o *OKGroup) GetMarginTradingAccountsForCurrency(currency string) (resp GetMarginAccountsResponse, _ error) { +func (o *OKGroup) GetMarginTradingAccountsForCurrency(ctx context.Context, currency string) (resp GetMarginAccountsResponse, _ error) { requestURL := fmt.Sprintf("%v/%v", OKGroupAccounts, currency) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupMarginTradingSubsection, requestURL, nil, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupMarginTradingSubsection, requestURL, nil, &resp, true) } // GetMarginBillDetails List all bill details. Pagination is used here. // before and after cursor arguments should not be confused with before and after in chronological time. // Most paginated requests return the latest information (newest) as the first page sorted by newest (in chronological time) first. -func (o *OKGroup) GetMarginBillDetails(request GetMarginBillDetailsRequest) (resp []GetSpotBillDetailsForCurrencyResponse, _ error) { +func (o *OKGroup) GetMarginBillDetails(ctx context.Context, request GetMarginBillDetailsRequest) (resp []GetSpotBillDetailsForCurrencyResponse, _ error) { requestURL := fmt.Sprintf("%v/%v/%v%v", OKGroupAccounts, request.InstrumentID, OKGroupLedger, FormatParameters(request)) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupMarginTradingSubsection, requestURL, nil, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupMarginTradingSubsection, requestURL, nil, &resp, true) } // GetMarginAccountSettings Get all information of the margin trading account, // including the maximum loan amount, interest rate, and maximum leverage. -func (o *OKGroup) GetMarginAccountSettings(currency string) (resp []GetMarginAccountSettingsResponse, _ error) { +func (o *OKGroup) GetMarginAccountSettings(ctx context.Context, currency string) (resp []GetMarginAccountSettingsResponse, _ error) { var requestURL string if currency != "" { requestURL = fmt.Sprintf("%v/%v/%v", OKGroupAccounts, currency, okGroupGetMarketAvailability) } else { requestURL = fmt.Sprintf("%v/%v", OKGroupAccounts, okGroupGetMarketAvailability) } - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupMarginTradingSubsection, requestURL, nil, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupMarginTradingSubsection, requestURL, nil, &resp, true) } // GetMarginLoanHistory Get loan history of the margin trading account. // Pagination is used here. before and after cursor arguments should not be confused with before and after in chronological time. // Most paginated requests return the latest information (newest) as the first page sorted by newest (in chronological time) first. -func (o *OKGroup) GetMarginLoanHistory(request GetMarginLoanHistoryRequest) (resp []GetMarginLoanHistoryResponse, _ error) { +func (o *OKGroup) GetMarginLoanHistory(ctx context.Context, request GetMarginLoanHistoryRequest) (resp []GetMarginLoanHistoryResponse, _ error) { var requestURL string if len(request.InstrumentID) > 0 { requestURL = fmt.Sprintf("%v/%v/%v", OKGroupAccounts, request.InstrumentID, okGroupGetLoan) } else { requestURL = fmt.Sprintf("%v/%v", OKGroupAccounts, okGroupGetLoan) } - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupMarginTradingSubsection, requestURL, nil, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupMarginTradingSubsection, requestURL, nil, &resp, true) } // OpenMarginLoan Borrowing tokens in a margin trading account. -func (o *OKGroup) OpenMarginLoan(request OpenMarginLoanRequest) (resp OpenMarginLoanResponse, _ error) { +func (o *OKGroup) OpenMarginLoan(ctx context.Context, request OpenMarginLoanRequest) (resp OpenMarginLoanResponse, _ error) { requestURL := fmt.Sprintf("%v/%v", OKGroupAccounts, okGroupGetLoan) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodPost, okGroupMarginTradingSubsection, requestURL, request, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, okGroupMarginTradingSubsection, requestURL, request, &resp, true) } // RepayMarginLoan Repaying tokens in a margin trading account. -func (o *OKGroup) RepayMarginLoan(request RepayMarginLoanRequest) (resp RepayMarginLoanResponse, _ error) { +func (o *OKGroup) RepayMarginLoan(ctx context.Context, request RepayMarginLoanRequest) (resp RepayMarginLoanResponse, _ error) { requestURL := fmt.Sprintf("%v/%v", OKGroupAccounts, okGroupGetRepayment) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodPost, okGroupMarginTradingSubsection, requestURL, request, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, okGroupMarginTradingSubsection, requestURL, request, &resp, true) } // PlaceMarginOrder OKEx API only supports limit and market orders (more orders will become available in the future). // You can place an order only if you have enough funds. Once your order is placed, the amount will be put on hold. -func (o *OKGroup) PlaceMarginOrder(request *PlaceOrderRequest) (resp PlaceOrderResponse, _ error) { - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodPost, okGroupMarginTradingSubsection, OKGroupOrders, request, &resp, true) +func (o *OKGroup) PlaceMarginOrder(ctx context.Context, request *PlaceOrderRequest) (resp PlaceOrderResponse, _ error) { + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, okGroupMarginTradingSubsection, OKGroupOrders, request, &resp, true) } // PlaceMultipleMarginOrders Place multiple orders for specific trading pairs (up to 4 trading pairs, maximum 4 orders each) -func (o *OKGroup) PlaceMultipleMarginOrders(request []PlaceOrderRequest) (map[string][]PlaceOrderResponse, []error) { +func (o *OKGroup) PlaceMultipleMarginOrders(ctx context.Context, request []PlaceOrderRequest) (map[string][]PlaceOrderResponse, []error) { currencyPairOrders := make(map[string]int) resp := make(map[string][]PlaceOrderResponse) for i := range request { @@ -456,7 +456,7 @@ func (o *OKGroup) PlaceMultipleMarginOrders(request []PlaceOrderRequest) (map[st } } - err := o.SendHTTPRequest(exchange.RestSpot, http.MethodPost, okGroupMarginTradingSubsection, OKGroupBatchOrders, request, &resp, true) + err := o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, okGroupMarginTradingSubsection, OKGroupBatchOrders, request, &resp, true) if err != nil { return resp, []error{err} } @@ -474,19 +474,19 @@ func (o *OKGroup) PlaceMultipleMarginOrders(request []PlaceOrderRequest) (map[st } // CancelMarginOrder Cancelling an unfilled order. -func (o *OKGroup) CancelMarginOrder(request CancelSpotOrderRequest) (resp CancelSpotOrderResponse, _ error) { +func (o *OKGroup) CancelMarginOrder(ctx context.Context, request CancelSpotOrderRequest) (resp CancelSpotOrderResponse, _ error) { requestURL := fmt.Sprintf("%v/%v", OKGroupCancelOrders, request.OrderID) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodPost, okGroupMarginTradingSubsection, requestURL, request, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, okGroupMarginTradingSubsection, requestURL, request, &resp, true) } // CancelMultipleMarginOrders Cancelling multiple unfilled orders. -func (o *OKGroup) CancelMultipleMarginOrders(request CancelMultipleSpotOrdersRequest) (map[string][]CancelMultipleSpotOrdersResponse, []error) { +func (o *OKGroup) CancelMultipleMarginOrders(ctx context.Context, request CancelMultipleSpotOrdersRequest) (map[string][]CancelMultipleSpotOrdersResponse, []error) { resp := make(map[string][]CancelMultipleSpotOrdersResponse) if len(request.OrderIDs) > 4 { return resp, []error{errors.New("maximum 4 order cancellations for each pair")} } - err := o.SendHTTPRequest(exchange.RestSpot, http.MethodPost, okGroupMarginTradingSubsection, OKGroupCancelBatchOrders, []CancelMultipleSpotOrdersRequest{request}, &resp, true) + err := o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, okGroupMarginTradingSubsection, OKGroupCancelBatchOrders, []CancelMultipleSpotOrdersRequest{request}, &resp, true) if err != nil { return resp, []error{err} } @@ -504,28 +504,28 @@ func (o *OKGroup) CancelMultipleMarginOrders(request CancelMultipleSpotOrdersReq } // GetMarginOrders List your orders. Cursor pagination is used. All paginated requests return the latest information (newest) as the first page sorted by newest (in chronological time) first. -func (o *OKGroup) GetMarginOrders(request GetSpotOrdersRequest) (resp []GetSpotOrderResponse, _ error) { +func (o *OKGroup) GetMarginOrders(ctx context.Context, request GetSpotOrdersRequest) (resp []GetSpotOrderResponse, _ error) { requestURL := fmt.Sprintf("%v%v", OKGroupOrders, FormatParameters(request)) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupMarginTradingSubsection, requestURL, nil, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupMarginTradingSubsection, requestURL, nil, &resp, true) } // GetMarginOpenOrders List all your current open orders. Cursor pagination is used. All paginated requests return the latest information (newest) as the first page sorted by newest (in chronological time) first. -func (o *OKGroup) GetMarginOpenOrders(request GetSpotOpenOrdersRequest) (resp []GetSpotOrderResponse, _ error) { +func (o *OKGroup) GetMarginOpenOrders(ctx context.Context, request GetSpotOpenOrdersRequest) (resp []GetSpotOrderResponse, _ error) { requestURL := fmt.Sprintf("%v%v", OKGroupPendingOrders, FormatParameters(request)) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupMarginTradingSubsection, requestURL, nil, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupMarginTradingSubsection, requestURL, nil, &resp, true) } // GetMarginOrder Get order details by order ID. -func (o *OKGroup) GetMarginOrder(request GetSpotOrderRequest) (resp GetSpotOrderResponse, _ error) { +func (o *OKGroup) GetMarginOrder(ctx context.Context, request GetSpotOrderRequest) (resp GetSpotOrderResponse, _ error) { requestURL := fmt.Sprintf("%v/%v%v", OKGroupOrders, request.OrderID, FormatParameters(request)) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupMarginTradingSubsection, requestURL, request, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupMarginTradingSubsection, requestURL, request, &resp, true) } // GetMarginTransactionDetails Get details of the recent filled orders. Cursor pagination is used. // All paginated requests return the latest information (newest) as the first page sorted by newest (in chronological time) first. -func (o *OKGroup) GetMarginTransactionDetails(request GetSpotTransactionDetailsRequest) (resp []GetSpotTransactionDetailsResponse, _ error) { +func (o *OKGroup) GetMarginTransactionDetails(ctx context.Context, request GetSpotTransactionDetailsRequest) (resp []GetSpotTransactionDetailsResponse, _ error) { requestURL := fmt.Sprintf("%v%v", OKGroupGetSpotTransactionDetails, FormatParameters(request)) - return resp, o.SendHTTPRequest(exchange.RestSpot, http.MethodGet, okGroupMarginTradingSubsection, requestURL, nil, &resp, true) + return resp, o.SendHTTPRequest(ctx, exchange.RestSpot, http.MethodGet, okGroupMarginTradingSubsection, requestURL, nil, &resp, true) } // FormatParameters Formats URL parameters, useful for optional parameters due to OKEX signature check @@ -564,7 +564,7 @@ func (o *OKGroup) GetErrorCode(code interface{}) error { // SendHTTPRequest sends an authenticated http request to a desired // path with a JSON payload (of present) // URL arguments must be in the request path and not as url.URL values -func (o *OKGroup) SendHTTPRequest(ep exchange.URL, httpMethod, requestType, requestPath string, data, result interface{}, authenticated bool) (err error) { +func (o *OKGroup) SendHTTPRequest(ctx context.Context, ep exchange.URL, httpMethod, requestType, requestPath string, data, result interface{}, authenticated bool) (err error) { if authenticated && !o.AllowAuthenticatedRequest() { return fmt.Errorf("%s %w", o.Name, exchange.ErrAuthenticatedRequestWithoutCredentialsSet) } @@ -619,7 +619,7 @@ func (o *OKGroup) SendHTTPRequest(ep exchange.URL, httpMethod, requestType, requ }, nil } - err = o.SendPayload(context.Background(), request.Unset, newRequest) + err = o.SendPayload(ctx, request.Unset, newRequest) if err != nil { return err } @@ -660,12 +660,12 @@ func (o *OKGroup) SetCheckVarDefaults() { } // GetFee returns an estimate of fee based on type of transaction -func (o *OKGroup) GetFee(feeBuilder *exchange.FeeBuilder) (fee float64, _ error) { +func (o *OKGroup) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) (fee float64, _ error) { switch feeBuilder.FeeType { case exchange.CryptocurrencyTradeFee: fee = calculateTradingFee(feeBuilder.PurchasePrice, feeBuilder.Amount, feeBuilder.IsMaker) case exchange.CryptocurrencyWithdrawalFee: - withdrawFees, err := o.GetAccountWithdrawalFee(feeBuilder.FiatCurrency.String()) + withdrawFees, err := o.GetAccountWithdrawalFee(ctx, feeBuilder.FiatCurrency.String()) if err != nil { return -1, err } diff --git a/exchanges/okgroup/okgroup_wrapper.go b/exchanges/okgroup/okgroup_wrapper.go index ad25afa3..f8617efe 100644 --- a/exchanges/okgroup/okgroup_wrapper.go +++ b/exchanges/okgroup/okgroup_wrapper.go @@ -1,6 +1,7 @@ package okgroup import ( + "context" "errors" "fmt" "strconv" @@ -71,20 +72,20 @@ func (o *OKGroup) Setup(exch *config.ExchangeConfig) error { } // FetchOrderbook returns orderbook base on the currency pair -func (o *OKGroup) FetchOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (o *OKGroup) FetchOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { fPair, err := o.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err } ob, err := orderbook.Get(o.Name, fPair, assetType) if err != nil { - return o.UpdateOrderbook(fPair, assetType) + return o.UpdateOrderbook(ctx, fPair, assetType) } return ob, nil } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (o *OKGroup) UpdateOrderbook(p currency.Pair, a asset.Item) (*orderbook.Base, error) { +func (o *OKGroup) UpdateOrderbook(ctx context.Context, p currency.Pair, a asset.Item) (*orderbook.Base, error) { book := &orderbook.Base{ Exchange: o.Name, Pair: p, @@ -101,10 +102,11 @@ func (o *OKGroup) UpdateOrderbook(p currency.Pair, a asset.Item) (*orderbook.Bas return nil, err } - orderbookNew, err := o.GetOrderBook(GetOrderBookRequest{ - InstrumentID: fPair.String(), - Size: 200, - }, a) + orderbookNew, err := o.GetOrderBook(ctx, + GetOrderBookRequest{ + InstrumentID: fPair.String(), + Size: 200, + }, a) if err != nil { return book, err } @@ -182,8 +184,8 @@ func (o *OKGroup) UpdateOrderbook(p currency.Pair, a asset.Item) (*orderbook.Bas } // UpdateAccountInfo retrieves balances for all enabled currencies -func (o *OKGroup) UpdateAccountInfo(assetType asset.Item) (account.Holdings, error) { - currencies, err := o.GetSpotTradingAccounts() +func (o *OKGroup) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { + currencies, err := o.GetSpotTradingAccounts(ctx) if err != nil { return account.Holdings{}, err } @@ -220,10 +222,10 @@ func (o *OKGroup) UpdateAccountInfo(assetType asset.Item) (account.Holdings, err } // FetchAccountInfo retrieves balances for all enabled currencies -func (o *OKGroup) FetchAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (o *OKGroup) FetchAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { acc, err := account.GetHoldings(o.Name, assetType) if err != nil { - return o.UpdateAccountInfo(assetType) + return o.UpdateAccountInfo(ctx, assetType) } return acc, nil @@ -231,8 +233,8 @@ func (o *OKGroup) FetchAccountInfo(assetType asset.Item) (account.Holdings, erro // GetFundingHistory returns funding history, deposits and // withdrawals -func (o *OKGroup) GetFundingHistory() (resp []exchange.FundHistory, err error) { - accountDepositHistory, err := o.GetAccountDepositHistory("") +func (o *OKGroup) GetFundingHistory(ctx context.Context) (resp []exchange.FundHistory, err error) { + accountDepositHistory, err := o.GetAccountDepositHistory(ctx, "") if err != nil { return } @@ -257,7 +259,7 @@ func (o *OKGroup) GetFundingHistory() (resp []exchange.FundHistory, err error) { TransferType: "deposit", }) } - accountWithdrawlHistory, err := o.GetAccountWithdrawalHistory("") + accountWithdrawlHistory, err := o.GetAccountWithdrawalHistory(ctx, "") for i := range accountWithdrawlHistory { resp = append(resp, exchange.FundHistory{ Amount: accountWithdrawlHistory[i].Amount, @@ -273,7 +275,7 @@ func (o *OKGroup) GetFundingHistory() (resp []exchange.FundHistory, err error) { } // SubmitOrder submits a new order -func (o *OKGroup) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { +func (o *OKGroup) SubmitOrder(ctx context.Context, s *order.Submit) (order.SubmitResponse, error) { err := s.Validate() if err != nil { return order.SubmitResponse{}, err @@ -295,7 +297,7 @@ func (o *OKGroup) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { request.Price = strconv.FormatFloat(s.Price, 'f', -1, 64) } - orderResponse, err := o.PlaceSpotOrder(&request) + orderResponse, err := o.PlaceSpotOrder(ctx, &request) if err != nil { return order.SubmitResponse{}, err } @@ -312,12 +314,12 @@ func (o *OKGroup) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (o *OKGroup) ModifyOrder(action *order.Modify) (order.Modify, error) { +func (o *OKGroup) ModifyOrder(ctx context.Context, action *order.Modify) (order.Modify, error) { return order.Modify{}, common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number -func (o *OKGroup) CancelOrder(cancel *order.Cancel) (err error) { +func (o *OKGroup) CancelOrder(ctx context.Context, cancel *order.Cancel) (err error) { err = cancel.Validate(cancel.StandardCancel()) if err != nil { return @@ -334,10 +336,11 @@ func (o *OKGroup) CancelOrder(cancel *order.Cancel) (err error) { return } - orderCancellationResponse, err := o.CancelSpotOrder(CancelSpotOrderRequest{ - InstrumentID: fpair.String(), - OrderID: orderID, - }) + orderCancellationResponse, err := o.CancelSpotOrder(ctx, + CancelSpotOrderRequest{ + InstrumentID: fpair.String(), + OrderID: orderID, + }) if !orderCancellationResponse.Result { err = fmt.Errorf("order %d failed to be cancelled", @@ -348,7 +351,7 @@ func (o *OKGroup) CancelOrder(cancel *order.Cancel) (err error) { } // CancelAllOrders cancels all orders associated with a currency pair -func (o *OKGroup) CancelAllOrders(orderCancellation *order.Cancel) (order.CancelAllResponse, error) { +func (o *OKGroup) CancelAllOrders(ctx context.Context, orderCancellation *order.Cancel) (order.CancelAllResponse, error) { if err := orderCancellation.Validate(); err != nil { return order.CancelAllResponse{}, err } @@ -372,10 +375,11 @@ func (o *OKGroup) CancelAllOrders(orderCancellation *order.Cancel) (order.Cancel return resp, err } - cancelOrdersResponse, err := o.CancelMultipleSpotOrders(CancelMultipleSpotOrdersRequest{ - InstrumentID: fpair.String(), - OrderIDs: orderIDNumbers, - }) + cancelOrdersResponse, err := o.CancelMultipleSpotOrders(ctx, + CancelMultipleSpotOrdersRequest{ + InstrumentID: fpair.String(), + OrderIDs: orderIDNumbers, + }) if err != nil { return resp, err } @@ -390,8 +394,8 @@ func (o *OKGroup) CancelAllOrders(orderCancellation *order.Cancel) (order.Cancel } // GetOrderInfo returns order information based on order ID -func (o *OKGroup) GetOrderInfo(orderID string, pair currency.Pair, assetType asset.Item) (resp order.Detail, err error) { - mOrder, err := o.GetSpotOrder(GetSpotOrderRequest{OrderID: orderID}) +func (o *OKGroup) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (resp order.Detail, err error) { + mOrder, err := o.GetSpotOrder(ctx, GetSpotOrderRequest{OrderID: orderID}) if err != nil { return } @@ -423,8 +427,8 @@ func (o *OKGroup) GetOrderInfo(orderID string, pair currency.Pair, assetType ass } // GetDepositAddress returns a deposit address for a specified currency -func (o *OKGroup) GetDepositAddress(p currency.Code, _ string) (string, error) { - wallet, err := o.GetAccountDepositAddressForCurrency(p.Lower().String()) +func (o *OKGroup) GetDepositAddress(ctx context.Context, p currency.Code, _ string) (string, error) { + wallet, err := o.GetAccountDepositAddressForCurrency(ctx, p.Lower().String()) if err != nil || len(wallet) == 0 { return "", err } @@ -433,18 +437,19 @@ func (o *OKGroup) GetDepositAddress(p currency.Code, _ string) (string, error) { // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is // submitted -func (o *OKGroup) WithdrawCryptocurrencyFunds(withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (o *OKGroup) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } - withdrawal, err := o.AccountWithdraw(AccountWithdrawRequest{ - Amount: withdrawRequest.Amount, - Currency: withdrawRequest.Currency.Lower().String(), - Destination: 4, // 1, 2, 3 are all internal - Fee: withdrawRequest.Crypto.FeeAmount, - ToAddress: withdrawRequest.Crypto.Address, - TradePwd: withdrawRequest.TradePassword, - }) + withdrawal, err := o.AccountWithdraw(ctx, + AccountWithdrawRequest{ + Amount: withdrawRequest.Amount, + Currency: withdrawRequest.Currency.Lower().String(), + Destination: 4, // 1, 2, 3 are all internal + Fee: withdrawRequest.Crypto.FeeAmount, + ToAddress: withdrawRequest.Crypto.Address, + TradePwd: withdrawRequest.TradePassword, + }) if err != nil { return nil, err } @@ -462,23 +467,23 @@ func (o *OKGroup) WithdrawCryptocurrencyFunds(withdrawRequest *withdraw.Request) // WithdrawFiatFunds returns a withdrawal ID when a // withdrawal is submitted -func (o *OKGroup) WithdrawFiatFunds(_ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (o *OKGroup) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a // withdrawal is submitted -func (o *OKGroup) WithdrawFiatFundsToInternationalBank(_ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (o *OKGroup) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // GetWithdrawalsHistory returns previous withdrawals data -func (o *OKGroup) GetWithdrawalsHistory(c currency.Code) (resp []exchange.WithdrawalHistory, err error) { +func (o *OKGroup) GetWithdrawalsHistory(ctx context.Context, c currency.Code) (resp []exchange.WithdrawalHistory, err error) { return nil, common.ErrNotYetImplemented } // GetActiveOrders retrieves any orders that are active/open -func (o *OKGroup) GetActiveOrders(req *order.GetOrdersRequest) (resp []order.Detail, err error) { +func (o *OKGroup) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) (resp []order.Detail, err error) { err = req.Validate() if err != nil { return nil, err @@ -491,9 +496,10 @@ func (o *OKGroup) GetActiveOrders(req *order.GetOrdersRequest) (resp []order.Det return nil, err } var spotOpenOrders []GetSpotOrderResponse - spotOpenOrders, err = o.GetSpotOpenOrders(GetSpotOpenOrdersRequest{ - InstrumentID: fPair.String(), - }) + spotOpenOrders, err = o.GetSpotOpenOrders(ctx, + GetSpotOpenOrdersRequest{ + InstrumentID: fPair.String(), + }) if err != nil { return resp, err } @@ -517,7 +523,7 @@ func (o *OKGroup) GetActiveOrders(req *order.GetOrdersRequest) (resp []order.Det // GetOrderHistory retrieves account order information // Can Limit response to specific order status -func (o *OKGroup) GetOrderHistory(req *order.GetOrdersRequest) (resp []order.Detail, err error) { +func (o *OKGroup) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) (resp []order.Detail, err error) { err = req.Validate() if err != nil { return nil, err @@ -530,10 +536,11 @@ func (o *OKGroup) GetOrderHistory(req *order.GetOrdersRequest) (resp []order.Det return nil, err } var spotOpenOrders []GetSpotOrderResponse - spotOpenOrders, err = o.GetSpotOrders(GetSpotOrdersRequest{ - Status: strings.Join([]string{"filled", "cancelled", "failure"}, "|"), - InstrumentID: fPair.String(), - }) + spotOpenOrders, err = o.GetSpotOrders(ctx, + GetSpotOrdersRequest{ + Status: strings.Join([]string{"filled", "cancelled", "failure"}, "|"), + InstrumentID: fPair.String(), + }) if err != nil { return resp, err } @@ -556,12 +563,12 @@ func (o *OKGroup) GetOrderHistory(req *order.GetOrdersRequest) (resp []order.Det } // GetFeeByType returns an estimate of fee based on type of transaction -func (o *OKGroup) GetFeeByType(feeBuilder *exchange.FeeBuilder) (float64, error) { +func (o *OKGroup) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { if !o.AllowAuthenticatedRequest() && // Todo check connection status feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { feeBuilder.FeeType = exchange.OfflineTradeFee } - return o.GetFee(feeBuilder) + return o.GetFee(ctx, feeBuilder) } // GetWithdrawCapabilities returns the types of withdrawal methods permitted by the exchange @@ -570,24 +577,24 @@ func (o *OKGroup) GetWithdrawCapabilities() uint32 { } // AuthenticateWebsocket sends an authentication message to the websocket -func (o *OKGroup) AuthenticateWebsocket() error { +func (o *OKGroup) AuthenticateWebsocket(_ context.Context) error { return o.WsLogin() } // ValidateCredentials validates current credentials used for wrapper // functionality -func (o *OKGroup) ValidateCredentials(assetType asset.Item) error { - _, err := o.UpdateAccountInfo(assetType) +func (o *OKGroup) ValidateCredentials(ctx context.Context, assetType asset.Item) error { + _, err := o.UpdateAccountInfo(ctx, assetType) return o.CheckTransientError(err) } // GetHistoricTrades returns historic trade data within the timeframe provided -func (o *OKGroup) GetHistoricTrades(_ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { +func (o *OKGroup) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { return nil, common.ErrFunctionNotSupported } // GetHistoricCandles returns candles between a time period for a set time interval -func (o *OKGroup) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (o *OKGroup) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { if err := o.ValidateKline(pair, a, interval); err != nil { return kline.Item{}, err } @@ -605,7 +612,7 @@ func (o *OKGroup) GetHistoricCandles(pair currency.Pair, a asset.Item, start, en InstrumentID: formattedPair.String(), } - candles, err := o.GetMarketData(req) + candles, err := o.GetMarketData(ctx, req) if err != nil { return kline.Item{}, err } @@ -659,7 +666,7 @@ func (o *OKGroup) GetHistoricCandles(pair currency.Pair, a asset.Item, start, en } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (o *OKGroup) GetHistoricCandlesExtended(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (o *OKGroup) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { if err := o.ValidateKline(pair, a, interval); err != nil { return kline.Item{}, err } @@ -690,7 +697,7 @@ func (o *OKGroup) GetHistoricCandlesExtended(pair currency.Pair, a asset.Item, s } var candles GetMarketDataResponse - candles, err = o.GetMarketData(req) + candles, err = o.GetMarketData(ctx, req) if err != nil { return kline.Item{}, err } diff --git a/exchanges/orderbook/simulator/simulator_test.go b/exchanges/orderbook/simulator/simulator_test.go index b9e3390e..eccc94a3 100644 --- a/exchanges/orderbook/simulator/simulator_test.go +++ b/exchanges/orderbook/simulator/simulator_test.go @@ -1,6 +1,7 @@ package simulator import ( + "context" "testing" "github.com/thrasher-corp/gocryptotrader/currency" @@ -11,7 +12,8 @@ import ( func TestSimulate(t *testing.T) { b := bitstamp.Bitstamp{} b.SetDefaults() - o, err := b.FetchOrderbook(currency.NewPair(currency.BTC, currency.USD), asset.Spot) + o, err := b.FetchOrderbook(context.Background(), + currency.NewPair(currency.BTC, currency.USD), asset.Spot) if err != nil { t.Error(err) } diff --git a/exchanges/poloniex/currency_details_test.go b/exchanges/poloniex/currency_details_test.go index ffbb8d98..a23dc1aa 100644 --- a/exchanges/poloniex/currency_details_test.go +++ b/exchanges/poloniex/currency_details_test.go @@ -1,6 +1,7 @@ package poloniex import ( + "context" "errors" "testing" @@ -64,7 +65,7 @@ func TestWsCurrencyMap(t *testing.T) { t.Fatalf("expected: %v but received: %v", errCodeMapIsNil, err) } - c, err := p.GetCurrencies() + c, err := p.GetCurrencies(context.Background()) if err != nil { t.Fatal(err) } @@ -74,7 +75,7 @@ func TestWsCurrencyMap(t *testing.T) { t.Fatal(err) } - tick, err := p.GetTicker() + tick, err := p.GetTicker(context.Background()) if err != nil { t.Fatal(err) } diff --git a/exchanges/poloniex/poloniex.go b/exchanges/poloniex/poloniex.go index 6f254c82..0b74fa5f 100644 --- a/exchanges/poloniex/poloniex.go +++ b/exchanges/poloniex/poloniex.go @@ -59,7 +59,7 @@ type Poloniex struct { } // GetTicker returns current ticker information -func (p *Poloniex) GetTicker() (map[string]Ticker, error) { +func (p *Poloniex) GetTicker(ctx context.Context) (map[string]Ticker, error) { type response struct { Data map[string]Ticker } @@ -67,19 +67,19 @@ func (p *Poloniex) GetTicker() (map[string]Ticker, error) { resp := response{} path := "/public?command=returnTicker" - return resp.Data, p.SendHTTPRequest(exchange.RestSpot, path, &resp.Data) + return resp.Data, p.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp.Data) } // GetVolume returns a list of currencies with associated volume -func (p *Poloniex) GetVolume() (interface{}, error) { +func (p *Poloniex) GetVolume(ctx context.Context) (interface{}, error) { var resp interface{} path := "/public?command=return24hVolume" - return resp, p.SendHTTPRequest(exchange.RestSpot, path, &resp) + return resp, p.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) } // GetOrderbook returns the full orderbook from poloniex -func (p *Poloniex) GetOrderbook(currencyPair string, depth int) (OrderbookAll, error) { +func (p *Poloniex) GetOrderbook(ctx context.Context, currencyPair string, depth int) (OrderbookAll, error) { vals := url.Values{} if depth != 0 { @@ -91,7 +91,7 @@ func (p *Poloniex) GetOrderbook(currencyPair string, depth int) (OrderbookAll, e vals.Set("currencyPair", currencyPair) resp := OrderbookResponse{} path := fmt.Sprintf("/public?command=returnOrderBook&%s", vals.Encode()) - err := p.SendHTTPRequest(exchange.RestSpot, path, &resp) + err := p.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) if err != nil { return oba, err } @@ -125,7 +125,7 @@ func (p *Poloniex) GetOrderbook(currencyPair string, depth int) (OrderbookAll, e vals.Set("currencyPair", "all") resp := OrderbookResponseAll{} path := fmt.Sprintf("/public?command=returnOrderBook&%s", vals.Encode()) - err := p.SendHTTPRequest(exchange.RestSpot, path, &resp.Data) + err := p.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp.Data) if err != nil { return oba, err } @@ -159,7 +159,7 @@ func (p *Poloniex) GetOrderbook(currencyPair string, depth int) (OrderbookAll, e } // GetTradeHistory returns trades history from poloniex -func (p *Poloniex) GetTradeHistory(currencyPair string, start, end int64) ([]TradeHistory, error) { +func (p *Poloniex) GetTradeHistory(ctx context.Context, currencyPair string, start, end int64) ([]TradeHistory, error) { vals := url.Values{} vals.Set("currencyPair", currencyPair) @@ -174,11 +174,11 @@ func (p *Poloniex) GetTradeHistory(currencyPair string, start, end int64) ([]Tra var resp []TradeHistory path := fmt.Sprintf("/public?command=returnTradeHistory&%s", vals.Encode()) - return resp, p.SendHTTPRequest(exchange.RestSpot, path, &resp) + return resp, p.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) } // GetChartData returns chart data for a specific currency pair -func (p *Poloniex) GetChartData(currencyPair string, start, end time.Time, period string) ([]ChartData, error) { +func (p *Poloniex) GetChartData(ctx context.Context, currencyPair string, start, end time.Time, period string) ([]ChartData, error) { vals := url.Values{} vals.Set("currencyPair", currencyPair) @@ -197,7 +197,7 @@ func (p *Poloniex) GetChartData(currencyPair string, start, end time.Time, perio var temp json.RawMessage var resp []ChartData path := "/public?command=returnChartData&" + vals.Encode() - err := p.SendHTTPRequest(exchange.RestSpot, path, &temp) + err := p.SendHTTPRequest(ctx, exchange.RestSpot, path, &temp) if err != nil { return nil, err } @@ -220,28 +220,28 @@ func (p *Poloniex) GetChartData(currencyPair string, start, end time.Time, perio } // GetCurrencies returns information about currencies -func (p *Poloniex) GetCurrencies() (map[string]Currencies, error) { +func (p *Poloniex) GetCurrencies(ctx context.Context) (map[string]Currencies, error) { type Response struct { Data map[string]Currencies } resp := Response{} - return resp.Data, p.SendHTTPRequest(exchange.RestSpot, "/public?command=returnCurrencies", &resp.Data) + return resp.Data, p.SendHTTPRequest(ctx, exchange.RestSpot, "/public?command=returnCurrencies", &resp.Data) } // GetLoanOrders returns the list of loan offers and demands for a given // currency, specified by the "currency" GET parameter. -func (p *Poloniex) GetLoanOrders(currency string) (LoanOrders, error) { +func (p *Poloniex) GetLoanOrders(ctx context.Context, currency string) (LoanOrders, error) { resp := LoanOrders{} path := fmt.Sprintf("/public?command=returnLoanOrders¤cy=%s", currency) - return resp, p.SendHTTPRequest(exchange.RestSpot, path, &resp) + return resp, p.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) } // GetBalances returns balances for your account. -func (p *Poloniex) GetBalances() (Balance, error) { +func (p *Poloniex) GetBalances(ctx context.Context) (Balance, error) { var result interface{} - err := p.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, poloniexBalances, url.Values{}, &result) + err := p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexBalances, url.Values{}, &result) if err != nil { return Balance{}, err } @@ -258,11 +258,11 @@ func (p *Poloniex) GetBalances() (Balance, error) { } // GetCompleteBalances returns complete balances from your account. -func (p *Poloniex) GetCompleteBalances() (CompleteBalances, error) { +func (p *Poloniex) GetCompleteBalances(ctx context.Context) (CompleteBalances, error) { var result CompleteBalances vals := url.Values{} vals.Set("account", "all") - err := p.SendAuthenticatedHTTPRequest(exchange.RestSpot, + err := p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexBalancesComplete, vals, @@ -271,11 +271,11 @@ func (p *Poloniex) GetCompleteBalances() (CompleteBalances, error) { } // GetDepositAddresses returns deposit addresses for all enabled cryptos. -func (p *Poloniex) GetDepositAddresses() (DepositAddresses, error) { +func (p *Poloniex) GetDepositAddresses(ctx context.Context) (DepositAddresses, error) { var result interface{} addresses := DepositAddresses{} - err := p.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, poloniexDepositAddresses, url.Values{}, &result) + err := p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexDepositAddresses, url.Values{}, &result) if err != nil { return addresses, err } @@ -294,7 +294,7 @@ func (p *Poloniex) GetDepositAddresses() (DepositAddresses, error) { } // GenerateNewAddress generates a new address for a currency -func (p *Poloniex) GenerateNewAddress(currency string) (string, error) { +func (p *Poloniex) GenerateNewAddress(ctx context.Context, curr string) (string, error) { type Response struct { Success int Error string @@ -302,9 +302,9 @@ func (p *Poloniex) GenerateNewAddress(currency string) (string, error) { } resp := Response{} values := url.Values{} - values.Set("currency", currency) + values.Set("currency", curr) - err := p.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, poloniexGenerateNewAddress, values, &resp) + err := p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexGenerateNewAddress, values, &resp) if err != nil { return "", err } @@ -317,7 +317,7 @@ func (p *Poloniex) GenerateNewAddress(currency string) (string, error) { } // GetDepositsWithdrawals returns a list of deposits and withdrawals -func (p *Poloniex) GetDepositsWithdrawals(start, end string) (DepositsWithdrawals, error) { +func (p *Poloniex) GetDepositsWithdrawals(ctx context.Context, start, end string) (DepositsWithdrawals, error) { resp := DepositsWithdrawals{} values := url.Values{} @@ -333,27 +333,27 @@ func (p *Poloniex) GetDepositsWithdrawals(start, end string) (DepositsWithdrawal values.Set("end", strconv.FormatInt(time.Now().Unix(), 10)) } - return resp, p.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, poloniexDepositsWithdrawals, values, &resp) + return resp, p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexDepositsWithdrawals, values, &resp) } // GetOpenOrders returns current unfilled opened orders -func (p *Poloniex) GetOpenOrders(currency string) (OpenOrdersResponse, error) { +func (p *Poloniex) GetOpenOrders(ctx context.Context, currency string) (OpenOrdersResponse, error) { values := url.Values{} values.Set("currencyPair", currency) result := OpenOrdersResponse{} - return result, p.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, poloniexOrders, values, &result.Data) + return result, p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexOrders, values, &result.Data) } // GetOpenOrdersForAllCurrencies returns all open orders -func (p *Poloniex) GetOpenOrdersForAllCurrencies() (OpenOrdersResponseAll, error) { +func (p *Poloniex) GetOpenOrdersForAllCurrencies(ctx context.Context) (OpenOrdersResponseAll, error) { values := url.Values{} values.Set("currencyPair", "all") result := OpenOrdersResponseAll{} - return result, p.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, poloniexOrders, values, &result.Data) + return result, p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexOrders, values, &result.Data) } // GetAuthenticatedTradeHistoryForCurrency returns account trade history -func (p *Poloniex) GetAuthenticatedTradeHistoryForCurrency(currency string, start, end, limit int64) (AuthenticatedTradeHistoryResponse, error) { +func (p *Poloniex) GetAuthenticatedTradeHistoryForCurrency(ctx context.Context, currency string, start, end, limit int64) (AuthenticatedTradeHistoryResponse, error) { values := url.Values{} if start > 0 { @@ -370,11 +370,11 @@ func (p *Poloniex) GetAuthenticatedTradeHistoryForCurrency(currency string, star values.Set("currencyPair", currency) result := AuthenticatedTradeHistoryResponse{} - return result, p.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, poloniexTradeHistory, values, &result.Data) + return result, p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexTradeHistory, values, &result.Data) } // GetAuthenticatedTradeHistory returns account trade history -func (p *Poloniex) GetAuthenticatedTradeHistory(start, end, limit int64) (AuthenticatedTradeHistoryAll, error) { +func (p *Poloniex) GetAuthenticatedTradeHistory(ctx context.Context, start, end, limit int64) (AuthenticatedTradeHistoryAll, error) { values := url.Values{} if start > 0 { @@ -392,7 +392,7 @@ func (p *Poloniex) GetAuthenticatedTradeHistory(start, end, limit int64) (Authen values.Set("currencyPair", "all") var result json.RawMessage - err := p.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, poloniexTradeHistory, values, &result) + err := p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexTradeHistory, values, &result) if err != nil { return AuthenticatedTradeHistoryAll{}, err } @@ -408,7 +408,7 @@ func (p *Poloniex) GetAuthenticatedTradeHistory(start, end, limit int64) (Authen } // GetAuthenticatedOrderStatus returns the status of a given orderId. -func (p *Poloniex) GetAuthenticatedOrderStatus(orderID string) (o OrderStatusData, err error) { +func (p *Poloniex) GetAuthenticatedOrderStatus(ctx context.Context, orderID string) (o OrderStatusData, err error) { values := url.Values{} if orderID == "" { @@ -417,7 +417,7 @@ func (p *Poloniex) GetAuthenticatedOrderStatus(orderID string) (o OrderStatusDat values.Set("orderNumber", orderID) var rawOrderStatus OrderStatus - err = p.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, poloniexOrderStatus, values, &rawOrderStatus) + err = p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexOrderStatus, values, &rawOrderStatus) if err != nil { return o, err } @@ -446,7 +446,7 @@ func (p *Poloniex) GetAuthenticatedOrderStatus(orderID string) (o OrderStatusDat } // GetAuthenticatedOrderTrades returns all trades involving a given orderId. -func (p *Poloniex) GetAuthenticatedOrderTrades(orderID string) (o []OrderTrade, err error) { +func (p *Poloniex) GetAuthenticatedOrderTrades(ctx context.Context, orderID string) (o []OrderTrade, err error) { values := url.Values{} if orderID == "" { @@ -455,7 +455,7 @@ func (p *Poloniex) GetAuthenticatedOrderTrades(orderID string) (o []OrderTrade, values.Set("orderNumber", orderID) var result json.RawMessage - err = p.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, poloniexOrderTrades, values, &result) + err = p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexOrderTrades, values, &result) if err != nil { return nil, err } @@ -484,7 +484,7 @@ func (p *Poloniex) GetAuthenticatedOrderTrades(orderID string) (o []OrderTrade, } // PlaceOrder places a new order on the exchange -func (p *Poloniex) PlaceOrder(currency string, rate, amount float64, immediate, fillOrKill, buy bool) (OrderResponse, error) { +func (p *Poloniex) PlaceOrder(ctx context.Context, currency string, rate, amount float64, immediate, fillOrKill, buy bool) (OrderResponse, error) { result := OrderResponse{} values := url.Values{} @@ -507,16 +507,16 @@ func (p *Poloniex) PlaceOrder(currency string, rate, amount float64, immediate, values.Set("fillOrKill", "1") } - return result, p.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, orderType, values, &result) + return result, p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, orderType, values, &result) } // CancelExistingOrder cancels and order by orderID -func (p *Poloniex) CancelExistingOrder(orderID int64) error { +func (p *Poloniex) CancelExistingOrder(ctx context.Context, orderID int64) error { result := GenericResponse{} values := url.Values{} values.Set("orderNumber", strconv.FormatInt(orderID, 10)) - err := p.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, poloniexOrderCancel, values, &result) + err := p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexOrderCancel, values, &result) if err != nil { return err } @@ -529,7 +529,7 @@ func (p *Poloniex) CancelExistingOrder(orderID int64) error { } // MoveOrder moves an order -func (p *Poloniex) MoveOrder(orderID int64, rate, amount float64, postOnly, immediateOrCancel bool) (MoveOrderResponse, error) { +func (p *Poloniex) MoveOrder(ctx context.Context, orderID int64, rate, amount float64, postOnly, immediateOrCancel bool) (MoveOrderResponse, error) { result := MoveOrderResponse{} values := url.Values{} @@ -556,7 +556,7 @@ func (p *Poloniex) MoveOrder(orderID int64, rate, amount float64, postOnly, imme values.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) } - err := p.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + err := p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexOrderMove, values, &result) @@ -572,7 +572,7 @@ func (p *Poloniex) MoveOrder(orderID int64, rate, amount float64, postOnly, imme } // Withdraw withdraws a currency to a specific delegated address -func (p *Poloniex) Withdraw(currency, address string, amount float64) (*Withdraw, error) { +func (p *Poloniex) Withdraw(ctx context.Context, currency, address string, amount float64) (*Withdraw, error) { result := &Withdraw{} values := url.Values{} @@ -580,7 +580,7 @@ func (p *Poloniex) Withdraw(currency, address string, amount float64) (*Withdraw values.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) values.Set("address", address) - err := p.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, poloniexWithdraw, values, &result) + err := p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexWithdraw, values, &result) if err != nil { return nil, err } @@ -593,20 +593,20 @@ func (p *Poloniex) Withdraw(currency, address string, amount float64) (*Withdraw } // GetFeeInfo returns fee information -func (p *Poloniex) GetFeeInfo() (Fee, error) { +func (p *Poloniex) GetFeeInfo(ctx context.Context) (Fee, error) { result := Fee{} - return result, p.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, poloniexFeeInfo, url.Values{}, &result) + return result, p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexFeeInfo, url.Values{}, &result) } // GetTradableBalances returns tradable balances -func (p *Poloniex) GetTradableBalances() (map[string]map[string]float64, error) { +func (p *Poloniex) GetTradableBalances(ctx context.Context) (map[string]map[string]float64, error) { type Response struct { Data map[string]map[string]interface{} } result := Response{} - err := p.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, poloniexTradableBalances, url.Values{}, &result.Data) + err := p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexTradableBalances, url.Values{}, &result.Data) if err != nil { return nil, err } @@ -624,7 +624,7 @@ func (p *Poloniex) GetTradableBalances() (map[string]map[string]float64, error) } // TransferBalance transfers balances between your accounts -func (p *Poloniex) TransferBalance(currency, from, to string, amount float64) (bool, error) { +func (p *Poloniex) TransferBalance(ctx context.Context, currency, from, to string, amount float64) (bool, error) { values := url.Values{} result := GenericResponse{} @@ -633,7 +633,7 @@ func (p *Poloniex) TransferBalance(currency, from, to string, amount float64) (b values.Set("fromAccount", from) values.Set("toAccount", to) - err := p.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, poloniexTransferBalance, values, &result) + err := p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexTransferBalance, values, &result) if err != nil { return false, err } @@ -646,13 +646,13 @@ func (p *Poloniex) TransferBalance(currency, from, to string, amount float64) (b } // GetMarginAccountSummary returns a summary on your margin accounts -func (p *Poloniex) GetMarginAccountSummary() (Margin, error) { +func (p *Poloniex) GetMarginAccountSummary(ctx context.Context) (Margin, error) { result := Margin{} - return result, p.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, poloniexMarginAccountSummary, url.Values{}, &result) + return result, p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexMarginAccountSummary, url.Values{}, &result) } // PlaceMarginOrder places a margin order -func (p *Poloniex) PlaceMarginOrder(currency string, rate, amount, lendingRate float64, buy bool) (OrderResponse, error) { +func (p *Poloniex) PlaceMarginOrder(ctx context.Context, currency string, rate, amount, lendingRate float64, buy bool) (OrderResponse, error) { result := OrderResponse{} values := url.Values{} @@ -671,17 +671,17 @@ func (p *Poloniex) PlaceMarginOrder(currency string, rate, amount, lendingRate f values.Set("lendingRate", strconv.FormatFloat(lendingRate, 'f', -1, 64)) } - return result, p.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, orderType, values, &result) + return result, p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, orderType, values, &result) } // GetMarginPosition returns a position on a margin order -func (p *Poloniex) GetMarginPosition(currency string) (interface{}, error) { +func (p *Poloniex) GetMarginPosition(ctx context.Context, currency string) (interface{}, error) { values := url.Values{} if currency != "" && currency != "all" { values.Set("currencyPair", currency) result := MarginPosition{} - return result, p.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, poloniexMarginPosition, values, &result) + return result, p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexMarginPosition, values, &result) } values.Set("currencyPair", "all") @@ -689,16 +689,16 @@ func (p *Poloniex) GetMarginPosition(currency string) (interface{}, error) { Data map[string]MarginPosition } result := Response{} - return result, p.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, poloniexMarginPosition, values, &result.Data) + return result, p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexMarginPosition, values, &result.Data) } // CloseMarginPosition closes a current margin position -func (p *Poloniex) CloseMarginPosition(currency string) (bool, error) { +func (p *Poloniex) CloseMarginPosition(ctx context.Context, currency string) (bool, error) { values := url.Values{} values.Set("currencyPair", currency) result := GenericResponse{} - err := p.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, poloniexMarginPositionClose, values, &result) + err := p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexMarginPositionClose, values, &result) if err != nil { return false, err } @@ -711,7 +711,7 @@ func (p *Poloniex) CloseMarginPosition(currency string) (bool, error) { } // CreateLoanOffer places a loan offer on the exchange -func (p *Poloniex) CreateLoanOffer(currency string, amount, rate float64, duration int, autoRenew bool) (int64, error) { +func (p *Poloniex) CreateLoanOffer(ctx context.Context, currency string, amount, rate float64, duration int, autoRenew bool) (int64, error) { values := url.Values{} values.Set("currency", currency) values.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) @@ -733,7 +733,7 @@ func (p *Poloniex) CreateLoanOffer(currency string, amount, rate float64, durati result := Response{} - err := p.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, poloniexCreateLoanOffer, values, &result) + err := p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexCreateLoanOffer, values, &result) if err != nil { return 0, err } @@ -746,12 +746,12 @@ func (p *Poloniex) CreateLoanOffer(currency string, amount, rate float64, durati } // CancelLoanOffer cancels a loan offer order -func (p *Poloniex) CancelLoanOffer(orderNumber int64) (bool, error) { +func (p *Poloniex) CancelLoanOffer(ctx context.Context, orderNumber int64) (bool, error) { result := GenericResponse{} values := url.Values{} values.Set("orderID", strconv.FormatInt(orderNumber, 10)) - err := p.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, poloniexCancelLoanOffer, values, &result) + err := p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexCancelLoanOffer, values, &result) if err != nil { return false, err } @@ -764,13 +764,13 @@ func (p *Poloniex) CancelLoanOffer(orderNumber int64) (bool, error) { } // GetOpenLoanOffers returns all open loan offers -func (p *Poloniex) GetOpenLoanOffers() (map[string][]LoanOffer, error) { +func (p *Poloniex) GetOpenLoanOffers(ctx context.Context) (map[string][]LoanOffer, error) { type Response struct { Data map[string][]LoanOffer } result := Response{} - err := p.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, poloniexOpenLoanOffers, url.Values{}, &result.Data) + err := p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexOpenLoanOffers, url.Values{}, &result.Data) if err != nil { return nil, err } @@ -783,13 +783,13 @@ func (p *Poloniex) GetOpenLoanOffers() (map[string][]LoanOffer, error) { } // GetActiveLoans returns active loans -func (p *Poloniex) GetActiveLoans() (ActiveLoans, error) { +func (p *Poloniex) GetActiveLoans(ctx context.Context) (ActiveLoans, error) { result := ActiveLoans{} - return result, p.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, poloniexActiveLoans, url.Values{}, &result) + return result, p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexActiveLoans, url.Values{}, &result) } // GetLendingHistory returns lending history for the account -func (p *Poloniex) GetLendingHistory(start, end string) ([]LendingHistory, error) { +func (p *Poloniex) GetLendingHistory(ctx context.Context, start, end string) ([]LendingHistory, error) { vals := url.Values{} if start != "" { @@ -801,19 +801,19 @@ func (p *Poloniex) GetLendingHistory(start, end string) ([]LendingHistory, error } var resp []LendingHistory - return resp, p.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + return resp, p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexLendingHistory, vals, &resp) } // ToggleAutoRenew allows for the autorenew of a contract -func (p *Poloniex) ToggleAutoRenew(orderNumber int64) (bool, error) { +func (p *Poloniex) ToggleAutoRenew(ctx context.Context, orderNumber int64) (bool, error) { values := url.Values{} values.Set("orderNumber", strconv.FormatInt(orderNumber, 10)) result := GenericResponse{} - err := p.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost, + err := p.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpot, http.MethodPost, poloniexAutoRenew, values, &result) @@ -829,7 +829,7 @@ func (p *Poloniex) ToggleAutoRenew(orderNumber int64) (bool, error) { } // SendHTTPRequest sends an unauthenticated HTTP request -func (p *Poloniex) SendHTTPRequest(ep exchange.URL, path string, result interface{}) error { +func (p *Poloniex) SendHTTPRequest(ctx context.Context, ep exchange.URL, path string, result interface{}) error { endpoint, err := p.API.Endpoints.GetURL(ep) if err != nil { return err @@ -844,13 +844,13 @@ func (p *Poloniex) SendHTTPRequest(ep exchange.URL, path string, result interfac HTTPRecording: p.HTTPRecording, } - return p.SendPayload(context.Background(), request.Unset, func() (*request.Item, error) { + return p.SendPayload(ctx, request.Unset, func() (*request.Item, error) { return item, nil }) } // SendAuthenticatedHTTPRequest sends an authenticated HTTP request -func (p *Poloniex) SendAuthenticatedHTTPRequest(ep exchange.URL, method, endpoint string, values url.Values, result interface{}) error { +func (p *Poloniex) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, method, endpoint string, values url.Values, result interface{}) error { if !p.AllowAuthenticatedRequest() { return fmt.Errorf("%s %w", p.Name, exchange.ErrAuthenticatedRequestWithoutCredentialsSet) } @@ -859,7 +859,7 @@ func (p *Poloniex) SendAuthenticatedHTTPRequest(ep exchange.URL, method, endpoin return err } - return p.SendPayload(context.Background(), request.Unset, func() (*request.Item, error) { + return p.SendPayload(ctx, request.Unset, func() (*request.Item, error) { headers := make(map[string]string) headers["Content-Type"] = "application/x-www-form-urlencoded" headers["Key"] = p.API.Credentials.Key @@ -890,11 +890,11 @@ func (p *Poloniex) SendAuthenticatedHTTPRequest(ep exchange.URL, method, endpoin } // GetFee returns an estimate of fee based on type of transaction -func (p *Poloniex) GetFee(feeBuilder *exchange.FeeBuilder) (float64, error) { +func (p *Poloniex) GetFee(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { var fee float64 switch feeBuilder.FeeType { case exchange.CryptocurrencyTradeFee: - feeInfo, err := p.GetFeeInfo() + feeInfo, err := p.GetFeeInfo(ctx) if err != nil { return 0, err } diff --git a/exchanges/poloniex/poloniex_test.go b/exchanges/poloniex/poloniex_test.go index 63f4d5f0..db4a4e58 100644 --- a/exchanges/poloniex/poloniex_test.go +++ b/exchanges/poloniex/poloniex_test.go @@ -1,6 +1,7 @@ package poloniex import ( + "context" "errors" "net/http" "strings" @@ -35,7 +36,7 @@ func areTestAPIKeysSet() bool { func TestGetTicker(t *testing.T) { t.Parallel() - _, err := p.GetTicker() + _, err := p.GetTicker(context.Background()) if err != nil { t.Error("Poloniex GetTicker() error", err) } @@ -43,7 +44,7 @@ func TestGetTicker(t *testing.T) { func TestGetVolume(t *testing.T) { t.Parallel() - _, err := p.GetVolume() + _, err := p.GetVolume(context.Background()) if err != nil { t.Error("Test faild - Poloniex GetVolume() error") } @@ -51,7 +52,7 @@ func TestGetVolume(t *testing.T) { func TestGetOrderbook(t *testing.T) { t.Parallel() - _, err := p.GetOrderbook("BTC_XMR", 50) + _, err := p.GetOrderbook(context.Background(), "BTC_XMR", 50) if err != nil { t.Error("Test faild - Poloniex GetOrderbook() error", err) } @@ -59,7 +60,7 @@ func TestGetOrderbook(t *testing.T) { func TestGetTradeHistory(t *testing.T) { t.Parallel() - _, err := p.GetTradeHistory("BTC_XMR", 0, 0) + _, err := p.GetTradeHistory(context.Background(), "BTC_XMR", 0, 0) if err != nil { t.Error("Test faild - Poloniex GetTradeHistory() error", err) } @@ -67,7 +68,8 @@ func TestGetTradeHistory(t *testing.T) { func TestGetChartData(t *testing.T) { t.Parallel() - _, err := p.GetChartData("BTC_XMR", + _, err := p.GetChartData(context.Background(), + "BTC_XMR", time.Unix(1405699200, 0), time.Unix(1405699400, 0), "300") if err != nil { t.Error("Test faild - Poloniex GetChartData() error", err) @@ -76,7 +78,7 @@ func TestGetChartData(t *testing.T) { func TestGetCurrencies(t *testing.T) { t.Parallel() - _, err := p.GetCurrencies() + _, err := p.GetCurrencies(context.Background()) if err != nil { t.Error("Test faild - Poloniex GetCurrencies() error", err) } @@ -84,7 +86,7 @@ func TestGetCurrencies(t *testing.T) { func TestGetLoanOrders(t *testing.T) { t.Parallel() - _, err := p.GetLoanOrders("BTC") + _, err := p.GetLoanOrders(context.Background(), "BTC") if err != nil { t.Error("Test faild - Poloniex GetLoanOrders() error", err) } @@ -108,7 +110,7 @@ func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { t.Parallel() var feeBuilder = setFeeBuilder() - _, err := p.GetFeeByType(feeBuilder) + _, err := p.GetFeeByType(context.Background(), feeBuilder) if err != nil { t.Fatal(err) } @@ -133,7 +135,7 @@ func TestGetFee(t *testing.T) { if areTestAPIKeysSet() || mockTests { // CryptocurrencyTradeFee Basic - if _, err := p.GetFee(feeBuilder); err != nil { + if _, err := p.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } @@ -141,21 +143,21 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.Amount = 1000 feeBuilder.PurchasePrice = 1000 - if _, err := p.GetFee(feeBuilder); err != nil { + if _, err := p.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyTradeFee Negative purchase price feeBuilder = setFeeBuilder() feeBuilder.PurchasePrice = -1000 - if _, err := p.GetFee(feeBuilder); err != nil { + if _, err := p.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } } // CryptocurrencyWithdrawalFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee - if _, err := p.GetFee(feeBuilder); err != nil { + if _, err := p.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } @@ -163,21 +165,21 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.Pair.Base = currency.NewCode("hello") feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee - if _, err := p.GetFee(feeBuilder); err != nil { + if _, err := p.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } // CryptocurrencyDepositFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.CryptocurrencyDepositFee - if _, err := p.GetFee(feeBuilder); err != nil { + if _, err := p.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } // InternationalBankDepositFee Basic feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankDepositFee - if _, err := p.GetFee(feeBuilder); err != nil { + if _, err := p.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } @@ -185,7 +187,7 @@ func TestGetFee(t *testing.T) { feeBuilder = setFeeBuilder() feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee feeBuilder.FiatCurrency = currency.USD - if _, err := p.GetFee(feeBuilder); err != nil { + if _, err := p.GetFee(context.Background(), feeBuilder); err != nil { t.Error(err) } } @@ -210,7 +212,7 @@ func TestGetActiveOrders(t *testing.T) { AssetType: asset.Spot, } - _, err := p.GetActiveOrders(&getOrdersRequest) + _, err := p.GetActiveOrders(context.Background(), &getOrdersRequest) switch { case areTestAPIKeysSet() && err != nil: t.Error("GetActiveOrders() error", err) @@ -228,7 +230,7 @@ func TestGetOrderHistory(t *testing.T) { AssetType: asset.Spot, } - _, err := p.GetOrderHistory(&getOrdersRequest) + _, err := p.GetOrderHistory(context.Background(), &getOrdersRequest) switch { case areTestAPIKeysSet() && err != nil: t.Errorf("Could not get order history: %s", err) @@ -272,8 +274,8 @@ func TestGetOrderStatus(t *testing.T) { t.Skip() } - _, err := p.GetAuthenticatedOrderStatus(tt.orderID) - + _, err := p.GetAuthenticatedOrderStatus(context.Background(), + tt.orderID) switch { case areTestAPIKeysSet() && err != nil: t.Errorf("Could not get order status: %s", err) @@ -327,7 +329,7 @@ func TestGetOrderTrades(t *testing.T) { t.Skip() } - _, err := p.GetAuthenticatedOrderTrades(tt.orderID) + _, err := p.GetAuthenticatedOrderTrades(context.Background(), tt.orderID) switch { case areTestAPIKeysSet() && err != nil: t.Errorf("Could not get order trades: %s", err) @@ -365,7 +367,7 @@ func TestSubmitOrder(t *testing.T) { AssetType: asset.Spot, } - response, err := p.SubmitOrder(orderSubmission) + response, err := p.SubmitOrder(context.Background(), orderSubmission) switch { case areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced): t.Errorf("Order failed to be placed: %v", err) @@ -389,7 +391,7 @@ func TestCancelExchangeOrder(t *testing.T) { AssetType: asset.Spot, } - err := p.CancelOrder(orderCancellation) + err := p.CancelOrder(context.Background(), orderCancellation) switch { case !areTestAPIKeysSet() && !mockTests && err == nil: t.Error("Expecting an error when no keys are set") @@ -415,7 +417,7 @@ func TestCancelAllExchangeOrders(t *testing.T) { AssetType: asset.Spot, } - resp, err := p.CancelAllOrders(orderCancellation) + resp, err := p.CancelAllOrders(context.Background(), orderCancellation) switch { case !areTestAPIKeysSet() && !mockTests && err == nil: t.Error("Expecting an error when no keys are set") @@ -435,7 +437,7 @@ func TestModifyOrder(t *testing.T) { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - _, err := p.ModifyOrder(&order.Modify{ID: "1337", + _, err := p.ModifyOrder(context.Background(), &order.Modify{ID: "1337", Price: 1337, AssetType: asset.Spot, Pair: currency.NewPair(currency.BTC, currency.USDT)}) @@ -466,7 +468,8 @@ func TestWithdraw(t *testing.T) { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - _, err := p.WithdrawCryptocurrencyFunds(&withdrawCryptoRequest) + _, err := p.WithdrawCryptocurrencyFunds(context.Background(), + &withdrawCryptoRequest) switch { case areTestAPIKeysSet() && err != nil: t.Errorf("Withdraw failed to be placed: %v", err) @@ -484,7 +487,7 @@ func TestWithdrawFiat(t *testing.T) { } var withdrawFiatRequest withdraw.Request - _, err := p.WithdrawFiatFunds(&withdrawFiatRequest) + _, err := p.WithdrawFiatFunds(context.Background(), &withdrawFiatRequest) if err != common.ErrFunctionNotSupported { t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err) @@ -498,7 +501,8 @@ func TestWithdrawInternationalBank(t *testing.T) { } var withdrawFiatRequest withdraw.Request - _, err := p.WithdrawFiatFundsToInternationalBank(&withdrawFiatRequest) + _, err := p.WithdrawFiatFundsToInternationalBank(context.Background(), + &withdrawFiatRequest) if err != common.ErrFunctionNotSupported { t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err) @@ -507,7 +511,7 @@ func TestWithdrawInternationalBank(t *testing.T) { func TestGetDepositAddress(t *testing.T) { t.Parallel() - _, err := p.GetDepositAddress(currency.DASH, "") + _, err := p.GetDepositAddress(context.Background(), currency.DASH, "") switch { case areTestAPIKeysSet() && err != nil: t.Error("GetDepositAddress()", err) @@ -553,7 +557,7 @@ func TestWsSubAck(t *testing.T) { } func TestWsTicker(t *testing.T) { - err := p.loadCurrencyDetails() + err := p.loadCurrencyDetails(context.Background()) if err != nil { t.Error(err) } @@ -565,7 +569,7 @@ func TestWsTicker(t *testing.T) { } func TestWsExchangeVolume(t *testing.T) { - err := p.loadCurrencyDetails() + err := p.loadCurrencyDetails(context.Background()) if err != nil { t.Error(err) } @@ -578,7 +582,7 @@ func TestWsExchangeVolume(t *testing.T) { func TestWsTrades(t *testing.T) { p.SetSaveTradeDataStatus(true) - err := p.loadCurrencyDetails() + err := p.loadCurrencyDetails(context.Background()) if err != nil { t.Error(err) } @@ -590,7 +594,7 @@ func TestWsTrades(t *testing.T) { } func TestWsPriceAggregateOrderbook(t *testing.T) { - err := p.loadCurrencyDetails() + err := p.loadCurrencyDetails(context.Background()) if err != nil { t.Error(err) } @@ -612,17 +616,29 @@ func TestGetHistoricCandles(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = p.GetHistoricCandles(currencyPair, asset.Spot, time.Unix(1588741402, 0), time.Unix(1588745003, 0), kline.FiveMin) + _, err = p.GetHistoricCandles(context.Background(), + currencyPair, asset.Spot, + time.Unix(1588741402, 0), + time.Unix(1588745003, 0), + kline.FiveMin) if err != nil { t.Fatal(err) } - _, err = p.GetHistoricCandles(currencyPair, asset.Spot, time.Unix(1588741402, 0), time.Unix(1588745003, 0), kline.Interval(time.Hour*7)) + _, err = p.GetHistoricCandles(context.Background(), + currencyPair, asset.Spot, + time.Unix(1588741402, 0), + time.Unix(1588745003, 0), + kline.Interval(time.Hour*7)) if err == nil { t.Fatal("unexpected result") } currencyPair.Quote = currency.NewCode("LTCC") - _, err = p.GetHistoricCandles(currencyPair, asset.Spot, time.Unix(1588741402, 0), time.Unix(1588745003, 0), kline.FiveMin) + _, err = p.GetHistoricCandles(context.Background(), + currencyPair, asset.Spot, + time.Unix(1588741402, 0), + time.Unix(1588745003, 0), + kline.FiveMin) if err == nil { t.Fatal(err) } @@ -633,17 +649,29 @@ func TestGetHistoricCandlesExtended(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = p.GetHistoricCandlesExtended(currencyPair, asset.Spot, time.Unix(1588741402, 0), time.Unix(1588745003, 0), kline.FiveMin) + _, err = p.GetHistoricCandlesExtended(context.Background(), + currencyPair, asset.Spot, + time.Unix(1588741402, 0), + time.Unix(1588745003, 0), + kline.FiveMin) if err != nil { t.Fatal(err) } - _, err = p.GetHistoricCandlesExtended(currencyPair, asset.Spot, time.Unix(1588741402, 0), time.Unix(1588745003, 0), kline.Interval(time.Hour*7)) + _, err = p.GetHistoricCandlesExtended(context.Background(), + currencyPair, asset.Spot, + time.Unix(1588741402, 0), + time.Unix(1588745003, 0), + kline.Interval(time.Hour*7)) if err == nil { t.Fatal("unexpected result") } currencyPair.Quote = currency.NewCode("LTCC") - _, err = p.GetHistoricCandlesExtended(currencyPair, asset.Spot, time.Unix(1588741402, 0), time.Unix(1588745003, 0), kline.FiveMin) + _, err = p.GetHistoricCandlesExtended(context.Background(), + currencyPair, asset.Spot, + time.Unix(1588741402, 0), + time.Unix(1588745003, 0), + kline.FiveMin) if err == nil { t.Fatal(err) } @@ -658,7 +686,7 @@ func TestGetRecentTrades(t *testing.T) { if mockTests { t.Skip("relies on time.Now()") } - _, err = p.GetRecentTrades(currencyPair, asset.Spot) + _, err = p.GetRecentTrades(context.Background(), currencyPair, asset.Spot) if err != nil { t.Error(err) } @@ -677,14 +705,15 @@ func TestGetHistoricTrades(t *testing.T) { tStart = time.Date(tmNow.Year(), tmNow.Month()-3, 6, 0, 0, 0, 0, time.UTC) tEnd = time.Date(tmNow.Year(), tmNow.Month()-3, 7, 0, 0, 0, 0, time.UTC) } - _, err = p.GetHistoricTrades(currencyPair, asset.Spot, tStart, tEnd) + _, err = p.GetHistoricTrades(context.Background(), + currencyPair, asset.Spot, tStart, tEnd) if err != nil { t.Error(err) } } func TestProcessAccountMarginPosition(t *testing.T) { - err := p.loadCurrencyDetails() + err := p.loadCurrencyDetails(context.Background()) if err != nil { t.Error(err) } @@ -721,7 +750,7 @@ func TestProcessAccountMarginPosition(t *testing.T) { } func TestProcessAccountPendingOrder(t *testing.T) { - err := p.loadCurrencyDetails() + err := p.loadCurrencyDetails(context.Background()) if err != nil { t.Error(err) } @@ -833,7 +862,7 @@ func TestProcessAccountOrderUpdate(t *testing.T) { } func TestProcessAccountOrderLimit(t *testing.T) { - err := p.loadCurrencyDetails() + err := p.loadCurrencyDetails(context.Background()) if err != nil { t.Error(err) } @@ -894,7 +923,7 @@ func TestProcessAccountOrderLimit(t *testing.T) { } func TestProcessAccountBalanceUpdate(t *testing.T) { - err := p.loadCurrencyDetails() + err := p.loadCurrencyDetails(context.Background()) if err != nil { t.Error(err) } @@ -1004,7 +1033,7 @@ func TestGetCompleteBalances(t *testing.T) { if !mockTests && !areTestAPIKeysSet() { t.Skip("API keys not set, mockTests false, skipping test") } - _, err := p.GetCompleteBalances() + _, err := p.GetCompleteBalances(context.Background()) if err != nil { t.Fatal(err) } @@ -1016,7 +1045,7 @@ func TestUpdateTicker(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = p.UpdateTicker(cp, asset.Spot) + _, err = p.UpdateTicker(context.Background(), cp, asset.Spot) if err != nil { t.Error(err) } @@ -1024,7 +1053,7 @@ func TestUpdateTicker(t *testing.T) { func TestUpdateTickers(t *testing.T) { t.Parallel() - err := p.UpdateTickers(asset.Spot) + err := p.UpdateTickers(context.Background(), asset.Spot) if err != nil { t.Error(err) } diff --git a/exchanges/poloniex/poloniex_websocket.go b/exchanges/poloniex/poloniex_websocket.go index 5d72c3fa..6207a825 100644 --- a/exchanges/poloniex/poloniex_websocket.go +++ b/exchanges/poloniex/poloniex_websocket.go @@ -1,6 +1,7 @@ package poloniex import ( + "context" "encoding/json" "errors" "fmt" @@ -63,7 +64,7 @@ func (p *Poloniex) WsConnect() error { return err } - err = p.loadCurrencyDetails() + err = p.loadCurrencyDetails(context.TODO()) if err != nil { return err } @@ -75,9 +76,9 @@ func (p *Poloniex) WsConnect() error { } // TODO: Create routine to refresh list every day/week(?) for production -func (p *Poloniex) loadCurrencyDetails() error { +func (p *Poloniex) loadCurrencyDetails(ctx context.Context) error { if p.details.isInitial() { - ticks, err := p.GetTicker() + ticks, err := p.GetTicker(ctx) if err != nil { return err } @@ -86,7 +87,7 @@ func (p *Poloniex) loadCurrencyDetails() error { return err } - currs, err := p.GetCurrencies() + currs, err := p.GetCurrencies(ctx) if err != nil { return err } diff --git a/exchanges/poloniex/poloniex_wrapper.go b/exchanges/poloniex/poloniex_wrapper.go index b68827b3..4209664f 100644 --- a/exchanges/poloniex/poloniex_wrapper.go +++ b/exchanges/poloniex/poloniex_wrapper.go @@ -1,6 +1,7 @@ package poloniex import ( + "context" "fmt" "sort" "strconv" @@ -40,7 +41,7 @@ func (p *Poloniex) GetDefaultConfig() (*config.ExchangeConfig, error) { } if p.Features.Supports.RESTCapabilities.AutoPairUpdates { - err = p.UpdateTradablePairs(true) + err = p.UpdateTradablePairs(context.TODO(), true) if err != nil { return nil, err } @@ -232,7 +233,7 @@ func (p *Poloniex) Run() { return } - err = p.UpdateTradablePairs(forceUpdate) + err = p.UpdateTradablePairs(context.TODO(), forceUpdate) if err != nil { log.Errorf(log.ExchangeSys, "%s failed to update tradable pairs. Err: %s", @@ -242,8 +243,8 @@ func (p *Poloniex) Run() { } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (p *Poloniex) FetchTradablePairs(asset asset.Item) ([]string, error) { - resp, err := p.GetTicker() +func (p *Poloniex) FetchTradablePairs(ctx context.Context, asset asset.Item) ([]string, error) { + resp, err := p.GetTicker(ctx) if err != nil { return nil, err } @@ -258,8 +259,8 @@ func (p *Poloniex) FetchTradablePairs(asset asset.Item) ([]string, error) { // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (p *Poloniex) UpdateTradablePairs(forceUpgrade bool) error { - pairs, err := p.FetchTradablePairs(asset.Spot) +func (p *Poloniex) UpdateTradablePairs(ctx context.Context, forceUpgrade bool) error { + pairs, err := p.FetchTradablePairs(ctx, asset.Spot) if err != nil { return err } @@ -271,8 +272,8 @@ func (p *Poloniex) UpdateTradablePairs(forceUpgrade bool) error { } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (p *Poloniex) UpdateTickers(a asset.Item) error { - tick, err := p.GetTicker() +func (p *Poloniex) UpdateTickers(ctx context.Context, a asset.Item) error { + tick, err := p.GetTicker(ctx) if err != nil { return err } @@ -310,8 +311,8 @@ func (p *Poloniex) UpdateTickers(a asset.Item) error { } // UpdateTicker updates and returns the ticker for a currency pair -func (p *Poloniex) UpdateTicker(currencyPair currency.Pair, a asset.Item) (*ticker.Price, error) { - err := p.UpdateTickers(a) +func (p *Poloniex) UpdateTicker(ctx context.Context, currencyPair currency.Pair, a asset.Item) (*ticker.Price, error) { + err := p.UpdateTickers(ctx, a) if err != nil { return nil, err } @@ -319,32 +320,32 @@ func (p *Poloniex) UpdateTicker(currencyPair currency.Pair, a asset.Item) (*tick } // FetchTicker returns the ticker for a currency pair -func (p *Poloniex) FetchTicker(currencyPair currency.Pair, assetType asset.Item) (*ticker.Price, error) { +func (p *Poloniex) FetchTicker(ctx context.Context, currencyPair currency.Pair, assetType asset.Item) (*ticker.Price, error) { tickerNew, err := ticker.GetTicker(p.Name, currencyPair, assetType) if err != nil { - return p.UpdateTicker(currencyPair, assetType) + return p.UpdateTicker(ctx, currencyPair, assetType) } return tickerNew, nil } // FetchOrderbook returns orderbook base on the currency pair -func (p *Poloniex) FetchOrderbook(currencyPair currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (p *Poloniex) FetchOrderbook(ctx context.Context, currencyPair currency.Pair, assetType asset.Item) (*orderbook.Base, error) { ob, err := orderbook.Get(p.Name, currencyPair, assetType) if err != nil { - return p.UpdateOrderbook(currencyPair, assetType) + return p.UpdateOrderbook(ctx, currencyPair, assetType) } return ob, nil } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (p *Poloniex) UpdateOrderbook(c currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (p *Poloniex) UpdateOrderbook(ctx context.Context, c currency.Pair, assetType asset.Item) (*orderbook.Base, error) { callingBook := &orderbook.Base{ Exchange: p.Name, Pair: c, Asset: assetType, VerifyOrderbook: p.CanVerifyOrderbook, } - orderbookNew, err := p.GetOrderbook("", poloniexMaxOrderbookDepth) + orderbookNew, err := p.GetOrderbook(ctx, "", poloniexMaxOrderbookDepth) if err != nil { return callingBook, err } @@ -393,10 +394,10 @@ func (p *Poloniex) UpdateOrderbook(c currency.Pair, assetType asset.Item) (*orde // UpdateAccountInfo retrieves balances for all enabled currencies for the // Poloniex exchange -func (p *Poloniex) UpdateAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (p *Poloniex) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { var response account.Holdings response.Exchange = p.Name - accountBalance, err := p.GetBalances() + accountBalance, err := p.GetBalances(ctx) if err != nil { return response, err } @@ -422,38 +423,37 @@ func (p *Poloniex) UpdateAccountInfo(assetType asset.Item) (account.Holdings, er } // FetchAccountInfo retrieves balances for all enabled currencies -func (p *Poloniex) FetchAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (p *Poloniex) FetchAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { acc, err := account.GetHoldings(p.Name, assetType) if err != nil { - return p.UpdateAccountInfo(assetType) + return p.UpdateAccountInfo(ctx, assetType) } - return acc, nil } // GetFundingHistory returns funding history, deposits and // withdrawals -func (p *Poloniex) GetFundingHistory() ([]exchange.FundHistory, error) { +func (p *Poloniex) GetFundingHistory(ctx context.Context) ([]exchange.FundHistory, error) { return nil, common.ErrFunctionNotSupported } // GetWithdrawalsHistory returns previous withdrawals data -func (p *Poloniex) GetWithdrawalsHistory(c currency.Code) (resp []exchange.WithdrawalHistory, err error) { +func (p *Poloniex) GetWithdrawalsHistory(ctx context.Context, c currency.Code) (resp []exchange.WithdrawalHistory, err error) { return nil, common.ErrNotYetImplemented } // GetRecentTrades returns the most recent trades for a currency and asset -func (p *Poloniex) GetRecentTrades(currencyPair currency.Pair, assetType asset.Item) ([]trade.Data, error) { - return p.GetHistoricTrades(currencyPair, assetType, time.Now().Add(-time.Minute*15), time.Now()) +func (p *Poloniex) GetRecentTrades(ctx context.Context, pair currency.Pair, assetType asset.Item) ([]trade.Data, error) { + return p.GetHistoricTrades(ctx, pair, assetType, time.Now().Add(-time.Minute*15), time.Now()) } // GetHistoricTrades returns historic trade data within the timeframe provided -func (p *Poloniex) GetHistoricTrades(currencyPair currency.Pair, assetType asset.Item, timestampStart, timestampEnd time.Time) ([]trade.Data, error) { +func (p *Poloniex) GetHistoricTrades(ctx context.Context, pair currency.Pair, assetType asset.Item, timestampStart, timestampEnd time.Time) ([]trade.Data, error) { if err := common.StartEndTimeCheck(timestampStart, timestampEnd); err != nil { return nil, fmt.Errorf("invalid time range supplied. Start: %v End %v %w", timestampStart, timestampEnd, err) } var err error - currencyPair, err = p.FormatExchangeCurrency(currencyPair, assetType) + pair, err = p.FormatExchangeCurrency(pair, assetType) if err != nil { return nil, err } @@ -463,7 +463,10 @@ func (p *Poloniex) GetHistoricTrades(currencyPair currency.Pair, assetType asset allTrades: for { var tradeData []TradeHistory - tradeData, err = p.GetTradeHistory(currencyPair.String(), ts.Unix(), timestampEnd.Unix()) + tradeData, err = p.GetTradeHistory(ctx, + pair.String(), + ts.Unix(), + timestampEnd.Unix()) if err != nil { return nil, err } @@ -484,7 +487,7 @@ allTrades: resp = append(resp, trade.Data{ Exchange: p.Name, TID: strconv.FormatInt(tradeData[i].TradeID, 10), - CurrencyPair: currencyPair, + CurrencyPair: pair, AssetType: assetType, Side: side, Price: tradeData[i].Rate, @@ -515,7 +518,7 @@ allTrades: } // SubmitOrder submits a new order -func (p *Poloniex) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { +func (p *Poloniex) SubmitOrder(ctx context.Context, s *order.Submit) (order.SubmitResponse, error) { var submitOrderResponse order.SubmitResponse if err := s.Validate(); err != nil { return submitOrderResponse, err @@ -528,7 +531,8 @@ func (p *Poloniex) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { fillOrKill := s.Type == order.Market isBuyOrder := s.Side == order.Buy - response, err := p.PlaceOrder(fPair.String(), + response, err := p.PlaceOrder(ctx, + fPair.String(), s.Price, s.Amount, false, @@ -550,7 +554,7 @@ func (p *Poloniex) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (p *Poloniex) ModifyOrder(action *order.Modify) (order.Modify, error) { +func (p *Poloniex) ModifyOrder(ctx context.Context, action *order.Modify) (order.Modify, error) { if err := action.Validate(); err != nil { return order.Modify{}, err } @@ -560,7 +564,8 @@ func (p *Poloniex) ModifyOrder(action *order.Modify) (order.Modify, error) { return order.Modify{}, err } - resp, err := p.MoveOrder(oID, + resp, err := p.MoveOrder(ctx, + oID, action.Price, action.Amount, action.PostOnly, @@ -583,7 +588,7 @@ func (p *Poloniex) ModifyOrder(action *order.Modify) (order.Modify, error) { } // CancelOrder cancels an order by its corresponding ID number -func (p *Poloniex) CancelOrder(o *order.Cancel) error { +func (p *Poloniex) CancelOrder(ctx context.Context, o *order.Cancel) error { if err := o.Validate(o.StandardCancel()); err != nil { return err } @@ -593,27 +598,27 @@ func (p *Poloniex) CancelOrder(o *order.Cancel) error { return err } - return p.CancelExistingOrder(orderIDInt) + return p.CancelExistingOrder(ctx, orderIDInt) } // CancelBatchOrders cancels an orders by their corresponding ID numbers -func (p *Poloniex) CancelBatchOrders(o []order.Cancel) (order.CancelBatchResponse, error) { +func (p *Poloniex) CancelBatchOrders(ctx context.Context, o []order.Cancel) (order.CancelBatchResponse, error) { return order.CancelBatchResponse{}, common.ErrNotYetImplemented } // CancelAllOrders cancels all orders associated with a currency pair -func (p *Poloniex) CancelAllOrders(_ *order.Cancel) (order.CancelAllResponse, error) { +func (p *Poloniex) CancelAllOrders(ctx context.Context, _ *order.Cancel) (order.CancelAllResponse, error) { cancelAllOrdersResponse := order.CancelAllResponse{ Status: make(map[string]string), } - openOrders, err := p.GetOpenOrdersForAllCurrencies() + openOrders, err := p.GetOpenOrdersForAllCurrencies(ctx) if err != nil { return cancelAllOrdersResponse, err } for key := range openOrders.Data { for i := range openOrders.Data[key] { - err = p.CancelExistingOrder(openOrders.Data[key][i].OrderNumber) + err = p.CancelExistingOrder(ctx, openOrders.Data[key][i].OrderNumber) if err != nil { id := strconv.FormatInt(openOrders.Data[key][i].OrderNumber, 10) cancelAllOrdersResponse.Status[id] = err.Error() @@ -625,13 +630,13 @@ func (p *Poloniex) CancelAllOrders(_ *order.Cancel) (order.CancelAllResponse, er } // GetOrderInfo returns order information based on order ID -func (p *Poloniex) GetOrderInfo(orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { +func (p *Poloniex) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { orderInfo := order.Detail{ Exchange: p.Name, Pair: pair, } - trades, err := p.GetAuthenticatedOrderTrades(orderID) + trades, err := p.GetAuthenticatedOrderTrades(ctx, orderID) if err != nil && !strings.Contains(err.Error(), "Order not found") { return orderInfo, err } @@ -655,7 +660,7 @@ func (p *Poloniex) GetOrderInfo(orderID string, pair currency.Pair, assetType as orderInfo.Trades = append(orderInfo.Trades, tradeHistory) } - resp, err := p.GetAuthenticatedOrderStatus(orderID) + resp, err := p.GetAuthenticatedOrderStatus(ctx, orderID) if err != nil { if len(orderInfo.Trades) > 0 { // on closed orders return trades only if strings.Contains(err.Error(), "Order not found") { @@ -687,8 +692,8 @@ func (p *Poloniex) GetOrderInfo(orderID string, pair currency.Pair, assetType as } // GetDepositAddress returns a deposit address for a specified currency -func (p *Poloniex) GetDepositAddress(cryptocurrency currency.Code, _ string) (string, error) { - a, err := p.GetDepositAddresses() +func (p *Poloniex) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _ string) (string, error) { + a, err := p.GetDepositAddresses(ctx) if err != nil { return "", err } @@ -704,11 +709,11 @@ func (p *Poloniex) GetDepositAddress(cryptocurrency currency.Code, _ string) (st // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is // submitted -func (p *Poloniex) WithdrawCryptocurrencyFunds(withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (p *Poloniex) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } - v, err := p.Withdraw(withdrawRequest.Currency.String(), withdrawRequest.Crypto.Address, withdrawRequest.Amount) + v, err := p.Withdraw(ctx, withdrawRequest.Currency.String(), withdrawRequest.Crypto.Address, withdrawRequest.Amount) if err != nil { return nil, err } @@ -719,32 +724,32 @@ func (p *Poloniex) WithdrawCryptocurrencyFunds(withdrawRequest *withdraw.Request // WithdrawFiatFunds returns a withdrawal ID when a // withdrawal is submitted -func (p *Poloniex) WithdrawFiatFunds(_ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (p *Poloniex) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a // withdrawal is submitted -func (p *Poloniex) WithdrawFiatFundsToInternationalBank(_ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (p *Poloniex) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // GetFeeByType returns an estimate of fee based on type of transaction -func (p *Poloniex) GetFeeByType(feeBuilder *exchange.FeeBuilder) (float64, error) { +func (p *Poloniex) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { if (!p.AllowAuthenticatedRequest() || p.SkipAuthCheck) && // Todo check connection status feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { feeBuilder.FeeType = exchange.OfflineTradeFee } - return p.GetFee(feeBuilder) + return p.GetFee(ctx, feeBuilder) } // GetActiveOrders retrieves any orders that are active/open -func (p *Poloniex) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, error) { +func (p *Poloniex) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) { if err := req.Validate(); err != nil { return nil, err } - resp, err := p.GetOpenOrdersForAllCurrencies() + resp, err := p.GetOpenOrdersForAllCurrencies(ctx) if err != nil { return nil, err } @@ -794,12 +799,13 @@ func (p *Poloniex) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, // GetOrderHistory retrieves account order information // Can Limit response to specific order status -func (p *Poloniex) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, error) { +func (p *Poloniex) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) { if err := req.Validate(); err != nil { return nil, err } - resp, err := p.GetAuthenticatedTradeHistory(req.StartTime.Unix(), + resp, err := p.GetAuthenticatedTradeHistory(ctx, + req.StartTime.Unix(), req.EndTime.Unix(), 10000) if err != nil { @@ -852,13 +858,13 @@ func (p *Poloniex) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, // ValidateCredentials validates current credentials used for wrapper // functionality -func (p *Poloniex) ValidateCredentials(assetType asset.Item) error { - _, err := p.UpdateAccountInfo(assetType) +func (p *Poloniex) ValidateCredentials(ctx context.Context, assetType asset.Item) error { + _, err := p.UpdateAccountInfo(ctx, assetType) return p.CheckTransientError(err) } // GetHistoricCandles returns candles between a time period for a set time interval -func (p *Poloniex) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (p *Poloniex) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { if err := p.ValidateKline(pair, a, interval); err != nil { return kline.Item{}, err } @@ -871,7 +877,8 @@ func (p *Poloniex) GetHistoricCandles(pair currency.Pair, a asset.Item, start, e // we use Truncate here to round star to the nearest even number that matches the requested interval // example 10:17 with an interval of 15 minutes will go down 10:15 // this is due to poloniex returning a non-complete candle if the time does not match - candles, err := p.GetChartData(formattedPair.String(), + candles, err := p.GetChartData(ctx, + formattedPair.String(), start.Truncate(interval.Duration()), end, p.FormatExchangeKlineInterval(interval)) if err != nil { @@ -901,6 +908,6 @@ func (p *Poloniex) GetHistoricCandles(pair currency.Pair, a asset.Item, start, e } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (p *Poloniex) GetHistoricCandlesExtended(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { - return p.GetHistoricCandles(pair, a, start, end, interval) +func (p *Poloniex) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { + return p.GetHistoricCandles(ctx, pair, a, start, end, interval) } diff --git a/exchanges/request/request.go b/exchanges/request/request.go index 0c6ea775..6e84875f 100644 --- a/exchanges/request/request.go +++ b/exchanges/request/request.go @@ -28,6 +28,7 @@ var ( errInvalidPath = errors.New("invalid path") errHeaderResponseMapIsNil = errors.New("header response map is nil") errFailedToRetryRequest = errors.New("failed to retry request") + errContextRequired = errors.New("context is required") ) // New returns a new Requester @@ -54,6 +55,10 @@ func (r *Requester) SendPayload(ctx context.Context, ep EndpointLimit, newReques return errRequestSystemIsNil } + if ctx == nil { + return errContextRequired + } + defer r.timedLock.UnlockIfLocked() if newRequest == nil { diff --git a/exchanges/sharedtestvalues/customex.go b/exchanges/sharedtestvalues/customex.go index 2653b40d..2f96c7f4 100644 --- a/exchanges/sharedtestvalues/customex.go +++ b/exchanges/sharedtestvalues/customex.go @@ -1,6 +1,7 @@ package sharedtestvalues import ( + "context" "sync" "time" @@ -43,35 +44,35 @@ func (c *CustomEx) IsEnabled() bool { func (c *CustomEx) SetEnabled(bool) { } -func (c *CustomEx) ValidateCredentials(a asset.Item) error { +func (c *CustomEx) ValidateCredentials(ctx context.Context, a asset.Item) error { return nil } -func (c *CustomEx) FetchTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) { +func (c *CustomEx) FetchTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { return nil, nil } -func (c *CustomEx) UpdateTickers(a asset.Item) error { +func (c *CustomEx) UpdateTickers(ctx context.Context, a asset.Item) error { return nil } -func (c *CustomEx) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) { +func (c *CustomEx) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { return nil, nil } -func (c *CustomEx) FetchOrderbook(p currency.Pair, a asset.Item) (*orderbook.Base, error) { +func (c *CustomEx) FetchOrderbook(ctx context.Context, p currency.Pair, a asset.Item) (*orderbook.Base, error) { return nil, nil } -func (c *CustomEx) UpdateOrderbook(p currency.Pair, a asset.Item) (*orderbook.Base, error) { +func (c *CustomEx) UpdateOrderbook(ctx context.Context, p currency.Pair, a asset.Item) (*orderbook.Base, error) { return nil, nil } -func (c *CustomEx) FetchTradablePairs(a asset.Item) ([]string, error) { +func (c *CustomEx) FetchTradablePairs(ctx context.Context, a asset.Item) ([]string, error) { return nil, nil } -func (c *CustomEx) UpdateTradablePairs(forceUpdate bool) error { +func (c *CustomEx) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { return nil } @@ -83,11 +84,11 @@ func (c *CustomEx) GetAvailablePairs(a asset.Item) (currency.Pairs, error) { return nil, nil } -func (c *CustomEx) FetchAccountInfo(a asset.Item) (account.Holdings, error) { +func (c *CustomEx) FetchAccountInfo(ctx context.Context, a asset.Item) (account.Holdings, error) { return account.Holdings{}, nil } -func (c *CustomEx) UpdateAccountInfo(a asset.Item) (account.Holdings, error) { +func (c *CustomEx) UpdateAccountInfo(ctx context.Context, a asset.Item) (account.Holdings, error) { return account.Holdings{}, nil } @@ -103,11 +104,11 @@ func (c *CustomEx) GetAssetTypes(enabled bool) asset.Items { return nil } -func (c *CustomEx) GetRecentTrades(p currency.Pair, a asset.Item) ([]trade.Data, error) { +func (c *CustomEx) GetRecentTrades(ctx context.Context, p currency.Pair, a asset.Item) ([]trade.Data, error) { return nil, nil } -func (c *CustomEx) GetHistoricTrades(p currency.Pair, a asset.Item, startTime, endTime time.Time) ([]trade.Data, error) { +func (c *CustomEx) GetHistoricTrades(ctx context.Context, p currency.Pair, a asset.Item, startTime, endTime time.Time) ([]trade.Data, error) { return nil, nil } @@ -119,7 +120,7 @@ func (c *CustomEx) SupportsRESTTickerBatchUpdates() bool { return false } -func (c *CustomEx) GetFeeByType(f *exchange.FeeBuilder) (float64, error) { +func (c *CustomEx) GetFeeByType(ctx context.Context, f *exchange.FeeBuilder) (float64, error) { return 0.0, nil } @@ -139,59 +140,59 @@ func (c *CustomEx) SupportsWithdrawPermissions(permissions uint32) bool { return false } -func (c *CustomEx) GetFundingHistory() ([]exchange.FundHistory, error) { +func (c *CustomEx) GetFundingHistory(ctx context.Context) ([]exchange.FundHistory, error) { return nil, nil } -func (c *CustomEx) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { +func (c *CustomEx) SubmitOrder(ctx context.Context, s *order.Submit) (order.SubmitResponse, error) { return order.SubmitResponse{}, nil } -func (c *CustomEx) ModifyOrder(action *order.Modify) (order.Modify, error) { +func (c *CustomEx) ModifyOrder(ctx context.Context, action *order.Modify) (order.Modify, error) { return order.Modify{}, nil } -func (c *CustomEx) CancelOrder(o *order.Cancel) error { +func (c *CustomEx) CancelOrder(ctx context.Context, o *order.Cancel) error { return nil } -func (c *CustomEx) CancelBatchOrders(o []order.Cancel) (order.CancelBatchResponse, error) { +func (c *CustomEx) CancelBatchOrders(ctx context.Context, o []order.Cancel) (order.CancelBatchResponse, error) { return order.CancelBatchResponse{}, nil } -func (c *CustomEx) CancelAllOrders(orders *order.Cancel) (order.CancelAllResponse, error) { +func (c *CustomEx) CancelAllOrders(ctx context.Context, orders *order.Cancel) (order.CancelAllResponse, error) { return order.CancelAllResponse{}, nil } -func (c *CustomEx) GetOrderInfo(orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { +func (c *CustomEx) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { return order.Detail{}, nil } -func (c *CustomEx) GetDepositAddress(cryptocurrency currency.Code, accountID string) (string, error) { +func (c *CustomEx) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, accountID string) (string, error) { return "", nil } -func (c *CustomEx) GetOrderHistory(getOrdersRequest *order.GetOrdersRequest) ([]order.Detail, error) { +func (c *CustomEx) GetOrderHistory(ctx context.Context, getOrdersRequest *order.GetOrdersRequest) ([]order.Detail, error) { return nil, nil } -func (c *CustomEx) GetWithdrawalsHistory(code currency.Code) ([]exchange.WithdrawalHistory, error) { +func (c *CustomEx) GetWithdrawalsHistory(ctx context.Context, code currency.Code) ([]exchange.WithdrawalHistory, error) { return []exchange.WithdrawalHistory{}, nil } -func (c *CustomEx) GetActiveOrders(getOrdersRequest *order.GetOrdersRequest) ([]order.Detail, error) { +func (c *CustomEx) GetActiveOrders(ctx context.Context, getOrdersRequest *order.GetOrdersRequest) ([]order.Detail, error) { return []order.Detail{}, nil } -func (c *CustomEx) WithdrawCryptocurrencyFunds(withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (c *CustomEx) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, nil } -func (c *CustomEx) WithdrawFiatFunds(withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (c *CustomEx) WithdrawFiatFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, nil } -func (c *CustomEx) WithdrawFiatFundsToInternationalBank(withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (c *CustomEx) WithdrawFiatFundsToInternationalBank(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, nil } @@ -226,11 +227,11 @@ func (c *CustomEx) SupportsAsset(assetType asset.Item) bool { return false } -func (c *CustomEx) GetHistoricCandles(p currency.Pair, a asset.Item, timeStart, timeEnd time.Time, interval kline.Interval) (kline.Item, error) { +func (c *CustomEx) GetHistoricCandles(ctx context.Context, p currency.Pair, a asset.Item, timeStart, timeEnd time.Time, interval kline.Interval) (kline.Item, error) { return kline.Item{}, nil } -func (c *CustomEx) GetHistoricCandlesExtended(p currency.Pair, a asset.Item, timeStart, timeEnd time.Time, interval kline.Interval) (kline.Item, error) { +func (c *CustomEx) GetHistoricCandlesExtended(ctx context.Context, p currency.Pair, a asset.Item, timeStart, timeEnd time.Time, interval kline.Interval) (kline.Item, error) { return kline.Item{}, nil } @@ -270,7 +271,7 @@ func (c *CustomEx) FlushWebsocketChannels() error { return nil } -func (c *CustomEx) AuthenticateWebsocket() error { +func (c *CustomEx) AuthenticateWebsocket(ctx context.Context) error { return nil } @@ -282,6 +283,6 @@ func (c *CustomEx) CheckOrderExecutionLimits(a asset.Item, cp currency.Pair, pri return nil } -func (c *CustomEx) UpdateOrderExecutionLimits(a asset.Item) error { +func (c *CustomEx) UpdateOrderExecutionLimits(ctx context.Context, a asset.Item) error { return nil } diff --git a/exchanges/yobit/yobit.go b/exchanges/yobit/yobit.go index 1e7cf86b..27dc18b3 100644 --- a/exchanges/yobit/yobit.go +++ b/exchanges/yobit/yobit.go @@ -44,15 +44,15 @@ type Yobit struct { } // GetInfo returns the Yobit info -func (y *Yobit) GetInfo() (Info, error) { +func (y *Yobit) GetInfo(ctx context.Context) (Info, error) { resp := Info{} path := fmt.Sprintf("/%s/%s/", apiPublicVersion, publicInfo) - return resp, y.SendHTTPRequest(exchange.RestSpot, path, &resp) + return resp, y.SendHTTPRequest(ctx, exchange.RestSpot, path, &resp) } // GetTicker returns a ticker for a specific currency -func (y *Yobit) GetTicker(symbol string) (map[string]Ticker, error) { +func (y *Yobit) GetTicker(ctx context.Context, symbol string) (map[string]Ticker, error) { type Response struct { Data map[string]Ticker } @@ -60,11 +60,11 @@ func (y *Yobit) GetTicker(symbol string) (map[string]Ticker, error) { response := Response{} path := fmt.Sprintf("/%s/%s/%s", apiPublicVersion, publicTicker, symbol) - return response.Data, y.SendHTTPRequest(exchange.RestSpot, path, &response.Data) + return response.Data, y.SendHTTPRequest(ctx, exchange.RestSpot, path, &response.Data) } // GetDepth returns the depth for a specific currency -func (y *Yobit) GetDepth(symbol string) (Orderbook, error) { +func (y *Yobit) GetDepth(ctx context.Context, symbol string) (Orderbook, error) { type Response struct { Data map[string]Orderbook } @@ -73,18 +73,18 @@ func (y *Yobit) GetDepth(symbol string) (Orderbook, error) { path := fmt.Sprintf("/%s/%s/%s", apiPublicVersion, publicDepth, symbol) return response.Data[symbol], - y.SendHTTPRequest(exchange.RestSpot, path, &response.Data) + y.SendHTTPRequest(ctx, exchange.RestSpot, path, &response.Data) } // GetTrades returns the trades for a specific currency -func (y *Yobit) GetTrades(symbol string) ([]Trade, error) { +func (y *Yobit) GetTrades(ctx context.Context, symbol string) ([]Trade, error) { type respDataHolder struct { Data map[string][]Trade } var dataHolder respDataHolder path := "/" + apiPublicVersion + "/" + publicTrades + "/" + symbol - err := y.SendHTTPRequest(exchange.RestSpot, path, &dataHolder.Data) + err := y.SendHTTPRequest(ctx, exchange.RestSpot, path, &dataHolder.Data) if err != nil { return nil, err } @@ -96,10 +96,10 @@ func (y *Yobit) GetTrades(symbol string) ([]Trade, error) { } // GetAccountInformation returns a users account info -func (y *Yobit) GetAccountInformation() (AccountInfo, error) { +func (y *Yobit) GetAccountInformation(ctx context.Context) (AccountInfo, error) { result := AccountInfo{} - err := y.SendAuthenticatedHTTPRequest(exchange.RestSpotSupplementary, privateAccountInfo, url.Values{}, &result) + err := y.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpotSupplementary, privateAccountInfo, url.Values{}, &result) if err != nil { return result, err } @@ -110,7 +110,7 @@ func (y *Yobit) GetAccountInformation() (AccountInfo, error) { } // Trade places an order and returns the order ID if successful or an error -func (y *Yobit) Trade(pair, orderType string, amount, price float64) (int64, error) { +func (y *Yobit) Trade(ctx context.Context, pair, orderType string, amount, price float64) (int64, error) { req := url.Values{} req.Add("pair", pair) req.Add("type", strings.ToLower(orderType)) @@ -119,7 +119,7 @@ func (y *Yobit) Trade(pair, orderType string, amount, price float64) (int64, err result := TradeOrderResponse{} - err := y.SendAuthenticatedHTTPRequest(exchange.RestSpotSupplementary, privateTrade, req, &result) + err := y.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpotSupplementary, privateTrade, req, &result) if err != nil { return int64(result.OrderID), err } @@ -130,33 +130,33 @@ func (y *Yobit) Trade(pair, orderType string, amount, price float64) (int64, err } // GetOpenOrders returns the active orders for a specific currency -func (y *Yobit) GetOpenOrders(pair string) (map[string]ActiveOrders, error) { +func (y *Yobit) GetOpenOrders(ctx context.Context, pair string) (map[string]ActiveOrders, error) { req := url.Values{} req.Add("pair", pair) result := map[string]ActiveOrders{} - return result, y.SendAuthenticatedHTTPRequest(exchange.RestSpotSupplementary, privateActiveOrders, req, &result) + return result, y.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpotSupplementary, privateActiveOrders, req, &result) } // GetOrderInformation returns the order info for a specific order ID -func (y *Yobit) GetOrderInformation(orderID int64) (map[string]OrderInfo, error) { +func (y *Yobit) GetOrderInformation(ctx context.Context, orderID int64) (map[string]OrderInfo, error) { req := url.Values{} req.Add("order_id", strconv.FormatInt(orderID, 10)) result := map[string]OrderInfo{} - return result, y.SendAuthenticatedHTTPRequest(exchange.RestSpotSupplementary, privateOrderInfo, req, &result) + return result, y.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpotSupplementary, privateOrderInfo, req, &result) } // CancelExistingOrder cancels an order for a specific order ID -func (y *Yobit) CancelExistingOrder(orderID int64) error { +func (y *Yobit) CancelExistingOrder(ctx context.Context, orderID int64) error { req := url.Values{} req.Add("order_id", strconv.FormatInt(orderID, 10)) result := CancelOrder{} - err := y.SendAuthenticatedHTTPRequest(exchange.RestSpotSupplementary, privateCancelOrder, req, &result) + err := y.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpotSupplementary, privateCancelOrder, req, &result) if err != nil { return err } @@ -167,7 +167,7 @@ func (y *Yobit) CancelExistingOrder(orderID int64) error { } // GetTradeHistory returns the trade history -func (y *Yobit) GetTradeHistory(tidFrom, count, tidEnd, since, end int64, order, pair string) (map[string]TradeHistory, error) { +func (y *Yobit) GetTradeHistory(ctx context.Context, tidFrom, count, tidEnd, since, end int64, order, pair string) (map[string]TradeHistory, error) { req := url.Values{} req.Add("from", strconv.FormatInt(tidFrom, 10)) req.Add("count", strconv.FormatInt(count, 10)) @@ -180,7 +180,7 @@ func (y *Yobit) GetTradeHistory(tidFrom, count, tidEnd, since, end int64, order, result := TradeHistoryResponse{} - err := y.SendAuthenticatedHTTPRequest(exchange.RestSpotSupplementary, privateTradeHistory, req, &result) + err := y.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpotSupplementary, privateTradeHistory, req, &result) if err != nil { return nil, err } @@ -192,13 +192,13 @@ func (y *Yobit) GetTradeHistory(tidFrom, count, tidEnd, since, end int64, order, } // GetCryptoDepositAddress returns the deposit address for a specific currency -func (y *Yobit) GetCryptoDepositAddress(coin string) (DepositAddress, error) { +func (y *Yobit) GetCryptoDepositAddress(ctx context.Context, coin string) (DepositAddress, error) { req := url.Values{} req.Add("coinName", coin) result := DepositAddress{} - err := y.SendAuthenticatedHTTPRequest(exchange.RestSpotSupplementary, privateGetDepositAddress, req, &result) + err := y.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpotSupplementary, privateGetDepositAddress, req, &result) if err != nil { return result, err } @@ -209,7 +209,7 @@ func (y *Yobit) GetCryptoDepositAddress(coin string) (DepositAddress, error) { } // WithdrawCoinsToAddress initiates a withdrawal to a specified address -func (y *Yobit) WithdrawCoinsToAddress(coin string, amount float64, address string) (WithdrawCoinsToAddress, error) { +func (y *Yobit) WithdrawCoinsToAddress(ctx context.Context, coin string, amount float64, address string) (WithdrawCoinsToAddress, error) { req := url.Values{} req.Add("coinName", coin) req.Add("amount", strconv.FormatFloat(amount, 'f', -1, 64)) @@ -217,7 +217,7 @@ func (y *Yobit) WithdrawCoinsToAddress(coin string, amount float64, address stri result := WithdrawCoinsToAddress{} - err := y.SendAuthenticatedHTTPRequest(exchange.RestSpotSupplementary, privateWithdrawCoinsToAddress, req, &result) + err := y.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpotSupplementary, privateWithdrawCoinsToAddress, req, &result) if err != nil { return result, err } @@ -228,14 +228,14 @@ func (y *Yobit) WithdrawCoinsToAddress(coin string, amount float64, address stri } // CreateCoupon creates an exchange coupon for a sepcific currency -func (y *Yobit) CreateCoupon(currency string, amount float64) (CreateCoupon, error) { +func (y *Yobit) CreateCoupon(ctx context.Context, currency string, amount float64) (CreateCoupon, error) { req := url.Values{} req.Add("currency", currency) req.Add("amount", strconv.FormatFloat(amount, 'f', -1, 64)) var result CreateCoupon - err := y.SendAuthenticatedHTTPRequest(exchange.RestSpotSupplementary, privateCreateCoupon, req, &result) + err := y.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpotSupplementary, privateCreateCoupon, req, &result) if err != nil { return result, err } @@ -246,13 +246,13 @@ func (y *Yobit) CreateCoupon(currency string, amount float64) (CreateCoupon, err } // RedeemCoupon redeems an exchange coupon -func (y *Yobit) RedeemCoupon(coupon string) (RedeemCoupon, error) { +func (y *Yobit) RedeemCoupon(ctx context.Context, coupon string) (RedeemCoupon, error) { req := url.Values{} req.Add("coupon", coupon) result := RedeemCoupon{} - err := y.SendAuthenticatedHTTPRequest(exchange.RestSpotSupplementary, privateRedeemCoupon, req, &result) + err := y.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpotSupplementary, privateRedeemCoupon, req, &result) if err != nil { return result, err } @@ -263,7 +263,7 @@ func (y *Yobit) RedeemCoupon(coupon string) (RedeemCoupon, error) { } // SendHTTPRequest sends an unauthenticated HTTP request -func (y *Yobit) SendHTTPRequest(ep exchange.URL, path string, result interface{}) error { +func (y *Yobit) SendHTTPRequest(ctx context.Context, ep exchange.URL, path string, result interface{}) error { endpoint, err := y.API.Endpoints.GetURL(ep) if err != nil { return err @@ -278,13 +278,13 @@ func (y *Yobit) SendHTTPRequest(ep exchange.URL, path string, result interface{} HTTPRecording: y.HTTPRecording, } - return y.SendPayload(context.Background(), request.Unset, func() (*request.Item, error) { + return y.SendPayload(ctx, request.Unset, func() (*request.Item, error) { return item, nil }) } // SendAuthenticatedHTTPRequest sends an authenticated HTTP request to Yobit -func (y *Yobit) SendAuthenticatedHTTPRequest(ep exchange.URL, path string, params url.Values, result interface{}) (err error) { +func (y *Yobit) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, path string, params url.Values, result interface{}) (err error) { if !y.AllowAuthenticatedRequest() { return fmt.Errorf("%s %w", y.Name, exchange.ErrAuthenticatedRequestWithoutCredentialsSet) } @@ -296,7 +296,7 @@ func (y *Yobit) SendAuthenticatedHTTPRequest(ep exchange.URL, path string, param params = url.Values{} } - return y.SendPayload(context.Background(), request.Unset, func() (*request.Item, error) { + return y.SendPayload(ctx, request.Unset, func() (*request.Item, error) { n := y.Requester.GetNonce(false).String() params.Set("nonce", n) diff --git a/exchanges/yobit/yobit_test.go b/exchanges/yobit/yobit_test.go index f4d4bf48..6bf0dc19 100644 --- a/exchanges/yobit/yobit_test.go +++ b/exchanges/yobit/yobit_test.go @@ -1,6 +1,7 @@ package yobit import ( + "context" "log" "math" "os" @@ -51,7 +52,7 @@ func TestMain(m *testing.M) { func TestFetchTradablePairs(t *testing.T) { t.Parallel() - _, err := y.FetchTradablePairs(asset.Spot) + _, err := y.FetchTradablePairs(context.Background(), asset.Spot) if err != nil { t.Errorf("FetchTradablePairs err: %s", err) } @@ -59,7 +60,7 @@ func TestFetchTradablePairs(t *testing.T) { func TestGetInfo(t *testing.T) { t.Parallel() - _, err := y.GetInfo() + _, err := y.GetInfo(context.Background()) if err != nil { t.Error("GetInfo() error") } @@ -67,7 +68,7 @@ func TestGetInfo(t *testing.T) { func TestGetTicker(t *testing.T) { t.Parallel() - _, err := y.GetTicker("btc_usd") + _, err := y.GetTicker(context.Background(), "btc_usd") if err != nil { t.Error("GetTicker() error", err) } @@ -75,7 +76,7 @@ func TestGetTicker(t *testing.T) { func TestGetDepth(t *testing.T) { t.Parallel() - _, err := y.GetDepth("btc_usd") + _, err := y.GetDepth(context.Background(), "btc_usd") if err != nil { t.Error("GetDepth() error", err) } @@ -83,7 +84,7 @@ func TestGetDepth(t *testing.T) { func TestGetTrades(t *testing.T) { t.Parallel() - _, err := y.GetTrades("btc_usd") + _, err := y.GetTrades(context.Background(), "btc_usd") if err != nil { t.Error("GetTrades() error", err) } @@ -91,7 +92,7 @@ func TestGetTrades(t *testing.T) { func TestGetAccountInfo(t *testing.T) { t.Parallel() - _, err := y.UpdateAccountInfo(asset.Spot) + _, err := y.UpdateAccountInfo(context.Background(), asset.Spot) if err == nil { t.Error("GetAccountInfo() Expected error") } @@ -99,7 +100,7 @@ func TestGetAccountInfo(t *testing.T) { func TestGetOpenOrders(t *testing.T) { t.Parallel() - _, err := y.GetOpenOrders("") + _, err := y.GetOpenOrders(context.Background(), "") if err == nil { t.Error("GetOpenOrders() Expected error") } @@ -107,7 +108,8 @@ func TestGetOpenOrders(t *testing.T) { func TestGetOrderInfo(t *testing.T) { t.Parallel() - _, err := y.GetOrderInfo("6196974", currency.Pair{}, asset.Spot) + _, err := y.GetOrderInfo(context.Background(), + "6196974", currency.Pair{}, asset.Spot) if err == nil { t.Error("GetOrderInfo() Expected error") } @@ -115,7 +117,7 @@ func TestGetOrderInfo(t *testing.T) { func TestCancelOrder(t *testing.T) { t.Parallel() - err := y.CancelExistingOrder(1337) + err := y.CancelExistingOrder(context.Background(), 1337) if err == nil { t.Error("CancelOrder() Expected error") } @@ -123,7 +125,7 @@ func TestCancelOrder(t *testing.T) { func TestTrade(t *testing.T) { t.Parallel() - _, err := y.Trade("", order.Buy.String(), 0, 0) + _, err := y.Trade(context.Background(), "", order.Buy.String(), 0, 0) if err == nil { t.Error("Trade() Expected error") } @@ -131,7 +133,7 @@ func TestTrade(t *testing.T) { func TestWithdrawCoinsToAddress(t *testing.T) { t.Parallel() - _, err := y.WithdrawCoinsToAddress("", 0, "") + _, err := y.WithdrawCoinsToAddress(context.Background(), "", 0, "") if err == nil { t.Error("WithdrawCoinsToAddress() Expected error") } @@ -139,7 +141,7 @@ func TestWithdrawCoinsToAddress(t *testing.T) { func TestCreateYobicode(t *testing.T) { t.Parallel() - _, err := y.CreateCoupon("bla", 0) + _, err := y.CreateCoupon(context.Background(), "bla", 0) if err == nil { t.Error("CreateYobicode() Expected error") } @@ -147,7 +149,7 @@ func TestCreateYobicode(t *testing.T) { func TestRedeemYobicode(t *testing.T) { t.Parallel() - _, err := y.RedeemCoupon("bla2") + _, err := y.RedeemCoupon(context.Background(), "bla2") if err == nil { t.Error("RedeemYobicode() Expected error") } @@ -169,7 +171,7 @@ func setFeeBuilder() *exchange.FeeBuilder { // TestGetFeeByTypeOfflineTradeFee logic test func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { var feeBuilder = setFeeBuilder() - _, err := y.GetFeeByType(feeBuilder) + _, err := y.GetFeeByType(context.Background(), feeBuilder) if err != nil { t.Fatal(err) } @@ -311,7 +313,7 @@ func TestGetActiveOrders(t *testing.T) { AssetType: asset.Spot, } - _, err := y.GetActiveOrders(&getOrdersRequest) + _, err := y.GetActiveOrders(context.Background(), &getOrdersRequest) if areTestAPIKeysSet() && err != nil { t.Errorf("Could not get open orders: %s", err) } else if !areTestAPIKeysSet() && err == nil { @@ -329,7 +331,7 @@ func TestGetOrderHistory(t *testing.T) { EndTime: time.Unix(math.MaxInt64, 0), } - _, err := y.GetOrderHistory(&getOrdersRequest) + _, err := y.GetOrderHistory(context.Background(), &getOrdersRequest) if areTestAPIKeysSet() && err != nil { t.Errorf("Could not get order history: %s", err) } else if !areTestAPIKeysSet() && err == nil { @@ -361,7 +363,7 @@ func TestSubmitOrder(t *testing.T) { ClientID: "meowOrder", AssetType: asset.Spot, } - response, err := y.SubmitOrder(orderSubmission) + response, err := y.SubmitOrder(context.Background(), orderSubmission) if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) { t.Errorf("Order failed to be placed: %v", err) } else if !areTestAPIKeysSet() && err == nil { @@ -383,7 +385,7 @@ func TestCancelExchangeOrder(t *testing.T) { AssetType: asset.Spot, } - err := y.CancelOrder(orderCancellation) + err := y.CancelOrder(context.Background(), orderCancellation) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") } @@ -406,7 +408,7 @@ func TestCancelAllExchangeOrders(t *testing.T) { AssetType: asset.Spot, } - resp, err := y.CancelAllOrders(orderCancellation) + resp, err := y.CancelAllOrders(context.Background(), orderCancellation) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") @@ -424,7 +426,8 @@ func TestModifyOrder(t *testing.T) { if areTestAPIKeysSet() && !canManipulateRealOrders { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - _, err := y.ModifyOrder(&order.Modify{AssetType: asset.Spot}) + _, err := y.ModifyOrder(context.Background(), + &order.Modify{AssetType: asset.Spot}) if err == nil { t.Error("ModifyOrder() Expected error") } @@ -444,7 +447,8 @@ func TestWithdraw(t *testing.T) { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - _, err := y.WithdrawCryptocurrencyFunds(&withdrawCryptoRequest) + _, err := y.WithdrawCryptocurrencyFunds(context.Background(), + &withdrawCryptoRequest) if !areTestAPIKeysSet() && err == nil { t.Error("Expecting an error when no keys are set") } @@ -459,7 +463,7 @@ func TestWithdrawFiat(t *testing.T) { } var withdrawFiatRequest = withdraw.Request{} - _, err := y.WithdrawFiatFunds(&withdrawFiatRequest) + _, err := y.WithdrawFiatFunds(context.Background(), &withdrawFiatRequest) if err != common.ErrFunctionNotSupported { t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, @@ -473,7 +477,8 @@ func TestWithdrawInternationalBank(t *testing.T) { } var withdrawFiatRequest = withdraw.Request{} - _, err := y.WithdrawFiatFundsToInternationalBank(&withdrawFiatRequest) + _, err := y.WithdrawFiatFundsToInternationalBank(context.Background(), + &withdrawFiatRequest) if err != common.ErrFunctionNotSupported { t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, @@ -483,12 +488,12 @@ func TestWithdrawInternationalBank(t *testing.T) { func TestGetDepositAddress(t *testing.T) { if areTestAPIKeysSet() { - _, err := y.GetDepositAddress(currency.BTC, "") + _, err := y.GetDepositAddress(context.Background(), currency.BTC, "") if err != nil { t.Error("GetDepositAddress() Expected error") } } else { - _, err := y.GetDepositAddress(currency.BTC, "") + _, err := y.GetDepositAddress(context.Background(), currency.BTC, "") if err == nil { t.Error("GetDepositAddress() error") } @@ -500,7 +505,7 @@ func TestGetRecentTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = y.GetRecentTrades(currencyPair, asset.Spot) + _, err = y.GetRecentTrades(context.Background(), currencyPair, asset.Spot) if err != nil { t.Error(err) } @@ -511,7 +516,8 @@ func TestGetHistoricTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = y.GetHistoricTrades(currencyPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) + _, err = y.GetHistoricTrades(context.Background(), + currencyPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) if err != nil && err != common.ErrFunctionNotSupported { t.Error(err) } @@ -523,7 +529,7 @@ func TestUpdateTicker(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = y.UpdateTicker(cp, asset.Spot) + _, err = y.UpdateTicker(context.Background(), cp, asset.Spot) if err != nil { t.Error(err) } @@ -531,7 +537,7 @@ func TestUpdateTicker(t *testing.T) { func TestUpdateTickers(t *testing.T) { t.Parallel() - err := y.UpdateTickers(asset.Spot) + err := y.UpdateTickers(context.Background(), asset.Spot) if err != nil { t.Error(err) } diff --git a/exchanges/yobit/yobit_wrapper.go b/exchanges/yobit/yobit_wrapper.go index ed556202..349db47e 100644 --- a/exchanges/yobit/yobit_wrapper.go +++ b/exchanges/yobit/yobit_wrapper.go @@ -1,6 +1,7 @@ package yobit import ( + "context" "errors" "math" "sort" @@ -40,7 +41,7 @@ func (y *Yobit) GetDefaultConfig() (*config.ExchangeConfig, error) { } if y.Features.Supports.RESTCapabilities.AutoPairUpdates { - err = y.UpdateTradablePairs(true) + err = y.UpdateTradablePairs(context.TODO(), true) if err != nil { return nil, err } @@ -136,7 +137,7 @@ func (y *Yobit) Run() { return } - err := y.UpdateTradablePairs(false) + err := y.UpdateTradablePairs(context.TODO(), false) if err != nil { log.Errorf(log.ExchangeSys, "%s failed to update tradable pairs. Err: %s", @@ -146,8 +147,8 @@ func (y *Yobit) Run() { } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (y *Yobit) FetchTradablePairs(asset asset.Item) ([]string, error) { - info, err := y.GetInfo() +func (y *Yobit) FetchTradablePairs(ctx context.Context, asset asset.Item) ([]string, error) { + info, err := y.GetInfo(ctx) if err != nil { return nil, err } @@ -162,8 +163,8 @@ func (y *Yobit) FetchTradablePairs(asset asset.Item) ([]string, error) { // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (y *Yobit) UpdateTradablePairs(forceUpdate bool) error { - pairs, err := y.FetchTradablePairs(asset.Spot) +func (y *Yobit) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { + pairs, err := y.FetchTradablePairs(ctx, asset.Spot) if err != nil { return err } @@ -175,7 +176,7 @@ func (y *Yobit) UpdateTradablePairs(forceUpdate bool) error { } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (y *Yobit) UpdateTickers(a asset.Item) error { +func (y *Yobit) UpdateTickers(ctx context.Context, a asset.Item) error { enabledPairs, err := y.GetEnabledPairs(a) if err != nil { return err @@ -185,7 +186,7 @@ func (y *Yobit) UpdateTickers(a asset.Item) error { return err } - result, err := y.GetTicker(pairsCollated) + result, err := y.GetTicker(ctx, pairsCollated) if err != nil { return err } @@ -220,8 +221,8 @@ func (y *Yobit) UpdateTickers(a asset.Item) error { } // UpdateTicker updates and returns the ticker for a currency pair -func (y *Yobit) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) { - err := y.UpdateTickers(a) +func (y *Yobit) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { + err := y.UpdateTickers(ctx, a) if err != nil { return nil, err } @@ -229,25 +230,25 @@ func (y *Yobit) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, erro } // FetchTicker returns the ticker for a currency pair -func (y *Yobit) FetchTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) { +func (y *Yobit) FetchTicker(ctx context.Context, p currency.Pair, assetType asset.Item) (*ticker.Price, error) { tick, err := ticker.GetTicker(y.Name, p, assetType) if err != nil { - return y.UpdateTicker(p, assetType) + return y.UpdateTicker(ctx, p, assetType) } return tick, nil } // FetchOrderbook returns the orderbook for a currency pair -func (y *Yobit) FetchOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (y *Yobit) FetchOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { ob, err := orderbook.Get(y.Name, p, assetType) if err != nil { - return y.UpdateOrderbook(p, assetType) + return y.UpdateOrderbook(ctx, p, assetType) } return ob, nil } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (y *Yobit) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (y *Yobit) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { book := &orderbook.Base{ Exchange: y.Name, Pair: p, @@ -258,7 +259,7 @@ func (y *Yobit) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderbo if err != nil { return book, err } - orderbookNew, err := y.GetDepth(fpair.String()) + orderbookNew, err := y.GetDepth(ctx, fpair.String()) if err != nil { return book, err } @@ -287,10 +288,10 @@ func (y *Yobit) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderbo // UpdateAccountInfo retrieves balances for all enabled currencies for the // Yobit exchange -func (y *Yobit) UpdateAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (y *Yobit) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { var response account.Holdings response.Exchange = y.Name - accountBalance, err := y.GetAccountInformation() + accountBalance, err := y.GetAccountInformation(ctx) if err != nil { return response, err } @@ -323,10 +324,10 @@ func (y *Yobit) UpdateAccountInfo(assetType asset.Item) (account.Holdings, error } // FetchAccountInfo retrieves balances for all enabled currencies -func (y *Yobit) FetchAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (y *Yobit) FetchAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { acc, err := account.GetHoldings(y.Name, assetType) if err != nil { - return y.UpdateAccountInfo(assetType) + return y.UpdateAccountInfo(ctx, assetType) } return acc, nil @@ -334,17 +335,17 @@ func (y *Yobit) FetchAccountInfo(assetType asset.Item) (account.Holdings, error) // GetFundingHistory returns funding history, deposits and // withdrawals -func (y *Yobit) GetFundingHistory() ([]exchange.FundHistory, error) { +func (y *Yobit) GetFundingHistory(ctx context.Context) ([]exchange.FundHistory, error) { return nil, common.ErrFunctionNotSupported } // GetWithdrawalsHistory returns previous withdrawals data -func (y *Yobit) GetWithdrawalsHistory(c currency.Code) (resp []exchange.WithdrawalHistory, err error) { +func (y *Yobit) GetWithdrawalsHistory(ctx context.Context, c currency.Code) (resp []exchange.WithdrawalHistory, err error) { return nil, common.ErrNotYetImplemented } // GetRecentTrades returns the most recent trades for a currency and asset -func (y *Yobit) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade.Data, error) { +func (y *Yobit) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { var err error p, err = y.FormatExchangeCurrency(p, assetType) if err != nil { @@ -352,7 +353,7 @@ func (y *Yobit) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade. } var resp []trade.Data var tradeData []Trade - tradeData, err = y.GetTrades(p.String()) + tradeData, err = y.GetTrades(ctx, p.String()) if err != nil { return nil, err } @@ -384,13 +385,13 @@ func (y *Yobit) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade. } // GetHistoricTrades returns historic trade data within the timeframe provided -func (y *Yobit) GetHistoricTrades(_ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { +func (y *Yobit) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { return nil, common.ErrFunctionNotSupported } // SubmitOrder submits a new order // Yobit only supports limit orders -func (y *Yobit) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { +func (y *Yobit) SubmitOrder(ctx context.Context, s *order.Submit) (order.SubmitResponse, error) { var submitOrderResponse order.SubmitResponse if err := s.Validate(); err != nil { return submitOrderResponse, err @@ -405,7 +406,8 @@ func (y *Yobit) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { return submitOrderResponse, err } - response, err := y.Trade(fPair.String(), + response, err := y.Trade(ctx, + fPair.String(), s.Side.String(), s.Amount, s.Price) @@ -422,12 +424,12 @@ func (y *Yobit) SubmitOrder(s *order.Submit) (order.SubmitResponse, error) { // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (y *Yobit) ModifyOrder(action *order.Modify) (order.Modify, error) { +func (y *Yobit) ModifyOrder(ctx context.Context, action *order.Modify) (order.Modify, error) { return order.Modify{}, common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number -func (y *Yobit) CancelOrder(o *order.Cancel) error { +func (y *Yobit) CancelOrder(ctx context.Context, o *order.Cancel) error { if err := o.Validate(o.StandardCancel()); err != nil { return err } @@ -437,16 +439,16 @@ func (y *Yobit) CancelOrder(o *order.Cancel) error { return err } - return y.CancelExistingOrder(orderIDInt) + return y.CancelExistingOrder(ctx, orderIDInt) } // CancelBatchOrders cancels an orders by their corresponding ID numbers -func (y *Yobit) CancelBatchOrders(o []order.Cancel) (order.CancelBatchResponse, error) { +func (y *Yobit) CancelBatchOrders(ctx context.Context, o []order.Cancel) (order.CancelBatchResponse, error) { return order.CancelBatchResponse{}, common.ErrNotYetImplemented } // CancelAllOrders cancels all orders associated with a currency pair -func (y *Yobit) CancelAllOrders(_ *order.Cancel) (order.CancelAllResponse, error) { +func (y *Yobit) CancelAllOrders(ctx context.Context, _ *order.Cancel) (order.CancelAllResponse, error) { cancelAllOrdersResponse := order.CancelAllResponse{ Status: make(map[string]string), } @@ -461,7 +463,7 @@ func (y *Yobit) CancelAllOrders(_ *order.Cancel) (order.CancelAllResponse, error if err != nil { return cancelAllOrdersResponse, err } - activeOrdersForPair, err := y.GetOpenOrders(fCurr.String()) + activeOrdersForPair, err := y.GetOpenOrders(ctx, fCurr.String()) if err != nil { return cancelAllOrdersResponse, err } @@ -477,7 +479,7 @@ func (y *Yobit) CancelAllOrders(_ *order.Cancel) (order.CancelAllResponse, error continue } - err = y.CancelExistingOrder(orderIDInt) + err = y.CancelExistingOrder(ctx, orderIDInt) if err != nil { cancelAllOrdersResponse.Status[key] = err.Error() } @@ -488,14 +490,14 @@ func (y *Yobit) CancelAllOrders(_ *order.Cancel) (order.CancelAllResponse, error } // GetOrderInfo returns order information based on order ID -func (y *Yobit) GetOrderInfo(orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { +func (y *Yobit) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { var orderDetail order.Detail return orderDetail, common.ErrNotYetImplemented } // GetDepositAddress returns a deposit address for a specified currency -func (y *Yobit) GetDepositAddress(cryptocurrency currency.Code, _ string) (string, error) { - a, err := y.GetCryptoDepositAddress(cryptocurrency.String()) +func (y *Yobit) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _ string) (string, error) { + a, err := y.GetCryptoDepositAddress(ctx, cryptocurrency.String()) if err != nil { return "", err } @@ -505,11 +507,12 @@ func (y *Yobit) GetDepositAddress(cryptocurrency currency.Code, _ string) (strin // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is // submitted -func (y *Yobit) WithdrawCryptocurrencyFunds(withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (y *Yobit) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } - resp, err := y.WithdrawCoinsToAddress(withdrawRequest.Currency.String(), + resp, err := y.WithdrawCoinsToAddress(ctx, + withdrawRequest.Currency.String(), withdrawRequest.Amount, withdrawRequest.Crypto.Address) if err != nil { @@ -523,18 +526,18 @@ func (y *Yobit) WithdrawCryptocurrencyFunds(withdrawRequest *withdraw.Request) ( // WithdrawFiatFunds returns a withdrawal ID when a // withdrawal is submitted -func (y *Yobit) WithdrawFiatFunds(_ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (y *Yobit) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a // withdrawal is submitted -func (y *Yobit) WithdrawFiatFundsToInternationalBank(_ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (y *Yobit) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // GetFeeByType returns an estimate of fee based on type of transaction -func (y *Yobit) GetFeeByType(feeBuilder *exchange.FeeBuilder) (float64, error) { +func (y *Yobit) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { if !y.AllowAuthenticatedRequest() && // Todo check connection status feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { feeBuilder.FeeType = exchange.OfflineTradeFee @@ -543,7 +546,7 @@ func (y *Yobit) GetFeeByType(feeBuilder *exchange.FeeBuilder) (float64, error) { } // GetActiveOrders retrieves any orders that are active/open -func (y *Yobit) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, error) { +func (y *Yobit) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) { if err := req.Validate(); err != nil { return nil, err } @@ -560,7 +563,7 @@ func (y *Yobit) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, er if err != nil { return nil, err } - resp, err := y.GetOpenOrders(fCurr.String()) + resp, err := y.GetOpenOrders(ctx, fCurr.String()) if err != nil { return nil, err } @@ -592,7 +595,7 @@ func (y *Yobit) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, er // GetOrderHistory retrieves account order information // Can Limit response to specific order status -func (y *Yobit) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, error) { +func (y *Yobit) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) { if err := req.Validate(); err != nil { return nil, err } @@ -603,7 +606,8 @@ func (y *Yobit) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, er if err != nil { return nil, err } - resp, err := y.GetTradeHistory(0, + resp, err := y.GetTradeHistory(ctx, + 0, 10000, math.MaxInt64, req.StartTime.Unix(), @@ -651,17 +655,17 @@ func (y *Yobit) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, er // ValidateCredentials validates current credentials used for wrapper // functionality -func (y *Yobit) ValidateCredentials(assetType asset.Item) error { - _, err := y.UpdateAccountInfo(assetType) +func (y *Yobit) ValidateCredentials(ctx context.Context, assetType asset.Item) error { + _, err := y.UpdateAccountInfo(ctx, assetType) return y.CheckTransientError(err) } // GetHistoricCandles returns candles between a time period for a set time interval -func (y *Yobit) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (y *Yobit) GetHistoricCandles(ctx context.Context, pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { return kline.Item{}, common.ErrFunctionNotSupported } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (y *Yobit) GetHistoricCandlesExtended(pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (y *Yobit) GetHistoricCandlesExtended(ctx context.Context, pair currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { return kline.Item{}, common.ErrFunctionNotSupported } diff --git a/exchanges/zb/zb.go b/exchanges/zb/zb.go index b88915b2..cba1d2be 100644 --- a/exchanges/zb/zb.go +++ b/exchanges/zb/zb.go @@ -45,7 +45,7 @@ type ZB struct { } // SpotNewOrder submits an order to ZB -func (z *ZB) SpotNewOrder(arg SpotNewOrderRequestParams) (int64, error) { +func (z *ZB) SpotNewOrder(ctx context.Context, arg SpotNewOrderRequestParams) (int64, error) { var result SpotNewOrderResponse vals := url.Values{} @@ -56,7 +56,7 @@ func (z *ZB) SpotNewOrder(arg SpotNewOrderRequestParams) (int64, error) { vals.Set("price", strconv.FormatFloat(arg.Price, 'f', -1, 64)) vals.Set("tradeType", string(arg.Type)) - err := z.SendAuthenticatedHTTPRequest(exchange.RestSpotSupplementary, http.MethodGet, vals, &result, request.Auth) + err := z.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, vals, &result, request.Auth) if err != nil { return 0, err } @@ -71,7 +71,7 @@ func (z *ZB) SpotNewOrder(arg SpotNewOrderRequestParams) (int64, error) { } // CancelExistingOrder cancels an order -func (z *ZB) CancelExistingOrder(orderID int64, symbol string) error { +func (z *ZB) CancelExistingOrder(ctx context.Context, orderID int64, symbol string) error { type response struct { Code int `json:"code"` // Result code Message string `json:"message"` // Result Message @@ -84,7 +84,7 @@ func (z *ZB) CancelExistingOrder(orderID int64, symbol string) error { vals.Set("currency", symbol) var result response - err := z.SendAuthenticatedHTTPRequest(exchange.RestSpotSupplementary, http.MethodGet, vals, &result, request.Auth) + err := z.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, vals, &result, request.Auth) if err != nil { return err } @@ -97,18 +97,18 @@ func (z *ZB) CancelExistingOrder(orderID int64, symbol string) error { // GetAccountInformation returns account information including coin information // and pricing -func (z *ZB) GetAccountInformation() (AccountsResponse, error) { +func (z *ZB) GetAccountInformation(ctx context.Context) (AccountsResponse, error) { var result AccountsResponse vals := url.Values{} vals.Set("accesskey", z.API.Credentials.Key) vals.Set("method", "getAccountInfo") - return result, z.SendAuthenticatedHTTPRequest(exchange.RestSpotSupplementary, http.MethodGet, vals, &result, request.Auth) + return result, z.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, vals, &result, request.Auth) } // GetUnfinishedOrdersIgnoreTradeType returns unfinished orders -func (z *ZB) GetUnfinishedOrdersIgnoreTradeType(currency string, pageindex, pagesize int64) ([]Order, error) { +func (z *ZB) GetUnfinishedOrdersIgnoreTradeType(ctx context.Context, currency string, pageindex, pagesize int64) ([]Order, error) { var result []Order vals := url.Values{} vals.Set("accesskey", z.API.Credentials.Key) @@ -117,12 +117,12 @@ func (z *ZB) GetUnfinishedOrdersIgnoreTradeType(currency string, pageindex, page vals.Set("pageIndex", strconv.FormatInt(pageindex, 10)) vals.Set("pageSize", strconv.FormatInt(pagesize, 10)) - err := z.SendAuthenticatedHTTPRequest(exchange.RestSpotSupplementary, http.MethodGet, vals, &result, request.Auth) + err := z.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, vals, &result, request.Auth) return result, err } // GetOrders returns finished orders -func (z *ZB) GetOrders(currency string, pageindex, side int64) ([]Order, error) { +func (z *ZB) GetOrders(ctx context.Context, currency string, pageindex, side int64) ([]Order, error) { var response []Order vals := url.Values{} vals.Set("accesskey", z.API.Credentials.Key) @@ -130,16 +130,16 @@ func (z *ZB) GetOrders(currency string, pageindex, side int64) ([]Order, error) vals.Set("currency", currency) vals.Set("pageIndex", strconv.FormatInt(pageindex, 10)) vals.Set("tradeType", strconv.FormatInt(side, 10)) - return response, z.SendAuthenticatedHTTPRequest(exchange.RestSpotSupplementary, http.MethodGet, vals, &response, request.Auth) + return response, z.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, vals, &response, request.Auth) } // GetMarkets returns market information including pricing, symbols and // each symbols decimal precision -func (z *ZB) GetMarkets() (map[string]MarketResponseItem, error) { +func (z *ZB) GetMarkets(ctx context.Context) (map[string]MarketResponseItem, error) { endpoint := fmt.Sprintf("/%s/%s/%s", zbData, zbAPIVersion, zbMarkets) var res map[string]MarketResponseItem - err := z.SendHTTPRequest(exchange.RestSpot, endpoint, &res, request.UnAuth) + err := z.SendHTTPRequest(ctx, exchange.RestSpot, endpoint, &res, request.UnAuth) if err != nil { return nil, err } @@ -151,9 +151,8 @@ func (z *ZB) GetMarkets() (map[string]MarketResponseItem, error) { // // symbol: string of currency pair // 获取最新价格 -func (z *ZB) GetLatestSpotPrice(symbol string) (float64, error) { - res, err := z.GetTicker(symbol) - +func (z *ZB) GetLatestSpotPrice(ctx context.Context, symbol string) (float64, error) { + res, err := z.GetTicker(ctx, symbol) if err != nil { return 0, err } @@ -162,35 +161,35 @@ func (z *ZB) GetLatestSpotPrice(symbol string) (float64, error) { } // GetTicker returns a ticker for a given symbol -func (z *ZB) GetTicker(symbol string) (TickerResponse, error) { +func (z *ZB) GetTicker(ctx context.Context, symbol string) (TickerResponse, error) { urlPath := fmt.Sprintf("/%s/%s/%s?market=%s", zbData, zbAPIVersion, zbTicker, symbol) var res TickerResponse - err := z.SendHTTPRequest(exchange.RestSpot, urlPath, &res, request.UnAuth) + err := z.SendHTTPRequest(ctx, exchange.RestSpot, urlPath, &res, request.UnAuth) return res, err } // GetTrades returns trades for a given symbol -func (z *ZB) GetTrades(symbol string) (TradeHistory, error) { +func (z *ZB) GetTrades(ctx context.Context, symbol string) (TradeHistory, error) { urlPath := fmt.Sprintf("/%s/%s/%s?market=%s", zbData, zbAPIVersion, zbTrades, symbol) var res TradeHistory - err := z.SendHTTPRequest(exchange.RestSpot, urlPath, &res, request.UnAuth) + err := z.SendHTTPRequest(ctx, exchange.RestSpot, urlPath, &res, request.UnAuth) return res, err } // GetTickers returns ticker data for all supported symbols -func (z *ZB) GetTickers() (map[string]TickerChildResponse, error) { +func (z *ZB) GetTickers(ctx context.Context) (map[string]TickerChildResponse, error) { urlPath := fmt.Sprintf("/%s/%s/%s", zbData, zbAPIVersion, zbTickers) resp := make(map[string]TickerChildResponse) - err := z.SendHTTPRequest(exchange.RestSpot, urlPath, &resp, request.UnAuth) + err := z.SendHTTPRequest(ctx, exchange.RestSpot, urlPath, &resp, request.UnAuth) return resp, err } // GetOrderbook returns the orderbook for a given symbol -func (z *ZB) GetOrderbook(symbol string) (OrderbookResponse, error) { +func (z *ZB) GetOrderbook(ctx context.Context, symbol string) (OrderbookResponse, error) { urlPath := fmt.Sprintf("/%s/%s/%s?market=%s", zbData, zbAPIVersion, zbDepth, symbol) var res OrderbookResponse - err := z.SendHTTPRequest(exchange.RestSpot, urlPath, &res, request.UnAuth) + err := z.SendHTTPRequest(ctx, exchange.RestSpot, urlPath, &res, request.UnAuth) if err != nil { return res, err } @@ -214,7 +213,7 @@ func (z *ZB) GetOrderbook(symbol string) (OrderbookResponse, error) { } // GetSpotKline returns Kline data -func (z *ZB) GetSpotKline(arg KlinesRequestParams) (KLineResponse, error) { +func (z *ZB) GetSpotKline(ctx context.Context, arg KlinesRequestParams) (KLineResponse, error) { vals := url.Values{} vals.Set("type", arg.Type) vals.Set("market", arg.Symbol) @@ -229,7 +228,7 @@ func (z *ZB) GetSpotKline(arg KlinesRequestParams) (KLineResponse, error) { var res KLineResponse var rawKlines map[string]interface{} - err := z.SendHTTPRequest(exchange.RestSpot, urlPath, &rawKlines, klineFunc) + err := z.SendHTTPRequest(ctx, exchange.RestSpot, urlPath, &rawKlines, klineFunc) if err != nil { return res, err } @@ -268,7 +267,7 @@ func (z *ZB) GetSpotKline(arg KlinesRequestParams) (KLineResponse, error) { // NOTE - PLEASE BE AWARE THAT YOU NEED TO GENERATE A DEPOSIT ADDRESS VIA // LOGGING IN AND NOT BY USING THIS ENDPOINT OTHERWISE THIS WILL GIVE YOU A // GENERAL ERROR RESPONSE. -func (z *ZB) GetCryptoAddress(currency currency.Code) (UserAddress, error) { +func (z *ZB) GetCryptoAddress(ctx context.Context, currency currency.Code) (UserAddress, error) { var resp UserAddress vals := url.Values{} @@ -276,11 +275,11 @@ func (z *ZB) GetCryptoAddress(currency currency.Code) (UserAddress, error) { vals.Set("currency", currency.Lower().String()) return resp, - z.SendAuthenticatedHTTPRequest(exchange.RestSpotSupplementary, http.MethodGet, vals, &resp, request.Auth) + z.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, vals, &resp, request.Auth) } // SendHTTPRequest sends an unauthenticated HTTP request -func (z *ZB) SendHTTPRequest(ep exchange.URL, path string, result interface{}, f request.EndpointLimit) error { +func (z *ZB) SendHTTPRequest(ctx context.Context, ep exchange.URL, path string, result interface{}, f request.EndpointLimit) error { endpoint, err := z.API.Endpoints.GetURL(ep) if err != nil { return err @@ -295,13 +294,13 @@ func (z *ZB) SendHTTPRequest(ep exchange.URL, path string, result interface{}, f HTTPRecording: z.HTTPRecording, } - return z.SendPayload(context.Background(), f, func() (*request.Item, error) { + return z.SendPayload(ctx, f, func() (*request.Item, error) { return item, nil }) } // SendAuthenticatedHTTPRequest sends authenticated requests to the zb API -func (z *ZB) SendAuthenticatedHTTPRequest(ep exchange.URL, httpMethod string, params url.Values, result interface{}, f request.EndpointLimit) error { +func (z *ZB) SendAuthenticatedHTTPRequest(ctx context.Context, ep exchange.URL, httpMethod string, params url.Values, result interface{}, f request.EndpointLimit) error { if !z.AllowAuthenticatedRequest() { return fmt.Errorf("%s %w", z.Name, exchange.ErrAuthenticatedRequestWithoutCredentialsSet) } @@ -345,7 +344,7 @@ func (z *ZB) SendAuthenticatedHTTPRequest(ep exchange.URL, httpMethod string, pa }, nil } - err = z.SendPayload(context.Background(), f, newRequest) + err = z.SendPayload(ctx, f, newRequest) if err != nil { return err } @@ -431,7 +430,7 @@ var errorCode = map[int64]string{ } // Withdraw transfers funds -func (z *ZB) Withdraw(currency, address, safepassword string, amount, fees float64, itransfer bool) (string, error) { +func (z *ZB) Withdraw(ctx context.Context, currency, address, safepassword string, amount, fees float64, itransfer bool) (string, error) { type response struct { Code int `json:"code"` // Result code Message string `json:"message"` // Result Message @@ -449,7 +448,7 @@ func (z *ZB) Withdraw(currency, address, safepassword string, amount, fees float vals.Set("safePwd", safepassword) var resp response - err := z.SendAuthenticatedHTTPRequest(exchange.RestSpotSupplementary, http.MethodGet, vals, &resp, request.Auth) + err := z.SendAuthenticatedHTTPRequest(ctx, exchange.RestSpotSupplementary, http.MethodGet, vals, &resp, request.Auth) if err != nil { return "", err } diff --git a/exchanges/zb/zb_test.go b/exchanges/zb/zb_test.go index 6771a361..5ee511b2 100644 --- a/exchanges/zb/zb_test.go +++ b/exchanges/zb/zb_test.go @@ -1,6 +1,7 @@ package zb import ( + "context" "encoding/json" "errors" "fmt" @@ -65,7 +66,7 @@ func TestSpotNewOrder(t *testing.T) { Amount: 0.01, Price: 10246.1, } - _, err := z.SpotNewOrder(arg) + _, err := z.SpotNewOrder(context.Background(), arg) if err != nil { t.Errorf("ZB SpotNewOrder: %s", err) } @@ -78,7 +79,7 @@ func TestCancelExistingOrder(t *testing.T) { t.Skip() } - err := z.CancelExistingOrder(20180629145864850, testCurrency) + err := z.CancelExistingOrder(context.Background(), 20180629145864850, testCurrency) if err != nil { t.Errorf("ZB CancelExistingOrder: %s", err) } @@ -86,7 +87,7 @@ func TestCancelExistingOrder(t *testing.T) { func TestGetLatestSpotPrice(t *testing.T) { t.Parallel() - _, err := z.GetLatestSpotPrice(testCurrency) + _, err := z.GetLatestSpotPrice(context.Background(), testCurrency) if err != nil { t.Errorf("ZB GetLatestSpotPrice: %s", err) } @@ -94,7 +95,7 @@ func TestGetLatestSpotPrice(t *testing.T) { func TestGetTicker(t *testing.T) { t.Parallel() - _, err := z.GetTicker(testCurrency) + _, err := z.GetTicker(context.Background(), testCurrency) if err != nil { t.Errorf("ZB GetTicker: %s", err) } @@ -102,7 +103,7 @@ func TestGetTicker(t *testing.T) { func TestGetTickers(t *testing.T) { t.Parallel() - _, err := z.GetTickers() + _, err := z.GetTickers(context.Background()) if err != nil { t.Errorf("ZB GetTicker: %s", err) } @@ -110,7 +111,7 @@ func TestGetTickers(t *testing.T) { func TestGetOrderbook(t *testing.T) { t.Parallel() - _, err := z.GetOrderbook(testCurrency) + _, err := z.GetOrderbook(context.Background(), testCurrency) if err != nil { t.Errorf("ZB GetTicker: %s", err) } @@ -118,7 +119,7 @@ func TestGetOrderbook(t *testing.T) { func TestGetMarkets(t *testing.T) { t.Parallel() - _, err := z.GetMarkets() + _, err := z.GetMarkets(context.Background()) if err != nil { t.Errorf("ZB GetMarkets: %s", err) } @@ -141,7 +142,7 @@ func setFeeBuilder() *exchange.FeeBuilder { func TestGetFeeByTypeOfflineTradeFee(t *testing.T) { t.Parallel() var feeBuilder = setFeeBuilder() - _, err := z.GetFeeByType(feeBuilder) + _, err := z.GetFeeByType(context.Background(), feeBuilder) if err != nil { t.Fatal(err) } @@ -235,7 +236,7 @@ func TestGetActiveOrders(t *testing.T) { AssetType: asset.Spot, } - _, err := z.GetActiveOrders(&getOrdersRequest) + _, err := z.GetActiveOrders(context.Background(), &getOrdersRequest) if z.ValidateAPICredentials() && err != nil { t.Error(err) } else if !z.ValidateAPICredentials() && err == nil { @@ -255,7 +256,7 @@ func TestGetOrderHistory(t *testing.T) { currency.BTC)}, } - _, err := z.GetOrderHistory(&getOrdersRequest) + _, err := z.GetOrderHistory(context.Background(), &getOrdersRequest) if z.ValidateAPICredentials() && err != nil { t.Error(err) } else if !z.ValidateAPICredentials() && err == nil { @@ -288,7 +289,7 @@ func TestSubmitOrder(t *testing.T) { ClientID: "meowOrder", AssetType: asset.Spot, } - response, err := z.SubmitOrder(orderSubmission) + response, err := z.SubmitOrder(context.Background(), orderSubmission) if z.ValidateAPICredentials() && err != nil { t.Error(err) } else if !z.ValidateAPICredentials() && err == nil { @@ -316,7 +317,7 @@ func TestCancelExchangeOrder(t *testing.T) { AssetType: asset.Spot, } - err := z.CancelOrder(orderCancellation) + err := z.CancelOrder(context.Background(), orderCancellation) if z.ValidateAPICredentials() && err != nil { t.Error(err) } else if !z.ValidateAPICredentials() && err == nil { @@ -341,7 +342,7 @@ func TestCancelAllExchangeOrders(t *testing.T) { AssetType: asset.Spot, } - resp, err := z.CancelAllOrders(orderCancellation) + resp, err := z.CancelAllOrders(context.Background(), orderCancellation) if z.ValidateAPICredentials() && err != nil { t.Error(err) @@ -358,12 +359,12 @@ func TestGetAccountInfo(t *testing.T) { t.Skip("skipping authenticated function for mock testing") } if z.ValidateAPICredentials() { - _, err := z.UpdateAccountInfo(asset.Spot) + _, err := z.UpdateAccountInfo(context.Background(), asset.Spot) if err != nil { t.Error("GetAccountInfo() error", err) } } else { - _, err := z.UpdateAccountInfo(asset.Spot) + _, err := z.UpdateAccountInfo(context.Background(), asset.Spot) if err == nil { t.Error("GetAccountInfo() Expected error") } @@ -377,7 +378,8 @@ func TestModifyOrder(t *testing.T) { if z.ValidateAPICredentials() && !canManipulateRealOrders { t.Skip("API keys set, canManipulateRealOrders false, skipping test") } - _, err := z.ModifyOrder(&order.Modify{AssetType: asset.Spot}) + _, err := z.ModifyOrder(context.Background(), + &order.Modify{AssetType: asset.Spot}) if err == nil { t.Error("ModifyOrder() Expected error") } @@ -401,7 +403,8 @@ func TestWithdraw(t *testing.T) { Description: "WITHDRAW IT ALL", } - _, err := z.WithdrawCryptocurrencyFunds(&withdrawCryptoRequest) + _, err := z.WithdrawCryptocurrencyFunds(context.Background(), + &withdrawCryptoRequest) if z.ValidateAPICredentials() && err != nil { t.Error(err) } else if !z.ValidateAPICredentials() && err == nil { @@ -418,7 +421,7 @@ func TestWithdrawFiat(t *testing.T) { } var withdrawFiatRequest = withdraw.Request{} - _, err := z.WithdrawFiatFunds(&withdrawFiatRequest) + _, err := z.WithdrawFiatFunds(context.Background(), &withdrawFiatRequest) if err != common.ErrFunctionNotSupported { t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err) } @@ -433,7 +436,8 @@ func TestWithdrawInternationalBank(t *testing.T) { } var withdrawFiatRequest = withdraw.Request{} - _, err := z.WithdrawFiatFundsToInternationalBank(&withdrawFiatRequest) + _, err := z.WithdrawFiatFundsToInternationalBank(context.Background(), + &withdrawFiatRequest) if err != common.ErrFunctionNotSupported { t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err) } @@ -444,13 +448,13 @@ func TestGetDepositAddress(t *testing.T) { t.Skip("skipping authenticated function for mock testing") } if z.ValidateAPICredentials() { - _, err := z.GetDepositAddress(currency.BTC, "") + _, err := z.GetDepositAddress(context.Background(), currency.BTC, "") if err != nil { t.Error("GetDepositAddress() error PLEASE MAKE SURE YOU CREATE DEPOSIT ADDRESSES VIA ZB.COM", err) } } else { - _, err := z.GetDepositAddress(currency.BTC, "") + _, err := z.GetDepositAddress(context.Background(), currency.BTC, "") if err == nil { t.Error("GetDepositAddress() Expected error") } @@ -833,7 +837,7 @@ func TestGetSpotKline(t *testing.T) { arg.Type = "1day" } - _, err := z.GetSpotKline(arg) + _, err := z.GetSpotKline(context.Background(), arg) if err != nil { t.Errorf("ZB GetSpotKline: %s", err) } @@ -852,11 +856,13 @@ func TestGetHistoricCandles(t *testing.T) { endTime = time.Date(2020, 9, 2, 0, 0, 0, 0, time.UTC) } - _, err = z.GetHistoricCandles(currencyPair, asset.Spot, startTime, endTime, kline.OneDay) + _, err = z.GetHistoricCandles(context.Background(), + currencyPair, asset.Spot, startTime, endTime, kline.OneDay) if err != nil { t.Fatal(err) } - _, err = z.GetHistoricCandles(currencyPair, asset.Spot, startTime, endTime, kline.Interval(time.Hour*7)) + _, err = z.GetHistoricCandles(context.Background(), + currencyPair, asset.Spot, startTime, endTime, kline.Interval(time.Hour*7)) if err == nil { t.Fatal("unexpected result") } @@ -873,7 +879,8 @@ func TestGetHistoricCandlesExtended(t *testing.T) { startTime = time.Date(2020, 9, 1, 0, 0, 0, 0, time.UTC) endTime = time.Date(2020, 9, 2, 0, 0, 0, 0, time.UTC) } - _, err = z.GetHistoricCandlesExtended(currencyPair, asset.Spot, startTime, endTime, kline.OneDay) + _, err = z.GetHistoricCandlesExtended(context.Background(), + currencyPair, asset.Spot, startTime, endTime, kline.OneDay) if err != nil { t.Fatal(err) } @@ -970,7 +977,7 @@ func TestValidateCandlesRequest(t *testing.T) { func TestGetTrades(t *testing.T) { t.Parallel() - trades, err := z.GetTrades("btc_usdt") + trades, err := z.GetTrades(context.Background(), "btc_usdt") if err != nil { t.Error(err) } @@ -986,7 +993,7 @@ func TestGetRecentTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = z.GetRecentTrades(currencyPair, asset.Spot) + _, err = z.GetRecentTrades(context.Background(), currencyPair, asset.Spot) if err != nil { t.Error(err) } @@ -998,7 +1005,8 @@ func TestGetHistoricTrades(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = z.GetHistoricTrades(currencyPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) + _, err = z.GetHistoricTrades(context.Background(), + currencyPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()) if err != nil && err != common.ErrFunctionNotSupported { t.Error(err) } @@ -1010,7 +1018,7 @@ func TestUpdateTicker(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = z.UpdateTicker(cp, asset.Spot) + _, err = z.UpdateTicker(context.Background(), cp, asset.Spot) if err != nil { t.Error(err) } @@ -1018,7 +1026,7 @@ func TestUpdateTicker(t *testing.T) { func TestUpdateTickers(t *testing.T) { t.Parallel() - err := z.UpdateTickers(asset.Spot) + err := z.UpdateTickers(context.Background(), asset.Spot) if err != nil { t.Error(err) } diff --git a/exchanges/zb/zb_wrapper.go b/exchanges/zb/zb_wrapper.go index 7178f727..16d7d909 100644 --- a/exchanges/zb/zb_wrapper.go +++ b/exchanges/zb/zb_wrapper.go @@ -1,6 +1,7 @@ package zb import ( + "context" "errors" "fmt" "sort" @@ -42,7 +43,7 @@ func (z *ZB) GetDefaultConfig() (*config.ExchangeConfig, error) { } if z.Features.Supports.RESTCapabilities.AutoPairUpdates { - err = z.UpdateTradablePairs(true) + err = z.UpdateTradablePairs(context.TODO(), true) if err != nil { return nil, err } @@ -208,15 +209,15 @@ func (z *ZB) Run() { return } - err := z.UpdateTradablePairs(false) + err := z.UpdateTradablePairs(context.TODO(), false) if err != nil { log.Errorf(log.ExchangeSys, "%s failed to update tradable pairs. Err: %s", z.Name, err) } } // FetchTradablePairs returns a list of the exchanges tradable pairs -func (z *ZB) FetchTradablePairs(asset asset.Item) ([]string, error) { - markets, err := z.GetMarkets() +func (z *ZB) FetchTradablePairs(ctx context.Context, asset asset.Item) ([]string, error) { + markets, err := z.GetMarkets(ctx) if err != nil { return nil, err } @@ -231,8 +232,8 @@ func (z *ZB) FetchTradablePairs(asset asset.Item) ([]string, error) { // UpdateTradablePairs updates the exchanges available pairs and stores // them in the exchanges config -func (z *ZB) UpdateTradablePairs(forceUpdate bool) error { - pairs, err := z.FetchTradablePairs(asset.Spot) +func (z *ZB) UpdateTradablePairs(ctx context.Context, forceUpdate bool) error { + pairs, err := z.FetchTradablePairs(ctx, asset.Spot) if err != nil { return err } @@ -244,8 +245,8 @@ func (z *ZB) UpdateTradablePairs(forceUpdate bool) error { } // UpdateTickers updates the ticker for all currency pairs of a given asset type -func (z *ZB) UpdateTickers(a asset.Item) error { - result, err := z.GetTickers() +func (z *ZB) UpdateTickers(ctx context.Context, a asset.Item) error { + result, err := z.GetTickers(ctx) if err != nil { return err } @@ -281,8 +282,8 @@ func (z *ZB) UpdateTickers(a asset.Item) error { } // UpdateTicker updates and returns the ticker for a currency pair -func (z *ZB) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) { - err := z.UpdateTickers(a) +func (z *ZB) UpdateTicker(ctx context.Context, p currency.Pair, a asset.Item) (*ticker.Price, error) { + err := z.UpdateTickers(ctx, a) if err != nil { return nil, err } @@ -290,25 +291,25 @@ func (z *ZB) UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) } // FetchTicker returns the ticker for a currency pair -func (z *ZB) FetchTicker(p currency.Pair, assetType asset.Item) (*ticker.Price, error) { +func (z *ZB) FetchTicker(ctx context.Context, p currency.Pair, assetType asset.Item) (*ticker.Price, error) { tickerNew, err := ticker.GetTicker(z.Name, p, assetType) if err != nil { - return z.UpdateTicker(p, assetType) + return z.UpdateTicker(ctx, p, assetType) } return tickerNew, nil } // FetchOrderbook returns orderbook base on the currency pair -func (z *ZB) FetchOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (z *ZB) FetchOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { ob, err := orderbook.Get(z.Name, p, assetType) if err != nil { - return z.UpdateOrderbook(p, assetType) + return z.UpdateOrderbook(ctx, p, assetType) } return ob, nil } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (z *ZB) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { +func (z *ZB) UpdateOrderbook(ctx context.Context, p currency.Pair, assetType asset.Item) (*orderbook.Base, error) { book := &orderbook.Base{ Exchange: z.Name, Pair: p, @@ -320,7 +321,7 @@ func (z *ZB) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderbook. return book, err } - orderbookNew, err := z.GetOrderbook(currFormat.String()) + orderbookNew, err := z.GetOrderbook(ctx, currFormat.String()) if err != nil { return book, err } @@ -347,7 +348,7 @@ func (z *ZB) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderbook. // UpdateAccountInfo retrieves balances for all enabled currencies for the // ZB exchange -func (z *ZB) UpdateAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (z *ZB) UpdateAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { var info account.Holdings var balances []account.Balance var coins []AccountsResponseCoin @@ -358,7 +359,7 @@ func (z *ZB) UpdateAccountInfo(assetType asset.Item) (account.Holdings, error) { } coins = resp.Data.Coins } else { - bal, err := z.GetAccountInformation() + bal, err := z.GetAccountInformation(ctx) if err != nil { return info, err } @@ -397,10 +398,10 @@ func (z *ZB) UpdateAccountInfo(assetType asset.Item) (account.Holdings, error) { } // FetchAccountInfo retrieves balances for all enabled currencies -func (z *ZB) FetchAccountInfo(assetType asset.Item) (account.Holdings, error) { +func (z *ZB) FetchAccountInfo(ctx context.Context, assetType asset.Item) (account.Holdings, error) { acc, err := account.GetHoldings(z.Name, assetType) if err != nil { - return z.UpdateAccountInfo(assetType) + return z.UpdateAccountInfo(ctx, assetType) } return acc, nil @@ -408,24 +409,24 @@ func (z *ZB) FetchAccountInfo(assetType asset.Item) (account.Holdings, error) { // GetFundingHistory returns funding history, deposits and // withdrawals -func (z *ZB) GetFundingHistory() ([]exchange.FundHistory, error) { +func (z *ZB) GetFundingHistory(ctx context.Context) ([]exchange.FundHistory, error) { return nil, common.ErrFunctionNotSupported } // GetWithdrawalsHistory returns previous withdrawals data -func (z *ZB) GetWithdrawalsHistory(c currency.Code) (resp []exchange.WithdrawalHistory, err error) { +func (z *ZB) GetWithdrawalsHistory(ctx context.Context, c currency.Code) (resp []exchange.WithdrawalHistory, err error) { return nil, common.ErrNotYetImplemented } // GetRecentTrades returns the most recent trades for a currency and asset -func (z *ZB) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade.Data, error) { +func (z *ZB) GetRecentTrades(ctx context.Context, p currency.Pair, assetType asset.Item) ([]trade.Data, error) { var err error p, err = z.FormatExchangeCurrency(p, assetType) if err != nil { return nil, err } var tradeData TradeHistory - tradeData, err = z.GetTrades(p.String()) + tradeData, err = z.GetTrades(ctx, p.String()) if err != nil { return nil, err } @@ -459,12 +460,12 @@ func (z *ZB) GetRecentTrades(p currency.Pair, assetType asset.Item) ([]trade.Dat } // GetHistoricTrades returns historic trade data within the timeframe provided -func (z *ZB) GetHistoricTrades(_ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { +func (z *ZB) GetHistoricTrades(_ context.Context, _ currency.Pair, _ asset.Item, _, _ time.Time) ([]trade.Data, error) { return nil, common.ErrFunctionNotSupported } // SubmitOrder submits a new order -func (z *ZB) SubmitOrder(o *order.Submit) (order.SubmitResponse, error) { +func (z *ZB) SubmitOrder(ctx context.Context, o *order.Submit) (order.SubmitResponse, error) { var submitOrderResponse order.SubmitResponse err := o.Validate() if err != nil { @@ -503,7 +504,7 @@ func (z *ZB) SubmitOrder(o *order.Submit) (order.SubmitResponse, error) { Type: oT, } var response int64 - response, err = z.SpotNewOrder(params) + response, err = z.SpotNewOrder(ctx, params) if err != nil { return submitOrderResponse, err } @@ -520,12 +521,12 @@ func (z *ZB) SubmitOrder(o *order.Submit) (order.SubmitResponse, error) { // ModifyOrder will allow of changing orderbook placement and limit to // market conversion -func (z *ZB) ModifyOrder(action *order.Modify) (order.Modify, error) { +func (z *ZB) ModifyOrder(ctx context.Context, action *order.Modify) (order.Modify, error) { return order.Modify{}, common.ErrFunctionNotSupported } // CancelOrder cancels an order by its corresponding ID number -func (z *ZB) CancelOrder(o *order.Cancel) error { +func (z *ZB) CancelOrder(ctx context.Context, o *order.Cancel) error { if err := o.Validate(o.StandardCancel()); err != nil { return err } @@ -550,16 +551,16 @@ func (z *ZB) CancelOrder(o *order.Cancel) error { if err != nil { return err } - return z.CancelExistingOrder(orderIDInt, fpair.String()) + return z.CancelExistingOrder(ctx, orderIDInt, fpair.String()) } // CancelBatchOrders cancels an orders by their corresponding ID numbers -func (z *ZB) CancelBatchOrders(o []order.Cancel) (order.CancelBatchResponse, error) { +func (z *ZB) CancelBatchOrders(ctx context.Context, o []order.Cancel) (order.CancelBatchResponse, error) { return order.CancelBatchResponse{}, common.ErrNotYetImplemented } // CancelAllOrders cancels all orders associated with a currency pair -func (z *ZB) CancelAllOrders(_ *order.Cancel) (order.CancelAllResponse, error) { +func (z *ZB) CancelAllOrders(ctx context.Context, _ *order.Cancel) (order.CancelAllResponse, error) { cancelAllOrdersResponse := order.CancelAllResponse{ Status: make(map[string]string), } @@ -575,7 +576,8 @@ func (z *ZB) CancelAllOrders(_ *order.Cancel) (order.CancelAllResponse, error) { return cancelAllOrdersResponse, err } for y := int64(1); ; y++ { - openOrders, err := z.GetUnfinishedOrdersIgnoreTradeType(fPair.String(), y, 10) + openOrders, err := z.GetUnfinishedOrdersIgnoreTradeType(ctx, + fPair.String(), y, 10) if err != nil { if strings.Contains(err.Error(), "3001") { break @@ -602,11 +604,12 @@ func (z *ZB) CancelAllOrders(_ *order.Cancel) (order.CancelAllResponse, error) { continue } - err = z.CancelOrder(&order.Cancel{ - ID: strconv.FormatInt(allOpenOrders[i].ID, 10), - Pair: p, - AssetType: asset.Spot, - }) + err = z.CancelOrder(ctx, + &order.Cancel{ + ID: strconv.FormatInt(allOpenOrders[i].ID, 10), + Pair: p, + AssetType: asset.Spot, + }) if err != nil { cancelAllOrdersResponse.Status[strconv.FormatInt(allOpenOrders[i].ID, 10)] = err.Error() } @@ -616,14 +619,14 @@ func (z *ZB) CancelAllOrders(_ *order.Cancel) (order.CancelAllResponse, error) { } // GetOrderInfo returns order information based on order ID -func (z *ZB) GetOrderInfo(orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { +func (z *ZB) GetOrderInfo(ctx context.Context, orderID string, pair currency.Pair, assetType asset.Item) (order.Detail, error) { var orderDetail order.Detail return orderDetail, common.ErrNotYetImplemented } // GetDepositAddress returns a deposit address for a specified currency -func (z *ZB) GetDepositAddress(cryptocurrency currency.Code, _ string) (string, error) { - address, err := z.GetCryptoAddress(cryptocurrency) +func (z *ZB) GetDepositAddress(ctx context.Context, cryptocurrency currency.Code, _ string) (string, error) { + address, err := z.GetCryptoAddress(ctx, cryptocurrency) if err != nil { return "", err } @@ -633,11 +636,12 @@ func (z *ZB) GetDepositAddress(cryptocurrency currency.Code, _ string) (string, // WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is // submitted -func (z *ZB) WithdrawCryptocurrencyFunds(withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (z *ZB) WithdrawCryptocurrencyFunds(ctx context.Context, withdrawRequest *withdraw.Request) (*withdraw.ExchangeResponse, error) { if err := withdrawRequest.Validate(); err != nil { return nil, err } - v, err := z.Withdraw(withdrawRequest.Currency.Lower().String(), + v, err := z.Withdraw(ctx, + withdrawRequest.Currency.Lower().String(), withdrawRequest.Crypto.Address, withdrawRequest.TradePassword, withdrawRequest.Amount, @@ -653,18 +657,18 @@ func (z *ZB) WithdrawCryptocurrencyFunds(withdrawRequest *withdraw.Request) (*wi // WithdrawFiatFunds returns a withdrawal ID when a // withdrawal is submitted -func (z *ZB) WithdrawFiatFunds(_ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (z *ZB) WithdrawFiatFunds(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // WithdrawFiatFundsToInternationalBank returns a withdrawal ID when a // withdrawal is submitted -func (z *ZB) WithdrawFiatFundsToInternationalBank(_ *withdraw.Request) (*withdraw.ExchangeResponse, error) { +func (z *ZB) WithdrawFiatFundsToInternationalBank(_ context.Context, _ *withdraw.Request) (*withdraw.ExchangeResponse, error) { return nil, common.ErrFunctionNotSupported } // GetFeeByType returns an estimate of fee based on type of transaction -func (z *ZB) GetFeeByType(feeBuilder *exchange.FeeBuilder) (float64, error) { +func (z *ZB) GetFeeByType(ctx context.Context, feeBuilder *exchange.FeeBuilder) (float64, error) { if (!z.AllowAuthenticatedRequest() || z.SkipAuthCheck) && // Todo check connection status feeBuilder.FeeType == exchange.CryptocurrencyTradeFee { feeBuilder.FeeType = exchange.OfflineTradeFee @@ -674,7 +678,7 @@ func (z *ZB) GetFeeByType(feeBuilder *exchange.FeeBuilder) (float64, error) { // GetActiveOrders retrieves any orders that are active/open // This function is not concurrency safe due to orderSide/orderType maps -func (z *ZB) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, error) { +func (z *ZB) GetActiveOrders(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) { if err := req.Validate(); err != nil { return nil, err } @@ -686,7 +690,8 @@ func (z *ZB) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, error if err != nil { return nil, err } - resp, err := z.GetUnfinishedOrdersIgnoreTradeType(fPair.String(), i, 10) + resp, err := z.GetUnfinishedOrdersIgnoreTradeType(ctx, + fPair.String(), i, 10) if err != nil { if strings.Contains(err.Error(), "3001") { break @@ -740,7 +745,7 @@ func (z *ZB) GetActiveOrders(req *order.GetOrdersRequest) ([]order.Detail, error // GetOrderHistory retrieves account order information // Can Limit response to specific order status // This function is not concurrency safe due to orderSide/orderType maps -func (z *ZB) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, error) { +func (z *ZB) GetOrderHistory(ctx context.Context, req *order.GetOrdersRequest) ([]order.Detail, error) { if err := req.Validate(); err != nil { return nil, err } @@ -775,7 +780,7 @@ func (z *ZB) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, error if err != nil { return nil, err } - resp, err := z.GetOrders(fPair.String(), y, side) + resp, err := z.GetOrders(ctx, fPair.String(), y, side) if err != nil { return nil, err } @@ -821,8 +826,8 @@ func (z *ZB) GetOrderHistory(req *order.GetOrdersRequest) ([]order.Detail, error // ValidateCredentials validates current credentials used for wrapper // functionality -func (z *ZB) ValidateCredentials(assetType asset.Item) error { - _, err := z.UpdateAccountInfo(assetType) +func (z *ZB) ValidateCredentials(ctx context.Context, assetType asset.Item) error { + _, err := z.UpdateAccountInfo(ctx, assetType) return z.CheckTransientError(err) } @@ -845,7 +850,7 @@ func (z *ZB) FormatExchangeKlineInterval(in kline.Interval) string { } // GetHistoricCandles returns candles between a time period for a set time interval -func (z *ZB) GetHistoricCandles(p currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (z *ZB) GetHistoricCandles(ctx context.Context, p currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { ret, err := z.validateCandlesRequest(p, a, start, end, interval) if err != nil { return kline.Item{}, err @@ -863,7 +868,7 @@ func (z *ZB) GetHistoricCandles(p currency.Pair, a asset.Item, start, end time.T Size: int64(z.Features.Enabled.Kline.ResultLimit), } var candles KLineResponse - candles, err = z.GetSpotKline(klineParams) + candles, err = z.GetSpotKline(ctx, klineParams) if err != nil { return kline.Item{}, err } @@ -887,7 +892,7 @@ func (z *ZB) GetHistoricCandles(p currency.Pair, a asset.Item, start, end time.T } // GetHistoricCandlesExtended returns candles between a time period for a set time interval -func (z *ZB) GetHistoricCandlesExtended(p currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (z *ZB) GetHistoricCandlesExtended(ctx context.Context, p currency.Pair, a asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { ret, err := z.validateCandlesRequest(p, a, start, end, interval) if err != nil { return kline.Item{}, err @@ -908,7 +913,7 @@ allKlines: Size: int64(z.Features.Enabled.Kline.ResultLimit), } - candles, err := z.GetSpotKline(klineParams) + candles, err := z.GetSpotKline(ctx, klineParams) if err != nil { return kline.Item{}, err } diff --git a/gctscript/modules/gct/exchange.go b/gctscript/modules/gct/exchange.go index 676720d1..8b5ec7b3 100644 --- a/gctscript/modules/gct/exchange.go +++ b/gctscript/modules/gct/exchange.go @@ -1,6 +1,7 @@ package gct import ( + "context" "fmt" "time" @@ -63,7 +64,8 @@ func ExchangeOrderbook(args ...objects.Object) (objects.Object, error) { return nil, err } - ob, err := wrappers.GetWrapper().Orderbook(exchangeName, pair, assetType) + ob, err := wrappers.GetWrapper(). + Orderbook(context.TODO(), exchangeName, pair, assetType) if err != nil { return nil, err } @@ -129,7 +131,8 @@ func ExchangeTicker(args ...objects.Object) (objects.Object, error) { return nil, err } - tx, err := wrappers.GetWrapper().Ticker(exchangeName, pair, assetType) + tx, err := wrappers.GetWrapper(). + Ticker(context.TODO(), exchangeName, pair, assetType) if err != nil { return nil, err } @@ -229,7 +232,8 @@ func ExchangeAccountInfo(args ...objects.Object) (objects.Object, error) { if err != nil { return nil, err } - rtnValue, err := wrappers.GetWrapper().AccountInformation(exchangeName, assetType) + rtnValue, err := wrappers.GetWrapper(). + AccountInformation(context.TODO(), exchangeName, assetType) if err != nil { return nil, err } @@ -297,7 +301,8 @@ func ExchangeOrderQuery(args ...objects.Object) (objects.Object, error) { return nil, err } - orderDetails, err := wrappers.GetWrapper().QueryOrder(exchangeName, orderID, pair, assetType) + orderDetails, err := wrappers.GetWrapper(). + QueryOrder(context.TODO(), exchangeName, orderID, pair, assetType) if err != nil { return nil, err } @@ -384,7 +389,8 @@ func ExchangeOrderCancel(args ...objects.Object) (objects.Object, error) { } var isCancelled bool - isCancelled, err = wrappers.GetWrapper().CancelOrder(exchangeName, orderID, cp, a) + isCancelled, err = wrappers.GetWrapper(). + CancelOrder(context.TODO(), exchangeName, orderID, cp, a) if err != nil { return nil, err } @@ -457,7 +463,7 @@ func ExchangeOrderSubmit(args ...objects.Object) (objects.Object, error) { Exchange: exchangeName, } - rtn, err := wrappers.GetWrapper().SubmitOrder(tempSubmit) + rtn, err := wrappers.GetWrapper().SubmitOrder(context.TODO(), tempSubmit) if err != nil { return nil, err } @@ -547,7 +553,8 @@ func ExchangeWithdrawCrypto(args ...objects.Object) (objects.Object, error) { Amount: amount, } - rtn, err := wrappers.GetWrapper().WithdrawalCryptoFunds(withdrawRequest) + rtn, err := wrappers.GetWrapper(). + WithdrawalCryptoFunds(context.TODO(), withdrawRequest) if err != nil { return nil, err } @@ -589,7 +596,8 @@ func ExchangeWithdrawFiat(args ...objects.Object) (objects.Object, error) { Amount: amount, } - rtn, err := wrappers.GetWrapper().WithdrawalFiatFunds(bankAccountID, withdrawRequest) + rtn, err := wrappers.GetWrapper(). + WithdrawalFiatFunds(context.TODO(), bankAccountID, withdrawRequest) if err != nil { return nil, err } @@ -656,7 +664,14 @@ func exchangeOHLCV(args ...objects.Object) (objects.Object, error) { return nil, err } - ret, err := wrappers.GetWrapper().OHLCV(exchangeName, pair, assetType, startTime, endTime, kline.Interval(interval)) + ret, err := wrappers.GetWrapper(). + OHLCV(context.TODO(), + exchangeName, + pair, + assetType, + startTime, + endTime, + kline.Interval(interval)) if err != nil { return nil, err } diff --git a/gctscript/modules/wrapper_types.go b/gctscript/modules/wrapper_types.go index b3602a62..8deb7b53 100644 --- a/gctscript/modules/wrapper_types.go +++ b/gctscript/modules/wrapper_types.go @@ -1,6 +1,7 @@ package modules import ( + "context" "time" "github.com/thrasher-corp/gocryptotrader/currency" @@ -32,17 +33,17 @@ type GCT interface { type Exchange interface { Exchanges(enabledOnly bool) []string IsEnabled(exch string) bool - Orderbook(exch string, pair currency.Pair, item asset.Item) (*orderbook.Base, error) - Ticker(exch string, pair currency.Pair, item asset.Item) (*ticker.Price, error) + Orderbook(ctx context.Context, exch string, pair currency.Pair, item asset.Item) (*orderbook.Base, error) + Ticker(ctx context.Context, exch string, pair currency.Pair, item asset.Item) (*ticker.Price, error) Pairs(exch string, enabledOnly bool, item asset.Item) (*currency.Pairs, error) - QueryOrder(exch, orderid string, pair currency.Pair, assetType asset.Item) (*order.Detail, error) - SubmitOrder(submit *order.Submit) (*order.SubmitResponse, error) - CancelOrder(exch, orderid string, pair currency.Pair, item asset.Item) (bool, error) - AccountInformation(exch string, assetType asset.Item) (account.Holdings, error) + QueryOrder(ctx context.Context, exch, orderid string, pair currency.Pair, assetType asset.Item) (*order.Detail, error) + SubmitOrder(ctx context.Context, submit *order.Submit) (*order.SubmitResponse, error) + CancelOrder(ctx context.Context, exch, orderid string, pair currency.Pair, item asset.Item) (bool, error) + AccountInformation(ctx context.Context, exch string, assetType asset.Item) (account.Holdings, error) DepositAddress(exch string, currencyCode currency.Code) (string, error) - WithdrawalFiatFunds(bankAccountID string, request *withdraw.Request) (out string, err error) - WithdrawalCryptoFunds(request *withdraw.Request) (out string, err error) - OHLCV(exch string, pair currency.Pair, item asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) + WithdrawalFiatFunds(ctx context.Context, bankAccountID string, request *withdraw.Request) (out string, err error) + WithdrawalCryptoFunds(ctx context.Context, request *withdraw.Request) (out string, err error) + OHLCV(ctx context.Context, exch string, pair currency.Pair, item asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) } // SetModuleWrapper link the wrapper and interface to use for modules diff --git a/gctscript/vm/gctscript.go b/gctscript/vm/gctscript.go index bced60f4..5f388afe 100644 --- a/gctscript/vm/gctscript.go +++ b/gctscript/vm/gctscript.go @@ -41,7 +41,7 @@ func (g *GctScriptManager) Validate(file string) (err error) { if err != nil { return } - return tempVM.Run() + return tempVM.RunCtx() } // ShutdownAll shutdown all diff --git a/gctscript/vm/vm.go b/gctscript/vm/vm.go index 92361944..f1904143 100644 --- a/gctscript/vm/vm.go +++ b/gctscript/vm/vm.go @@ -109,38 +109,19 @@ func (vm *VM) Compile() (err error) { return } -// Run runs byte code -func (vm *VM) Run() (err error) { - if vm.config.Verbose { - log.Debugf(log.GCTScriptMgr, "Running script: %s ID: %v", vm.ShortName(), vm.ID) - } - - err = vm.Compiled.Run() - if err != nil { - vm.event(StatusFailure, TypeExecute) - return Error{ - Action: "Run", - Cause: err, - } - } - vm.event(StatusSuccess, TypeExecute) - return -} - // RunCtx runs compiled byte code with context.Context support. func (vm *VM) RunCtx() (err error) { - if vm.ctx == nil { - vm.ctx = context.Background() - } - - ct, cancel := context.WithTimeout(vm.ctx, vm.config.ScriptTimeout) + ctx, cancel := context.WithTimeout(context.Background(), vm.config.ScriptTimeout) defer cancel() if vm.config.Verbose { - log.Debugf(log.GCTScriptMgr, "Running script: %s ID: %v", vm.ShortName(), vm.ID) + log.Debugf(log.GCTScriptMgr, + "Running script: %s ID: %v", + vm.ShortName(), + vm.ID) } - err = vm.Compiled.RunContext(ct) + err = vm.Compiled.RunContext(ctx) if err != nil { vm.event(StatusFailure, TypeExecute) return Error{ diff --git a/gctscript/vm/vm_test.go b/gctscript/vm/vm_test.go index 1062c8e5..c8e1a851 100644 --- a/gctscript/vm/vm_test.go +++ b/gctscript/vm/vm_test.go @@ -219,7 +219,7 @@ func TestVMRun(t *testing.T) { t.Fatal(err) } - err = testVM.Run() + err = testVM.RunCtx() if err != nil { t.Fatal(err) } @@ -444,7 +444,7 @@ func TestVM_CompileInvalid(t *testing.T) { if err != nil { t.Fatal(err) } - err = testVM.Run() + err = testVM.RunCtx() if err == nil { t.Fatal("unexpected result broken script compiled successfully ") } diff --git a/gctscript/vm/vm_types.go b/gctscript/vm/vm_types.go index d336c5a7..34db127d 100644 --- a/gctscript/vm/vm_types.go +++ b/gctscript/vm/vm_types.go @@ -1,7 +1,6 @@ package vm import ( - "context" "sync" "time" @@ -54,7 +53,6 @@ type VM struct { Path string Script *tengo.Script Compiled *tengo.Compiled - ctx context.Context T time.Duration NextRun time.Time S chan struct{} diff --git a/gctscript/wrappers/gct/exchange/exchange.go b/gctscript/wrappers/gct/exchange/exchange.go index 3e580d77..24619366 100644 --- a/gctscript/wrappers/gct/exchange/exchange.go +++ b/gctscript/wrappers/gct/exchange/exchange.go @@ -1,6 +1,7 @@ package exchange import ( + "context" "errors" "sort" "strconv" @@ -43,18 +44,18 @@ func (e Exchange) IsEnabled(exch string) bool { } // Orderbook returns current orderbook requested exchange, pair and asset -func (e Exchange) Orderbook(exch string, pair currency.Pair, item asset.Item) (*orderbook.Base, error) { - return engine.Bot.GetSpecificOrderbook(pair, exch, item) +func (e Exchange) Orderbook(ctx context.Context, exch string, pair currency.Pair, item asset.Item) (*orderbook.Base, error) { + return engine.Bot.GetSpecificOrderbook(ctx, pair, exch, item) } // Ticker returns ticker for provided currency pair & asset type -func (e Exchange) Ticker(exch string, pair currency.Pair, item asset.Item) (*ticker.Price, error) { +func (e Exchange) Ticker(ctx context.Context, exch string, pair currency.Pair, item asset.Item) (*ticker.Price, error) { ex, err := e.GetExchange(exch) if err != nil { return nil, err } - return ex.FetchTicker(pair, item) + return ex.FetchTicker(ctx, pair, item) } // Pairs returns either all or enabled currency pairs @@ -76,8 +77,8 @@ func (e Exchange) Pairs(exch string, enabledOnly bool, item asset.Item) (*curren } // QueryOrder returns details of a valid exchange order -func (e Exchange) QueryOrder(exch, orderID string, pair currency.Pair, assetType asset.Item) (*order.Detail, error) { - o, err := engine.Bot.OrderManager.GetOrderInfo(exch, orderID, pair, assetType) +func (e Exchange) QueryOrder(ctx context.Context, exch, orderID string, pair currency.Pair, assetType asset.Item) (*order.Detail, error) { + o, err := engine.Bot.OrderManager.GetOrderInfo(ctx, exch, orderID, pair, assetType) if err != nil { return nil, err } @@ -86,8 +87,8 @@ func (e Exchange) QueryOrder(exch, orderID string, pair currency.Pair, assetType } // SubmitOrder submit new order on exchange -func (e Exchange) SubmitOrder(submit *order.Submit) (*order.SubmitResponse, error) { - r, err := engine.Bot.OrderManager.Submit(submit) +func (e Exchange) SubmitOrder(ctx context.Context, submit *order.Submit) (*order.SubmitResponse, error) { + r, err := engine.Bot.OrderManager.Submit(ctx, submit) if err != nil { return nil, err } @@ -96,8 +97,8 @@ func (e Exchange) SubmitOrder(submit *order.Submit) (*order.SubmitResponse, erro } // CancelOrder wrapper to cancel order on exchange -func (e Exchange) CancelOrder(exch, orderID string, cp currency.Pair, a asset.Item) (bool, error) { - orderDetails, err := e.QueryOrder(exch, orderID, cp, a) +func (e Exchange) CancelOrder(ctx context.Context, exch, orderID string, cp currency.Pair, a asset.Item) (bool, error) { + orderDetails, err := e.QueryOrder(ctx, exch, orderID, cp, a) if err != nil { return false, err } @@ -111,7 +112,7 @@ func (e Exchange) CancelOrder(exch, orderID string, cp currency.Pair, a asset.It Exchange: exch, } - err = engine.Bot.OrderManager.Cancel(cancel) + err = engine.Bot.OrderManager.Cancel(ctx, cancel) if err != nil { return false, err } @@ -119,13 +120,13 @@ func (e Exchange) CancelOrder(exch, orderID string, cp currency.Pair, a asset.It } // AccountInformation returns account information (balance etc) for requested exchange -func (e Exchange) AccountInformation(exch string, assetType asset.Item) (account.Holdings, error) { +func (e Exchange) AccountInformation(ctx context.Context, exch string, assetType asset.Item) (account.Holdings, error) { ex, err := e.GetExchange(exch) if err != nil { return account.Holdings{}, err } - accountInfo, err := ex.FetchAccountInfo(assetType) + accountInfo, err := ex.FetchAccountInfo(ctx, assetType) if err != nil { return account.Holdings{}, err } @@ -136,14 +137,13 @@ func (e Exchange) AccountInformation(exch string, assetType asset.Item) (account // DepositAddress gets the address required to deposit funds for currency type func (e Exchange) DepositAddress(exch string, currencyCode currency.Code) (out string, err error) { if currencyCode.IsEmpty() { - err = errors.New("currency code is empty") - return + return "", errors.New("currency code is empty") } return engine.Bot.DepositAddressManager.GetDepositAddressByExchangeAndCurrency(exch, currencyCode) } // WithdrawalFiatFunds withdraw funds from exchange to requested fiat source -func (e Exchange) WithdrawalFiatFunds(bankAccountID string, request *withdraw.Request) (string, error) { +func (e Exchange) WithdrawalFiatFunds(ctx context.Context, bankAccountID string, request *withdraw.Request) (string, error) { ex, err := e.GetExchange(request.Exchange) if err != nil { return "", err @@ -176,7 +176,7 @@ func (e Exchange) WithdrawalFiatFunds(bankAccountID string, request *withdraw.Re request.Fiat.Bank.SWIFTCode = v.SWIFTCode request.Fiat.Bank.IBAN = v.IBAN - resp, err := engine.Bot.WithdrawManager.SubmitWithdrawal(request) + resp, err := engine.Bot.WithdrawManager.SubmitWithdrawal(ctx, request) if err != nil { return "", err } @@ -184,7 +184,7 @@ func (e Exchange) WithdrawalFiatFunds(bankAccountID string, request *withdraw.Re } // WithdrawalCryptoFunds withdraw funds from exchange to requested Crypto source -func (e Exchange) WithdrawalCryptoFunds(request *withdraw.Request) (string, error) { +func (e Exchange) WithdrawalCryptoFunds(ctx context.Context, request *withdraw.Request) (string, error) { // Checks if exchange is enabled or not so we don't call OTP generation _, err := e.GetExchange(request.Exchange) if err != nil { @@ -199,7 +199,7 @@ func (e Exchange) WithdrawalCryptoFunds(request *withdraw.Request) (string, erro request.OneTimePassword = v } - resp, err := engine.Bot.WithdrawManager.SubmitWithdrawal(request) + resp, err := engine.Bot.WithdrawManager.SubmitWithdrawal(ctx, request) if err != nil { return "", err } @@ -207,12 +207,12 @@ func (e Exchange) WithdrawalCryptoFunds(request *withdraw.Request) (string, erro } // OHLCV returns open high low close volume candles for requested exchange/pair/asset/start & end time -func (e Exchange) OHLCV(exch string, pair currency.Pair, item asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { +func (e Exchange) OHLCV(ctx context.Context, exch string, pair currency.Pair, item asset.Item, start, end time.Time, interval kline.Interval) (kline.Item, error) { ex, err := e.GetExchange(exch) if err != nil { return kline.Item{}, err } - ret, err := ex.GetHistoricCandlesExtended(pair, item, start, end, interval) + ret, err := ex.GetHistoricCandlesExtended(ctx, pair, item, start, end, interval) if err != nil { return kline.Item{}, err } diff --git a/gctscript/wrappers/gct/exchange/exchange_test.go b/gctscript/wrappers/gct/exchange/exchange_test.go index 5ed0e261..aa6990f7 100644 --- a/gctscript/wrappers/gct/exchange/exchange_test.go +++ b/gctscript/wrappers/gct/exchange/exchange_test.go @@ -1,6 +1,7 @@ package exchange import ( + "context" "fmt" "os" "path/filepath" @@ -95,7 +96,7 @@ func TestExchange_Ticker(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = exchangeTest.Ticker(exchName, c, assetType) + _, err = exchangeTest.Ticker(context.Background(), exchName, c, assetType) if err != nil { t.Fatal(err) } @@ -107,7 +108,7 @@ func TestExchange_Orderbook(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = exchangeTest.Orderbook(exchName, c, assetType) + _, err = exchangeTest.Orderbook(context.Background(), exchName, c, assetType) if err != nil { t.Fatal(err) } @@ -129,7 +130,8 @@ func TestExchange_AccountInformation(t *testing.T) { if !configureExchangeKeys() { t.Skip("no exchange configured test skipped") } - _, err := exchangeTest.AccountInformation(exchName, asset.Spot) + _, err := exchangeTest.AccountInformation(context.Background(), + exchName, asset.Spot) if err != nil { t.Fatal(err) } @@ -140,7 +142,8 @@ func TestExchange_QueryOrder(t *testing.T) { t.Skip("no exchange configured test skipped") } t.Parallel() - _, err := exchangeTest.QueryOrder(exchName, orderID, currency.Pair{}, assetType) + _, err := exchangeTest.QueryOrder(context.Background(), + exchName, orderID, currency.Pair{}, assetType) if err != nil { t.Fatal(err) } @@ -168,7 +171,7 @@ func TestExchange_SubmitOrder(t *testing.T) { Exchange: exchName, AssetType: asset.Spot, } - _, err = exchangeTest.SubmitOrder(tempOrder) + _, err = exchangeTest.SubmitOrder(context.Background(), tempOrder) if err != nil { t.Fatal(err) } @@ -181,7 +184,8 @@ func TestExchange_CancelOrder(t *testing.T) { t.Parallel() cp := currency.NewPair(currency.BTC, currency.USD) a := asset.Spot - _, err := exchangeTest.CancelOrder(exchName, orderID, cp, a) + _, err := exchangeTest.CancelOrder(context.Background(), + exchName, orderID, cp, a) if err != nil { t.Fatal(err) } @@ -191,7 +195,7 @@ func TestOHLCV(t *testing.T) { t.Parallel() cp := currency.NewPair(currency.BTC, currency.AUD) cp.Delimiter = currency.DashDelimiter - calvinKline, err := exchangeTest.OHLCV(exchName, cp, assetType, time.Now().Add(-time.Hour*24).UTC(), time.Now().UTC(), kline.OneHour) + calvinKline, err := exchangeTest.OHLCV(context.Background(), exchName, cp, assetType, time.Now().Add(-time.Hour*24).UTC(), time.Now().UTC(), kline.OneHour) if err != nil { t.Error(err) } diff --git a/gctscript/wrappers/validator/validator.go b/gctscript/wrappers/validator/validator.go index 90cc31c5..53443678 100644 --- a/gctscript/wrappers/validator/validator.go +++ b/gctscript/wrappers/validator/validator.go @@ -1,6 +1,7 @@ package validator import ( + "context" "math/rand" "time" @@ -43,7 +44,7 @@ func (w Wrapper) IsEnabled(exch string) (v bool) { } // Orderbook validator for test execution/scripts -func (w Wrapper) Orderbook(exch string, pair currency.Pair, item asset.Item) (*orderbook.Base, error) { +func (w Wrapper) Orderbook(ctx context.Context, exch string, pair currency.Pair, item asset.Item) (*orderbook.Base, error) { if exch == exchError.String() { return nil, errTestFailed } @@ -68,7 +69,7 @@ func (w Wrapper) Orderbook(exch string, pair currency.Pair, item asset.Item) (*o } // Ticker validator for test execution/scripts -func (w Wrapper) Ticker(exch string, pair currency.Pair, item asset.Item) (*ticker.Price, error) { +func (w Wrapper) Ticker(ctx context.Context, exch string, pair currency.Pair, item asset.Item) (*ticker.Price, error) { if exch == exchError.String() { return nil, errTestFailed } @@ -106,7 +107,7 @@ func (w Wrapper) Pairs(exch string, _ bool, _ asset.Item) (*currency.Pairs, erro } // QueryOrder validator for test execution/scripts -func (w Wrapper) QueryOrder(exch, _ string, _ currency.Pair, _ asset.Item) (*order.Detail, error) { +func (w Wrapper) QueryOrder(ctx context.Context, exch, _ string, _ currency.Pair, _ asset.Item) (*order.Detail, error) { if exch == exchError.String() { return nil, errTestFailed } @@ -146,7 +147,7 @@ func (w Wrapper) QueryOrder(exch, _ string, _ currency.Pair, _ asset.Item) (*ord } // SubmitOrder validator for test execution/scripts -func (w Wrapper) SubmitOrder(o *order.Submit) (*order.SubmitResponse, error) { +func (w Wrapper) SubmitOrder(ctx context.Context, o *order.Submit) (*order.SubmitResponse, error) { if o == nil { return nil, errTestFailed } @@ -167,7 +168,7 @@ func (w Wrapper) SubmitOrder(o *order.Submit) (*order.SubmitResponse, error) { } // CancelOrder validator for test execution/scripts -func (w Wrapper) CancelOrder(exch, orderid string, cp currency.Pair, a asset.Item) (bool, error) { +func (w Wrapper) CancelOrder(ctx context.Context, exch, orderid string, cp currency.Pair, a asset.Item) (bool, error) { if exch == exchError.String() { return false, errTestFailed } @@ -184,7 +185,7 @@ func (w Wrapper) CancelOrder(exch, orderid string, cp currency.Pair, a asset.Ite } // AccountInformation validator for test execution/scripts -func (w Wrapper) AccountInformation(exch string, assetType asset.Item) (account.Holdings, error) { +func (w Wrapper) AccountInformation(ctx context.Context, exch string, assetType asset.Item) (account.Holdings, error) { if exch == exchError.String() { return account.Holdings{}, errTestFailed } @@ -224,7 +225,7 @@ func (w Wrapper) DepositAddress(exch string, _ currency.Code) (string, error) { } // WithdrawalCryptoFunds validator for test execution/scripts -func (w Wrapper) WithdrawalCryptoFunds(r *withdraw.Request) (out string, err error) { +func (w Wrapper) WithdrawalCryptoFunds(ctx context.Context, r *withdraw.Request) (out string, err error) { if r.Exchange == exchError.String() { return r.Exchange, errTestFailed } @@ -233,7 +234,7 @@ func (w Wrapper) WithdrawalCryptoFunds(r *withdraw.Request) (out string, err err } // WithdrawalFiatFunds validator for test execution/scripts -func (w Wrapper) WithdrawalFiatFunds(_ string, r *withdraw.Request) (out string, err error) { +func (w Wrapper) WithdrawalFiatFunds(ctx context.Context, _ string, r *withdraw.Request) (out string, err error) { if r.Exchange == exchError.String() { return r.Exchange, errTestFailed } @@ -242,7 +243,7 @@ func (w Wrapper) WithdrawalFiatFunds(_ string, r *withdraw.Request) (out string, } // OHLCV returns open high low close volume candles for requested exchange/pair/asset/start & end time -func (w Wrapper) OHLCV(exch string, p currency.Pair, a asset.Item, start, end time.Time, i kline.Interval) (kline.Item, error) { +func (w Wrapper) OHLCV(ctx context.Context, exch string, p currency.Pair, a asset.Item, start, end time.Time, i kline.Interval) (kline.Item, error) { if exch == exchError.String() { return kline.Item{}, errTestFailed } diff --git a/gctscript/wrappers/validator/validator_test.go b/gctscript/wrappers/validator/validator_test.go index 3bd2436d..1c9d22f8 100644 --- a/gctscript/wrappers/validator/validator_test.go +++ b/gctscript/wrappers/validator/validator_test.go @@ -1,6 +1,7 @@ package validator import ( + "context" "testing" "time" @@ -63,12 +64,14 @@ func TestWrapper_IsEnabled(t *testing.T) { func TestWrapper_AccountInformation(t *testing.T) { t.Parallel() - _, err := testWrapper.AccountInformation(exchName, asset.Spot) + _, err := testWrapper.AccountInformation(context.Background(), + exchName, asset.Spot) if err != nil { t.Fatal(err) } - _, err = testWrapper.AccountInformation(exchError.String(), asset.Spot) + _, err = testWrapper.AccountInformation(context.Background(), + exchError.String(), asset.Spot) if err == nil { t.Fatal("expected AccountInformation to return error on invalid name") } @@ -77,27 +80,32 @@ func TestWrapper_AccountInformation(t *testing.T) { func TestWrapper_CancelOrder(t *testing.T) { t.Parallel() cp := currency.NewPair(currency.BTC, currency.USD) - _, err := testWrapper.CancelOrder(exchName, orderID, cp, assetType) + _, err := testWrapper.CancelOrder(context.Background(), + exchName, orderID, cp, assetType) if err != nil { t.Error(err) } - _, err = testWrapper.CancelOrder(exchError.String(), orderID, cp, assetType) + _, err = testWrapper.CancelOrder(context.Background(), + exchError.String(), orderID, cp, assetType) if err == nil { t.Error("expected CancelOrder to return error on invalid name") } - _, err = testWrapper.CancelOrder(exchName, "", cp, assetType) + _, err = testWrapper.CancelOrder(context.Background(), + exchName, "", cp, assetType) if err == nil { t.Error("expected CancelOrder to return error on invalid name") } - _, err = testWrapper.CancelOrder(exchName, orderID, currency.Pair{}, assetType) + _, err = testWrapper.CancelOrder(context.Background(), + exchName, orderID, currency.Pair{}, assetType) if err != nil { t.Error(err) } - _, err = testWrapper.CancelOrder(exchName, orderID, cp, "") + _, err = testWrapper.CancelOrder(context.Background(), + exchName, orderID, cp, "") if err != nil { t.Error(err) } @@ -121,12 +129,14 @@ func TestWrapper_Orderbook(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = testWrapper.Orderbook(exchName, c, assetType) + _, err = testWrapper.Orderbook(context.Background(), + exchName, c, assetType) if err != nil { t.Fatal(err) } - _, err = testWrapper.Orderbook(exchError.String(), currencyPair, asset.Spot) + _, err = testWrapper.Orderbook(context.Background(), + exchError.String(), currencyPair, asset.Spot) if err == nil { t.Fatal("expected Orderbook to return error with invalid name") } @@ -152,12 +162,14 @@ func TestWrapper_Pairs(t *testing.T) { func TestWrapper_QueryOrder(t *testing.T) { t.Parallel() - _, err := testWrapper.QueryOrder(exchName, orderID, currency.Pair{}, assetType) + _, err := testWrapper.QueryOrder(context.Background(), + exchName, orderID, currency.Pair{}, assetType) if err != nil { t.Fatal(err) } - _, err = testWrapper.QueryOrder(exchError.String(), "", currency.Pair{}, assetType) + _, err = testWrapper.QueryOrder(context.Background(), + exchError.String(), "", currency.Pair{}, assetType) if err == nil { t.Fatal("expected QueryOrder to return error on invalid name") } @@ -181,12 +193,12 @@ func TestWrapper_SubmitOrder(t *testing.T) { Exchange: "true", AssetType: asset.Spot, } - _, err = testWrapper.SubmitOrder(tempOrder) + _, err = testWrapper.SubmitOrder(context.Background(), tempOrder) if err != nil { t.Fatal(err) } - _, err = testWrapper.SubmitOrder(nil) + _, err = testWrapper.SubmitOrder(context.Background(), nil) if err == nil { t.Fatal("expected SubmitOrder to return error with invalid name") } @@ -198,36 +210,40 @@ func TestWrapper_Ticker(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = testWrapper.Ticker(exchName, c, assetType) + _, err = testWrapper.Ticker(context.Background(), exchName, c, assetType) if err != nil { t.Fatal(err) } - _, err = testWrapper.Ticker(exchError.String(), currencyPair, asset.Spot) + _, err = testWrapper.Ticker(context.Background(), exchError.String(), currencyPair, asset.Spot) if err == nil { t.Fatal("expected Ticker to return error with invalid name") } } func TestWrapper_WithdrawalCryptoFunds(t *testing.T) { - _, err := testWrapper.WithdrawalCryptoFunds(&withdraw.Request{Exchange: exchError.String()}) + _, err := testWrapper.WithdrawalCryptoFunds(context.Background(), + &withdraw.Request{Exchange: exchError.String()}) if err == nil { t.Fatal("expected WithdrawalCryptoFunds to return error with invalid name") } - _, err = testWrapper.WithdrawalCryptoFunds(&withdraw.Request{Exchange: exchName}) + _, err = testWrapper.WithdrawalCryptoFunds(context.Background(), + &withdraw.Request{Exchange: exchName}) if err != nil { t.Fatal("expected WithdrawalCryptoFunds to return error with invalid name") } } func TestWrapper_WithdrawalFiatFunds(t *testing.T) { - _, err := testWrapper.WithdrawalFiatFunds("", &withdraw.Request{Exchange: exchError.String()}) + _, err := testWrapper.WithdrawalFiatFunds(context.Background(), + "", &withdraw.Request{Exchange: exchError.String()}) if err == nil { t.Fatal("expected WithdrawalFiatFunds to return error with invalid name") } - _, err = testWrapper.WithdrawalFiatFunds("", &withdraw.Request{Exchange: exchName}) + _, err = testWrapper.WithdrawalFiatFunds(context.Background(), + "", &withdraw.Request{Exchange: exchName}) if err != nil { t.Fatal("expected WithdrawalCryptoFunds to return error with invalid name") } @@ -238,11 +254,15 @@ func TestWrapper_OHLCV(t *testing.T) { if err != nil { t.Fatal(err) } - _, err = testWrapper.OHLCV("test", c, asset.Spot, time.Now().Add(-24*time.Hour), time.Now(), kline.OneDay) + _, err = testWrapper.OHLCV(context.Background(), + "test", c, asset.Spot, time.Now().Add(-24*time.Hour), time.Now(), kline.OneDay) if err != nil { t.Fatal(err) } - _, err = testWrapper.OHLCV(exchError.String(), c, asset.Spot, time.Now().Add(-24*time.Hour), time.Now(), kline.OneDay) + _, err = testWrapper.OHLCV(context.Background(), + exchError.String(), c, asset.Spot, + time.Now().Add(-24*time.Hour), + time.Now(), kline.OneDay) if err == nil { t.Fatal("expected OHLCV to return error with invalid name") } diff --git a/portfolio/portfolio.go b/portfolio/portfolio.go index c7e23602..a5b0bd55 100644 --- a/portfolio/portfolio.go +++ b/portfolio/portfolio.go @@ -1,8 +1,11 @@ package portfolio import ( + "context" + "encoding/json" "errors" "fmt" + "net/http" "strings" "time" @@ -39,7 +42,17 @@ func (b *Base) GetEthereumBalance(address string) (EthplorerResponse, error) { ) result := EthplorerResponse{} - return result, common.SendHTTPGetRequest(urlPath, true, b.Verbose, &result) + contents, err := common.SendHTTPRequest(context.TODO(), + http.MethodGet, + urlPath, + nil, + nil, + b.Verbose) + if err != nil { + return result, err + } + + return result, json.Unmarshal(contents, &result) } // GetCryptoIDAddress queries CryptoID for an address balance for a @@ -50,23 +63,39 @@ func (b *Base) GetCryptoIDAddress(address string, coinType currency.Code) (float return 0, errors.New("invalid address") } - var result interface{} url := fmt.Sprintf("%s/%s/api.dws?q=getbalance&a=%s", cryptoIDAPIURL, coinType.Lower(), address) - err = common.SendHTTPGetRequest(url, true, b.Verbose, &result) + contents, err := common.SendHTTPRequest(context.TODO(), + http.MethodGet, + url, + nil, + nil, + b.Verbose) if err != nil { return 0, err } - return result.(float64), nil + + var result float64 + return result, json.Unmarshal(contents, &result) } // GetRippleBalance returns the value for a ripple address func (b *Base) GetRippleBalance(address string) (float64, error) { var result XRPScanAccount - err := common.SendHTTPGetRequest(xrpScanAPIURL+address, true, b.Verbose, &result) + contents, err := common.SendHTTPRequest(context.TODO(), + http.MethodGet, + xrpScanAPIURL+address, + nil, + nil, + b.Verbose) + if err != nil { + return 0, err + } + + err = json.Unmarshal(contents, &result) if err != nil { return 0, err }