exchanges: Initial context propagation (#744)

* gct: phase one context awareness pass

* exchanges: context propagation pass

* common/requester: force context requirement

* gctcli/exchanges: linter fix

* rpcserver: fix test using dummy rpc server

* backtester: fix comments

* grpc: add correct cancel and timeout for commands

* rpcserver_test: add comment on dummy server

* common: deprecated SendHTTPGetRequest

* linter: fix

* linter: turn on no context check

* apichecker: fix context linter issue

* binance: use param context

* common: remove checks as this gets executed before main

* common: change mutex to RW as clients can be used by multiple go routines.

* common: remove init and JIT default client. Unexport global variables and add protection.

* common: Add comments

* bithumb: after dinner mints fix
This commit is contained in:
Ryan O'Hara-Reid
2021-09-11 13:52:07 +10:00
committed by GitHub
parent 72516f7268
commit d636049fb2
168 changed files with 8085 additions and 6996 deletions

View File

@@ -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)

View File

@@ -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)
}

View File

@@ -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
}