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

@@ -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, &currencies)
return currencies, c.SendHTTPRequest(ctx, exchange.RestSpot, coinbaseproCurrencies, &currencies)
}
// 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
}

View File

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

View File

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