6142 lines
284 KiB
Go
6142 lines
284 KiB
Go
package ccxt
|
||
|
||
// PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
||
// https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
||
|
||
type coinbase struct {
|
||
Exchange
|
||
|
||
}
|
||
|
||
func NewCoinbaseCore() coinbase {
|
||
p := coinbase{}
|
||
setDefaults(&p)
|
||
return p
|
||
}
|
||
|
||
func (this *coinbase) Describe() interface{} {
|
||
return this.DeepExtend(this.Exchange.Describe(), map[string]interface{} {
|
||
"id": "coinbase",
|
||
"name": "Coinbase Advanced",
|
||
"countries": []interface{}{"US"},
|
||
"pro": true,
|
||
"certified": false,
|
||
"rateLimit": 34,
|
||
"version": "v2",
|
||
"userAgent": GetValue(this.UserAgents, "chrome"),
|
||
"headers": map[string]interface{} {
|
||
"CB-VERSION": "2018-05-30",
|
||
},
|
||
"has": map[string]interface{} {
|
||
"CORS": true,
|
||
"spot": true,
|
||
"margin": false,
|
||
"swap": false,
|
||
"future": false,
|
||
"option": false,
|
||
"addMargin": false,
|
||
"cancelOrder": true,
|
||
"cancelOrders": true,
|
||
"closeAllPositions": false,
|
||
"closePosition": true,
|
||
"createConvertTrade": true,
|
||
"createDepositAddress": true,
|
||
"createLimitBuyOrder": true,
|
||
"createLimitSellOrder": true,
|
||
"createMarketBuyOrder": true,
|
||
"createMarketBuyOrderWithCost": true,
|
||
"createMarketOrderWithCost": false,
|
||
"createMarketSellOrder": true,
|
||
"createMarketSellOrderWithCost": false,
|
||
"createOrder": true,
|
||
"createPostOnlyOrder": true,
|
||
"createReduceOnlyOrder": false,
|
||
"createStopLimitOrder": true,
|
||
"createStopMarketOrder": false,
|
||
"createStopOrder": true,
|
||
"deposit": true,
|
||
"editOrder": true,
|
||
"fetchAccounts": true,
|
||
"fetchBalance": true,
|
||
"fetchBidsAsks": true,
|
||
"fetchBorrowRateHistories": false,
|
||
"fetchBorrowRateHistory": false,
|
||
"fetchCanceledOrders": true,
|
||
"fetchClosedOrders": true,
|
||
"fetchConvertQuote": true,
|
||
"fetchConvertTrade": true,
|
||
"fetchConvertTradeHistory": false,
|
||
"fetchCrossBorrowRate": false,
|
||
"fetchCrossBorrowRates": false,
|
||
"fetchCurrencies": true,
|
||
"fetchDeposit": true,
|
||
"fetchDepositAddress": "emulated",
|
||
"fetchDepositAddresses": false,
|
||
"fetchDepositAddressesByNetwork": true,
|
||
"fetchDepositMethodId": true,
|
||
"fetchDepositMethodIds": true,
|
||
"fetchDeposits": true,
|
||
"fetchDepositsWithdrawals": true,
|
||
"fetchFundingHistory": false,
|
||
"fetchFundingRate": false,
|
||
"fetchFundingRateHistory": false,
|
||
"fetchFundingRates": false,
|
||
"fetchIndexOHLCV": false,
|
||
"fetchIsolatedBorrowRate": false,
|
||
"fetchIsolatedBorrowRates": false,
|
||
"fetchL2OrderBook": false,
|
||
"fetchLedger": true,
|
||
"fetchLeverage": false,
|
||
"fetchLeverageTiers": false,
|
||
"fetchMarginMode": false,
|
||
"fetchMarkets": true,
|
||
"fetchMarkOHLCV": false,
|
||
"fetchMyBuys": true,
|
||
"fetchMySells": true,
|
||
"fetchMyTrades": true,
|
||
"fetchOHLCV": true,
|
||
"fetchOpenInterestHistory": false,
|
||
"fetchOpenOrders": true,
|
||
"fetchOrder": true,
|
||
"fetchOrderBook": true,
|
||
"fetchOrders": true,
|
||
"fetchPosition": true,
|
||
"fetchPositionMode": false,
|
||
"fetchPositions": true,
|
||
"fetchPositionsRisk": false,
|
||
"fetchPremiumIndexOHLCV": false,
|
||
"fetchTicker": true,
|
||
"fetchTickers": true,
|
||
"fetchTime": true,
|
||
"fetchTrades": true,
|
||
"fetchTradingFee": "emulated",
|
||
"fetchTradingFees": true,
|
||
"fetchWithdrawals": true,
|
||
"reduceMargin": false,
|
||
"setLeverage": false,
|
||
"setMarginMode": false,
|
||
"setPositionMode": false,
|
||
"withdraw": true,
|
||
},
|
||
"urls": map[string]interface{} {
|
||
"logo": "https://user-images.githubusercontent.com/1294454/40811661-b6eceae2-653a-11e8-829e-10bfadb078cf.jpg",
|
||
"api": map[string]interface{} {
|
||
"rest": "https://api.coinbase.com",
|
||
},
|
||
"www": "https://www.coinbase.com",
|
||
"doc": []interface{}{"https://developers.coinbase.com/api/v2", "https://docs.cloud.coinbase.com/advanced-trade/docs/welcome"},
|
||
"fees": []interface{}{"https://support.coinbase.com/customer/portal/articles/2109597-buy-sell-bank-transfer-fees", "https://www.coinbase.com/advanced-fees"},
|
||
"referral": "https://www.coinbase.com/join/58cbe25a355148797479dbd2",
|
||
},
|
||
"requiredCredentials": map[string]interface{} {
|
||
"apiKey": true,
|
||
"secret": true,
|
||
},
|
||
"api": map[string]interface{} {
|
||
"v2": map[string]interface{} {
|
||
"public": map[string]interface{} {
|
||
"get": map[string]interface{} {
|
||
"currencies": 10.6,
|
||
"currencies/crypto": 10.6,
|
||
"time": 10.6,
|
||
"exchange-rates": 10.6,
|
||
"users/{user_id}": 10.6,
|
||
"prices/{symbol}/buy": 10.6,
|
||
"prices/{symbol}/sell": 10.6,
|
||
"prices/{symbol}/spot": 10.6,
|
||
},
|
||
},
|
||
"private": map[string]interface{} {
|
||
"get": map[string]interface{} {
|
||
"accounts": 10.6,
|
||
"accounts/{account_id}": 10.6,
|
||
"accounts/{account_id}/addresses": 10.6,
|
||
"accounts/{account_id}/addresses/{address_id}": 10.6,
|
||
"accounts/{account_id}/addresses/{address_id}/transactions": 10.6,
|
||
"accounts/{account_id}/transactions": 10.6,
|
||
"accounts/{account_id}/transactions/{transaction_id}": 10.6,
|
||
"accounts/{account_id}/buys": 10.6,
|
||
"accounts/{account_id}/buys/{buy_id}": 10.6,
|
||
"accounts/{account_id}/sells": 10.6,
|
||
"accounts/{account_id}/sells/{sell_id}": 10.6,
|
||
"accounts/{account_id}/deposits": 10.6,
|
||
"accounts/{account_id}/deposits/{deposit_id}": 10.6,
|
||
"accounts/{account_id}/withdrawals": 10.6,
|
||
"accounts/{account_id}/withdrawals/{withdrawal_id}": 10.6,
|
||
"payment-methods": 10.6,
|
||
"payment-methods/{payment_method_id}": 10.6,
|
||
"user": 10.6,
|
||
"user/auth": 10.6,
|
||
},
|
||
"post": map[string]interface{} {
|
||
"accounts": 10.6,
|
||
"accounts/{account_id}/primary": 10.6,
|
||
"accounts/{account_id}/addresses": 10.6,
|
||
"accounts/{account_id}/transactions": 10.6,
|
||
"accounts/{account_id}/transactions/{transaction_id}/complete": 10.6,
|
||
"accounts/{account_id}/transactions/{transaction_id}/resend": 10.6,
|
||
"accounts/{account_id}/buys": 10.6,
|
||
"accounts/{account_id}/buys/{buy_id}/commit": 10.6,
|
||
"accounts/{account_id}/sells": 10.6,
|
||
"accounts/{account_id}/sells/{sell_id}/commit": 10.6,
|
||
"accounts/{account_id}/deposits": 10.6,
|
||
"accounts/{account_id}/deposits/{deposit_id}/commit": 10.6,
|
||
"accounts/{account_id}/withdrawals": 10.6,
|
||
"accounts/{account_id}/withdrawals/{withdrawal_id}/commit": 10.6,
|
||
},
|
||
"put": map[string]interface{} {
|
||
"accounts/{account_id}": 10.6,
|
||
"user": 10.6,
|
||
},
|
||
"delete": map[string]interface{} {
|
||
"accounts/{id}": 10.6,
|
||
"accounts/{account_id}/transactions/{transaction_id}": 10.6,
|
||
},
|
||
},
|
||
},
|
||
"v3": map[string]interface{} {
|
||
"public": map[string]interface{} {
|
||
"get": map[string]interface{} {
|
||
"brokerage/time": 3,
|
||
"brokerage/market/product_book": 3,
|
||
"brokerage/market/products": 3,
|
||
"brokerage/market/products/{product_id}": 3,
|
||
"brokerage/market/products/{product_id}/candles": 3,
|
||
"brokerage/market/products/{product_id}/ticker": 3,
|
||
},
|
||
},
|
||
"private": map[string]interface{} {
|
||
"get": map[string]interface{} {
|
||
"brokerage/accounts": 1,
|
||
"brokerage/accounts/{account_uuid}": 1,
|
||
"brokerage/orders/historical/batch": 1,
|
||
"brokerage/orders/historical/fills": 1,
|
||
"brokerage/orders/historical/{order_id}": 1,
|
||
"brokerage/products": 3,
|
||
"brokerage/products/{product_id}": 3,
|
||
"brokerage/products/{product_id}/candles": 3,
|
||
"brokerage/products/{product_id}/ticker": 3,
|
||
"brokerage/best_bid_ask": 3,
|
||
"brokerage/product_book": 3,
|
||
"brokerage/transaction_summary": 3,
|
||
"brokerage/portfolios": 1,
|
||
"brokerage/portfolios/{portfolio_uuid}": 1,
|
||
"brokerage/convert/trade/{trade_id}": 1,
|
||
"brokerage/cfm/balance_summary": 1,
|
||
"brokerage/cfm/positions": 1,
|
||
"brokerage/cfm/positions/{product_id}": 1,
|
||
"brokerage/cfm/sweeps": 1,
|
||
"brokerage/intx/portfolio/{portfolio_uuid}": 1,
|
||
"brokerage/intx/positions/{portfolio_uuid}": 1,
|
||
"brokerage/intx/positions/{portfolio_uuid}/{symbol}": 1,
|
||
"brokerage/payment_methods": 1,
|
||
"brokerage/payment_methods/{payment_method_id}": 1,
|
||
},
|
||
"post": map[string]interface{} {
|
||
"brokerage/orders": 1,
|
||
"brokerage/orders/batch_cancel": 1,
|
||
"brokerage/orders/edit": 1,
|
||
"brokerage/orders/edit_preview": 1,
|
||
"brokerage/orders/preview": 1,
|
||
"brokerage/portfolios": 1,
|
||
"brokerage/portfolios/move_funds": 1,
|
||
"brokerage/convert/quote": 1,
|
||
"brokerage/convert/trade/{trade_id}": 1,
|
||
"brokerage/cfm/sweeps/schedule": 1,
|
||
"brokerage/intx/allocate": 1,
|
||
"brokerage/orders/close_position": 1,
|
||
},
|
||
"put": map[string]interface{} {
|
||
"brokerage/portfolios/{portfolio_uuid}": 1,
|
||
},
|
||
"delete": map[string]interface{} {
|
||
"brokerage/portfolios/{portfolio_uuid}": 1,
|
||
"brokerage/cfm/sweeps": 1,
|
||
},
|
||
},
|
||
},
|
||
},
|
||
"fees": map[string]interface{} {
|
||
"trading": map[string]interface{} {
|
||
"taker": this.ParseNumber("0.012"),
|
||
"maker": this.ParseNumber("0.006"),
|
||
"tierBased": true,
|
||
"percentage": true,
|
||
"tiers": map[string]interface{} {
|
||
"taker": []interface{}{[]interface{}{this.ParseNumber("0"), this.ParseNumber("0.006")}, []interface{}{this.ParseNumber("10000"), this.ParseNumber("0.004")}, []interface{}{this.ParseNumber("50000"), this.ParseNumber("0.0025")}, []interface{}{this.ParseNumber("100000"), this.ParseNumber("0.002")}, []interface{}{this.ParseNumber("1000000"), this.ParseNumber("0.0018")}, []interface{}{this.ParseNumber("15000000"), this.ParseNumber("0.0016")}, []interface{}{this.ParseNumber("75000000"), this.ParseNumber("0.0012")}, []interface{}{this.ParseNumber("250000000"), this.ParseNumber("0.0008")}, []interface{}{this.ParseNumber("400000000"), this.ParseNumber("0.0005")}},
|
||
"maker": []interface{}{[]interface{}{this.ParseNumber("0"), this.ParseNumber("0.004")}, []interface{}{this.ParseNumber("10000"), this.ParseNumber("0.0025")}, []interface{}{this.ParseNumber("50000"), this.ParseNumber("0.0015")}, []interface{}{this.ParseNumber("100000"), this.ParseNumber("0.001")}, []interface{}{this.ParseNumber("1000000"), this.ParseNumber("0.0008")}, []interface{}{this.ParseNumber("15000000"), this.ParseNumber("0.0006")}, []interface{}{this.ParseNumber("75000000"), this.ParseNumber("0.0003")}, []interface{}{this.ParseNumber("250000000"), this.ParseNumber("0.0")}, []interface{}{this.ParseNumber("400000000"), this.ParseNumber("0.0")}},
|
||
},
|
||
},
|
||
},
|
||
"precisionMode": TICK_SIZE,
|
||
"exceptions": map[string]interface{} {
|
||
"exact": map[string]interface{} {
|
||
"two_factor_required": AuthenticationError,
|
||
"param_required": ExchangeError,
|
||
"validation_error": ExchangeError,
|
||
"invalid_request": ExchangeError,
|
||
"personal_details_required": AuthenticationError,
|
||
"identity_verification_required": AuthenticationError,
|
||
"jumio_verification_required": AuthenticationError,
|
||
"jumio_face_match_verification_required": AuthenticationError,
|
||
"unverified_email": AuthenticationError,
|
||
"authentication_error": AuthenticationError,
|
||
"invalid_authentication_method": AuthenticationError,
|
||
"invalid_token": AuthenticationError,
|
||
"revoked_token": AuthenticationError,
|
||
"expired_token": AuthenticationError,
|
||
"invalid_scope": AuthenticationError,
|
||
"not_found": ExchangeError,
|
||
"rate_limit_exceeded": RateLimitExceeded,
|
||
"internal_server_error": ExchangeError,
|
||
"UNSUPPORTED_ORDER_CONFIGURATION": BadRequest,
|
||
"INSUFFICIENT_FUND": BadRequest,
|
||
"PERMISSION_DENIED": PermissionDenied,
|
||
"INVALID_ARGUMENT": BadRequest,
|
||
},
|
||
"broad": map[string]interface{} {
|
||
"request timestamp expired": InvalidNonce,
|
||
"order with this orderID was not found": OrderNotFound,
|
||
},
|
||
},
|
||
"timeframes": map[string]interface{} {
|
||
"1m": "ONE_MINUTE",
|
||
"5m": "FIVE_MINUTE",
|
||
"15m": "FIFTEEN_MINUTE",
|
||
"30m": "THIRTY_MINUTE",
|
||
"1h": "ONE_HOUR",
|
||
"2h": "TWO_HOUR",
|
||
"6h": "SIX_HOUR",
|
||
"1d": "ONE_DAY",
|
||
},
|
||
"commonCurrencies": map[string]interface{} {
|
||
"CGLD": "CELO",
|
||
},
|
||
"options": map[string]interface{} {
|
||
"usePrivate": false,
|
||
"brokerId": "ccxt",
|
||
"stablePairs": []interface{}{"BUSD-USD", "CBETH-ETH", "DAI-USD", "GUSD-USD", "GYEN-USD", "PAX-USD", "PAX-USDT", "USDC-EUR", "USDC-GBP", "USDT-EUR", "USDT-GBP", "USDT-USD", "USDT-USDC", "WBTC-BTC"},
|
||
"fetchCurrencies": map[string]interface{} {
|
||
"expires": 5000,
|
||
},
|
||
"accounts": []interface{}{"wallet", "fiat"},
|
||
"v3Accounts": []interface{}{"ACCOUNT_TYPE_CRYPTO", "ACCOUNT_TYPE_FIAT"},
|
||
"networks": map[string]interface{} {
|
||
"ERC20": "ethereum",
|
||
"XLM": "stellar",
|
||
},
|
||
"createMarketBuyOrderRequiresPrice": true,
|
||
"advanced": true,
|
||
"fetchMarkets": "fetchMarketsV3",
|
||
"timeDifference": 0,
|
||
"adjustForTimeDifference": false,
|
||
"fetchTicker": "fetchTickerV3",
|
||
"fetchTickers": "fetchTickersV3",
|
||
"fetchAccounts": "fetchAccountsV3",
|
||
"fetchBalance": "v2PrivateGetAccounts",
|
||
"fetchTime": "v2PublicGetTime",
|
||
"user_native_currency": "USD",
|
||
},
|
||
"features": map[string]interface{} {
|
||
"default": map[string]interface{} {
|
||
"sandbox": false,
|
||
"createOrder": map[string]interface{} {
|
||
"marginMode": true,
|
||
"triggerPrice": true,
|
||
"triggerPriceType": nil,
|
||
"triggerDirection": true,
|
||
"stopLossPrice": true,
|
||
"takeProfitPrice": true,
|
||
"attachedStopLossTakeProfit": nil,
|
||
"timeInForce": map[string]interface{} {
|
||
"IOC": true,
|
||
"FOK": true,
|
||
"PO": true,
|
||
"GTD": true,
|
||
},
|
||
"hedged": false,
|
||
"trailing": false,
|
||
"leverage": true,
|
||
"marketBuyByCost": true,
|
||
"marketBuyRequiresPrice": true,
|
||
"selfTradePrevention": false,
|
||
"iceberg": false,
|
||
},
|
||
"createOrders": nil,
|
||
"fetchMyTrades": map[string]interface{} {
|
||
"marginMode": false,
|
||
"limit": 3000,
|
||
"daysBack": nil,
|
||
"untilDays": 10000,
|
||
"symbolRequired": false,
|
||
},
|
||
"fetchOrder": map[string]interface{} {
|
||
"marginMode": false,
|
||
"trigger": false,
|
||
"trailing": false,
|
||
"symbolRequired": false,
|
||
},
|
||
"fetchOpenOrders": map[string]interface{} {
|
||
"marginMode": false,
|
||
"limit": nil,
|
||
"trigger": false,
|
||
"trailing": false,
|
||
"symbolRequired": false,
|
||
},
|
||
"fetchOrders": map[string]interface{} {
|
||
"marginMode": false,
|
||
"limit": nil,
|
||
"daysBack": nil,
|
||
"untilDays": 10000,
|
||
"trigger": false,
|
||
"trailing": false,
|
||
"symbolRequired": false,
|
||
},
|
||
"fetchClosedOrders": map[string]interface{} {
|
||
"marginMode": false,
|
||
"limit": nil,
|
||
"daysBack": nil,
|
||
"daysBackCanceled": nil,
|
||
"untilDays": 10000,
|
||
"trigger": false,
|
||
"trailing": false,
|
||
"symbolRequired": false,
|
||
},
|
||
"fetchOHLCV": map[string]interface{} {
|
||
"limit": 300,
|
||
},
|
||
},
|
||
"spot": map[string]interface{} {
|
||
"extends": "default",
|
||
},
|
||
"swap": map[string]interface{} {
|
||
"linear": map[string]interface{} {
|
||
"extends": "default",
|
||
},
|
||
"inverse": nil,
|
||
},
|
||
"future": map[string]interface{} {
|
||
"linear": map[string]interface{} {
|
||
"extends": "default",
|
||
},
|
||
"inverse": nil,
|
||
},
|
||
},
|
||
})
|
||
}
|
||
/**
|
||
* @method
|
||
* @name coinbase#fetchTime
|
||
* @description fetches the current integer timestamp in milliseconds from the exchange server
|
||
* @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-time#http-request
|
||
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
* @param {string} [params.method] 'v2PublicGetTime' or 'v3PublicGetBrokerageTime' default is 'v2PublicGetTime'
|
||
* @returns {int} the current integer timestamp in milliseconds from the exchange server
|
||
*/
|
||
func (this *coinbase) FetchTime(optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
||
_ = params
|
||
var defaultMethod interface{} = this.SafeString(this.Options, "fetchTime", "v2PublicGetTime")
|
||
var method interface{} = this.SafeString(params, "method", defaultMethod)
|
||
params = this.Omit(params, "method")
|
||
var response interface{} = nil
|
||
if IsTrue(IsEqual(method, "v2PublicGetTime")) {
|
||
|
||
response = (<-this.V2PublicGetTime(params))
|
||
PanicOnError(response)
|
||
//
|
||
// {
|
||
// "data": {
|
||
// "epoch": 1589295679,
|
||
// "iso": "2020-05-12T15:01:19Z"
|
||
// }
|
||
// }
|
||
//
|
||
response = this.SafeDict(response, "data", map[string]interface{} {})
|
||
} else {
|
||
|
||
response = (<-this.V3PublicGetBrokerageTime(params))
|
||
PanicOnError(response)
|
||
}
|
||
|
||
ch <- this.SafeTimestamp2(response, "epoch", "epochSeconds")
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
/**
|
||
* @method
|
||
* @name coinbase#fetchAccounts
|
||
* @description fetch all the accounts associated with a profile
|
||
* @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getaccounts
|
||
* @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-accounts#list-accounts
|
||
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
* @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
|
||
* @returns {object} a dictionary of [account structures]{@link https://docs.ccxt.com/#/?id=account-structure} indexed by the account type
|
||
*/
|
||
func (this *coinbase) FetchAccounts(optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
||
_ = params
|
||
var method interface{} = this.SafeString(this.Options, "fetchAccounts", "fetchAccountsV3")
|
||
if IsTrue(IsEqual(method, "fetchAccountsV3")) {
|
||
|
||
retRes51919 := (<-this.FetchAccountsV3(params))
|
||
PanicOnError(retRes51919)
|
||
ch <- retRes51919
|
||
return nil
|
||
}
|
||
|
||
retRes52115 := (<-this.FetchAccountsV2(params))
|
||
PanicOnError(retRes52115)
|
||
ch <- retRes52115
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
func (this *coinbase) FetchAccountsV2(optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
||
_ = params
|
||
|
||
retRes5258 := (<-this.LoadMarkets())
|
||
PanicOnError(retRes5258)
|
||
var paginate interface{} = false
|
||
paginateparamsVariable := this.HandleOptionAndParams(params, "fetchAccounts", "paginate");
|
||
paginate = GetValue(paginateparamsVariable,0);
|
||
params = GetValue(paginateparamsVariable,1)
|
||
if IsTrue(paginate) {
|
||
|
||
retRes52919 := (<-this.FetchPaginatedCallCursor("fetchAccounts", nil, nil, nil, params, "next_starting_after", "starting_after", nil, 100))
|
||
PanicOnError(retRes52919)
|
||
ch <- retRes52919
|
||
return nil
|
||
}
|
||
var request interface{} = map[string]interface{} {
|
||
"limit": 100,
|
||
}
|
||
|
||
response:= (<-this.V2PrivateGetAccounts(this.Extend(request, params)))
|
||
PanicOnError(response)
|
||
//
|
||
// {
|
||
// "pagination": {
|
||
// "ending_before": null,
|
||
// "starting_after": null,
|
||
// "previous_ending_before": null,
|
||
// "next_starting_after": null,
|
||
// "limit": 244,
|
||
// "order": "desc",
|
||
// "previous_uri": null,
|
||
// "next_uri": null
|
||
// },
|
||
// "data": [
|
||
// {
|
||
// "id": "XLM",
|
||
// "name": "XLM Wallet",
|
||
// "primary": false,
|
||
// "type": "wallet",
|
||
// "currency": {
|
||
// "code": "XLM",
|
||
// "name": "Stellar Lumens",
|
||
// "color": "#000000",
|
||
// "sort_index": 127,
|
||
// "exponent": 7,
|
||
// "type": "crypto",
|
||
// "address_regex": "^G[A-Z2-7]{55}$",
|
||
// "asset_id": "13b83335-5ede-595b-821e-5bcdfa80560f",
|
||
// "destination_tag_name": "XLM Memo ID",
|
||
// "destination_tag_regex": "^[ -~]{1,28}$"
|
||
// },
|
||
// "balance": {
|
||
// "amount": "0.0000000",
|
||
// "currency": "XLM"
|
||
// },
|
||
// "created_at": null,
|
||
// "updated_at": null,
|
||
// "resource": "account",
|
||
// "resource_path": "/v2/accounts/XLM",
|
||
// "allow_deposits": true,
|
||
// "allow_withdrawals": true
|
||
// },
|
||
// ]
|
||
// }
|
||
//
|
||
var data interface{} = this.SafeList(response, "data", []interface{}{})
|
||
var pagination interface{} = this.SafeDict(response, "pagination", map[string]interface{} {})
|
||
var cursor interface{} = this.SafeString(pagination, "next_starting_after")
|
||
var accounts interface{} = this.SafeList(response, "data", []interface{}{})
|
||
var length interface{} = GetArrayLength(accounts)
|
||
var lastIndex interface{} = Subtract(length, 1)
|
||
var last interface{} = this.SafeDict(accounts, lastIndex)
|
||
if IsTrue(IsTrue((!IsEqual(cursor, nil))) && IsTrue((!IsEqual(cursor, "")))) {
|
||
AddElementToObject(last, "next_starting_after", cursor)
|
||
AddElementToObject(accounts, lastIndex, last)
|
||
}
|
||
|
||
ch <- this.ParseAccounts(data, params)
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
func (this *coinbase) FetchAccountsV3(optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
||
_ = params
|
||
|
||
retRes5948 := (<-this.LoadMarkets())
|
||
PanicOnError(retRes5948)
|
||
var paginate interface{} = false
|
||
paginateparamsVariable := this.HandleOptionAndParams(params, "fetchAccounts", "paginate");
|
||
paginate = GetValue(paginateparamsVariable,0);
|
||
params = GetValue(paginateparamsVariable,1)
|
||
if IsTrue(paginate) {
|
||
|
||
retRes59819 := (<-this.FetchPaginatedCallCursor("fetchAccounts", nil, nil, nil, params, "cursor", "cursor", nil, 250))
|
||
PanicOnError(retRes59819)
|
||
ch <- retRes59819
|
||
return nil
|
||
}
|
||
var request interface{} = map[string]interface{} {
|
||
"limit": 250,
|
||
}
|
||
|
||
response:= (<-this.V3PrivateGetBrokerageAccounts(this.Extend(request, params)))
|
||
PanicOnError(response)
|
||
//
|
||
// {
|
||
// "accounts": [
|
||
// {
|
||
// "uuid": "11111111-1111-1111-1111-111111111111",
|
||
// "name": "USDC Wallet",
|
||
// "currency": "USDC",
|
||
// "available_balance": {
|
||
// "value": "0.0000000000000000",
|
||
// "currency": "USDC"
|
||
// },
|
||
// "default": true,
|
||
// "active": true,
|
||
// "created_at": "2023-01-04T06:20:06.456Z",
|
||
// "updated_at": "2023-01-04T06:20:07.181Z",
|
||
// "deleted_at": null,
|
||
// "type": "ACCOUNT_TYPE_CRYPTO",
|
||
// "ready": false,
|
||
// "hold": {
|
||
// "value": "0.0000000000000000",
|
||
// "currency": "USDC"
|
||
// }
|
||
// },
|
||
// ...
|
||
// ],
|
||
// "has_next": false,
|
||
// "cursor": "",
|
||
// "size": 9
|
||
// }
|
||
//
|
||
var accounts interface{} = this.SafeList(response, "accounts", []interface{}{})
|
||
var length interface{} = GetArrayLength(accounts)
|
||
var lastIndex interface{} = Subtract(length, 1)
|
||
var last interface{} = this.SafeDict(accounts, lastIndex)
|
||
var cursor interface{} = this.SafeString(response, "cursor")
|
||
if IsTrue(IsTrue((!IsEqual(cursor, nil))) && IsTrue((!IsEqual(cursor, "")))) {
|
||
AddElementToObject(last, "cursor", cursor)
|
||
AddElementToObject(accounts, lastIndex, last)
|
||
}
|
||
|
||
ch <- this.ParseAccounts(accounts, params)
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
/**
|
||
* @method
|
||
* @name coinbase#fetchPortfolios
|
||
* @description fetch all the portfolios
|
||
* @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getportfolios
|
||
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
* @returns {object} a dictionary of [account structures]{@link https://docs.ccxt.com/#/?id=account-structure} indexed by the account type
|
||
*/
|
||
func (this *coinbase) FetchPortfolios(optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
||
_ = params
|
||
|
||
response:= (<-this.V3PrivateGetBrokeragePortfolios(params))
|
||
PanicOnError(response)
|
||
var portfolios interface{} = this.SafeList(response, "portfolios", []interface{}{})
|
||
var result interface{} = []interface{}{}
|
||
for i := 0; IsLessThan(i, GetArrayLength(portfolios)); i++ {
|
||
var portfolio interface{} = GetValue(portfolios, i)
|
||
AppendToArray(&result,map[string]interface{} {
|
||
"id": this.SafeString(portfolio, "uuid"),
|
||
"type": this.SafeString(portfolio, "type"),
|
||
"code": nil,
|
||
"info": portfolio,
|
||
})
|
||
}
|
||
|
||
ch <- result
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
func (this *coinbase) ParseAccount(account interface{}) interface{} {
|
||
//
|
||
// fetchAccountsV2
|
||
//
|
||
// {
|
||
// "id": "XLM",
|
||
// "name": "XLM Wallet",
|
||
// "primary": false,
|
||
// "type": "wallet",
|
||
// "currency": {
|
||
// "code": "XLM",
|
||
// "name": "Stellar Lumens",
|
||
// "color": "#000000",
|
||
// "sort_index": 127,
|
||
// "exponent": 7,
|
||
// "type": "crypto",
|
||
// "address_regex": "^G[A-Z2-7]{55}$",
|
||
// "asset_id": "13b83335-5ede-595b-821e-5bcdfa80560f",
|
||
// "destination_tag_name": "XLM Memo ID",
|
||
// "destination_tag_regex": "^[ -~]{1,28}$"
|
||
// },
|
||
// "balance": {
|
||
// "amount": "0.0000000",
|
||
// "currency": "XLM"
|
||
// },
|
||
// "created_at": null,
|
||
// "updated_at": null,
|
||
// "resource": "account",
|
||
// "resource_path": "/v2/accounts/XLM",
|
||
// "allow_deposits": true,
|
||
// "allow_withdrawals": true
|
||
// }
|
||
//
|
||
// fetchAccountsV3
|
||
//
|
||
// {
|
||
// "uuid": "11111111-1111-1111-1111-111111111111",
|
||
// "name": "USDC Wallet",
|
||
// "currency": "USDC",
|
||
// "available_balance": {
|
||
// "value": "0.0000000000000000",
|
||
// "currency": "USDC"
|
||
// },
|
||
// "default": true,
|
||
// "active": true,
|
||
// "created_at": "2023-01-04T06:20:06.456Z",
|
||
// "updated_at": "2023-01-04T06:20:07.181Z",
|
||
// "deleted_at": null,
|
||
// "type": "ACCOUNT_TYPE_CRYPTO",
|
||
// "ready": false,
|
||
// "hold": {
|
||
// "value": "0.0000000000000000",
|
||
// "currency": "USDC"
|
||
// }
|
||
// }
|
||
//
|
||
var active interface{} = this.SafeBool(account, "active")
|
||
var currencyIdV3 interface{} = this.SafeString(account, "currency")
|
||
var currency interface{} = this.SafeDict(account, "currency", map[string]interface{} {})
|
||
var currencyId interface{} = this.SafeString(currency, "code", currencyIdV3)
|
||
var typeV3 interface{} = this.SafeString(account, "name")
|
||
var typeV2 interface{} = this.SafeString(account, "type")
|
||
var parts interface{} = Split(typeV3, " ")
|
||
return map[string]interface{} {
|
||
"id": this.SafeString2(account, "id", "uuid"),
|
||
"type": Ternary(IsTrue((!IsEqual(active, nil))), this.SafeStringLower(parts, 1), typeV2),
|
||
"code": this.SafeCurrencyCode(currencyId),
|
||
"info": account,
|
||
}
|
||
}
|
||
/**
|
||
* @method
|
||
* @name coinbase#createDepositAddress
|
||
* @description create a currency deposit address
|
||
* @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-addresses#create-address
|
||
* @param {string} code unified currency code of the currency for the deposit address
|
||
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
* @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure}
|
||
*/
|
||
func (this *coinbase) CreateDepositAddress(code interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
||
_ = params
|
||
var accountId interface{} = this.SafeString(params, "account_id")
|
||
params = this.Omit(params, "account_id")
|
||
if IsTrue(IsEqual(accountId, nil)) {
|
||
|
||
retRes75412 := (<-this.LoadAccounts())
|
||
PanicOnError(retRes75412)
|
||
for i := 0; IsLessThan(i, GetArrayLength(this.Accounts)); i++ {
|
||
var account interface{} = GetValue(this.Accounts, i)
|
||
if IsTrue(IsTrue(IsEqual(GetValue(account, "code"), code)) && IsTrue(IsEqual(GetValue(account, "type"), "wallet"))) {
|
||
accountId = GetValue(account, "id")
|
||
break
|
||
}
|
||
}
|
||
}
|
||
if IsTrue(IsEqual(accountId, nil)) {
|
||
panic(ExchangeError(Add(Add(Add(this.Id, " createDepositAddress() could not find the account with matching currency code "), code), ", specify an `account_id` extra param to target specific wallet")))
|
||
}
|
||
var request interface{} = map[string]interface{} {
|
||
"account_id": accountId,
|
||
}
|
||
|
||
response:= (<-this.V2PrivatePostAccountsAccountIdAddresses(this.Extend(request, params)))
|
||
PanicOnError(response)
|
||
//
|
||
// {
|
||
// "data": {
|
||
// "id": "05b1ebbf-9438-5dd4-b297-2ddedc98d0e4",
|
||
// "address": "coinbasebase",
|
||
// "address_info": {
|
||
// "address": "coinbasebase",
|
||
// "destination_tag": "287594668"
|
||
// },
|
||
// "name": null,
|
||
// "created_at": "2019-07-01T14:39:29Z",
|
||
// "updated_at": "2019-07-01T14:39:29Z",
|
||
// "network": "eosio",
|
||
// "uri_scheme": "eosio",
|
||
// "resource": "address",
|
||
// "resource_path": "/v2/accounts/14cfc769-e852-52f3-b831-711c104d194c/addresses/05b1ebbf-9438-5dd4-b297-2ddedc98d0e4",
|
||
// "warnings": [
|
||
// {
|
||
// "title": "Only send EOS (EOS) to this address",
|
||
// "details": "Sending any other cryptocurrency will result in permanent loss.",
|
||
// "image_url": "https://dynamic-assets.coinbase.com/deaca3d47b10ed4a91a872e9618706eec34081127762d88f2476ac8e99ada4b48525a9565cf2206d18c04053f278f693434af4d4629ca084a9d01b7a286a7e26/asset_icons/1f8489bb280fb0a0fd643c1161312ba49655040e9aaaced5f9ad3eeaf868eadc.png"
|
||
// },
|
||
// {
|
||
// "title": "Both an address and EOS memo are required to receive EOS",
|
||
// "details": "If you send funds without an EOS memo or with an incorrect EOS memo, your funds cannot be credited to your account.",
|
||
// "image_url": "https://www.coinbase.com/assets/receive-warning-2f3269d83547a7748fb39d6e0c1c393aee26669bfea6b9f12718094a1abff155.png"
|
||
// }
|
||
// ],
|
||
// "warning_title": "Only send EOS (EOS) to this address",
|
||
// "warning_details": "Sending any other cryptocurrency will result in permanent loss.",
|
||
// "destination_tag": "287594668",
|
||
// "deposit_uri": "eosio:coinbasebase?dt=287594668",
|
||
// "callback_url": null
|
||
// }
|
||
// }
|
||
//
|
||
var data interface{} = this.SafeDict(response, "data", map[string]interface{} {})
|
||
var tag interface{} = this.SafeString(data, "destination_tag")
|
||
var address interface{} = this.SafeString(data, "address")
|
||
|
||
ch <- map[string]interface{} {
|
||
"currency": code,
|
||
"tag": tag,
|
||
"address": address,
|
||
"info": response,
|
||
}
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
/**
|
||
* @method
|
||
* @name coinbase#fetchMySells
|
||
* @ignore
|
||
* @description fetch sells
|
||
* @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-sells#list-sells
|
||
* @param {string} symbol not used by coinbase fetchMySells ()
|
||
* @param {int} [since] timestamp in ms of the earliest sell, default is undefined
|
||
* @param {int} [limit] max number of sells to return, default is undefined
|
||
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
* @returns {object} a [list of order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
||
*/
|
||
func (this *coinbase) FetchMySells(optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
// v2 did't have an endpoint for all historical trades
|
||
symbol := GetArg(optionalArgs, 0, nil)
|
||
_ = symbol
|
||
since := GetArg(optionalArgs, 1, nil)
|
||
_ = since
|
||
limit := GetArg(optionalArgs, 2, nil)
|
||
_ = limit
|
||
params := GetArg(optionalArgs, 3, map[string]interface{} {})
|
||
_ = params
|
||
var request interface{} = this.PrepareAccountRequest(limit, params)
|
||
|
||
retRes8328 := (<-this.LoadMarkets())
|
||
PanicOnError(retRes8328)
|
||
var query interface{} = this.Omit(params, []interface{}{"account_id", "accountId"})
|
||
|
||
sells:= (<-this.V2PrivateGetAccountsAccountIdSells(this.Extend(request, query)))
|
||
PanicOnError(sells)
|
||
|
||
ch <- this.ParseTrades(GetValue(sells, "data"), nil, since, limit)
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
/**
|
||
* @method
|
||
* @name coinbase#fetchMyBuys
|
||
* @ignore
|
||
* @description fetch buys
|
||
* @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-buys#list-buys
|
||
* @param {string} symbol not used by coinbase fetchMyBuys ()
|
||
* @param {int} [since] timestamp in ms of the earliest buy, default is undefined
|
||
* @param {int} [limit] max number of buys to return, default is undefined
|
||
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
* @returns {object} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
||
*/
|
||
func (this *coinbase) FetchMyBuys(optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
// v2 did't have an endpoint for all historical trades
|
||
symbol := GetArg(optionalArgs, 0, nil)
|
||
_ = symbol
|
||
since := GetArg(optionalArgs, 1, nil)
|
||
_ = since
|
||
limit := GetArg(optionalArgs, 2, nil)
|
||
_ = limit
|
||
params := GetArg(optionalArgs, 3, map[string]interface{} {})
|
||
_ = params
|
||
var request interface{} = this.PrepareAccountRequest(limit, params)
|
||
|
||
retRes8538 := (<-this.LoadMarkets())
|
||
PanicOnError(retRes8538)
|
||
var query interface{} = this.Omit(params, []interface{}{"account_id", "accountId"})
|
||
|
||
buys:= (<-this.V2PrivateGetAccountsAccountIdBuys(this.Extend(request, query)))
|
||
PanicOnError(buys)
|
||
|
||
ch <- this.ParseTrades(GetValue(buys, "data"), nil, since, limit)
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
func (this *coinbase) FetchTransactionsWithMethod(method interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
code := GetArg(optionalArgs, 0, nil)
|
||
_ = code
|
||
since := GetArg(optionalArgs, 1, nil)
|
||
_ = since
|
||
limit := GetArg(optionalArgs, 2, nil)
|
||
_ = limit
|
||
params := GetArg(optionalArgs, 3, map[string]interface{} {})
|
||
_ = params
|
||
var request interface{} = nil
|
||
requestparamsVariable := (<-this.PrepareAccountRequestWithCurrencyCode(code, limit, params));
|
||
request = GetValue(requestparamsVariable,0);
|
||
params = GetValue(requestparamsVariable,1)
|
||
|
||
retRes8628 := (<-this.LoadMarkets())
|
||
PanicOnError(retRes8628)
|
||
|
||
response:= (<-this.callDynamically(method, this.Extend(request, params)))
|
||
PanicOnError(response)
|
||
|
||
ch <- this.ParseTransactions(GetValue(response, "data"), nil, since, limit)
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
/**
|
||
* @method
|
||
* @name coinbase#fetchWithdrawals
|
||
* @description Fetch all withdrawals made from an account. Won't return crypto withdrawals. Use fetchLedger for those.
|
||
* @see https://docs.cdp.coinbase.com/coinbase-app/docs/api-withdrawals#list-withdrawals
|
||
* @param {string} code unified currency code
|
||
* @param {int} [since] the earliest time in ms to fetch withdrawals for
|
||
* @param {int} [limit] the maximum number of withdrawals structures to retrieve
|
||
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
* @param {string} [params.currencyType] "fiat" or "crypto"
|
||
* @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
||
*/
|
||
func (this *coinbase) FetchWithdrawals(optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
code := GetArg(optionalArgs, 0, nil)
|
||
_ = code
|
||
since := GetArg(optionalArgs, 1, nil)
|
||
_ = since
|
||
limit := GetArg(optionalArgs, 2, nil)
|
||
_ = limit
|
||
params := GetArg(optionalArgs, 3, map[string]interface{} {})
|
||
_ = params
|
||
var currencyType interface{} = nil
|
||
currencyTypeparamsVariable := this.HandleOptionAndParams(params, "fetchWithdrawals", "currencyType");
|
||
currencyType = GetValue(currencyTypeparamsVariable,0);
|
||
params = GetValue(currencyTypeparamsVariable,1)
|
||
if IsTrue(IsEqual(currencyType, "crypto")) {
|
||
|
||
results:= (<-this.FetchTransactionsWithMethod("v2PrivateGetAccountsAccountIdTransactions", code, since, limit, params))
|
||
PanicOnError(results)
|
||
|
||
ch <- this.FilterByArray(results, "type", "withdrawal", false)
|
||
return nil
|
||
}
|
||
|
||
retRes88615 := (<-this.FetchTransactionsWithMethod("v2PrivateGetAccountsAccountIdWithdrawals", code, since, limit, params))
|
||
PanicOnError(retRes88615)
|
||
ch <- retRes88615
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
/**
|
||
* @method
|
||
* @name coinbase#fetchDeposits
|
||
* @description Fetch all fiat deposits made to an account. Won't return crypto deposits or staking rewards. Use fetchLedger for those.
|
||
* @see https://docs.cdp.coinbase.com/coinbase-app/docs/api-deposits#list-deposits
|
||
* @param {string} code unified currency code
|
||
* @param {int} [since] the earliest time in ms to fetch deposits for
|
||
* @param {int} [limit] the maximum number of deposits structures to retrieve
|
||
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
* @param {string} [params.currencyType] "fiat" or "crypto"
|
||
* @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
||
*/
|
||
func (this *coinbase) FetchDeposits(optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
code := GetArg(optionalArgs, 0, nil)
|
||
_ = code
|
||
since := GetArg(optionalArgs, 1, nil)
|
||
_ = since
|
||
limit := GetArg(optionalArgs, 2, nil)
|
||
_ = limit
|
||
params := GetArg(optionalArgs, 3, map[string]interface{} {})
|
||
_ = params
|
||
var currencyType interface{} = nil
|
||
currencyTypeparamsVariable := this.HandleOptionAndParams(params, "fetchWithdrawals", "currencyType");
|
||
currencyType = GetValue(currencyTypeparamsVariable,0);
|
||
params = GetValue(currencyTypeparamsVariable,1)
|
||
if IsTrue(IsEqual(currencyType, "crypto")) {
|
||
|
||
results:= (<-this.FetchTransactionsWithMethod("v2PrivateGetAccountsAccountIdTransactions", code, since, limit, params))
|
||
PanicOnError(results)
|
||
|
||
ch <- this.FilterByArray(results, "type", "deposit", false)
|
||
return nil
|
||
}
|
||
|
||
retRes90815 := (<-this.FetchTransactionsWithMethod("v2PrivateGetAccountsAccountIdDeposits", code, since, limit, params))
|
||
PanicOnError(retRes90815)
|
||
ch <- retRes90815
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
/**
|
||
* @method
|
||
* @name coinbase#fetchDepositsWithdrawals
|
||
* @description fetch history of deposits and withdrawals
|
||
* @see https://docs.cdp.coinbase.com/coinbase-app/docs/api-transactions
|
||
* @param {string} [code] unified currency code for the currency of the deposit/withdrawals, default is undefined
|
||
* @param {int} [since] timestamp in ms of the earliest deposit/withdrawal, default is undefined
|
||
* @param {int} [limit] max number of deposit/withdrawals to return, default = 50, Min: 1, Max: 100
|
||
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
* @returns {object} a list of [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
||
*/
|
||
func (this *coinbase) FetchDepositsWithdrawals(optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
code := GetArg(optionalArgs, 0, nil)
|
||
_ = code
|
||
since := GetArg(optionalArgs, 1, nil)
|
||
_ = since
|
||
limit := GetArg(optionalArgs, 2, nil)
|
||
_ = limit
|
||
params := GetArg(optionalArgs, 3, map[string]interface{} {})
|
||
_ = params
|
||
|
||
retRes9238 := (<-this.LoadMarkets())
|
||
PanicOnError(retRes9238)
|
||
|
||
results:= (<-this.FetchTransactionsWithMethod("v2PrivateGetAccountsAccountIdTransactions", code, since, limit, params))
|
||
PanicOnError(results)
|
||
|
||
ch <- this.FilterByArray(results, "type", []interface{}{"deposit", "withdrawal"}, false)
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
func (this *coinbase) ParseTransactionStatus(status interface{}) interface{} {
|
||
var statuses interface{} = map[string]interface{} {
|
||
"created": "pending",
|
||
"completed": "ok",
|
||
"canceled": "canceled",
|
||
}
|
||
return this.SafeString(statuses, status, status)
|
||
}
|
||
func (this *coinbase) ParseTransaction(transaction interface{}, optionalArgs ...interface{}) interface{} {
|
||
//
|
||
// fiat deposit
|
||
//
|
||
// {
|
||
// "id": "f34c19f3-b730-5e3d-9f72",
|
||
// "status": "completed",
|
||
// "payment_method": {
|
||
// "id": "a022b31d-f9c7-5043-98f2",
|
||
// "resource": "payment_method",
|
||
// "resource_path": "/v2/payment-methods/a022b31d-f9c7-5043-98f2"
|
||
// },
|
||
// "transaction": {
|
||
// "id": "04ed4113-3732-5b0c-af86-b1d2146977d0",
|
||
// "resource": "transaction",
|
||
// "resource_path": "/v2/accounts/91cd2d36-3a91-55b6-a5d4-0124cf105483/transactions/04ed4113-3732-5b0c-af86"
|
||
// },
|
||
// "user_reference": "2VTYTH",
|
||
// "created_at": "2017-02-09T07:01:18Z",
|
||
// "updated_at": "2017-02-09T07:01:26Z",
|
||
// "resource": "deposit",
|
||
// "resource_path": "/v2/accounts/91cd2d36-3a91-55b6-a5d4-0124cf105483/deposits/f34c19f3-b730-5e3d-9f72",
|
||
// "committed": true,
|
||
// "payout_at": "2017-02-12T07:01:17Z",
|
||
// "instant": false,
|
||
// "fee": { "amount": "0.00", "currency": "EUR" },
|
||
// "amount": { "amount": "114.02", "currency": "EUR" },
|
||
// "subtotal": { "amount": "114.02", "currency": "EUR" },
|
||
// "hold_until": null,
|
||
// "hold_days": 0,
|
||
// "hold_business_days": 0,
|
||
// "next_step": null
|
||
// }
|
||
//
|
||
// fiat_withdrawal
|
||
//
|
||
// {
|
||
// "id": "cfcc3b4a-eeb6-5e8c-8058",
|
||
// "status": "completed",
|
||
// "payment_method": {
|
||
// "id": "8b94cfa4-f7fd-5a12-a76a",
|
||
// "resource": "payment_method",
|
||
// "resource_path": "/v2/payment-methods/8b94cfa4-f7fd-5a12-a76a"
|
||
// },
|
||
// "transaction": {
|
||
// "id": "fcc2550b-5104-5f83-a444",
|
||
// "resource": "transaction",
|
||
// "resource_path": "/v2/accounts/91cd2d36-3a91-55b6-a5d4-0124cf105483/transactions/fcc2550b-5104-5f83-a444"
|
||
// },
|
||
// "user_reference": "MEUGK",
|
||
// "created_at": "2018-07-26T08:55:12Z",
|
||
// "updated_at": "2018-07-26T08:58:18Z",
|
||
// "resource": "withdrawal",
|
||
// "resource_path": "/v2/accounts/91cd2d36-3a91-55b6-a5d4-0124cf105483/withdrawals/cfcc3b4a-eeb6-5e8c-8058",
|
||
// "committed": true,
|
||
// "payout_at": "2018-07-31T08:55:12Z",
|
||
// "instant": false,
|
||
// "fee": { "amount": "0.15", "currency": "EUR" },
|
||
// "amount": { "amount": "13130.69", "currency": "EUR" },
|
||
// "subtotal": { "amount": "13130.84", "currency": "EUR" },
|
||
// "idem": "e549dee5-63ed-4e79-8a96",
|
||
// "next_step": null
|
||
// }
|
||
//
|
||
// withdraw
|
||
//
|
||
// {
|
||
// "id": "a1794ecf-5693-55fa-70cf-ef731748ed82",
|
||
// "type": "send",
|
||
// "status": "pending",
|
||
// "amount": {
|
||
// "amount": "-14.008308",
|
||
// "currency": "USDC"
|
||
// },
|
||
// "native_amount": {
|
||
// "amount": "-18.74",
|
||
// "currency": "CAD"
|
||
// },
|
||
// "description": null,
|
||
// "created_at": "2024-01-12T01:27:31Z",
|
||
// "updated_at": "2024-01-12T01:27:31Z",
|
||
// "resource": "transaction",
|
||
// "resource_path": "/v2/accounts/a34bgfad-ed67-538b-bffc-730c98c10da0/transactions/a1794ecf-5693-55fa-70cf-ef731748ed82",
|
||
// "instant_exchange": false,
|
||
// "network": {
|
||
// "status": "pending",
|
||
// "status_description": "Pending (est. less than 10 minutes)",
|
||
// "transaction_fee": {
|
||
// "amount": "4.008308",
|
||
// "currency": "USDC"
|
||
// },
|
||
// "transaction_amount": {
|
||
// "amount": "10.000000",
|
||
// "currency": "USDC"
|
||
// },
|
||
// "confirmations": 0
|
||
// },
|
||
// "to": {
|
||
// "resource": "ethereum_address",
|
||
// "address": "0x9...",
|
||
// "currency": "USDC",
|
||
// "address_info": {
|
||
// "address": "0x9..."
|
||
// }
|
||
// },
|
||
// "idem": "748d8591-dg9a-7831-a45b-crd61dg78762",
|
||
// "details": {
|
||
// "title": "Sent USDC",
|
||
// "subtitle": "To USDC address on Ethereum network",
|
||
// "header": "Sent 14.008308 USDC ($18.74)",
|
||
// "health": "warning"
|
||
// },
|
||
// "hide_native_amount": false
|
||
// }
|
||
//
|
||
//
|
||
// crypto deposit & withdrawal (using `/transactions` endpoint)
|
||
// {
|
||
// "amount": {
|
||
// "amount": "0.00014200", (negative for withdrawal)
|
||
// "currency": "BTC"
|
||
// },
|
||
// "created_at": "2024-03-29T15:48:30Z",
|
||
// "id": "0031a605-241d-514d-a97b-d4b99f3225d3",
|
||
// "idem": "092a979b-017e-4403-940a-2ca57811f442", // field present only in case of withdrawal
|
||
// "native_amount": {
|
||
// "amount": "9.85", (negative for withdrawal)
|
||
// "currency": "USD"
|
||
// },
|
||
// "network": {
|
||
// "status": "pending", // if status is `off_blockchain` then no more other fields are present in this object
|
||
// "hash": "5jYuvrNsvX2DZoMnzGYzVpYxJLfYu4GSK3xetG1H5LHrSovsuFCFYdFMwNRoiht3s6fBk92MM8QLLnz65xuEFTrE",
|
||
// "network_name": "solana",
|
||
// "transaction_fee": {
|
||
// "amount": "0.000100000",
|
||
// "currency": "SOL"
|
||
// }
|
||
// },
|
||
// "resource": "transaction",
|
||
// "resource_path": "/v2/accounts/dc504b1c-248e-5b68-a3b0-b991f7fa84e6/transactions/0031a605-241d-514d-a97b-d4b99f3225d3",
|
||
// "status": "completed",
|
||
// "type": "send",
|
||
// "from": { // in some cases, field might be present for deposit
|
||
// "id": "7fd10cd7-b091-5cee-ba41-c29e49a7cccf",
|
||
// "name": "Coinbase",
|
||
// "resource": "user"
|
||
// },
|
||
// "to": { // field only present for withdrawal
|
||
// "address": "5HA12BNthAvBwNYARYf9y5MqqCpB4qhCNFCs1Qw48ACE",
|
||
// "resource": "address"
|
||
// },
|
||
// "description": "C3 - One Time BTC Credit . Reference Case # 123.", // in some cases, field might be present for deposit
|
||
// }
|
||
//
|
||
currency := GetArg(optionalArgs, 0, nil)
|
||
_ = currency
|
||
var transactionType interface{} = this.SafeString(transaction, "type")
|
||
var amountAndCurrencyObject interface{} = nil
|
||
var feeObject interface{} = nil
|
||
var network interface{} = this.SafeDict(transaction, "network", map[string]interface{} {})
|
||
if IsTrue(IsEqual(transactionType, "send")) {
|
||
amountAndCurrencyObject = this.SafeDict(network, "transaction_amount")
|
||
feeObject = this.SafeDict(network, "transaction_fee", map[string]interface{} {})
|
||
} else {
|
||
amountAndCurrencyObject = this.SafeDict(transaction, "subtotal")
|
||
feeObject = this.SafeDict(transaction, "fee", map[string]interface{} {})
|
||
}
|
||
if IsTrue(IsEqual(amountAndCurrencyObject, nil)) {
|
||
amountAndCurrencyObject = this.SafeDict(transaction, "amount")
|
||
}
|
||
var amountString interface{} = this.SafeString(amountAndCurrencyObject, "amount")
|
||
var amountStringAbs interface{} = Precise.StringAbs(amountString)
|
||
var status interface{} = this.ParseTransactionStatus(this.SafeString(transaction, "status"))
|
||
if IsTrue(IsEqual(status, nil)) {
|
||
var committed interface{} = this.SafeBool(transaction, "committed")
|
||
status = Ternary(IsTrue(committed), "ok", "pending")
|
||
}
|
||
var id interface{} = this.SafeString(transaction, "id")
|
||
var currencyId interface{} = this.SafeString(amountAndCurrencyObject, "currency")
|
||
var feeCurrencyId interface{} = this.SafeString(feeObject, "currency")
|
||
var datetime interface{} = this.SafeString(transaction, "created_at")
|
||
var resource interface{} = this.SafeString(transaction, "resource")
|
||
var typeVar interface{} = resource
|
||
if !IsTrue(this.InArray(typeVar, []interface{}{"deposit", "withdrawal"})) {
|
||
if IsTrue(Precise.StringGt(amountString, "0")) {
|
||
typeVar = "deposit"
|
||
} else if IsTrue(Precise.StringLt(amountString, "0")) {
|
||
typeVar = "withdrawal"
|
||
}
|
||
}
|
||
var toObject interface{} = this.SafeDict(transaction, "to")
|
||
var addressTo interface{} = this.SafeString(toObject, "address")
|
||
var networkId interface{} = this.SafeString(network, "network_name")
|
||
return map[string]interface{} {
|
||
"info": transaction,
|
||
"id": id,
|
||
"txid": this.SafeString(network, "hash", id),
|
||
"timestamp": this.Parse8601(datetime),
|
||
"datetime": datetime,
|
||
"network": this.NetworkIdToCode(networkId),
|
||
"address": addressTo,
|
||
"addressTo": addressTo,
|
||
"addressFrom": nil,
|
||
"tag": nil,
|
||
"tagTo": nil,
|
||
"tagFrom": nil,
|
||
"type": typeVar,
|
||
"amount": this.ParseNumber(amountStringAbs),
|
||
"currency": this.SafeCurrencyCode(currencyId, currency),
|
||
"status": status,
|
||
"updated": this.Parse8601(this.SafeString(transaction, "updated_at")),
|
||
"fee": map[string]interface{} {
|
||
"cost": this.SafeNumber(feeObject, "amount"),
|
||
"currency": this.SafeCurrencyCode(feeCurrencyId),
|
||
},
|
||
}
|
||
}
|
||
func (this *coinbase) ParseTrade(trade interface{}, optionalArgs ...interface{}) interface{} {
|
||
//
|
||
// fetchMyBuys, fetchMySells
|
||
//
|
||
// {
|
||
// "id": "67e0eaec-07d7-54c4-a72c-2e92826897df",
|
||
// "status": "completed",
|
||
// "payment_method": {
|
||
// "id": "83562370-3e5c-51db-87da-752af5ab9559",
|
||
// "resource": "payment_method",
|
||
// "resource_path": "/v2/payment-methods/83562370-3e5c-51db-87da-752af5ab9559"
|
||
// },
|
||
// "transaction": {
|
||
// "id": "441b9494-b3f0-5b98-b9b0-4d82c21c252a",
|
||
// "resource": "transaction",
|
||
// "resource_path": "/v2/accounts/2bbf394c-193b-5b2a-9155-3b4732659ede/transactions/441b9494-b3f0-5b98-b9b0-4d82c21c252a"
|
||
// },
|
||
// "amount": { "amount": "1.00000000", "currency": "BTC" },
|
||
// "total": { "amount": "10.25", "currency": "USD" },
|
||
// "subtotal": { "amount": "10.10", "currency": "USD" },
|
||
// "created_at": "2015-01-31T20:49:02Z",
|
||
// "updated_at": "2015-02-11T16:54:02-08:00",
|
||
// "resource": "buy",
|
||
// "resource_path": "/v2/accounts/2bbf394c-193b-5b2a-9155-3b4732659ede/buys/67e0eaec-07d7-54c4-a72c-2e92826897df",
|
||
// "committed": true,
|
||
// "instant": false,
|
||
// "fee": { "amount": "0.15", "currency": "USD" },
|
||
// "payout_at": "2015-02-18T16:54:00-08:00"
|
||
// }
|
||
//
|
||
// fetchTrades
|
||
//
|
||
// {
|
||
// "trade_id": "10092327",
|
||
// "product_id": "BTC-USDT",
|
||
// "price": "17488.12",
|
||
// "size": "0.0000623",
|
||
// "time": "2023-01-11T00:52:37.557001Z",
|
||
// "side": "BUY",
|
||
// "bid": "",
|
||
// "ask": ""
|
||
// }
|
||
//
|
||
// fetchMyTrades
|
||
//
|
||
// {
|
||
// "entry_id": "b88b82cc89e326a2778874795102cbafd08dd979a2a7a3c69603fc4c23c2e010",
|
||
// "trade_id": "cdc39e45-bbd3-44ec-bf02-61742dfb16a1",
|
||
// "order_id": "813a53c5-3e39-47bb-863d-2faf685d22d8",
|
||
// "trade_time": "2023-01-18T01:37:38.091377090Z",
|
||
// "trade_type": "FILL",
|
||
// "price": "21220.64",
|
||
// "size": "0.0046830664333996",
|
||
// "commission": "0.0000280983986004",
|
||
// "product_id": "BTC-USDT",
|
||
// "sequence_timestamp": "2023-01-18T01:37:38.092520Z",
|
||
// "liquidity_indicator": "UNKNOWN_LIQUIDITY_INDICATOR",
|
||
// "size_in_quote": true,
|
||
// "user_id": "1111111-1111-1111-1111-111111111111",
|
||
// "side": "BUY"
|
||
// }
|
||
//
|
||
market := GetArg(optionalArgs, 0, nil)
|
||
_ = market
|
||
var symbol interface{} = nil
|
||
var totalObject interface{} = this.SafeDict(trade, "total", map[string]interface{} {})
|
||
var amountObject interface{} = this.SafeDict(trade, "amount", map[string]interface{} {})
|
||
var subtotalObject interface{} = this.SafeDict(trade, "subtotal", map[string]interface{} {})
|
||
var feeObject interface{} = this.SafeDict(trade, "fee", map[string]interface{} {})
|
||
var marketId interface{} = this.SafeString(trade, "product_id")
|
||
market = this.SafeMarket(marketId, market, "-")
|
||
if IsTrue(!IsEqual(market, nil)) {
|
||
symbol = GetValue(market, "symbol")
|
||
} else {
|
||
var baseId interface{} = this.SafeString(amountObject, "currency")
|
||
var quoteId interface{} = this.SafeString(totalObject, "currency")
|
||
if IsTrue(IsTrue((!IsEqual(baseId, nil))) && IsTrue((!IsEqual(quoteId, nil)))) {
|
||
var base interface{} = this.SafeCurrencyCode(baseId)
|
||
var quote interface{} = this.SafeCurrencyCode(quoteId)
|
||
symbol = Add(Add(base, "/"), quote)
|
||
}
|
||
}
|
||
var sizeInQuote interface{} = this.SafeBool(trade, "size_in_quote")
|
||
var v3Price interface{} = this.SafeString(trade, "price")
|
||
var v3Cost interface{} = nil
|
||
var v3Amount interface{} = this.SafeString(trade, "size")
|
||
if IsTrue(sizeInQuote) {
|
||
// calculate base size
|
||
v3Cost = v3Amount
|
||
v3Amount = Precise.StringDiv(v3Amount, v3Price)
|
||
}
|
||
var v3FeeCost interface{} = this.SafeString(trade, "commission")
|
||
var amountString interface{} = this.SafeString(amountObject, "amount", v3Amount)
|
||
var costString interface{} = this.SafeString(subtotalObject, "amount", v3Cost)
|
||
var priceString interface{} = nil
|
||
var cost interface{} = nil
|
||
if IsTrue(IsTrue((!IsEqual(costString, nil))) && IsTrue((!IsEqual(amountString, nil)))) {
|
||
priceString = Precise.StringDiv(costString, amountString)
|
||
} else {
|
||
priceString = v3Price
|
||
}
|
||
if IsTrue(IsTrue((!IsEqual(priceString, nil))) && IsTrue((!IsEqual(amountString, nil)))) {
|
||
cost = Precise.StringMul(priceString, amountString)
|
||
} else {
|
||
cost = costString
|
||
}
|
||
var feeCurrencyId interface{} = this.SafeString(feeObject, "currency")
|
||
var feeCost interface{} = this.SafeNumber(feeObject, "amount", this.ParseNumber(v3FeeCost))
|
||
if IsTrue(IsTrue(IsTrue((IsEqual(feeCurrencyId, nil))) && IsTrue((!IsEqual(market, nil)))) && IsTrue((!IsEqual(feeCost, nil)))) {
|
||
feeCurrencyId = GetValue(market, "quote")
|
||
}
|
||
var datetime interface{} = this.SafeStringN(trade, []interface{}{"created_at", "trade_time", "time"})
|
||
var side interface{} = this.SafeStringLower2(trade, "resource", "side")
|
||
var takerOrMaker interface{} = this.SafeStringLower(trade, "liquidity_indicator")
|
||
return this.SafeTrade(map[string]interface{} {
|
||
"info": trade,
|
||
"id": this.SafeString2(trade, "id", "trade_id"),
|
||
"order": this.SafeString(trade, "order_id"),
|
||
"timestamp": this.Parse8601(datetime),
|
||
"datetime": datetime,
|
||
"symbol": symbol,
|
||
"type": nil,
|
||
"side": Ternary(IsTrue((IsEqual(side, "unknown_order_side"))), nil, side),
|
||
"takerOrMaker": Ternary(IsTrue((IsEqual(takerOrMaker, "unknown_liquidity_indicator"))), nil, takerOrMaker),
|
||
"price": priceString,
|
||
"amount": amountString,
|
||
"cost": cost,
|
||
"fee": map[string]interface{} {
|
||
"cost": feeCost,
|
||
"currency": this.SafeCurrencyCode(feeCurrencyId),
|
||
},
|
||
})
|
||
}
|
||
/**
|
||
* @method
|
||
* @name coinbase#fetchMarkets
|
||
* @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getpublicproducts
|
||
* @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-currencies#get-fiat-currencies
|
||
* @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-exchange-rates#get-exchange-rates
|
||
* @description retrieves data on all markets for coinbase
|
||
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
* @param {boolean} [params.usePrivate] use private endpoint for fetching markets
|
||
* @returns {object[]} an array of objects representing market data
|
||
*/
|
||
func (this *coinbase) FetchMarkets(optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
||
_ = params
|
||
if IsTrue(GetValue(this.Options, "adjustForTimeDifference")) {
|
||
|
||
retRes129812 := (<-this.LoadTimeDifference())
|
||
PanicOnError(retRes129812)
|
||
}
|
||
var method interface{} = this.SafeString(this.Options, "fetchMarkets", "fetchMarketsV3")
|
||
if IsTrue(IsEqual(method, "fetchMarketsV3")) {
|
||
|
||
retRes130219 := (<-this.FetchMarketsV3(params))
|
||
PanicOnError(retRes130219)
|
||
ch <- retRes130219
|
||
return nil
|
||
}
|
||
|
||
retRes130415 := (<-this.FetchMarketsV2(params))
|
||
PanicOnError(retRes130415)
|
||
ch <- retRes130415
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
func (this *coinbase) FetchMarketsV2(optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
||
_ = params
|
||
|
||
response:= (<-this.FetchCurrenciesFromCache(params))
|
||
PanicOnError(response)
|
||
var currencies interface{} = this.SafeDict(response, "currencies", map[string]interface{} {})
|
||
var exchangeRates interface{} = this.SafeDict(response, "exchangeRates", map[string]interface{} {})
|
||
var data interface{} = this.SafeList(currencies, "data", []interface{}{})
|
||
var dataById interface{} = this.IndexBy(data, "id")
|
||
var rates interface{} = this.SafeDict(this.SafeDict(exchangeRates, "data", map[string]interface{} {}), "rates", map[string]interface{} {})
|
||
var baseIds interface{} = ObjectKeys(rates)
|
||
var result interface{} = []interface{}{}
|
||
for i := 0; IsLessThan(i, GetArrayLength(baseIds)); i++ {
|
||
var baseId interface{} = GetValue(baseIds, i)
|
||
var base interface{} = this.SafeCurrencyCode(baseId)
|
||
var typeVar interface{} = Ternary(IsTrue((InOp(dataById, baseId))), "fiat", "crypto")
|
||
// https://github.com/ccxt/ccxt/issues/6066
|
||
if IsTrue(IsEqual(typeVar, "crypto")) {
|
||
for j := 0; IsLessThan(j, GetArrayLength(data)); j++ {
|
||
var quoteCurrency interface{} = GetValue(data, j)
|
||
var quoteId interface{} = this.SafeString(quoteCurrency, "id")
|
||
var quote interface{} = this.SafeCurrencyCode(quoteId)
|
||
AppendToArray(&result,this.SafeMarketStructure(map[string]interface{} {
|
||
"id": Add(Add(baseId, "-"), quoteId),
|
||
"symbol": Add(Add(base, "/"), quote),
|
||
"base": base,
|
||
"quote": quote,
|
||
"settle": nil,
|
||
"baseId": baseId,
|
||
"quoteId": quoteId,
|
||
"settleId": nil,
|
||
"type": "spot",
|
||
"spot": true,
|
||
"margin": false,
|
||
"swap": false,
|
||
"future": false,
|
||
"option": false,
|
||
"active": nil,
|
||
"contract": false,
|
||
"linear": nil,
|
||
"inverse": nil,
|
||
"contractSize": nil,
|
||
"expiry": nil,
|
||
"expiryDatetime": nil,
|
||
"strike": nil,
|
||
"optionType": nil,
|
||
"precision": map[string]interface{} {
|
||
"amount": nil,
|
||
"price": nil,
|
||
},
|
||
"limits": map[string]interface{} {
|
||
"leverage": map[string]interface{} {
|
||
"min": nil,
|
||
"max": nil,
|
||
},
|
||
"amount": map[string]interface{} {
|
||
"min": nil,
|
||
"max": nil,
|
||
},
|
||
"price": map[string]interface{} {
|
||
"min": nil,
|
||
"max": nil,
|
||
},
|
||
"cost": map[string]interface{} {
|
||
"min": this.SafeNumber(quoteCurrency, "min_size"),
|
||
"max": nil,
|
||
},
|
||
},
|
||
"info": quoteCurrency,
|
||
}))
|
||
}
|
||
}
|
||
}
|
||
|
||
ch <- result
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
func (this *coinbase) FetchMarketsV3(optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
||
_ = params
|
||
var usePrivate interface{} = false
|
||
usePrivateparamsVariable := this.HandleOptionAndParams(params, "fetchMarkets", "usePrivate", false);
|
||
usePrivate = GetValue(usePrivateparamsVariable,0);
|
||
params = GetValue(usePrivateparamsVariable,1)
|
||
var spotUnresolvedPromises interface{} = []interface{}{}
|
||
if IsTrue(usePrivate) {
|
||
AppendToArray(&spotUnresolvedPromises,this.V3PrivateGetBrokerageProducts(params))
|
||
} else {
|
||
AppendToArray(&spotUnresolvedPromises,this.V3PublicGetBrokerageMarketProducts(params))
|
||
}
|
||
//
|
||
// {
|
||
// products: [
|
||
// {
|
||
// product_id: 'BTC-USD',
|
||
// price: '67060',
|
||
// price_percentage_change_24h: '3.30054960636883',
|
||
// volume_24h: '10967.87426597',
|
||
// volume_percentage_change_24h: '141.73048325503036',
|
||
// base_increment: '0.00000001',
|
||
// quote_increment: '0.01',
|
||
// quote_min_size: '1',
|
||
// quote_max_size: '150000000',
|
||
// base_min_size: '0.00000001',
|
||
// base_max_size: '3400',
|
||
// base_name: 'Bitcoin',
|
||
// quote_name: 'US Dollar',
|
||
// watched: false,
|
||
// is_disabled: false,
|
||
// new: false,
|
||
// status: 'online',
|
||
// cancel_only: false,
|
||
// limit_only: false,
|
||
// post_only: false,
|
||
// trading_disabled: false,
|
||
// auction_mode: false,
|
||
// product_type: 'SPOT',
|
||
// quote_currency_id: 'USD',
|
||
// base_currency_id: 'BTC',
|
||
// fcm_trading_session_details: null,
|
||
// mid_market_price: '',
|
||
// alias: '',
|
||
// alias_to: [ 'BTC-USDC' ],
|
||
// base_display_symbol: 'BTC',
|
||
// quote_display_symbol: 'USD',
|
||
// view_only: false,
|
||
// price_increment: '0.01',
|
||
// display_name: 'BTC-USD',
|
||
// product_venue: 'CBE'
|
||
// },
|
||
// ...
|
||
// ],
|
||
// num_products: '646'
|
||
// }
|
||
//
|
||
if IsTrue(this.CheckRequiredCredentials(false)) {
|
||
AppendToArray(&spotUnresolvedPromises,this.V3PrivateGetBrokerageTransactionSummary(params))
|
||
}
|
||
//
|
||
// {
|
||
// total_volume: '9.995989116664404',
|
||
// total_fees: '0.07996791093331522',
|
||
// fee_tier: {
|
||
// pricing_tier: 'Advanced 1',
|
||
// usd_from: '0',
|
||
// usd_to: '1000',
|
||
// taker_fee_rate: '0.008',
|
||
// maker_fee_rate: '0.006',
|
||
// aop_from: '',
|
||
// aop_to: ''
|
||
// },
|
||
// margin_rate: null,
|
||
// goods_and_services_tax: null,
|
||
// advanced_trade_only_volume: '9.995989116664404',
|
||
// advanced_trade_only_fees: '0.07996791093331522',
|
||
// coinbase_pro_volume: '0',
|
||
// coinbase_pro_fees: '0',
|
||
// total_balance: '',
|
||
// has_promo_fee: false
|
||
// }
|
||
//
|
||
var unresolvedContractPromises interface{} = []interface{}{}
|
||
|
||
{ ret__ := func(this *coinbase) (ret_ interface{}) {
|
||
defer func() {
|
||
if e := recover(); e != nil {
|
||
if e == "break" {
|
||
return
|
||
}
|
||
ret_ = func(this *coinbase) interface{} {
|
||
// catch block:
|
||
unresolvedContractPromises = []interface{}{} // the sync version of ccxt won't have the promise.all line so the request is made here. Some users can't access perpetual products
|
||
return nil
|
||
}(this)
|
||
}
|
||
}()
|
||
// try block:
|
||
unresolvedContractPromises = []interface{}{this.V3PublicGetBrokerageMarketProducts(this.Extend(params, map[string]interface{} {
|
||
"product_type": "FUTURE",
|
||
})), this.V3PublicGetBrokerageMarketProducts(this.Extend(params, map[string]interface{} {
|
||
"product_type": "FUTURE",
|
||
"contract_expiry_type": "PERPETUAL",
|
||
}))}
|
||
if IsTrue(this.CheckRequiredCredentials(false)) {
|
||
AppendToArray(&unresolvedContractPromises,this.Extend(params, map[string]interface{} {
|
||
"product_type": "FUTURE",
|
||
}))
|
||
AppendToArray(&unresolvedContractPromises,this.Extend(params, map[string]interface{} {
|
||
"product_type": "FUTURE",
|
||
"contract_expiry_type": "PERPETUAL",
|
||
}))
|
||
}
|
||
return nil
|
||
}(this)
|
||
if ret__ != nil {
|
||
return ret__
|
||
}
|
||
}
|
||
|
||
promises:= (<-promiseAll(spotUnresolvedPromises))
|
||
PanicOnError(promises)
|
||
var contractPromises interface{} = nil
|
||
|
||
{ ret__ := func(this *coinbase) (ret_ interface{}) {
|
||
defer func() {
|
||
if e := recover(); e != nil {
|
||
if e == "break" {
|
||
return
|
||
}
|
||
ret_ = func(this *coinbase) interface{} {
|
||
// catch block:
|
||
contractPromises = []interface{}{}
|
||
return nil
|
||
}(this)
|
||
}
|
||
}()
|
||
// try block:
|
||
|
||
contractPromises = (<-promiseAll(unresolvedContractPromises))
|
||
PanicOnError(contractPromises) // some users don't have access to contracts
|
||
return nil
|
||
}(this)
|
||
if ret__ != nil {
|
||
return ret__
|
||
}
|
||
}
|
||
var spot interface{} = this.SafeDict(promises, 0, map[string]interface{} {})
|
||
var fees interface{} = this.SafeDict(promises, 1, map[string]interface{} {})
|
||
var expiringFutures interface{} = this.SafeDict(contractPromises, 0, map[string]interface{} {})
|
||
var perpetualFutures interface{} = this.SafeDict(contractPromises, 1, map[string]interface{} {})
|
||
var expiringFees interface{} = this.SafeDict(contractPromises, 2, map[string]interface{} {})
|
||
var perpetualFees interface{} = this.SafeDict(contractPromises, 3, map[string]interface{} {})
|
||
//
|
||
// {
|
||
// "total_volume": 0,
|
||
// "total_fees": 0,
|
||
// "fee_tier": {
|
||
// "pricing_tier": "",
|
||
// "usd_from": "0",
|
||
// "usd_to": "10000",
|
||
// "taker_fee_rate": "0.006",
|
||
// "maker_fee_rate": "0.004"
|
||
// },
|
||
// "margin_rate": null,
|
||
// "goods_and_services_tax": null,
|
||
// "advanced_trade_only_volume": 0,
|
||
// "advanced_trade_only_fees": 0,
|
||
// "coinbase_pro_volume": 0,
|
||
// "coinbase_pro_fees": 0
|
||
// }
|
||
//
|
||
var feeTier interface{} = this.SafeDict(fees, "fee_tier", map[string]interface{} {})
|
||
var expiringFeeTier interface{} = this.SafeDict(expiringFees, "fee_tier", map[string]interface{} {}) // fee tier null?
|
||
var perpetualFeeTier interface{} = this.SafeDict(perpetualFees, "fee_tier", map[string]interface{} {}) // fee tier null?
|
||
var data interface{} = this.SafeList(spot, "products", []interface{}{})
|
||
var result interface{} = []interface{}{}
|
||
for i := 0; IsLessThan(i, GetArrayLength(data)); i++ {
|
||
AppendToArray(&result,this.ParseSpotMarket(GetValue(data, i), feeTier))
|
||
}
|
||
var futureData interface{} = this.SafeList(expiringFutures, "products", []interface{}{})
|
||
for i := 0; IsLessThan(i, GetArrayLength(futureData)); i++ {
|
||
AppendToArray(&result,this.ParseContractMarket(GetValue(futureData, i), expiringFeeTier))
|
||
}
|
||
var perpetualData interface{} = this.SafeList(perpetualFutures, "products", []interface{}{})
|
||
for i := 0; IsLessThan(i, GetArrayLength(perpetualData)); i++ {
|
||
AppendToArray(&result,this.ParseContractMarket(GetValue(perpetualData, i), perpetualFeeTier))
|
||
}
|
||
|
||
ch <- result
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
func (this *coinbase) ParseSpotMarket(market interface{}, feeTier interface{}) interface{} {
|
||
//
|
||
// {
|
||
// "product_id": "TONE-USD",
|
||
// "price": "0.01523",
|
||
// "price_percentage_change_24h": "1.94109772423025",
|
||
// "volume_24h": "19773129",
|
||
// "volume_percentage_change_24h": "437.0170530929949",
|
||
// "base_increment": "1",
|
||
// "quote_increment": "0.00001",
|
||
// "quote_min_size": "1",
|
||
// "quote_max_size": "10000000",
|
||
// "base_min_size": "26.7187147229469674",
|
||
// "base_max_size": "267187147.2294696735908216",
|
||
// "base_name": "TE-FOOD",
|
||
// "quote_name": "US Dollar",
|
||
// "watched": false,
|
||
// "is_disabled": false,
|
||
// "new": false,
|
||
// "status": "online",
|
||
// "cancel_only": false,
|
||
// "limit_only": false,
|
||
// "post_only": false,
|
||
// "trading_disabled": false,
|
||
// "auction_mode": false,
|
||
// "product_type": "SPOT",
|
||
// "quote_currency_id": "USD",
|
||
// "base_currency_id": "TONE",
|
||
// "fcm_trading_session_details": null,
|
||
// "mid_market_price": ""
|
||
// }
|
||
//
|
||
var id interface{} = this.SafeString(market, "product_id")
|
||
var baseId interface{} = this.SafeString(market, "base_currency_id")
|
||
var quoteId interface{} = this.SafeString(market, "quote_currency_id")
|
||
var base interface{} = this.SafeCurrencyCode(baseId)
|
||
var quote interface{} = this.SafeCurrencyCode(quoteId)
|
||
var marketType interface{} = this.SafeStringLower(market, "product_type")
|
||
var tradingDisabled interface{} = this.SafeBool(market, "trading_disabled")
|
||
var stablePairs interface{} = this.SafeList(this.Options, "stablePairs", []interface{}{})
|
||
var defaultTakerFee interface{} = this.SafeNumber(GetValue(this.Fees, "trading"), "taker")
|
||
var defaultMakerFee interface{} = this.SafeNumber(GetValue(this.Fees, "trading"), "maker")
|
||
var takerFee interface{} = Ternary(IsTrue(this.InArray(id, stablePairs)), 0.00001, this.SafeNumber(feeTier, "taker_fee_rate", defaultTakerFee))
|
||
var makerFee interface{} = Ternary(IsTrue(this.InArray(id, stablePairs)), 0, this.SafeNumber(feeTier, "maker_fee_rate", defaultMakerFee))
|
||
return this.SafeMarketStructure(map[string]interface{} {
|
||
"id": id,
|
||
"symbol": Add(Add(base, "/"), quote),
|
||
"base": base,
|
||
"quote": quote,
|
||
"settle": nil,
|
||
"baseId": baseId,
|
||
"quoteId": quoteId,
|
||
"settleId": nil,
|
||
"type": marketType,
|
||
"spot": (IsEqual(marketType, "spot")),
|
||
"margin": nil,
|
||
"swap": false,
|
||
"future": false,
|
||
"option": false,
|
||
"active": !IsTrue(tradingDisabled),
|
||
"contract": false,
|
||
"linear": nil,
|
||
"inverse": nil,
|
||
"taker": takerFee,
|
||
"maker": makerFee,
|
||
"contractSize": nil,
|
||
"expiry": nil,
|
||
"expiryDatetime": nil,
|
||
"strike": nil,
|
||
"optionType": nil,
|
||
"precision": map[string]interface{} {
|
||
"amount": this.SafeNumber(market, "base_increment"),
|
||
"price": this.SafeNumber2(market, "price_increment", "quote_increment"),
|
||
},
|
||
"limits": map[string]interface{} {
|
||
"leverage": map[string]interface{} {
|
||
"min": nil,
|
||
"max": nil,
|
||
},
|
||
"amount": map[string]interface{} {
|
||
"min": this.SafeNumber(market, "base_min_size"),
|
||
"max": this.SafeNumber(market, "base_max_size"),
|
||
},
|
||
"price": map[string]interface{} {
|
||
"min": nil,
|
||
"max": nil,
|
||
},
|
||
"cost": map[string]interface{} {
|
||
"min": this.SafeNumber(market, "quote_min_size"),
|
||
"max": this.SafeNumber(market, "quote_max_size"),
|
||
},
|
||
},
|
||
"created": nil,
|
||
"info": market,
|
||
})
|
||
}
|
||
func (this *coinbase) ParseContractMarket(market interface{}, feeTier interface{}) interface{} {
|
||
// expiring
|
||
//
|
||
// {
|
||
// "product_id":"BIT-26APR24-CDE",
|
||
// "price":"71145",
|
||
// "price_percentage_change_24h":"-2.36722931247427",
|
||
// "volume_24h":"108549",
|
||
// "volume_percentage_change_24h":"155.78255337197794",
|
||
// "base_increment":"1",
|
||
// "quote_increment":"0.01",
|
||
// "quote_min_size":"0",
|
||
// "quote_max_size":"100000000",
|
||
// "base_min_size":"1",
|
||
// "base_max_size":"100000000",
|
||
// "base_name":"",
|
||
// "quote_name":"US Dollar",
|
||
// "watched":false,
|
||
// "is_disabled":false,
|
||
// "new":false,
|
||
// "status":"",
|
||
// "cancel_only":false,
|
||
// "limit_only":false,
|
||
// "post_only":false,
|
||
// "trading_disabled":false,
|
||
// "auction_mode":false,
|
||
// "product_type":"FUTURE",
|
||
// "quote_currency_id":"USD",
|
||
// "base_currency_id":"",
|
||
// "fcm_trading_session_details":{
|
||
// "is_session_open":true,
|
||
// "open_time":"2024-04-08T22:00:00Z",
|
||
// "close_time":"2024-04-09T21:00:00Z"
|
||
// },
|
||
// "mid_market_price":"71105",
|
||
// "alias":"",
|
||
// "alias_to":[
|
||
// ],
|
||
// "base_display_symbol":"",
|
||
// "quote_display_symbol":"USD",
|
||
// "view_only":false,
|
||
// "price_increment":"5",
|
||
// "display_name":"BTC 26 APR 24",
|
||
// "product_venue":"FCM",
|
||
// "future_product_details":{
|
||
// "venue":"cde",
|
||
// "contract_code":"BIT",
|
||
// "contract_expiry":"2024-04-26T15:00:00Z",
|
||
// "contract_size":"0.01",
|
||
// "contract_root_unit":"BTC",
|
||
// "group_description":"Nano Bitcoin Futures",
|
||
// "contract_expiry_timezone":"Europe/London",
|
||
// "group_short_description":"Nano BTC",
|
||
// "risk_managed_by":"MANAGED_BY_FCM",
|
||
// "contract_expiry_type":"EXPIRING",
|
||
// "contract_display_name":"BTC 26 APR 24"
|
||
// }
|
||
// }
|
||
//
|
||
// perpetual
|
||
//
|
||
// {
|
||
// "product_id":"ETH-PERP-INTX",
|
||
// "price":"3630.98",
|
||
// "price_percentage_change_24h":"0.65142426292038",
|
||
// "volume_24h":"114020.1501",
|
||
// "volume_percentage_change_24h":"63.33650787154869",
|
||
// "base_increment":"0.0001",
|
||
// "quote_increment":"0.01",
|
||
// "quote_min_size":"10",
|
||
// "quote_max_size":"50000000",
|
||
// "base_min_size":"0.0001",
|
||
// "base_max_size":"50000",
|
||
// "base_name":"",
|
||
// "quote_name":"USDC",
|
||
// "watched":false,
|
||
// "is_disabled":false,
|
||
// "new":false,
|
||
// "status":"",
|
||
// "cancel_only":false,
|
||
// "limit_only":false,
|
||
// "post_only":false,
|
||
// "trading_disabled":false,
|
||
// "auction_mode":false,
|
||
// "product_type":"FUTURE",
|
||
// "quote_currency_id":"USDC",
|
||
// "base_currency_id":"",
|
||
// "fcm_trading_session_details":null,
|
||
// "mid_market_price":"3630.975",
|
||
// "alias":"",
|
||
// "alias_to":[],
|
||
// "base_display_symbol":"",
|
||
// "quote_display_symbol":"USDC",
|
||
// "view_only":false,
|
||
// "price_increment":"0.01",
|
||
// "display_name":"ETH PERP",
|
||
// "product_venue":"INTX",
|
||
// "future_product_details":{
|
||
// "venue":"",
|
||
// "contract_code":"ETH",
|
||
// "contract_expiry":null,
|
||
// "contract_size":"1",
|
||
// "contract_root_unit":"ETH",
|
||
// "group_description":"",
|
||
// "contract_expiry_timezone":"",
|
||
// "group_short_description":"",
|
||
// "risk_managed_by":"MANAGED_BY_VENUE",
|
||
// "contract_expiry_type":"PERPETUAL",
|
||
// "perpetual_details":{
|
||
// "open_interest":"0",
|
||
// "funding_rate":"0.000016",
|
||
// "funding_time":"2024-04-09T09:00:00.000008Z",
|
||
// "max_leverage":"10"
|
||
// },
|
||
// "contract_display_name":"ETH PERPETUAL"
|
||
// }
|
||
// }
|
||
//
|
||
var id interface{} = this.SafeString(market, "product_id")
|
||
var futureProductDetails interface{} = this.SafeDict(market, "future_product_details", map[string]interface{} {})
|
||
var contractExpiryType interface{} = this.SafeString(futureProductDetails, "contract_expiry_type")
|
||
var contractSize interface{} = this.SafeNumber(futureProductDetails, "contract_size")
|
||
var contractExpire interface{} = this.SafeString(futureProductDetails, "contract_expiry")
|
||
var expireTimestamp interface{} = this.Parse8601(contractExpire)
|
||
var expireDateTime interface{} = this.Iso8601(expireTimestamp)
|
||
var isSwap interface{} = (IsEqual(contractExpiryType, "PERPETUAL"))
|
||
var baseId interface{} = this.SafeString(futureProductDetails, "contract_root_unit")
|
||
var quoteId interface{} = this.SafeString(market, "quote_currency_id")
|
||
var base interface{} = this.SafeCurrencyCode(baseId)
|
||
var quote interface{} = this.SafeCurrencyCode(quoteId)
|
||
var tradingDisabled interface{} = this.SafeBool(market, "is_disabled")
|
||
var symbol interface{} = Add(Add(base, "/"), quote)
|
||
var typeVar interface{} = nil
|
||
if IsTrue(isSwap) {
|
||
typeVar = "swap"
|
||
symbol = Add(Add(symbol, ":"), quote)
|
||
} else {
|
||
typeVar = "future"
|
||
symbol = Add(Add(Add(Add(symbol, ":"), quote), "-"), this.Yymmdd(expireTimestamp))
|
||
}
|
||
var takerFeeRate interface{} = this.SafeNumber(feeTier, "taker_fee_rate")
|
||
var makerFeeRate interface{} = this.SafeNumber(feeTier, "maker_fee_rate")
|
||
var taker interface{} = Ternary(IsTrue(takerFeeRate), takerFeeRate, this.ParseNumber("0.06"))
|
||
var maker interface{} = Ternary(IsTrue(makerFeeRate), makerFeeRate, this.ParseNumber("0.04"))
|
||
return this.SafeMarketStructure(map[string]interface{} {
|
||
"id": id,
|
||
"symbol": symbol,
|
||
"base": base,
|
||
"quote": quote,
|
||
"settle": quote,
|
||
"baseId": baseId,
|
||
"quoteId": quoteId,
|
||
"settleId": quoteId,
|
||
"type": typeVar,
|
||
"spot": false,
|
||
"margin": false,
|
||
"swap": isSwap,
|
||
"future": !IsTrue(isSwap),
|
||
"option": false,
|
||
"active": !IsTrue(tradingDisabled),
|
||
"contract": true,
|
||
"linear": true,
|
||
"inverse": false,
|
||
"taker": taker,
|
||
"maker": maker,
|
||
"contractSize": contractSize,
|
||
"expiry": expireTimestamp,
|
||
"expiryDatetime": expireDateTime,
|
||
"strike": nil,
|
||
"optionType": nil,
|
||
"precision": map[string]interface{} {
|
||
"amount": this.SafeNumber(market, "base_increment"),
|
||
"price": this.SafeNumber2(market, "price_increment", "quote_increment"),
|
||
},
|
||
"limits": map[string]interface{} {
|
||
"leverage": map[string]interface{} {
|
||
"min": nil,
|
||
"max": nil,
|
||
},
|
||
"amount": map[string]interface{} {
|
||
"min": this.SafeNumber(market, "base_min_size"),
|
||
"max": this.SafeNumber(market, "base_max_size"),
|
||
},
|
||
"price": map[string]interface{} {
|
||
"min": nil,
|
||
"max": nil,
|
||
},
|
||
"cost": map[string]interface{} {
|
||
"min": this.SafeNumber(market, "quote_min_size"),
|
||
"max": this.SafeNumber(market, "quote_max_size"),
|
||
},
|
||
},
|
||
"created": nil,
|
||
"info": market,
|
||
})
|
||
}
|
||
func (this *coinbase) FetchCurrenciesFromCache(optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
||
_ = params
|
||
var options interface{} = this.SafeDict(this.Options, "fetchCurrencies", map[string]interface{} {})
|
||
var timestamp interface{} = this.SafeInteger(options, "timestamp")
|
||
var expires interface{} = this.SafeInteger(options, "expires", 1000)
|
||
var now interface{} = this.Milliseconds()
|
||
if IsTrue(IsTrue((IsEqual(timestamp, nil))) || IsTrue((IsGreaterThan((Subtract(now, timestamp)), expires)))) {
|
||
var promises interface{} = []interface{}{this.V2PublicGetCurrencies(params), this.V2PublicGetCurrenciesCrypto(params)}
|
||
|
||
promisesResult:= (<-promiseAll(promises))
|
||
PanicOnError(promisesResult)
|
||
var fiatResponse interface{} = this.SafeDict(promisesResult, 0, map[string]interface{} {})
|
||
//
|
||
// [
|
||
// "data": {
|
||
// id: 'IMP',
|
||
// name: 'Isle of Man Pound',
|
||
// min_size: '0.01'
|
||
// },
|
||
// ...
|
||
// ]
|
||
//
|
||
var cryptoResponse interface{} = this.SafeDict(promisesResult, 1, map[string]interface{} {})
|
||
//
|
||
// {
|
||
// asset_id: '9476e3be-b731-47fa-82be-347fabc573d9',
|
||
// code: 'AERO',
|
||
// name: 'Aerodrome Finance',
|
||
// color: '#0433FF',
|
||
// sort_index: '340',
|
||
// exponent: '8',
|
||
// type: 'crypto',
|
||
// address_regex: '^(?:0x)?[0-9a-fA-F]{40}$'
|
||
// }
|
||
//
|
||
var fiatData interface{} = this.SafeList(fiatResponse, "data", []interface{}{})
|
||
var cryptoData interface{} = this.SafeList(cryptoResponse, "data", []interface{}{})
|
||
|
||
exchangeRates:= (<-this.V2PublicGetExchangeRates(params))
|
||
PanicOnError(exchangeRates)
|
||
AddElementToObject(this.Options, "fetchCurrencies", this.Extend(options, map[string]interface{} {
|
||
"currencies": this.ArrayConcat(fiatData, cryptoData),
|
||
"exchangeRates": exchangeRates,
|
||
"timestamp": now,
|
||
}))
|
||
}
|
||
|
||
ch <- this.SafeDict(this.Options, "fetchCurrencies", map[string]interface{} {})
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
/**
|
||
* @method
|
||
* @name coinbase#fetchCurrencies
|
||
* @description fetches all available currencies on an exchange
|
||
* @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-currencies#get-fiat-currencies
|
||
* @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-exchange-rates#get-exchange-rates
|
||
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
* @returns {object} an associative dictionary of currencies
|
||
*/
|
||
func (this *coinbase) FetchCurrencies(optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
||
_ = params
|
||
|
||
response:= (<-this.FetchCurrenciesFromCache(params))
|
||
PanicOnError(response)
|
||
var currencies interface{} = this.SafeList(response, "currencies", []interface{}{})
|
||
//
|
||
// fiat
|
||
//
|
||
// {
|
||
// id: 'IMP',
|
||
// name: 'Isle of Man Pound',
|
||
// min_size: '0.01'
|
||
// },
|
||
//
|
||
// crypto
|
||
//
|
||
// {
|
||
// asset_id: '9476e3be-b731-47fa-82be-347fabc573d9',
|
||
// code: 'AERO',
|
||
// name: 'Aerodrome Finance',
|
||
// color: '#0433FF',
|
||
// sort_index: '340',
|
||
// exponent: '8',
|
||
// type: 'crypto',
|
||
// address_regex: '^(?:0x)?[0-9a-fA-F]{40}$'
|
||
// }
|
||
//
|
||
//
|
||
// {
|
||
// "data":{
|
||
// "currency":"USD",
|
||
// "rates":{
|
||
// "AED":"3.67",
|
||
// "AFN":"78.21",
|
||
// "ALL":"110.42",
|
||
// "AMD":"474.18",
|
||
// "ANG":"1.75",
|
||
// ...
|
||
// },
|
||
// }
|
||
// }
|
||
//
|
||
var result interface{} = map[string]interface{} {}
|
||
var networks interface{} = map[string]interface{} {}
|
||
var networksById interface{} = map[string]interface{} {}
|
||
for i := 0; IsLessThan(i, GetArrayLength(currencies)); i++ {
|
||
var currency interface{} = GetValue(currencies, i)
|
||
var assetId interface{} = this.SafeString(currency, "asset_id")
|
||
var id interface{} = this.SafeString2(currency, "id", "code")
|
||
var code interface{} = this.SafeCurrencyCode(id)
|
||
var name interface{} = this.SafeString(currency, "name")
|
||
AddElementToObject(GetValue(this.Options, "networks"), code, ToLower(name))
|
||
AddElementToObject(GetValue(this.Options, "networksById"), code, ToLower(name))
|
||
AddElementToObject(result, code, map[string]interface{} {
|
||
"info": currency,
|
||
"id": id,
|
||
"code": code,
|
||
"type": Ternary(IsTrue((!IsEqual(assetId, nil))), "crypto", "fiat"),
|
||
"name": this.SafeString(currency, "name"),
|
||
"active": true,
|
||
"deposit": nil,
|
||
"withdraw": nil,
|
||
"fee": nil,
|
||
"precision": nil,
|
||
"limits": map[string]interface{} {
|
||
"amount": map[string]interface{} {
|
||
"min": this.SafeNumber(currency, "min_size"),
|
||
"max": nil,
|
||
},
|
||
"withdraw": map[string]interface{} {
|
||
"min": nil,
|
||
"max": nil,
|
||
},
|
||
},
|
||
})
|
||
if IsTrue(!IsEqual(assetId, nil)) {
|
||
var lowerCaseName interface{} = ToLower(name)
|
||
AddElementToObject(networks, code, lowerCaseName)
|
||
AddElementToObject(networksById, lowerCaseName, code)
|
||
}
|
||
}
|
||
AddElementToObject(this.Options, "networks", this.Extend(networks, GetValue(this.Options, "networks")))
|
||
AddElementToObject(this.Options, "networksById", this.Extend(networksById, GetValue(this.Options, "networksById")))
|
||
|
||
ch <- result
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
/**
|
||
* @method
|
||
* @name coinbase#fetchTickers
|
||
* @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
|
||
* @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getproducts
|
||
* @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-exchange-rates#get-exchange-rates
|
||
* @param {string[]|undefined} symbols unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
|
||
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
* @param {boolean} [params.usePrivate] use private endpoint for fetching tickers
|
||
* @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
||
*/
|
||
func (this *coinbase) FetchTickers(optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
symbols := GetArg(optionalArgs, 0, nil)
|
||
_ = symbols
|
||
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
||
_ = params
|
||
var method interface{} = this.SafeString(this.Options, "fetchTickers", "fetchTickersV3")
|
||
if IsTrue(IsEqual(method, "fetchTickersV3")) {
|
||
|
||
retRes197219 := (<-this.FetchTickersV3(symbols, params))
|
||
PanicOnError(retRes197219)
|
||
ch <- retRes197219
|
||
return nil
|
||
}
|
||
|
||
retRes197415 := (<-this.FetchTickersV2(symbols, params))
|
||
PanicOnError(retRes197415)
|
||
ch <- retRes197415
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
func (this *coinbase) FetchTickersV2(optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
symbols := GetArg(optionalArgs, 0, nil)
|
||
_ = symbols
|
||
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
||
_ = params
|
||
|
||
retRes19788 := (<-this.LoadMarkets())
|
||
PanicOnError(retRes19788)
|
||
symbols = this.MarketSymbols(symbols)
|
||
var request interface{} = map[string]interface{} {}
|
||
|
||
response:= (<-this.V2PublicGetExchangeRates(this.Extend(request, params)))
|
||
PanicOnError(response)
|
||
//
|
||
// {
|
||
// "data":{
|
||
// "currency":"USD",
|
||
// "rates":{
|
||
// "AED":"3.6731",
|
||
// "AFN":"103.163942",
|
||
// "ALL":"106.973038",
|
||
// }
|
||
// }
|
||
// }
|
||
//
|
||
var data interface{} = this.SafeDict(response, "data", map[string]interface{} {})
|
||
var rates interface{} = this.SafeDict(data, "rates", map[string]interface{} {})
|
||
var quoteId interface{} = this.SafeString(data, "currency")
|
||
var result interface{} = map[string]interface{} {}
|
||
var baseIds interface{} = ObjectKeys(rates)
|
||
var delimiter interface{} = "-"
|
||
for i := 0; IsLessThan(i, GetArrayLength(baseIds)); i++ {
|
||
var baseId interface{} = GetValue(baseIds, i)
|
||
var marketId interface{} = Add(Add(baseId, delimiter), quoteId)
|
||
var market interface{} = this.SafeMarket(marketId, nil, delimiter)
|
||
var symbol interface{} = GetValue(market, "symbol")
|
||
AddElementToObject(result, symbol, this.ParseTicker(GetValue(rates, baseId), market))
|
||
}
|
||
|
||
ch <- this.FilterByArrayTickers(result, "symbol", symbols)
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
func (this *coinbase) FetchTickersV3(optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
symbols := GetArg(optionalArgs, 0, nil)
|
||
_ = symbols
|
||
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
||
_ = params
|
||
|
||
retRes20138 := (<-this.LoadMarkets())
|
||
PanicOnError(retRes20138)
|
||
symbols = this.MarketSymbols(symbols)
|
||
var request interface{} = map[string]interface{} {}
|
||
if IsTrue(!IsEqual(symbols, nil)) {
|
||
AddElementToObject(request, "product_ids", this.MarketIds(symbols))
|
||
}
|
||
var marketType interface{} = nil
|
||
marketTypeparamsVariable := this.HandleMarketTypeAndParams("fetchTickers", this.GetMarketFromSymbols(symbols), params, "default");
|
||
marketType = GetValue(marketTypeparamsVariable,0);
|
||
params = GetValue(marketTypeparamsVariable,1)
|
||
if IsTrue(IsTrue(!IsEqual(marketType, nil)) && IsTrue(!IsEqual(marketType, "default"))) {
|
||
AddElementToObject(request, "product_type", Ternary(IsTrue((IsEqual(marketType, "swap"))), "FUTURE", "SPOT"))
|
||
}
|
||
var response interface{} = nil
|
||
var usePrivate interface{} = false
|
||
usePrivateparamsVariable := this.HandleOptionAndParams(params, "fetchTickers", "usePrivate", false);
|
||
usePrivate = GetValue(usePrivateparamsVariable,0);
|
||
params = GetValue(usePrivateparamsVariable,1)
|
||
if IsTrue(usePrivate) {
|
||
|
||
response = (<-this.V3PrivateGetBrokerageProducts(this.Extend(request, params)))
|
||
PanicOnError(response)
|
||
} else {
|
||
|
||
response = (<-this.V3PublicGetBrokerageMarketProducts(this.Extend(request, params)))
|
||
PanicOnError(response)
|
||
}
|
||
//
|
||
// {
|
||
// "products": [
|
||
// {
|
||
// "product_id": "TONE-USD",
|
||
// "price": "0.01523",
|
||
// "price_percentage_change_24h": "1.94109772423025",
|
||
// "volume_24h": "19773129",
|
||
// "volume_percentage_change_24h": "437.0170530929949",
|
||
// "base_increment": "1",
|
||
// "quote_increment": "0.00001",
|
||
// "quote_min_size": "1",
|
||
// "quote_max_size": "10000000",
|
||
// "base_min_size": "26.7187147229469674",
|
||
// "base_max_size": "267187147.2294696735908216",
|
||
// "base_name": "TE-FOOD",
|
||
// "quote_name": "US Dollar",
|
||
// "watched": false,
|
||
// "is_disabled": false,
|
||
// "new": false,
|
||
// "status": "online",
|
||
// "cancel_only": false,
|
||
// "limit_only": false,
|
||
// "post_only": false,
|
||
// "trading_disabled": false,
|
||
// "auction_mode": false,
|
||
// "product_type": "SPOT",
|
||
// "quote_currency_id": "USD",
|
||
// "base_currency_id": "TONE",
|
||
// "fcm_trading_session_details": null,
|
||
// "mid_market_price": ""
|
||
// },
|
||
// ...
|
||
// ],
|
||
// "num_products": 549
|
||
// }
|
||
//
|
||
var data interface{} = this.SafeList(response, "products", []interface{}{})
|
||
var result interface{} = map[string]interface{} {}
|
||
for i := 0; IsLessThan(i, GetArrayLength(data)); i++ {
|
||
var entry interface{} = GetValue(data, i)
|
||
var marketId interface{} = this.SafeString(entry, "product_id")
|
||
var market interface{} = this.SafeMarket(marketId, nil, "-")
|
||
var symbol interface{} = GetValue(market, "symbol")
|
||
AddElementToObject(result, symbol, this.ParseTicker(entry, market))
|
||
}
|
||
|
||
ch <- this.FilterByArrayTickers(result, "symbol", symbols)
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
/**
|
||
* @method
|
||
* @name coinbase#fetchTicker
|
||
* @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
||
* @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getmarkettrades
|
||
* @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-prices#get-spot-price
|
||
* @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-prices#get-buy-price
|
||
* @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-prices#get-sell-price
|
||
* @param {string} symbol unified symbol of the market to fetch the ticker for
|
||
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
* @param {boolean} [params.usePrivate] whether to use the private endpoint for fetching the ticker
|
||
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
||
*/
|
||
func (this *coinbase) FetchTicker(symbol interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
||
_ = params
|
||
var method interface{} = this.SafeString(this.Options, "fetchTicker", "fetchTickerV3")
|
||
if IsTrue(IsEqual(method, "fetchTickerV3")) {
|
||
|
||
retRes209719 := (<-this.FetchTickerV3(symbol, params))
|
||
PanicOnError(retRes209719)
|
||
ch <- retRes209719
|
||
return nil
|
||
}
|
||
|
||
retRes209915 := (<-this.FetchTickerV2(symbol, params))
|
||
PanicOnError(retRes209915)
|
||
ch <- retRes209915
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
func (this *coinbase) FetchTickerV2(symbol interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
||
_ = params
|
||
|
||
retRes21038 := (<-this.LoadMarkets())
|
||
PanicOnError(retRes21038)
|
||
var market interface{} = this.Market(symbol)
|
||
var request interface{} = this.Extend(map[string]interface{} {
|
||
"symbol": GetValue(market, "id"),
|
||
}, params)
|
||
|
||
spot:= (<-this.V2PublicGetPricesSymbolSpot(request))
|
||
PanicOnError(spot)
|
||
//
|
||
// {"data":{"base":"BTC","currency":"USD","amount":"48691.23"}}
|
||
//
|
||
|
||
ask:= (<-this.V2PublicGetPricesSymbolBuy(request))
|
||
PanicOnError(ask)
|
||
//
|
||
// {"data":{"base":"BTC","currency":"USD","amount":"48691.23"}}
|
||
//
|
||
|
||
bid:= (<-this.V2PublicGetPricesSymbolSell(request))
|
||
PanicOnError(bid)
|
||
//
|
||
// {"data":{"base":"BTC","currency":"USD","amount":"48691.23"}}
|
||
//
|
||
var spotData interface{} = this.SafeDict(spot, "data", map[string]interface{} {})
|
||
var askData interface{} = this.SafeDict(ask, "data", map[string]interface{} {})
|
||
var bidData interface{} = this.SafeDict(bid, "data", map[string]interface{} {})
|
||
var bidAskLast interface{} = map[string]interface{} {
|
||
"bid": this.SafeNumber(bidData, "amount"),
|
||
"ask": this.SafeNumber(askData, "amount"),
|
||
"price": this.SafeNumber(spotData, "amount"),
|
||
}
|
||
|
||
ch <- this.ParseTicker(bidAskLast, market)
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
func (this *coinbase) FetchTickerV3(symbol interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
||
_ = params
|
||
|
||
retRes21328 := (<-this.LoadMarkets())
|
||
PanicOnError(retRes21328)
|
||
var market interface{} = this.Market(symbol)
|
||
var request interface{} = map[string]interface{} {
|
||
"product_id": GetValue(market, "id"),
|
||
"limit": 1,
|
||
}
|
||
var usePrivate interface{} = false
|
||
usePrivateparamsVariable := this.HandleOptionAndParams(params, "fetchTicker", "usePrivate", false);
|
||
usePrivate = GetValue(usePrivateparamsVariable,0);
|
||
params = GetValue(usePrivateparamsVariable,1)
|
||
var response interface{} = nil
|
||
if IsTrue(usePrivate) {
|
||
|
||
response = (<-this.V3PrivateGetBrokerageProductsProductIdTicker(this.Extend(request, params)))
|
||
PanicOnError(response)
|
||
} else {
|
||
|
||
response = (<-this.V3PublicGetBrokerageMarketProductsProductIdTicker(this.Extend(request, params)))
|
||
PanicOnError(response)
|
||
}
|
||
//
|
||
// {
|
||
// "trades": [
|
||
// {
|
||
// "trade_id": "518078013",
|
||
// "product_id": "BTC-USD",
|
||
// "price": "28208.1",
|
||
// "size": "0.00659179",
|
||
// "time": "2023-04-04T23:05:34.492746Z",
|
||
// "side": "BUY",
|
||
// "bid": "",
|
||
// "ask": ""
|
||
// }
|
||
// ],
|
||
// "best_bid": "28208.61",
|
||
// "best_ask": "28208.62"
|
||
// }
|
||
//
|
||
var data interface{} = this.SafeList(response, "trades", []interface{}{})
|
||
var ticker interface{} = this.ParseTicker(GetValue(data, 0), market)
|
||
AddElementToObject(ticker, "bid", this.SafeNumber(response, "best_bid"))
|
||
AddElementToObject(ticker, "ask", this.SafeNumber(response, "best_ask"))
|
||
|
||
ch <- ticker
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
func (this *coinbase) ParseTicker(ticker interface{}, optionalArgs ...interface{}) interface{} {
|
||
//
|
||
// fetchTickerV2
|
||
//
|
||
// {
|
||
// "bid": 20713.37,
|
||
// "ask": 20924.65,
|
||
// "price": 20809.83
|
||
// }
|
||
//
|
||
// fetchTickerV3
|
||
//
|
||
// {
|
||
// "trade_id": "10209805",
|
||
// "product_id": "BTC-USDT",
|
||
// "price": "19381.27",
|
||
// "size": "0.1",
|
||
// "time": "2023-01-13T20:35:41.865970Z",
|
||
// "side": "BUY",
|
||
// "bid": "",
|
||
// "ask": ""
|
||
// }
|
||
//
|
||
// fetchTickersV2
|
||
//
|
||
// "48691.23"
|
||
//
|
||
// fetchTickersV3
|
||
//
|
||
// [
|
||
// {
|
||
// "product_id": "TONE-USD",
|
||
// "price": "0.01523",
|
||
// "price_percentage_change_24h": "1.94109772423025",
|
||
// "volume_24h": "19773129",
|
||
// "volume_percentage_change_24h": "437.0170530929949",
|
||
// "base_increment": "1",
|
||
// "quote_increment": "0.00001",
|
||
// "quote_min_size": "1",
|
||
// "quote_max_size": "10000000",
|
||
// "base_min_size": "26.7187147229469674",
|
||
// "base_max_size": "267187147.2294696735908216",
|
||
// "base_name": "TE-FOOD",
|
||
// "quote_name": "US Dollar",
|
||
// "watched": false,
|
||
// "is_disabled": false,
|
||
// "new": false,
|
||
// "status": "online",
|
||
// "cancel_only": false,
|
||
// "limit_only": false,
|
||
// "post_only": false,
|
||
// "trading_disabled": false,
|
||
// "auction_mode": false,
|
||
// "product_type": "SPOT",
|
||
// "quote_currency_id": "USD",
|
||
// "base_currency_id": "TONE",
|
||
// "fcm_trading_session_details": null,
|
||
// "mid_market_price": ""
|
||
// },
|
||
// ...
|
||
// ]
|
||
//
|
||
// fetchBidsAsks
|
||
//
|
||
// {
|
||
// "product_id": "TRAC-EUR",
|
||
// "bids": [
|
||
// {
|
||
// "price": "0.2384",
|
||
// "size": "386.1"
|
||
// }
|
||
// ],
|
||
// "asks": [
|
||
// {
|
||
// "price": "0.2406",
|
||
// "size": "672"
|
||
// }
|
||
// ],
|
||
// "time": "2023-06-30T07:15:24.656044Z"
|
||
// }
|
||
//
|
||
market := GetArg(optionalArgs, 0, nil)
|
||
_ = market
|
||
var bid interface{} = this.SafeNumber(ticker, "bid")
|
||
var ask interface{} = this.SafeNumber(ticker, "ask")
|
||
var bidVolume interface{} = nil
|
||
var askVolume interface{} = nil
|
||
if IsTrue((InOp(ticker, "bids"))) {
|
||
var bids interface{} = this.SafeList(ticker, "bids", []interface{}{})
|
||
var asks interface{} = this.SafeList(ticker, "asks", []interface{}{})
|
||
bid = this.SafeNumber(GetValue(bids, 0), "price")
|
||
bidVolume = this.SafeNumber(GetValue(bids, 0), "size")
|
||
ask = this.SafeNumber(GetValue(asks, 0), "price")
|
||
askVolume = this.SafeNumber(GetValue(asks, 0), "size")
|
||
}
|
||
var marketId interface{} = this.SafeString(ticker, "product_id")
|
||
var last interface{} = this.SafeNumber(ticker, "price")
|
||
var datetime interface{} = this.SafeString(ticker, "time")
|
||
return this.SafeTicker(map[string]interface{} {
|
||
"symbol": this.SafeSymbol(marketId, market),
|
||
"timestamp": this.Parse8601(datetime),
|
||
"datetime": datetime,
|
||
"bid": bid,
|
||
"ask": ask,
|
||
"last": last,
|
||
"high": nil,
|
||
"low": nil,
|
||
"bidVolume": bidVolume,
|
||
"askVolume": askVolume,
|
||
"vwap": nil,
|
||
"open": nil,
|
||
"close": last,
|
||
"previousClose": nil,
|
||
"change": nil,
|
||
"percentage": this.SafeNumber(ticker, "price_percentage_change_24h"),
|
||
"average": nil,
|
||
"baseVolume": nil,
|
||
"quoteVolume": nil,
|
||
"info": ticker,
|
||
}, market)
|
||
}
|
||
func (this *coinbase) ParseCustomBalance(response interface{}, optionalArgs ...interface{}) interface{} {
|
||
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
||
_ = params
|
||
var balances interface{} = this.SafeList2(response, "data", "accounts", []interface{}{})
|
||
var accounts interface{} = this.SafeList(params, "type", GetValue(this.Options, "accounts"))
|
||
var v3Accounts interface{} = this.SafeList(params, "type", GetValue(this.Options, "v3Accounts"))
|
||
var result interface{} = map[string]interface{} {
|
||
"info": response,
|
||
}
|
||
for b := 0; IsLessThan(b, GetArrayLength(balances)); b++ {
|
||
var balance interface{} = GetValue(balances, b)
|
||
var typeVar interface{} = this.SafeString(balance, "type")
|
||
if IsTrue(this.InArray(typeVar, accounts)) {
|
||
var value interface{} = this.SafeDict(balance, "balance")
|
||
if IsTrue(!IsEqual(value, nil)) {
|
||
var currencyId interface{} = this.SafeString(value, "currency")
|
||
var code interface{} = this.SafeCurrencyCode(currencyId)
|
||
var total interface{} = this.SafeString(value, "amount")
|
||
var free interface{} = total
|
||
var account interface{} = this.SafeDict(result, code)
|
||
if IsTrue(IsEqual(account, nil)) {
|
||
account = this.Account()
|
||
AddElementToObject(account, "free", free)
|
||
AddElementToObject(account, "total", total)
|
||
} else {
|
||
AddElementToObject(account, "free", Precise.StringAdd(GetValue(account, "free"), total))
|
||
AddElementToObject(account, "total", Precise.StringAdd(GetValue(account, "total"), total))
|
||
}
|
||
AddElementToObject(result, code, account)
|
||
}
|
||
} else if IsTrue(this.InArray(typeVar, v3Accounts)) {
|
||
var available interface{} = this.SafeDict(balance, "available_balance")
|
||
var hold interface{} = this.SafeDict(balance, "hold")
|
||
if IsTrue(IsTrue(!IsEqual(available, nil)) && IsTrue(!IsEqual(hold, nil))) {
|
||
var currencyId interface{} = this.SafeString(available, "currency")
|
||
var code interface{} = this.SafeCurrencyCode(currencyId)
|
||
var used interface{} = this.SafeString(hold, "value")
|
||
var free interface{} = this.SafeString(available, "value")
|
||
var total interface{} = Precise.StringAdd(used, free)
|
||
var account interface{} = this.SafeDict(result, code)
|
||
if IsTrue(IsEqual(account, nil)) {
|
||
account = this.Account()
|
||
AddElementToObject(account, "free", free)
|
||
AddElementToObject(account, "used", used)
|
||
AddElementToObject(account, "total", total)
|
||
} else {
|
||
AddElementToObject(account, "free", Precise.StringAdd(GetValue(account, "free"), free))
|
||
AddElementToObject(account, "used", Precise.StringAdd(GetValue(account, "used"), used))
|
||
AddElementToObject(account, "total", Precise.StringAdd(GetValue(account, "total"), total))
|
||
}
|
||
AddElementToObject(result, code, account)
|
||
}
|
||
}
|
||
}
|
||
return this.SafeBalance(result)
|
||
}
|
||
/**
|
||
* @method
|
||
* @name coinbase#fetchBalance
|
||
* @description query for balance and get the amount of funds available for trading or funds locked in orders
|
||
* @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getaccounts
|
||
* @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-accounts#list-accounts
|
||
* @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getfcmbalancesummary
|
||
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
* @param {boolean} [params.v3] default false, set true to use v3 api endpoint
|
||
* @param {string} [params.type] "spot" (default) or "swap" or "future"
|
||
* @param {int} [params.limit] default 250, maximum number of accounts to return
|
||
* @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
|
||
*/
|
||
func (this *coinbase) FetchBalance(optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
||
_ = params
|
||
|
||
retRes23588 := (<-this.LoadMarkets())
|
||
PanicOnError(retRes23588)
|
||
var request interface{} = map[string]interface{} {}
|
||
var response interface{} = nil
|
||
var isV3 interface{} = this.SafeBool(params, "v3", false)
|
||
params = this.Omit(params, []interface{}{"v3"})
|
||
var marketType interface{} = nil
|
||
marketTypeparamsVariable := this.HandleMarketTypeAndParams("fetchBalance", nil, params);
|
||
marketType = GetValue(marketTypeparamsVariable,0);
|
||
params = GetValue(marketTypeparamsVariable,1)
|
||
var method interface{} = this.SafeString(this.Options, "fetchBalance", "v3PrivateGetBrokerageAccounts")
|
||
if IsTrue(IsEqual(marketType, "future")) {
|
||
|
||
response = (<-this.V3PrivateGetBrokerageCfmBalanceSummary(this.Extend(request, params)))
|
||
PanicOnError(response)
|
||
} else if IsTrue(IsTrue((isV3)) || IsTrue((IsEqual(method, "v3PrivateGetBrokerageAccounts")))) {
|
||
AddElementToObject(request, "limit", 250)
|
||
|
||
response = (<-this.V3PrivateGetBrokerageAccounts(this.Extend(request, params)))
|
||
PanicOnError(response)
|
||
} else {
|
||
AddElementToObject(request, "limit", 250)
|
||
|
||
response = (<-this.V2PrivateGetAccounts(this.Extend(request, params)))
|
||
PanicOnError(response)
|
||
}
|
||
//
|
||
// v2PrivateGetAccounts
|
||
// {
|
||
// "pagination":{
|
||
// "ending_before":null,
|
||
// "starting_after":null,
|
||
// "previous_ending_before":null,
|
||
// "next_starting_after":"6b17acd6-2e68-5eb0-9f45-72d67cef578b",
|
||
// "limit":100,
|
||
// "order":"desc",
|
||
// "previous_uri":null,
|
||
// "next_uri":"/v2/accounts?limit=100\u0026starting_after=6b17acd6-2e68-5eb0-9f45-72d67cef578b"
|
||
// },
|
||
// "data":[
|
||
// {
|
||
// "id":"94ad58bc-0f15-5309-b35a-a4c86d7bad60",
|
||
// "name":"MINA Wallet",
|
||
// "primary":false,
|
||
// "type":"wallet",
|
||
// "currency":{
|
||
// "code":"MINA",
|
||
// "name":"Mina",
|
||
// "color":"#EA6B48",
|
||
// "sort_index":397,
|
||
// "exponent":9,
|
||
// "type":"crypto",
|
||
// "address_regex":"^(B62)[A-Za-z0-9]{52}$",
|
||
// "asset_id":"a4ffc575-942c-5e26-b70c-cb3befdd4229",
|
||
// "slug":"mina"
|
||
// },
|
||
// "balance":{"amount":"0.000000000","currency":"MINA"},
|
||
// "created_at":"2022-03-25T00:36:16Z",
|
||
// "updated_at":"2022-03-25T00:36:16Z",
|
||
// "resource":"account",
|
||
// "resource_path":"/v2/accounts/94ad58bc-0f15-5309-b35a-a4c86d7bad60",
|
||
// "allow_deposits":true,
|
||
// "allow_withdrawals":true
|
||
// },
|
||
// ]
|
||
// }
|
||
//
|
||
// v3PrivateGetBrokerageAccounts
|
||
// {
|
||
// "accounts": [
|
||
// {
|
||
// "uuid": "11111111-1111-1111-1111-111111111111",
|
||
// "name": "USDC Wallet",
|
||
// "currency": "USDC",
|
||
// "available_balance": {
|
||
// "value": "0.0000000000000000",
|
||
// "currency": "USDC"
|
||
// },
|
||
// "default": true,
|
||
// "active": true,
|
||
// "created_at": "2023-01-04T06:20:06.456Z",
|
||
// "updated_at": "2023-01-04T06:20:07.181Z",
|
||
// "deleted_at": null,
|
||
// "type": "ACCOUNT_TYPE_CRYPTO",
|
||
// "ready": false,
|
||
// "hold": {
|
||
// "value": "0.0000000000000000",
|
||
// "currency": "USDC"
|
||
// }
|
||
// },
|
||
// ...
|
||
// ],
|
||
// "has_next": false,
|
||
// "cursor": "",
|
||
// "size": 9
|
||
// }
|
||
//
|
||
AddElementToObject(params, "type", marketType)
|
||
|
||
ch <- this.ParseCustomBalance(response, params)
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
/**
|
||
* @method
|
||
* @name coinbase#fetchLedger
|
||
* @description Fetch the history of changes, i.e. actions done by the user or operations that altered the balance. Will return staking rewards, and crypto deposits or withdrawals.
|
||
* @see https://docs.cdp.coinbase.com/coinbase-app/docs/api-transactions#list-transactions
|
||
* @param {string} [code] unified currency code, default is undefined
|
||
* @param {int} [since] timestamp in ms of the earliest ledger entry, default is undefined
|
||
* @param {int} [limit] max number of ledger entries to return, default is undefined
|
||
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
* @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [available parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
|
||
* @returns {object} a [ledger structure]{@link https://docs.ccxt.com/#/?id=ledger}
|
||
*/
|
||
func (this *coinbase) FetchLedger(optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
code := GetArg(optionalArgs, 0, nil)
|
||
_ = code
|
||
since := GetArg(optionalArgs, 1, nil)
|
||
_ = since
|
||
limit := GetArg(optionalArgs, 2, nil)
|
||
_ = limit
|
||
params := GetArg(optionalArgs, 3, map[string]interface{} {})
|
||
_ = params
|
||
|
||
retRes24638 := (<-this.LoadMarkets())
|
||
PanicOnError(retRes24638)
|
||
var paginate interface{} = false
|
||
paginateparamsVariable := this.HandleOptionAndParams(params, "fetchLedger", "paginate");
|
||
paginate = GetValue(paginateparamsVariable,0);
|
||
params = GetValue(paginateparamsVariable,1)
|
||
if IsTrue(paginate) {
|
||
|
||
retRes246719 := (<-this.FetchPaginatedCallCursor("fetchLedger", code, since, limit, params, "next_starting_after", "starting_after", nil, 100))
|
||
PanicOnError(retRes246719)
|
||
ch <- retRes246719
|
||
return nil
|
||
}
|
||
var currency interface{} = nil
|
||
if IsTrue(!IsEqual(code, nil)) {
|
||
currency = this.Currency(code)
|
||
}
|
||
var request interface{} = nil
|
||
requestparamsVariable := (<-this.PrepareAccountRequestWithCurrencyCode(code, limit, params));
|
||
request = GetValue(requestparamsVariable,0);
|
||
params = GetValue(requestparamsVariable,1)
|
||
// for pagination use parameter 'starting_after'
|
||
// the value for the next page can be obtained from the result of the previous call in the 'pagination' field
|
||
// eg: instance.last_http_response -> pagination.next_starting_after
|
||
|
||
response:= (<-this.V2PrivateGetAccountsAccountIdTransactions(this.Extend(request, params)))
|
||
PanicOnError(response)
|
||
var ledger interface{} = this.ParseLedger(GetValue(response, "data"), currency, since, limit)
|
||
var length interface{} = GetArrayLength(ledger)
|
||
if IsTrue(IsEqual(length, 0)) {
|
||
|
||
ch <- ledger
|
||
return nil
|
||
}
|
||
var lastIndex interface{} = Subtract(length, 1)
|
||
var last interface{} = this.SafeDict(ledger, lastIndex)
|
||
var pagination interface{} = this.SafeDict(response, "pagination", map[string]interface{} {})
|
||
var cursor interface{} = this.SafeString(pagination, "next_starting_after")
|
||
if IsTrue(IsTrue((!IsEqual(cursor, nil))) && IsTrue((!IsEqual(cursor, "")))) {
|
||
AddElementToObject(GetValue(last, "info"), "next_starting_after", cursor)
|
||
AddElementToObject(ledger, lastIndex, last)
|
||
}
|
||
|
||
ch <- ledger
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
func (this *coinbase) ParseLedgerEntryStatus(status interface{}) interface{} {
|
||
var types interface{} = map[string]interface{} {
|
||
"completed": "ok",
|
||
}
|
||
return this.SafeString(types, status, status)
|
||
}
|
||
func (this *coinbase) ParseLedgerEntryType(typeVar interface{}) interface{} {
|
||
var types interface{} = map[string]interface{} {
|
||
"buy": "trade",
|
||
"sell": "trade",
|
||
"fiat_deposit": "transaction",
|
||
"fiat_withdrawal": "transaction",
|
||
"exchange_deposit": "transaction",
|
||
"exchange_withdrawal": "transaction",
|
||
"send": "transaction",
|
||
"pro_deposit": "transaction",
|
||
"pro_withdrawal": "transaction",
|
||
}
|
||
return this.SafeString(types, typeVar, typeVar)
|
||
}
|
||
func (this *coinbase) ParseLedgerEntry(item interface{}, optionalArgs ...interface{}) interface{} {
|
||
//
|
||
// crypto deposit transaction
|
||
//
|
||
// {
|
||
// "id": "34e4816b-4c8c-5323-a01c-35a9fa26e490",
|
||
// "type": "send",
|
||
// "status": "completed",
|
||
// "amount": { amount: "28.31976528", currency: "BCH" },
|
||
// "native_amount": { amount: "2799.65", currency: "GBP" },
|
||
// "description": null,
|
||
// "created_at": "2019-02-28T12:35:20Z",
|
||
// "updated_at": "2019-02-28T12:43:24Z",
|
||
// "resource": "transaction",
|
||
// "resource_path": "/v2/accounts/c01d7364-edd7-5f3a-bd1d-de53d4cbb25e/transactions/34e4816b-4c8c-5323-a01c-35a9fa26e490",
|
||
// "instant_exchange": false,
|
||
// "network": {
|
||
// "status": "confirmed",
|
||
// "hash": "56222d865dae83774fccb2efbd9829cf08c75c94ce135bfe4276f3fb46d49701",
|
||
// "transaction_url": "https://bch.btc.com/56222d865dae83774fccb2efbd9829cf08c75c94ce135bfe4276f3fb46d49701"
|
||
// },
|
||
// "from": { resource: "bitcoin_cash_network", currency: "BCH" },
|
||
// "details": { title: 'Received Bitcoin Cash', subtitle: "From Bitcoin Cash address" }
|
||
// }
|
||
//
|
||
// crypto withdrawal transaction
|
||
//
|
||
// {
|
||
// "id": "459aad99-2c41-5698-ac71-b6b81a05196c",
|
||
// "type": "send",
|
||
// "status": "completed",
|
||
// "amount": { amount: "-0.36775642", currency: "BTC" },
|
||
// "native_amount": { amount: "-1111.65", currency: "GBP" },
|
||
// "description": null,
|
||
// "created_at": "2019-03-20T08:37:07Z",
|
||
// "updated_at": "2019-03-20T08:49:33Z",
|
||
// "resource": "transaction",
|
||
// "resource_path": "/v2/accounts/c6afbd34-4bd0-501e-8616-4862c193cd84/transactions/459aad99-2c41-5698-ac71-b6b81a05196c",
|
||
// "instant_exchange": false,
|
||
// "network": {
|
||
// "status": "confirmed",
|
||
// "hash": "2732bbcf35c69217c47b36dce64933d103895277fe25738ffb9284092701e05b",
|
||
// "transaction_url": "https://blockchain.info/tx/2732bbcf35c69217c47b36dce64933d103895277fe25738ffb9284092701e05b",
|
||
// "transaction_fee": { amount: "0.00000000", currency: "BTC" },
|
||
// "transaction_amount": { amount: "0.36775642", currency: "BTC" },
|
||
// "confirmations": 15682
|
||
// },
|
||
// "to": {
|
||
// "resource": "bitcoin_address",
|
||
// "address": "1AHnhqbvbYx3rnZx8uC7NbFZaTe4tafFHX",
|
||
// "currency": "BTC",
|
||
// "address_info": { address: "1AHnhqbvbYx3rnZx8uC7NbFZaTe4tafFHX" }
|
||
// },
|
||
// "idem": "da0a2f14-a2af-4c5a-a37e-d4484caf582bsend",
|
||
// "application": {
|
||
// "id": "5756ab6e-836b-553b-8950-5e389451225d",
|
||
// "resource": "application",
|
||
// "resource_path": "/v2/applications/5756ab6e-836b-553b-8950-5e389451225d"
|
||
// },
|
||
// "details": { title: 'Sent Bitcoin', subtitle: "To Bitcoin address" }
|
||
// }
|
||
//
|
||
// withdrawal transaction from coinbase to coinbasepro
|
||
//
|
||
// {
|
||
// "id": "5b1b9fb8-5007-5393-b923-02903b973fdc",
|
||
// "type": "pro_deposit",
|
||
// "status": "completed",
|
||
// "amount": { amount: "-0.00001111", currency: "BCH" },
|
||
// "native_amount": { amount: "0.00", currency: "GBP" },
|
||
// "description": null,
|
||
// "created_at": "2019-02-28T13:31:58Z",
|
||
// "updated_at": "2019-02-28T13:31:58Z",
|
||
// "resource": "transaction",
|
||
// "resource_path": "/v2/accounts/c01d7364-edd7-5f3a-bd1d-de53d4cbb25e/transactions/5b1b9fb8-5007-5393-b923-02903b973fdc",
|
||
// "instant_exchange": false,
|
||
// "application": {
|
||
// "id": "5756ab6e-836b-553b-8950-5e389451225d",
|
||
// "resource": "application",
|
||
// "resource_path": "/v2/applications/5756ab6e-836b-553b-8950-5e389451225d"
|
||
// },
|
||
// "details": { title: 'Transferred Bitcoin Cash', subtitle: "To Coinbase Pro" }
|
||
// }
|
||
//
|
||
// withdrawal transaction from coinbase to gdax
|
||
//
|
||
// {
|
||
// "id": "badb7313-a9d3-5c07-abd0-00f8b44199b1",
|
||
// "type": "exchange_deposit",
|
||
// "status": "completed",
|
||
// "amount": { amount: "-0.43704149", currency: "BCH" },
|
||
// "native_amount": { amount: "-51.90", currency: "GBP" },
|
||
// "description": null,
|
||
// "created_at": "2019-03-19T10:30:40Z",
|
||
// "updated_at": "2019-03-19T10:30:40Z",
|
||
// "resource": "transaction",
|
||
// "resource_path": "/v2/accounts/c01d7364-edd7-5f3a-bd1d-de53d4cbb25e/transactions/badb7313-a9d3-5c07-abd0-00f8b44199b1",
|
||
// "instant_exchange": false,
|
||
// "details": { title: 'Transferred Bitcoin Cash', subtitle: "To GDAX" }
|
||
// }
|
||
//
|
||
// deposit transaction from gdax to coinbase
|
||
//
|
||
// {
|
||
// "id": "9c4b642c-8688-58bf-8962-13cef64097de",
|
||
// "type": "exchange_withdrawal",
|
||
// "status": "completed",
|
||
// "amount": { amount: "0.57729420", currency: "BTC" },
|
||
// "native_amount": { amount: "4418.72", currency: "GBP" },
|
||
// "description": null,
|
||
// "created_at": "2018-02-17T11:33:33Z",
|
||
// "updated_at": "2018-02-17T11:33:33Z",
|
||
// "resource": "transaction",
|
||
// "resource_path": "/v2/accounts/c6afbd34-4bd0-501e-8616-4862c193cd84/transactions/9c4b642c-8688-58bf-8962-13cef64097de",
|
||
// "instant_exchange": false,
|
||
// "details": { title: 'Transferred Bitcoin', subtitle: "From GDAX" }
|
||
// }
|
||
//
|
||
// deposit transaction from coinbasepro to coinbase
|
||
//
|
||
// {
|
||
// "id": "8d6dd0b9-3416-568a-889d-8f112fae9e81",
|
||
// "type": "pro_withdrawal",
|
||
// "status": "completed",
|
||
// "amount": { amount: "0.40555386", currency: "BTC" },
|
||
// "native_amount": { amount: "1140.27", currency: "GBP" },
|
||
// "description": null,
|
||
// "created_at": "2019-03-04T19:41:58Z",
|
||
// "updated_at": "2019-03-04T19:41:58Z",
|
||
// "resource": "transaction",
|
||
// "resource_path": "/v2/accounts/c6afbd34-4bd0-501e-8616-4862c193cd84/transactions/8d6dd0b9-3416-568a-889d-8f112fae9e81",
|
||
// "instant_exchange": false,
|
||
// "application": {
|
||
// "id": "5756ab6e-836b-553b-8950-5e389451225d",
|
||
// "resource": "application",
|
||
// "resource_path": "/v2/applications/5756ab6e-836b-553b-8950-5e389451225d"
|
||
// },
|
||
// "details": { title: 'Transferred Bitcoin', subtitle: "From Coinbase Pro" }
|
||
// }
|
||
//
|
||
// sell trade
|
||
//
|
||
// {
|
||
// "id": "a9409207-df64-585b-97ab-a50780d2149e",
|
||
// "type": "sell",
|
||
// "status": "completed",
|
||
// "amount": { amount: "-9.09922880", currency: "BTC" },
|
||
// "native_amount": { amount: "-7285.73", currency: "GBP" },
|
||
// "description": null,
|
||
// "created_at": "2017-03-27T15:38:34Z",
|
||
// "updated_at": "2017-03-27T15:38:34Z",
|
||
// "resource": "transaction",
|
||
// "resource_path": "/v2/accounts/c6afbd34-4bd0-501e-8616-4862c193cd84/transactions/a9409207-df64-585b-97ab-a50780d2149e",
|
||
// "instant_exchange": false,
|
||
// "sell": {
|
||
// "id": "e3550b4d-8ae6-5de3-95fe-1fb01ba83051",
|
||
// "resource": "sell",
|
||
// "resource_path": "/v2/accounts/c6afbd34-4bd0-501e-8616-4862c193cd84/sells/e3550b4d-8ae6-5de3-95fe-1fb01ba83051"
|
||
// },
|
||
// "details": {
|
||
// "title": "Sold Bitcoin",
|
||
// "subtitle": "Using EUR Wallet",
|
||
// "payment_method_name": "EUR Wallet"
|
||
// }
|
||
// }
|
||
//
|
||
// buy trade
|
||
//
|
||
// {
|
||
// "id": "63eeed67-9396-5912-86e9-73c4f10fe147",
|
||
// "type": "buy",
|
||
// "status": "completed",
|
||
// "amount": { amount: "2.39605772", currency: "ETH" },
|
||
// "native_amount": { amount: "98.31", currency: "GBP" },
|
||
// "description": null,
|
||
// "created_at": "2017-03-27T09:07:56Z",
|
||
// "updated_at": "2017-03-27T09:07:57Z",
|
||
// "resource": "transaction",
|
||
// "resource_path": "/v2/accounts/8902f85d-4a69-5d74-82fe-8e390201bda7/transactions/63eeed67-9396-5912-86e9-73c4f10fe147",
|
||
// "instant_exchange": false,
|
||
// "buy": {
|
||
// "id": "20b25b36-76c6-5353-aa57-b06a29a39d82",
|
||
// "resource": "buy",
|
||
// "resource_path": "/v2/accounts/8902f85d-4a69-5d74-82fe-8e390201bda7/buys/20b25b36-76c6-5353-aa57-b06a29a39d82"
|
||
// },
|
||
// "details": {
|
||
// "title": "Bought Ethereum",
|
||
// "subtitle": "Using EUR Wallet",
|
||
// "payment_method_name": "EUR Wallet"
|
||
// }
|
||
// }
|
||
//
|
||
// fiat deposit transaction
|
||
//
|
||
// {
|
||
// "id": "04ed4113-3732-5b0c-af86-b1d2146977d0",
|
||
// "type": "fiat_deposit",
|
||
// "status": "completed",
|
||
// "amount": { amount: "114.02", currency: "EUR" },
|
||
// "native_amount": { amount: "97.23", currency: "GBP" },
|
||
// "description": null,
|
||
// "created_at": "2017-02-09T07:01:21Z",
|
||
// "updated_at": "2017-02-09T07:01:22Z",
|
||
// "resource": "transaction",
|
||
// "resource_path": "/v2/accounts/91cd2d36-3a91-55b6-a5d4-0124cf105483/transactions/04ed4113-3732-5b0c-af86-b1d2146977d0",
|
||
// "instant_exchange": false,
|
||
// "fiat_deposit": {
|
||
// "id": "f34c19f3-b730-5e3d-9f72-96520448677a",
|
||
// "resource": "fiat_deposit",
|
||
// "resource_path": "/v2/accounts/91cd2d36-3a91-55b6-a5d4-0124cf105483/deposits/f34c19f3-b730-5e3d-9f72-96520448677a"
|
||
// },
|
||
// "details": {
|
||
// "title": "Deposited funds",
|
||
// "subtitle": "From SEPA Transfer (GB47 BARC 20..., reference CBADVI)",
|
||
// "payment_method_name": "SEPA Transfer (GB47 BARC 20..., reference CBADVI)"
|
||
// }
|
||
// }
|
||
//
|
||
// fiat withdrawal transaction
|
||
//
|
||
// {
|
||
// "id": "957d98e2-f80e-5e2f-a28e-02945aa93079",
|
||
// "type": "fiat_withdrawal",
|
||
// "status": "completed",
|
||
// "amount": { amount: "-11000.00", currency: "EUR" },
|
||
// "native_amount": { amount: "-9698.22", currency: "GBP" },
|
||
// "description": null,
|
||
// "created_at": "2017-12-06T13:19:19Z",
|
||
// "updated_at": "2017-12-06T13:19:19Z",
|
||
// "resource": "transaction",
|
||
// "resource_path": "/v2/accounts/91cd2d36-3a91-55b6-a5d4-0124cf105483/transactions/957d98e2-f80e-5e2f-a28e-02945aa93079",
|
||
// "instant_exchange": false,
|
||
// "fiat_withdrawal": {
|
||
// "id": "f4bf1fd9-ab3b-5de7-906d-ed3e23f7a4e7",
|
||
// "resource": "fiat_withdrawal",
|
||
// "resource_path": "/v2/accounts/91cd2d36-3a91-55b6-a5d4-0124cf105483/withdrawals/f4bf1fd9-ab3b-5de7-906d-ed3e23f7a4e7"
|
||
// },
|
||
// "details": {
|
||
// "title": "Withdrew funds",
|
||
// "subtitle": "To HSBC BANK PLC (GB74 MIDL...)",
|
||
// "payment_method_name": "HSBC BANK PLC (GB74 MIDL...)"
|
||
// }
|
||
// }
|
||
//
|
||
currency := GetArg(optionalArgs, 0, nil)
|
||
_ = currency
|
||
var amountInfo interface{} = this.SafeDict(item, "amount", map[string]interface{} {})
|
||
var amount interface{} = this.SafeString(amountInfo, "amount")
|
||
var direction interface{} = nil
|
||
if IsTrue(Precise.StringLt(amount, "0")) {
|
||
direction = "out"
|
||
amount = Precise.StringNeg(amount)
|
||
} else {
|
||
direction = "in"
|
||
}
|
||
var currencyId interface{} = this.SafeString(amountInfo, "currency")
|
||
var code interface{} = this.SafeCurrencyCode(currencyId, currency)
|
||
currency = this.SafeCurrency(currencyId, currency)
|
||
//
|
||
// the address and txid do not belong to the unified ledger structure
|
||
//
|
||
// let address = undefined;
|
||
// if (item['to']) {
|
||
// address = this.safeString (item['to'], 'address');
|
||
// }
|
||
// let txid = undefined;
|
||
//
|
||
var fee interface{} = nil
|
||
var networkInfo interface{} = this.SafeDict(item, "network", map[string]interface{} {})
|
||
// txid = network['hash']; // txid does not belong to the unified ledger structure
|
||
var feeInfo interface{} = this.SafeDict(networkInfo, "transaction_fee")
|
||
if IsTrue(!IsEqual(feeInfo, nil)) {
|
||
var feeCurrencyId interface{} = this.SafeString(feeInfo, "currency")
|
||
var feeCurrencyCode interface{} = this.SafeCurrencyCode(feeCurrencyId, currency)
|
||
var feeAmount interface{} = this.SafeNumber(feeInfo, "amount")
|
||
fee = map[string]interface{} {
|
||
"cost": feeAmount,
|
||
"currency": feeCurrencyCode,
|
||
}
|
||
}
|
||
var timestamp interface{} = this.Parse8601(this.SafeString(item, "created_at"))
|
||
var id interface{} = this.SafeString(item, "id")
|
||
var typeVar interface{} = this.ParseLedgerEntryType(this.SafeString(item, "type"))
|
||
var status interface{} = this.ParseLedgerEntryStatus(this.SafeString(item, "status"))
|
||
var path interface{} = this.SafeString(item, "resource_path")
|
||
var accountId interface{} = nil
|
||
if IsTrue(!IsEqual(path, nil)) {
|
||
var parts interface{} = Split(path, "/")
|
||
var numParts interface{} = GetArrayLength(parts)
|
||
if IsTrue(IsGreaterThan(numParts, 3)) {
|
||
accountId = GetValue(parts, 3)
|
||
}
|
||
}
|
||
return this.SafeLedgerEntry(map[string]interface{} {
|
||
"info": item,
|
||
"id": id,
|
||
"timestamp": timestamp,
|
||
"datetime": this.Iso8601(timestamp),
|
||
"direction": direction,
|
||
"account": accountId,
|
||
"referenceId": nil,
|
||
"referenceAccount": nil,
|
||
"type": typeVar,
|
||
"currency": code,
|
||
"amount": this.ParseNumber(amount),
|
||
"before": nil,
|
||
"after": nil,
|
||
"status": status,
|
||
"fee": fee,
|
||
}, currency)
|
||
}
|
||
func (this *coinbase) FindAccountId(code interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
||
_ = params
|
||
|
||
retRes28288 := (<-this.LoadMarkets())
|
||
PanicOnError(retRes28288)
|
||
|
||
retRes28298 := (<-this.LoadAccounts(false, params))
|
||
PanicOnError(retRes28298)
|
||
for i := 0; IsLessThan(i, GetArrayLength(this.Accounts)); i++ {
|
||
var account interface{} = GetValue(this.Accounts, i)
|
||
if IsTrue(IsEqual(GetValue(account, "code"), code)) {
|
||
|
||
ch <- GetValue(account, "id")
|
||
return nil
|
||
}
|
||
}
|
||
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
func (this *coinbase) PrepareAccountRequest(optionalArgs ...interface{}) interface{} {
|
||
limit := GetArg(optionalArgs, 0, nil)
|
||
_ = limit
|
||
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
||
_ = params
|
||
var accountId interface{} = this.SafeString2(params, "account_id", "accountId")
|
||
if IsTrue(IsEqual(accountId, nil)) {
|
||
panic(ArgumentsRequired(Add(this.Id, " prepareAccountRequest() method requires an account_id (or accountId) parameter")))
|
||
}
|
||
var request interface{} = map[string]interface{} {
|
||
"account_id": accountId,
|
||
}
|
||
if IsTrue(!IsEqual(limit, nil)) {
|
||
AddElementToObject(request, "limit", limit)
|
||
}
|
||
return request
|
||
}
|
||
func (this *coinbase) PrepareAccountRequestWithCurrencyCode(optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
code := GetArg(optionalArgs, 0, nil)
|
||
_ = code
|
||
limit := GetArg(optionalArgs, 1, nil)
|
||
_ = limit
|
||
params := GetArg(optionalArgs, 2, map[string]interface{} {})
|
||
_ = params
|
||
var accountId interface{} = this.SafeString2(params, "account_id", "accountId")
|
||
params = this.Omit(params, []interface{}{"account_id", "accountId"})
|
||
if IsTrue(IsEqual(accountId, nil)) {
|
||
if IsTrue(IsEqual(code, nil)) {
|
||
panic(ArgumentsRequired(Add(this.Id, " prepareAccountRequestWithCurrencyCode() method requires an account_id (or accountId) parameter OR a currency code argument")))
|
||
}
|
||
|
||
accountId = (<-this.FindAccountId(code, params))
|
||
PanicOnError(accountId)
|
||
if IsTrue(IsEqual(accountId, nil)) {
|
||
panic(ExchangeError(Add(Add(this.Id, " prepareAccountRequestWithCurrencyCode() could not find account id for "), code)))
|
||
}
|
||
}
|
||
var request interface{} = map[string]interface{} {
|
||
"account_id": accountId,
|
||
}
|
||
if IsTrue(!IsEqual(limit, nil)) {
|
||
AddElementToObject(request, "limit", limit)
|
||
}
|
||
|
||
ch <- []interface{}{request, params}
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
/**
|
||
* @method
|
||
* @name coinbase#createMarketBuyOrderWithCost
|
||
* @description create a market buy order by providing the symbol and cost
|
||
* @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_postorder
|
||
* @param {string} symbol unified symbol of the market to create an order in
|
||
* @param {float} cost how much you want to trade in units of the quote currency
|
||
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
||
*/
|
||
func (this *coinbase) CreateMarketBuyOrderWithCost(symbol interface{}, cost interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
||
_ = params
|
||
|
||
retRes28858 := (<-this.LoadMarkets())
|
||
PanicOnError(retRes28858)
|
||
var market interface{} = this.Market(symbol)
|
||
if !IsTrue(GetValue(market, "spot")) {
|
||
panic(NotSupported(Add(this.Id, " createMarketBuyOrderWithCost() supports spot orders only")))
|
||
}
|
||
AddElementToObject(params, "createMarketBuyOrderRequiresPrice", false)
|
||
|
||
retRes289115 := (<-this.CreateOrder(symbol, "market", "buy", cost, nil, params))
|
||
PanicOnError(retRes289115)
|
||
ch <- retRes289115
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
/**
|
||
* @method
|
||
* @name coinbase#createOrder
|
||
* @description create a trade order
|
||
* @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_postorder
|
||
* @param {string} symbol unified symbol of the market to create an order in
|
||
* @param {string} type 'market' or 'limit'
|
||
* @param {string} side 'buy' or 'sell'
|
||
* @param {float} amount how much you want to trade in units of the base currency, quote currency for 'market' 'buy' orders
|
||
* @param {float} [price] the price to fulfill the order, in units of the quote currency, ignored in market orders
|
||
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
* @param {float} [params.stopPrice] price to trigger stop orders
|
||
* @param {float} [params.triggerPrice] price to trigger stop orders
|
||
* @param {float} [params.stopLossPrice] price to trigger stop-loss orders
|
||
* @param {float} [params.takeProfitPrice] price to trigger take-profit orders
|
||
* @param {bool} [params.postOnly] true or false
|
||
* @param {string} [params.timeInForce] 'GTC', 'IOC', 'GTD' or 'PO', 'FOK'
|
||
* @param {string} [params.stop_direction] 'UNKNOWN_STOP_DIRECTION', 'STOP_DIRECTION_STOP_UP', 'STOP_DIRECTION_STOP_DOWN' the direction the stopPrice is triggered from
|
||
* @param {string} [params.end_time] '2023-05-25T17:01:05.092Z' for 'GTD' orders
|
||
* @param {float} [params.cost] *spot market buy only* the quote quantity that can be used as an alternative for the amount
|
||
* @param {boolean} [params.preview] default to false, wether to use the test/preview endpoint or not
|
||
* @param {float} [params.leverage] default to 1, the leverage to use for the order
|
||
* @param {string} [params.marginMode] 'cross' or 'isolated'
|
||
* @param {string} [params.retail_portfolio_id] portfolio uid
|
||
* @param {boolean} [params.is_max] Used in conjunction with tradable_balance to indicate the user wants to use their entire tradable balance
|
||
* @param {string} [params.tradable_balance] amount of tradable balance
|
||
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
||
*/
|
||
func (this *coinbase) CreateOrder(symbol interface{}, typeVar interface{}, side interface{}, amount interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
price := GetArg(optionalArgs, 0, nil)
|
||
_ = price
|
||
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
||
_ = params
|
||
|
||
retRes29238 := (<-this.LoadMarkets())
|
||
PanicOnError(retRes29238)
|
||
var market interface{} = this.Market(symbol)
|
||
var id interface{} = this.SafeString(this.Options, "brokerId", "ccxt")
|
||
var request interface{} = map[string]interface{} {
|
||
"client_order_id": Add(Add(id, "-"), this.Uuid()),
|
||
"product_id": GetValue(market, "id"),
|
||
"side": ToUpper(side),
|
||
}
|
||
var triggerPrice interface{} = this.SafeNumberN(params, []interface{}{"stopPrice", "stop_price", "triggerPrice"})
|
||
var stopLossPrice interface{} = this.SafeNumber(params, "stopLossPrice")
|
||
var takeProfitPrice interface{} = this.SafeNumber(params, "takeProfitPrice")
|
||
var isStop interface{} = !IsEqual(triggerPrice, nil)
|
||
var isStopLoss interface{} = !IsEqual(stopLossPrice, nil)
|
||
var isTakeProfit interface{} = !IsEqual(takeProfitPrice, nil)
|
||
var timeInForce interface{} = this.SafeString(params, "timeInForce")
|
||
var postOnly interface{} = Ternary(IsTrue((IsEqual(timeInForce, "PO"))), true, this.SafeBool2(params, "postOnly", "post_only", false))
|
||
var endTime interface{} = this.SafeString(params, "end_time")
|
||
var stopDirection interface{} = this.SafeString(params, "stop_direction")
|
||
if IsTrue(IsEqual(typeVar, "limit")) {
|
||
if IsTrue(isStop) {
|
||
if IsTrue(IsEqual(stopDirection, nil)) {
|
||
stopDirection = Ternary(IsTrue((IsEqual(side, "buy"))), "STOP_DIRECTION_STOP_DOWN", "STOP_DIRECTION_STOP_UP")
|
||
}
|
||
if IsTrue(IsTrue((IsEqual(timeInForce, "GTD"))) || IsTrue((!IsEqual(endTime, nil)))) {
|
||
if IsTrue(IsEqual(endTime, nil)) {
|
||
panic(ExchangeError(Add(this.Id, " createOrder() requires an end_time parameter for a GTD order")))
|
||
}
|
||
AddElementToObject(request, "order_configuration", map[string]interface{} {
|
||
"stop_limit_stop_limit_gtd": map[string]interface{} {
|
||
"base_size": this.AmountToPrecision(symbol, amount),
|
||
"limit_price": this.PriceToPrecision(symbol, price),
|
||
"stop_price": this.PriceToPrecision(symbol, triggerPrice),
|
||
"stop_direction": stopDirection,
|
||
"end_time": endTime,
|
||
},
|
||
})
|
||
} else {
|
||
AddElementToObject(request, "order_configuration", map[string]interface{} {
|
||
"stop_limit_stop_limit_gtc": map[string]interface{} {
|
||
"base_size": this.AmountToPrecision(symbol, amount),
|
||
"limit_price": this.PriceToPrecision(symbol, price),
|
||
"stop_price": this.PriceToPrecision(symbol, triggerPrice),
|
||
"stop_direction": stopDirection,
|
||
},
|
||
})
|
||
}
|
||
} else if IsTrue(IsTrue(isStopLoss) || IsTrue(isTakeProfit)) {
|
||
var tpslPrice interface{} = nil
|
||
if IsTrue(isStopLoss) {
|
||
if IsTrue(IsEqual(stopDirection, nil)) {
|
||
stopDirection = Ternary(IsTrue((IsEqual(side, "buy"))), "STOP_DIRECTION_STOP_UP", "STOP_DIRECTION_STOP_DOWN")
|
||
}
|
||
tpslPrice = this.PriceToPrecision(symbol, stopLossPrice)
|
||
} else {
|
||
if IsTrue(IsEqual(stopDirection, nil)) {
|
||
stopDirection = Ternary(IsTrue((IsEqual(side, "buy"))), "STOP_DIRECTION_STOP_DOWN", "STOP_DIRECTION_STOP_UP")
|
||
}
|
||
tpslPrice = this.PriceToPrecision(symbol, takeProfitPrice)
|
||
}
|
||
AddElementToObject(request, "order_configuration", map[string]interface{} {
|
||
"stop_limit_stop_limit_gtc": map[string]interface{} {
|
||
"base_size": this.AmountToPrecision(symbol, amount),
|
||
"limit_price": this.PriceToPrecision(symbol, price),
|
||
"stop_price": tpslPrice,
|
||
"stop_direction": stopDirection,
|
||
},
|
||
})
|
||
} else {
|
||
if IsTrue(IsTrue((IsEqual(timeInForce, "GTD"))) || IsTrue((!IsEqual(endTime, nil)))) {
|
||
if IsTrue(IsEqual(endTime, nil)) {
|
||
panic(ExchangeError(Add(this.Id, " createOrder() requires an end_time parameter for a GTD order")))
|
||
}
|
||
AddElementToObject(request, "order_configuration", map[string]interface{} {
|
||
"limit_limit_gtd": map[string]interface{} {
|
||
"base_size": this.AmountToPrecision(symbol, amount),
|
||
"limit_price": this.PriceToPrecision(symbol, price),
|
||
"end_time": endTime,
|
||
"post_only": postOnly,
|
||
},
|
||
})
|
||
} else if IsTrue(IsEqual(timeInForce, "IOC")) {
|
||
AddElementToObject(request, "order_configuration", map[string]interface{} {
|
||
"sor_limit_ioc": map[string]interface{} {
|
||
"base_size": this.AmountToPrecision(symbol, amount),
|
||
"limit_price": this.PriceToPrecision(symbol, price),
|
||
},
|
||
})
|
||
} else if IsTrue(IsEqual(timeInForce, "FOK")) {
|
||
AddElementToObject(request, "order_configuration", map[string]interface{} {
|
||
"limit_limit_fok": map[string]interface{} {
|
||
"base_size": this.AmountToPrecision(symbol, amount),
|
||
"limit_price": this.PriceToPrecision(symbol, price),
|
||
},
|
||
})
|
||
} else {
|
||
AddElementToObject(request, "order_configuration", map[string]interface{} {
|
||
"limit_limit_gtc": map[string]interface{} {
|
||
"base_size": this.AmountToPrecision(symbol, amount),
|
||
"limit_price": this.PriceToPrecision(symbol, price),
|
||
"post_only": postOnly,
|
||
},
|
||
})
|
||
}
|
||
}
|
||
} else {
|
||
if IsTrue(IsTrue(IsTrue(isStop) || IsTrue(isStopLoss)) || IsTrue(isTakeProfit)) {
|
||
panic(NotSupported(Add(this.Id, " createOrder() only stop limit orders are supported")))
|
||
}
|
||
if IsTrue(IsTrue(GetValue(market, "spot")) && IsTrue((IsEqual(side, "buy")))) {
|
||
var total interface{} = nil
|
||
var createMarketBuyOrderRequiresPrice interface{} = true
|
||
createMarketBuyOrderRequiresPriceparamsVariable := this.HandleOptionAndParams(params, "createOrder", "createMarketBuyOrderRequiresPrice", true);
|
||
createMarketBuyOrderRequiresPrice = GetValue(createMarketBuyOrderRequiresPriceparamsVariable,0);
|
||
params = GetValue(createMarketBuyOrderRequiresPriceparamsVariable,1)
|
||
var cost interface{} = this.SafeNumber(params, "cost")
|
||
params = this.Omit(params, "cost")
|
||
if IsTrue(!IsEqual(cost, nil)) {
|
||
total = this.CostToPrecision(symbol, cost)
|
||
} else if IsTrue(createMarketBuyOrderRequiresPrice) {
|
||
if IsTrue(IsEqual(price, nil)) {
|
||
panic(InvalidOrder(Add(this.Id, " createOrder() requires a price argument for market buy orders on spot markets to calculate the total amount to spend (amount * price), alternatively set the createMarketBuyOrderRequiresPrice option or param to false and pass the cost to spend in the amount argument")))
|
||
} else {
|
||
var amountString interface{} = this.NumberToString(amount)
|
||
var priceString interface{} = this.NumberToString(price)
|
||
var costRequest interface{} = Precise.StringMul(amountString, priceString)
|
||
total = this.CostToPrecision(symbol, costRequest)
|
||
}
|
||
} else {
|
||
total = this.CostToPrecision(symbol, amount)
|
||
}
|
||
AddElementToObject(request, "order_configuration", map[string]interface{} {
|
||
"market_market_ioc": map[string]interface{} {
|
||
"quote_size": total,
|
||
},
|
||
})
|
||
} else {
|
||
AddElementToObject(request, "order_configuration", map[string]interface{} {
|
||
"market_market_ioc": map[string]interface{} {
|
||
"base_size": this.AmountToPrecision(symbol, amount),
|
||
},
|
||
})
|
||
}
|
||
}
|
||
var marginMode interface{} = this.SafeString(params, "marginMode")
|
||
if IsTrue(!IsEqual(marginMode, nil)) {
|
||
if IsTrue(IsEqual(marginMode, "isolated")) {
|
||
AddElementToObject(request, "margin_type", "ISOLATED")
|
||
} else if IsTrue(IsEqual(marginMode, "cross")) {
|
||
AddElementToObject(request, "margin_type", "CROSS")
|
||
}
|
||
}
|
||
params = this.Omit(params, []interface{}{"timeInForce", "triggerPrice", "stopLossPrice", "takeProfitPrice", "stopPrice", "stop_price", "stopDirection", "stop_direction", "clientOrderId", "postOnly", "post_only", "end_time", "marginMode"})
|
||
var preview interface{} = this.SafeBool2(params, "preview", "test", false)
|
||
var response interface{} = nil
|
||
if IsTrue(preview) {
|
||
params = this.Omit(params, []interface{}{"preview", "test"})
|
||
request = this.Omit(request, "client_order_id")
|
||
|
||
response = (<-this.V3PrivatePostBrokerageOrdersPreview(this.Extend(request, params)))
|
||
PanicOnError(response)
|
||
} else {
|
||
|
||
response = (<-this.V3PrivatePostBrokerageOrders(this.Extend(request, params)))
|
||
PanicOnError(response)
|
||
}
|
||
//
|
||
// successful order
|
||
//
|
||
// {
|
||
// "success": true,
|
||
// "failure_reason": "UNKNOWN_FAILURE_REASON",
|
||
// "order_id": "52cfe5e2-0b29-4c19-a245-a6a773de5030",
|
||
// "success_response": {
|
||
// "order_id": "52cfe5e2-0b29-4c19-a245-a6a773de5030",
|
||
// "product_id": "LTC-BTC",
|
||
// "side": "SELL",
|
||
// "client_order_id": "4d760580-6fca-4094-a70b-ebcca8626288"
|
||
// },
|
||
// "order_configuration": null
|
||
// }
|
||
//
|
||
// failed order
|
||
//
|
||
// {
|
||
// "success": false,
|
||
// "failure_reason": "UNKNOWN_FAILURE_REASON",
|
||
// "order_id": "",
|
||
// "error_response": {
|
||
// "error": "UNSUPPORTED_ORDER_CONFIGURATION",
|
||
// "message": "source is not enabled for trading",
|
||
// "error_details": "",
|
||
// "new_order_failure_reason": "UNSUPPORTED_ORDER_CONFIGURATION"
|
||
// },
|
||
// "order_configuration": {
|
||
// "limit_limit_gtc": {
|
||
// "base_size": "100",
|
||
// "limit_price": "40000",
|
||
// "post_only": false
|
||
// }
|
||
// }
|
||
// }
|
||
//
|
||
var success interface{} = this.SafeBool(response, "success")
|
||
if IsTrue(!IsEqual(success, true)) {
|
||
var errorResponse interface{} = this.SafeDict(response, "error_response")
|
||
var errorTitle interface{} = this.SafeString(errorResponse, "error")
|
||
var errorMessage interface{} = this.SafeString(errorResponse, "message")
|
||
if IsTrue(!IsEqual(errorResponse, nil)) {
|
||
this.ThrowExactlyMatchedException(GetValue(this.Exceptions, "exact"), errorTitle, errorMessage)
|
||
this.ThrowBroadlyMatchedException(GetValue(this.Exceptions, "broad"), errorTitle, errorMessage)
|
||
panic(ExchangeError(errorMessage))
|
||
}
|
||
}
|
||
var data interface{} = this.SafeDict(response, "success_response", map[string]interface{} {})
|
||
|
||
ch <- this.ParseOrder(data, market)
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
func (this *coinbase) ParseOrder(order interface{}, optionalArgs ...interface{}) interface{} {
|
||
//
|
||
// createOrder
|
||
//
|
||
// {
|
||
// "order_id": "52cfe5e2-0b29-4c19-a245-a6a773de5030",
|
||
// "product_id": "LTC-BTC",
|
||
// "side": "SELL",
|
||
// "client_order_id": "4d760580-6fca-4094-a70b-ebcca8626288"
|
||
// }
|
||
//
|
||
// cancelOrder, cancelOrders
|
||
//
|
||
// {
|
||
// "success": true,
|
||
// "failure_reason": "UNKNOWN_CANCEL_FAILURE_REASON",
|
||
// "order_id": "bb8851a3-4fda-4a2c-aa06-9048db0e0f0d"
|
||
// }
|
||
//
|
||
// fetchOrder, fetchOrders, fetchOpenOrders, fetchClosedOrders, fetchCanceledOrders
|
||
//
|
||
// {
|
||
// "order_id": "9bc1eb3b-5b46-4b71-9628-ae2ed0cca75b",
|
||
// "product_id": "LTC-BTC",
|
||
// "user_id": "1111111-1111-1111-1111-111111111111",
|
||
// "order_configuration": {
|
||
// "limit_limit_gtc": {
|
||
// "base_size": "0.2",
|
||
// "limit_price": "0.006",
|
||
// "post_only": false
|
||
// },
|
||
// "stop_limit_stop_limit_gtc": {
|
||
// "base_size": "48.54",
|
||
// "limit_price": "6.998",
|
||
// "stop_price": "7.0687",
|
||
// "stop_direction": "STOP_DIRECTION_STOP_DOWN"
|
||
// }
|
||
// },
|
||
// "side": "SELL",
|
||
// "client_order_id": "e5fe8482-05bb-428f-ad4d-dbc8ce39239c",
|
||
// "status": "OPEN",
|
||
// "time_in_force": "GOOD_UNTIL_CANCELLED",
|
||
// "created_time": "2023-01-16T23:37:23.947030Z",
|
||
// "completion_percentage": "0",
|
||
// "filled_size": "0",
|
||
// "average_filled_price": "0",
|
||
// "fee": "",
|
||
// "number_of_fills": "0",
|
||
// "filled_value": "0",
|
||
// "pending_cancel": false,
|
||
// "size_in_quote": false,
|
||
// "total_fees": "0",
|
||
// "size_inclusive_of_fees": false,
|
||
// "total_value_after_fees": "0",
|
||
// "trigger_status": "INVALID_ORDER_TYPE",
|
||
// "order_type": "LIMIT",
|
||
// "reject_reason": "REJECT_REASON_UNSPECIFIED",
|
||
// "settled": false,
|
||
// "product_type": "SPOT",
|
||
// "reject_message": "",
|
||
// "cancel_message": ""
|
||
// }
|
||
//
|
||
market := GetArg(optionalArgs, 0, nil)
|
||
_ = market
|
||
var marketId interface{} = this.SafeString(order, "product_id")
|
||
var symbol interface{} = this.SafeSymbol(marketId, market, "-")
|
||
if IsTrue(!IsEqual(symbol, nil)) {
|
||
market = this.SafeMarket(symbol, market)
|
||
}
|
||
var orderConfiguration interface{} = this.SafeDict(order, "order_configuration", map[string]interface{} {})
|
||
var limitGTC interface{} = this.SafeDict(orderConfiguration, "limit_limit_gtc")
|
||
var limitGTD interface{} = this.SafeDict(orderConfiguration, "limit_limit_gtd")
|
||
var limitIOC interface{} = this.SafeDict(orderConfiguration, "sor_limit_ioc")
|
||
var stopLimitGTC interface{} = this.SafeDict(orderConfiguration, "stop_limit_stop_limit_gtc")
|
||
var stopLimitGTD interface{} = this.SafeDict(orderConfiguration, "stop_limit_stop_limit_gtd")
|
||
var marketIOC interface{} = this.SafeDict(orderConfiguration, "market_market_ioc")
|
||
var isLimit interface{} = (IsTrue(IsTrue((!IsEqual(limitGTC, nil))) || IsTrue((!IsEqual(limitGTD, nil)))) || IsTrue((!IsEqual(limitIOC, nil))))
|
||
var isStop interface{} = (IsTrue((!IsEqual(stopLimitGTC, nil))) || IsTrue((!IsEqual(stopLimitGTD, nil))))
|
||
var price interface{} = nil
|
||
var amount interface{} = nil
|
||
var postOnly interface{} = nil
|
||
var triggerPrice interface{} = nil
|
||
if IsTrue(isLimit) {
|
||
var target interface{} = nil
|
||
if IsTrue(!IsEqual(limitGTC, nil)) {
|
||
target = limitGTC
|
||
} else if IsTrue(!IsEqual(limitGTD, nil)) {
|
||
target = limitGTD
|
||
} else {
|
||
target = limitIOC
|
||
}
|
||
price = this.SafeString(target, "limit_price")
|
||
amount = this.SafeString(target, "base_size")
|
||
postOnly = this.SafeBool(target, "post_only")
|
||
} else if IsTrue(isStop) {
|
||
var stopTarget interface{} = Ternary(IsTrue((!IsEqual(stopLimitGTC, nil))), stopLimitGTC, stopLimitGTD)
|
||
price = this.SafeString(stopTarget, "limit_price")
|
||
amount = this.SafeString(stopTarget, "base_size")
|
||
postOnly = this.SafeBool(stopTarget, "post_only")
|
||
triggerPrice = this.SafeString(stopTarget, "stop_price")
|
||
} else {
|
||
amount = this.SafeString(marketIOC, "base_size")
|
||
}
|
||
var datetime interface{} = this.SafeString(order, "created_time")
|
||
var totalFees interface{} = this.SafeString(order, "total_fees")
|
||
var currencyFee interface{} = nil
|
||
if IsTrue(IsTrue((!IsEqual(totalFees, nil))) && IsTrue((!IsEqual(market, nil)))) {
|
||
currencyFee = GetValue(market, "quote")
|
||
}
|
||
return this.SafeOrder(map[string]interface{} {
|
||
"info": order,
|
||
"id": this.SafeString(order, "order_id"),
|
||
"clientOrderId": this.SafeString(order, "client_order_id"),
|
||
"timestamp": this.Parse8601(datetime),
|
||
"datetime": datetime,
|
||
"lastTradeTimestamp": nil,
|
||
"symbol": symbol,
|
||
"type": this.ParseOrderType(this.SafeString(order, "order_type")),
|
||
"timeInForce": this.ParseTimeInForce(this.SafeString(order, "time_in_force")),
|
||
"postOnly": postOnly,
|
||
"side": this.SafeStringLower(order, "side"),
|
||
"price": price,
|
||
"triggerPrice": triggerPrice,
|
||
"amount": amount,
|
||
"filled": this.SafeString(order, "filled_size"),
|
||
"remaining": nil,
|
||
"cost": nil,
|
||
"average": this.SafeString(order, "average_filled_price"),
|
||
"status": this.ParseOrderStatus(this.SafeString(order, "status")),
|
||
"fee": map[string]interface{} {
|
||
"cost": this.SafeString(order, "total_fees"),
|
||
"currency": currencyFee,
|
||
},
|
||
"trades": nil,
|
||
}, market)
|
||
}
|
||
func (this *coinbase) ParseOrderStatus(status interface{}) interface{} {
|
||
var statuses interface{} = map[string]interface{} {
|
||
"OPEN": "open",
|
||
"FILLED": "closed",
|
||
"CANCELLED": "canceled",
|
||
"EXPIRED": "canceled",
|
||
"FAILED": "canceled",
|
||
"UNKNOWN_ORDER_STATUS": nil,
|
||
}
|
||
return this.SafeString(statuses, status, status)
|
||
}
|
||
func (this *coinbase) ParseOrderType(typeVar interface{}) interface{} {
|
||
if IsTrue(IsEqual(typeVar, "UNKNOWN_ORDER_TYPE")) {
|
||
return nil
|
||
}
|
||
var types interface{} = map[string]interface{} {
|
||
"MARKET": "market",
|
||
"LIMIT": "limit",
|
||
"STOP": "limit",
|
||
"STOP_LIMIT": "limit",
|
||
}
|
||
return this.SafeString(types, typeVar, typeVar)
|
||
}
|
||
func (this *coinbase) ParseTimeInForce(timeInForce interface{}) interface{} {
|
||
var timeInForces interface{} = map[string]interface{} {
|
||
"GOOD_UNTIL_CANCELLED": "GTC",
|
||
"GOOD_UNTIL_DATE_TIME": "GTD",
|
||
"IMMEDIATE_OR_CANCEL": "IOC",
|
||
"FILL_OR_KILL": "FOK",
|
||
"UNKNOWN_TIME_IN_FORCE": nil,
|
||
}
|
||
return this.SafeString(timeInForces, timeInForce, timeInForce)
|
||
}
|
||
/**
|
||
* @method
|
||
* @name coinbase#cancelOrder
|
||
* @description cancels an open order
|
||
* @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_cancelorders
|
||
* @param {string} id order id
|
||
* @param {string} symbol not used by coinbase cancelOrder()
|
||
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
* @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
||
*/
|
||
func (this *coinbase) CancelOrder(id interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
symbol := GetArg(optionalArgs, 0, nil)
|
||
_ = symbol
|
||
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
||
_ = params
|
||
|
||
retRes33178 := (<-this.LoadMarkets())
|
||
PanicOnError(retRes33178)
|
||
|
||
orders:= (<-this.CancelOrders([]interface{}{id}, symbol, params))
|
||
PanicOnError(orders)
|
||
|
||
ch <- this.SafeDict(orders, 0, map[string]interface{} {})
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
/**
|
||
* @method
|
||
* @name coinbase#cancelOrders
|
||
* @description cancel multiple orders
|
||
* @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_cancelorders
|
||
* @param {string[]} ids order ids
|
||
* @param {string} symbol not used by coinbase cancelOrders()
|
||
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
* @returns {object} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
||
*/
|
||
func (this *coinbase) CancelOrders(ids interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
symbol := GetArg(optionalArgs, 0, nil)
|
||
_ = symbol
|
||
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
||
_ = params
|
||
|
||
retRes33338 := (<-this.LoadMarkets())
|
||
PanicOnError(retRes33338)
|
||
var market interface{} = nil
|
||
if IsTrue(!IsEqual(symbol, nil)) {
|
||
market = this.Market(symbol)
|
||
}
|
||
var request interface{} = map[string]interface{} {
|
||
"order_ids": ids,
|
||
}
|
||
|
||
response:= (<-this.V3PrivatePostBrokerageOrdersBatchCancel(this.Extend(request, params)))
|
||
PanicOnError(response)
|
||
//
|
||
// {
|
||
// "results": [
|
||
// {
|
||
// "success": true,
|
||
// "failure_reason": "UNKNOWN_CANCEL_FAILURE_REASON",
|
||
// "order_id": "bb8851a3-4fda-4a2c-aa06-9048db0e0f0d"
|
||
// }
|
||
// ]
|
||
// }
|
||
//
|
||
var orders interface{} = this.SafeList(response, "results", []interface{}{})
|
||
for i := 0; IsLessThan(i, GetArrayLength(orders)); i++ {
|
||
var success interface{} = this.SafeBool(GetValue(orders, i), "success")
|
||
if IsTrue(!IsEqual(success, true)) {
|
||
panic(BadRequest(Add(this.Id, " cancelOrders() has failed, check your arguments and parameters")))
|
||
}
|
||
}
|
||
|
||
ch <- this.ParseOrders(orders, market)
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
/**
|
||
* @method
|
||
* @name coinbase#editOrder
|
||
* @description edit a trade order
|
||
* @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_editorder
|
||
* @param {string} id cancel order id
|
||
* @param {string} symbol unified symbol of the market to create an order in
|
||
* @param {string} type 'market' or 'limit'
|
||
* @param {string} side 'buy' or 'sell'
|
||
* @param {float} amount how much of currency you want to trade in units of base currency
|
||
* @param {float} [price] the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
|
||
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
* @param {boolean} [params.preview] default to false, wether to use the test/preview endpoint or not
|
||
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
||
*/
|
||
func (this *coinbase) EditOrder(id interface{}, symbol interface{}, typeVar interface{}, side interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
amount := GetArg(optionalArgs, 0, nil)
|
||
_ = amount
|
||
price := GetArg(optionalArgs, 1, nil)
|
||
_ = price
|
||
params := GetArg(optionalArgs, 2, map[string]interface{} {})
|
||
_ = params
|
||
|
||
retRes33798 := (<-this.LoadMarkets())
|
||
PanicOnError(retRes33798)
|
||
var market interface{} = this.Market(symbol)
|
||
var request interface{} = map[string]interface{} {
|
||
"order_id": id,
|
||
}
|
||
if IsTrue(!IsEqual(amount, nil)) {
|
||
AddElementToObject(request, "size", this.AmountToPrecision(symbol, amount))
|
||
}
|
||
if IsTrue(!IsEqual(price, nil)) {
|
||
AddElementToObject(request, "price", this.PriceToPrecision(symbol, price))
|
||
}
|
||
var preview interface{} = this.SafeBool2(params, "preview", "test", false)
|
||
var response interface{} = nil
|
||
if IsTrue(preview) {
|
||
params = this.Omit(params, []interface{}{"preview", "test"})
|
||
|
||
response = (<-this.V3PrivatePostBrokerageOrdersEditPreview(this.Extend(request, params)))
|
||
PanicOnError(response)
|
||
} else {
|
||
|
||
response = (<-this.V3PrivatePostBrokerageOrdersEdit(this.Extend(request, params)))
|
||
PanicOnError(response)
|
||
}
|
||
|
||
//
|
||
// {
|
||
// "success": true,
|
||
// "errors": {
|
||
// "edit_failure_reason": "UNKNOWN_EDIT_ORDER_FAILURE_REASON",
|
||
// "preview_failure_reason": "UNKNOWN_PREVIEW_FAILURE_REASON"
|
||
// }
|
||
// }
|
||
//
|
||
ch <- this.ParseOrder(response, market)
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
/**
|
||
* @method
|
||
* @name coinbase#fetchOrder
|
||
* @description fetches information on an order made by the user
|
||
* @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_gethistoricalorder
|
||
* @param {string} id the order id
|
||
* @param {string} symbol unified market symbol that the order was made in
|
||
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
* @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
||
*/
|
||
func (this *coinbase) FetchOrder(id interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
symbol := GetArg(optionalArgs, 0, nil)
|
||
_ = symbol
|
||
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
||
_ = params
|
||
|
||
retRes34218 := (<-this.LoadMarkets())
|
||
PanicOnError(retRes34218)
|
||
var market interface{} = nil
|
||
if IsTrue(!IsEqual(symbol, nil)) {
|
||
market = this.Market(symbol)
|
||
}
|
||
var request interface{} = map[string]interface{} {
|
||
"order_id": id,
|
||
}
|
||
|
||
response:= (<-this.V3PrivateGetBrokerageOrdersHistoricalOrderId(this.Extend(request, params)))
|
||
PanicOnError(response)
|
||
//
|
||
// {
|
||
// "order": {
|
||
// "order_id": "9bc1eb3b-5b46-4b71-9628-ae2ed0cca75b",
|
||
// "product_id": "LTC-BTC",
|
||
// "user_id": "1111111-1111-1111-1111-111111111111",
|
||
// "order_configuration": {
|
||
// "limit_limit_gtc": {
|
||
// "base_size": "0.2",
|
||
// "limit_price": "0.006",
|
||
// "post_only": false
|
||
// }
|
||
// },
|
||
// "side": "SELL",
|
||
// "client_order_id": "e5fe8482-05bb-428f-ad4d-dbc8ce39239c",
|
||
// "status": "OPEN",
|
||
// "time_in_force": "GOOD_UNTIL_CANCELLED",
|
||
// "created_time": "2023-01-16T23:37:23.947030Z",
|
||
// "completion_percentage": "0",
|
||
// "filled_size": "0",
|
||
// "average_filled_price": "0",
|
||
// "fee": "",
|
||
// "number_of_fills": "0",
|
||
// "filled_value": "0",
|
||
// "pending_cancel": false,
|
||
// "size_in_quote": false,
|
||
// "total_fees": "0",
|
||
// "size_inclusive_of_fees": false,
|
||
// "total_value_after_fees": "0",
|
||
// "trigger_status": "INVALID_ORDER_TYPE",
|
||
// "order_type": "LIMIT",
|
||
// "reject_reason": "REJECT_REASON_UNSPECIFIED",
|
||
// "settled": false,
|
||
// "product_type": "SPOT",
|
||
// "reject_message": "",
|
||
// "cancel_message": ""
|
||
// }
|
||
// }
|
||
//
|
||
var order interface{} = this.SafeDict(response, "order", map[string]interface{} {})
|
||
|
||
ch <- this.ParseOrder(order, market)
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
/**
|
||
* @method
|
||
* @name coinbase#fetchOrders
|
||
* @description fetches information on multiple orders made by the user
|
||
* @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_gethistoricalorders
|
||
* @param {string} symbol unified market symbol that the orders were made in
|
||
* @param {int} [since] the earliest time in ms to fetch orders
|
||
* @param {int} [limit] the maximum number of order structures to retrieve
|
||
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
* @param {int} [params.until] the latest time in ms to fetch trades for
|
||
* @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
|
||
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
||
*/
|
||
func (this *coinbase) FetchOrders(optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
symbol := GetArg(optionalArgs, 0, nil)
|
||
_ = symbol
|
||
since := GetArg(optionalArgs, 1, nil)
|
||
_ = since
|
||
limit := GetArg(optionalArgs, 2, 100)
|
||
_ = limit
|
||
params := GetArg(optionalArgs, 3, map[string]interface{} {})
|
||
_ = params
|
||
|
||
retRes34878 := (<-this.LoadMarkets())
|
||
PanicOnError(retRes34878)
|
||
var paginate interface{} = false
|
||
paginateparamsVariable := this.HandleOptionAndParams(params, "fetchOrders", "paginate");
|
||
paginate = GetValue(paginateparamsVariable,0);
|
||
params = GetValue(paginateparamsVariable,1)
|
||
if IsTrue(paginate) {
|
||
|
||
retRes349119 := (<-this.FetchPaginatedCallCursor("fetchOrders", symbol, since, limit, params, "cursor", "cursor", nil, 1000))
|
||
PanicOnError(retRes349119)
|
||
ch <- retRes349119
|
||
return nil
|
||
}
|
||
var market interface{} = nil
|
||
if IsTrue(!IsEqual(symbol, nil)) {
|
||
market = this.Market(symbol)
|
||
}
|
||
var request interface{} = map[string]interface{} {}
|
||
if IsTrue(!IsEqual(market, nil)) {
|
||
AddElementToObject(request, "product_id", GetValue(market, "id"))
|
||
}
|
||
if IsTrue(!IsEqual(limit, nil)) {
|
||
AddElementToObject(request, "limit", limit)
|
||
}
|
||
if IsTrue(!IsEqual(since, nil)) {
|
||
AddElementToObject(request, "start_date", this.Iso8601(since))
|
||
}
|
||
var until interface{} = this.SafeIntegerN(params, []interface{}{"until"})
|
||
if IsTrue(!IsEqual(until, nil)) {
|
||
params = this.Omit(params, []interface{}{"until"})
|
||
AddElementToObject(request, "end_date", this.Iso8601(until))
|
||
}
|
||
|
||
response:= (<-this.V3PrivateGetBrokerageOrdersHistoricalBatch(this.Extend(request, params)))
|
||
PanicOnError(response)
|
||
//
|
||
// {
|
||
// "orders": [
|
||
// {
|
||
// "order_id": "813a53c5-3e39-47bb-863d-2faf685d22d8",
|
||
// "product_id": "BTC-USDT",
|
||
// "user_id": "1111111-1111-1111-1111-111111111111",
|
||
// "order_configuration": {
|
||
// "market_market_ioc": {
|
||
// "quote_size": "6.36"
|
||
// }
|
||
// },
|
||
// "side": "BUY",
|
||
// "client_order_id": "18eb9947-db49-4874-8e7b-39b8fe5f4317",
|
||
// "status": "FILLED",
|
||
// "time_in_force": "IMMEDIATE_OR_CANCEL",
|
||
// "created_time": "2023-01-18T01:37:37.975552Z",
|
||
// "completion_percentage": "100",
|
||
// "filled_size": "0.000297920684505",
|
||
// "average_filled_price": "21220.6399999973697697",
|
||
// "fee": "",
|
||
// "number_of_fills": "2",
|
||
// "filled_value": "6.3220675944333996",
|
||
// "pending_cancel": false,
|
||
// "size_in_quote": true,
|
||
// "total_fees": "0.0379324055666004",
|
||
// "size_inclusive_of_fees": true,
|
||
// "total_value_after_fees": "6.36",
|
||
// "trigger_status": "INVALID_ORDER_TYPE",
|
||
// "order_type": "MARKET",
|
||
// "reject_reason": "REJECT_REASON_UNSPECIFIED",
|
||
// "settled": true,
|
||
// "product_type": "SPOT",
|
||
// "reject_message": "",
|
||
// "cancel_message": "Internal error"
|
||
// },
|
||
// ],
|
||
// "sequence": "0",
|
||
// "has_next": false,
|
||
// "cursor": ""
|
||
// }
|
||
//
|
||
var orders interface{} = this.SafeList(response, "orders", []interface{}{})
|
||
var first interface{} = this.SafeDict(orders, 0)
|
||
var cursor interface{} = this.SafeString(response, "cursor")
|
||
if IsTrue(IsTrue((!IsEqual(cursor, nil))) && IsTrue((!IsEqual(cursor, "")))) {
|
||
AddElementToObject(first, "cursor", cursor)
|
||
AddElementToObject(orders, 0, first)
|
||
}
|
||
|
||
ch <- this.ParseOrders(orders, market, since, limit)
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
func (this *coinbase) FetchOrdersByStatus(status interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
symbol := GetArg(optionalArgs, 0, nil)
|
||
_ = symbol
|
||
since := GetArg(optionalArgs, 1, nil)
|
||
_ = since
|
||
limit := GetArg(optionalArgs, 2, nil)
|
||
_ = limit
|
||
params := GetArg(optionalArgs, 3, map[string]interface{} {})
|
||
_ = params
|
||
|
||
retRes35668 := (<-this.LoadMarkets())
|
||
PanicOnError(retRes35668)
|
||
var market interface{} = nil
|
||
if IsTrue(!IsEqual(symbol, nil)) {
|
||
market = this.Market(symbol)
|
||
}
|
||
var request interface{} = map[string]interface{} {
|
||
"order_status": status,
|
||
}
|
||
if IsTrue(!IsEqual(market, nil)) {
|
||
AddElementToObject(request, "product_id", GetValue(market, "id"))
|
||
}
|
||
if IsTrue(IsEqual(limit, nil)) {
|
||
limit = 100
|
||
}
|
||
AddElementToObject(request, "limit", limit)
|
||
if IsTrue(!IsEqual(since, nil)) {
|
||
AddElementToObject(request, "start_date", this.Iso8601(since))
|
||
}
|
||
var until interface{} = this.SafeIntegerN(params, []interface{}{"until"})
|
||
if IsTrue(!IsEqual(until, nil)) {
|
||
params = this.Omit(params, []interface{}{"until"})
|
||
AddElementToObject(request, "end_date", this.Iso8601(until))
|
||
}
|
||
|
||
response:= (<-this.V3PrivateGetBrokerageOrdersHistoricalBatch(this.Extend(request, params)))
|
||
PanicOnError(response)
|
||
//
|
||
// {
|
||
// "orders": [
|
||
// {
|
||
// "order_id": "813a53c5-3e39-47bb-863d-2faf685d22d8",
|
||
// "product_id": "BTC-USDT",
|
||
// "user_id": "1111111-1111-1111-1111-111111111111",
|
||
// "order_configuration": {
|
||
// "market_market_ioc": {
|
||
// "quote_size": "6.36"
|
||
// }
|
||
// },
|
||
// "side": "BUY",
|
||
// "client_order_id": "18eb9947-db49-4874-8e7b-39b8fe5f4317",
|
||
// "status": "FILLED",
|
||
// "time_in_force": "IMMEDIATE_OR_CANCEL",
|
||
// "created_time": "2023-01-18T01:37:37.975552Z",
|
||
// "completion_percentage": "100",
|
||
// "filled_size": "0.000297920684505",
|
||
// "average_filled_price": "21220.6399999973697697",
|
||
// "fee": "",
|
||
// "number_of_fills": "2",
|
||
// "filled_value": "6.3220675944333996",
|
||
// "pending_cancel": false,
|
||
// "size_in_quote": true,
|
||
// "total_fees": "0.0379324055666004",
|
||
// "size_inclusive_of_fees": true,
|
||
// "total_value_after_fees": "6.36",
|
||
// "trigger_status": "INVALID_ORDER_TYPE",
|
||
// "order_type": "MARKET",
|
||
// "reject_reason": "REJECT_REASON_UNSPECIFIED",
|
||
// "settled": true,
|
||
// "product_type": "SPOT",
|
||
// "reject_message": "",
|
||
// "cancel_message": "Internal error"
|
||
// },
|
||
// ],
|
||
// "sequence": "0",
|
||
// "has_next": false,
|
||
// "cursor": ""
|
||
// }
|
||
//
|
||
var orders interface{} = this.SafeList(response, "orders", []interface{}{})
|
||
var first interface{} = this.SafeDict(orders, 0)
|
||
var cursor interface{} = this.SafeString(response, "cursor")
|
||
if IsTrue(IsTrue((!IsEqual(cursor, nil))) && IsTrue((!IsEqual(cursor, "")))) {
|
||
AddElementToObject(first, "cursor", cursor)
|
||
AddElementToObject(orders, 0, first)
|
||
}
|
||
|
||
ch <- this.ParseOrders(orders, market, since, limit)
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
/**
|
||
* @method
|
||
* @name coinbase#fetchOpenOrders
|
||
* @description fetches information on all currently open orders
|
||
* @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_gethistoricalorders
|
||
* @param {string} symbol unified market symbol of the orders
|
||
* @param {int} [since] timestamp in ms of the earliest order, default is undefined
|
||
* @param {int} [limit] the maximum number of open order structures to retrieve
|
||
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
* @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
|
||
* @param {int} [params.until] the latest time in ms to fetch trades for
|
||
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
||
*/
|
||
func (this *coinbase) FetchOpenOrders(optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
symbol := GetArg(optionalArgs, 0, nil)
|
||
_ = symbol
|
||
since := GetArg(optionalArgs, 1, nil)
|
||
_ = since
|
||
limit := GetArg(optionalArgs, 2, nil)
|
||
_ = limit
|
||
params := GetArg(optionalArgs, 3, map[string]interface{} {})
|
||
_ = params
|
||
|
||
retRes36568 := (<-this.LoadMarkets())
|
||
PanicOnError(retRes36568)
|
||
var paginate interface{} = false
|
||
paginateparamsVariable := this.HandleOptionAndParams(params, "fetchOpenOrders", "paginate");
|
||
paginate = GetValue(paginateparamsVariable,0);
|
||
params = GetValue(paginateparamsVariable,1)
|
||
if IsTrue(paginate) {
|
||
|
||
retRes366019 := (<-this.FetchPaginatedCallCursor("fetchOpenOrders", symbol, since, limit, params, "cursor", "cursor", nil, 100))
|
||
PanicOnError(retRes366019)
|
||
ch <- retRes366019
|
||
return nil
|
||
}
|
||
|
||
retRes366215 := (<-this.FetchOrdersByStatus("OPEN", symbol, since, limit, params))
|
||
PanicOnError(retRes366215)
|
||
ch <- retRes366215
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
/**
|
||
* @method
|
||
* @name coinbase#fetchClosedOrders
|
||
* @description fetches information on multiple closed orders made by the user
|
||
* @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_gethistoricalorders
|
||
* @param {string} symbol unified market symbol of the orders
|
||
* @param {int} [since] timestamp in ms of the earliest order, default is undefined
|
||
* @param {int} [limit] the maximum number of closed order structures to retrieve
|
||
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
* @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
|
||
* @param {int} [params.until] the latest time in ms to fetch trades for
|
||
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
||
*/
|
||
func (this *coinbase) FetchClosedOrders(optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
symbol := GetArg(optionalArgs, 0, nil)
|
||
_ = symbol
|
||
since := GetArg(optionalArgs, 1, nil)
|
||
_ = since
|
||
limit := GetArg(optionalArgs, 2, nil)
|
||
_ = limit
|
||
params := GetArg(optionalArgs, 3, map[string]interface{} {})
|
||
_ = params
|
||
|
||
retRes36798 := (<-this.LoadMarkets())
|
||
PanicOnError(retRes36798)
|
||
var paginate interface{} = false
|
||
paginateparamsVariable := this.HandleOptionAndParams(params, "fetchClosedOrders", "paginate");
|
||
paginate = GetValue(paginateparamsVariable,0);
|
||
params = GetValue(paginateparamsVariable,1)
|
||
if IsTrue(paginate) {
|
||
|
||
retRes368319 := (<-this.FetchPaginatedCallCursor("fetchClosedOrders", symbol, since, limit, params, "cursor", "cursor", nil, 100))
|
||
PanicOnError(retRes368319)
|
||
ch <- retRes368319
|
||
return nil
|
||
}
|
||
|
||
retRes368515 := (<-this.FetchOrdersByStatus("FILLED", symbol, since, limit, params))
|
||
PanicOnError(retRes368515)
|
||
ch <- retRes368515
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
/**
|
||
* @method
|
||
* @name coinbase#fetchCanceledOrders
|
||
* @description fetches information on multiple canceled orders made by the user
|
||
* @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_gethistoricalorders
|
||
* @param {string} symbol unified market symbol of the orders
|
||
* @param {int} [since] timestamp in ms of the earliest order, default is undefined
|
||
* @param {int} [limit] the maximum number of canceled order structures to retrieve
|
||
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
* @returns {object} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
||
*/
|
||
func (this *coinbase) FetchCanceledOrders(optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
symbol := GetArg(optionalArgs, 0, nil)
|
||
_ = symbol
|
||
since := GetArg(optionalArgs, 1, nil)
|
||
_ = since
|
||
limit := GetArg(optionalArgs, 2, nil)
|
||
_ = limit
|
||
params := GetArg(optionalArgs, 3, map[string]interface{} {})
|
||
_ = params
|
||
|
||
retRes370015 := (<-this.FetchOrdersByStatus("CANCELLED", symbol, since, limit, params))
|
||
PanicOnError(retRes370015)
|
||
ch <- retRes370015
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
/**
|
||
* @method
|
||
* @name coinbase#fetchOHLCV
|
||
* @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
||
* @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getpubliccandles
|
||
* @param {string} symbol unified symbol of the market to fetch OHLCV data for
|
||
* @param {string} timeframe the length of time each candle represents
|
||
* @param {int} [since] timestamp in ms of the earliest candle to fetch
|
||
* @param {int} [limit] the maximum amount of candles to fetch, not used by coinbase
|
||
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
* @param {int} [params.until] the latest time in ms to fetch trades for
|
||
* @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
|
||
* @param {boolean} [params.usePrivate] default false, when true will use the private endpoint to fetch the candles
|
||
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
|
||
*/
|
||
func (this *coinbase) FetchOHLCV(symbol interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
timeframe := GetArg(optionalArgs, 0, "1m")
|
||
_ = timeframe
|
||
since := GetArg(optionalArgs, 1, nil)
|
||
_ = since
|
||
limit := GetArg(optionalArgs, 2, nil)
|
||
_ = limit
|
||
params := GetArg(optionalArgs, 3, map[string]interface{} {})
|
||
_ = params
|
||
|
||
retRes37198 := (<-this.LoadMarkets())
|
||
PanicOnError(retRes37198)
|
||
var maxLimit interface{} = 300
|
||
limit = Ternary(IsTrue((IsEqual(limit, nil))), maxLimit, mathMin(limit, maxLimit))
|
||
var paginate interface{} = false
|
||
paginateparamsVariable := this.HandleOptionAndParams(params, "fetchOHLCV", "paginate", false);
|
||
paginate = GetValue(paginateparamsVariable,0);
|
||
params = GetValue(paginateparamsVariable,1)
|
||
if IsTrue(paginate) {
|
||
|
||
retRes372519 := (<-this.FetchPaginatedCallDeterministic("fetchOHLCV", symbol, since, limit, timeframe, params, Subtract(maxLimit, 1)))
|
||
PanicOnError(retRes372519)
|
||
ch <- retRes372519
|
||
return nil
|
||
}
|
||
var market interface{} = this.Market(symbol)
|
||
var request interface{} = map[string]interface{} {
|
||
"product_id": GetValue(market, "id"),
|
||
"granularity": this.SafeString(this.Timeframes, timeframe, timeframe),
|
||
}
|
||
var until interface{} = this.SafeIntegerN(params, []interface{}{"until", "end"})
|
||
params = this.Omit(params, []interface{}{"until"})
|
||
var duration interface{} = this.ParseTimeframe(timeframe)
|
||
var requestedDuration interface{} = Multiply(limit, duration)
|
||
var sinceString interface{} = nil
|
||
if IsTrue(!IsEqual(since, nil)) {
|
||
sinceString = this.NumberToString(this.ParseToInt(Divide(since, 1000)))
|
||
} else {
|
||
var now interface{} = ToString(this.Seconds())
|
||
sinceString = Precise.StringSub(now, ToString(requestedDuration))
|
||
}
|
||
AddElementToObject(request, "start", sinceString)
|
||
if IsTrue(!IsEqual(until, nil)) {
|
||
AddElementToObject(request, "end", this.NumberToString(this.ParseToInt(Divide(until, 1000))))
|
||
} else {
|
||
// 300 candles max
|
||
AddElementToObject(request, "end", Precise.StringAdd(sinceString, ToString(requestedDuration)))
|
||
}
|
||
var response interface{} = nil
|
||
var usePrivate interface{} = false
|
||
usePrivateparamsVariable := this.HandleOptionAndParams(params, "fetchOHLCV", "usePrivate", false);
|
||
usePrivate = GetValue(usePrivateparamsVariable,0);
|
||
params = GetValue(usePrivateparamsVariable,1)
|
||
if IsTrue(usePrivate) {
|
||
|
||
response = (<-this.V3PrivateGetBrokerageProductsProductIdCandles(this.Extend(request, params)))
|
||
PanicOnError(response)
|
||
} else {
|
||
|
||
response = (<-this.V3PublicGetBrokerageMarketProductsProductIdCandles(this.Extend(request, params)))
|
||
PanicOnError(response)
|
||
}
|
||
//
|
||
// {
|
||
// "candles": [
|
||
// {
|
||
// "start": "1673391780",
|
||
// "low": "17414.36",
|
||
// "high": "17417.99",
|
||
// "open": "17417.74",
|
||
// "close": "17417.38",
|
||
// "volume": "1.87780853"
|
||
// },
|
||
// ]
|
||
// }
|
||
//
|
||
var candles interface{} = this.SafeList(response, "candles", []interface{}{})
|
||
|
||
ch <- this.ParseOHLCVs(candles, market, timeframe, since, limit)
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
func (this *coinbase) ParseOHLCV(ohlcv interface{}, optionalArgs ...interface{}) interface{} {
|
||
//
|
||
// [
|
||
// {
|
||
// "start": "1673391780",
|
||
// "low": "17414.36",
|
||
// "high": "17417.99",
|
||
// "open": "17417.74",
|
||
// "close": "17417.38",
|
||
// "volume": "1.87780853"
|
||
// },
|
||
// ]
|
||
//
|
||
market := GetArg(optionalArgs, 0, nil)
|
||
_ = market
|
||
return []interface{}{this.SafeTimestamp(ohlcv, "start"), this.SafeNumber(ohlcv, "open"), this.SafeNumber(ohlcv, "high"), this.SafeNumber(ohlcv, "low"), this.SafeNumber(ohlcv, "close"), this.SafeNumber(ohlcv, "volume")}
|
||
}
|
||
/**
|
||
* @method
|
||
* @name coinbase#fetchTrades
|
||
* @description get the list of most recent trades for a particular symbol
|
||
* @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getpublicmarkettrades
|
||
* @param {string} symbol unified market symbol of the trades
|
||
* @param {int} [since] not used by coinbase fetchTrades
|
||
* @param {int} [limit] the maximum number of trade structures to fetch
|
||
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
* @param {boolean} [params.usePrivate] default false, when true will use the private endpoint to fetch the trades
|
||
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
|
||
*/
|
||
func (this *coinbase) FetchTrades(symbol interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
since := GetArg(optionalArgs, 0, nil)
|
||
_ = since
|
||
limit := GetArg(optionalArgs, 1, nil)
|
||
_ = limit
|
||
params := GetArg(optionalArgs, 2, map[string]interface{} {})
|
||
_ = params
|
||
|
||
retRes38128 := (<-this.LoadMarkets())
|
||
PanicOnError(retRes38128)
|
||
var market interface{} = this.Market(symbol)
|
||
var request interface{} = map[string]interface{} {
|
||
"product_id": GetValue(market, "id"),
|
||
}
|
||
if IsTrue(!IsEqual(since, nil)) {
|
||
AddElementToObject(request, "start", this.NumberToString(this.ParseToInt(Divide(since, 1000))))
|
||
}
|
||
if IsTrue(!IsEqual(limit, nil)) {
|
||
AddElementToObject(request, "limit", mathMin(limit, 1000))
|
||
}
|
||
var until interface{} = nil
|
||
untilparamsVariable := this.HandleOptionAndParams(params, "fetchTrades", "until");
|
||
until = GetValue(untilparamsVariable,0);
|
||
params = GetValue(untilparamsVariable,1)
|
||
if IsTrue(!IsEqual(until, nil)) {
|
||
AddElementToObject(request, "end", this.NumberToString(this.ParseToInt(Divide(until, 1000))))
|
||
} else if IsTrue(!IsEqual(since, nil)) {
|
||
panic(ArgumentsRequired(Add(this.Id, " fetchTrades() requires a `until` parameter when you use `since` argument")))
|
||
}
|
||
var response interface{} = nil
|
||
var usePrivate interface{} = false
|
||
usePrivateparamsVariable := this.HandleOptionAndParams(params, "fetchTrades", "usePrivate", false);
|
||
usePrivate = GetValue(usePrivateparamsVariable,0);
|
||
params = GetValue(usePrivateparamsVariable,1)
|
||
if IsTrue(usePrivate) {
|
||
|
||
response = (<-this.V3PrivateGetBrokerageProductsProductIdTicker(this.Extend(request, params)))
|
||
PanicOnError(response)
|
||
} else {
|
||
|
||
response = (<-this.V3PublicGetBrokerageMarketProductsProductIdTicker(this.Extend(request, params)))
|
||
PanicOnError(response)
|
||
}
|
||
//
|
||
// {
|
||
// "trades": [
|
||
// {
|
||
// "trade_id": "10092327",
|
||
// "product_id": "BTC-USDT",
|
||
// "price": "17488.12",
|
||
// "size": "0.0000623",
|
||
// "time": "2023-01-11T00:52:37.557001Z",
|
||
// "side": "BUY",
|
||
// "bid": "",
|
||
// "ask": ""
|
||
// },
|
||
// ]
|
||
// }
|
||
//
|
||
var trades interface{} = this.SafeList(response, "trades", []interface{}{})
|
||
|
||
ch <- this.ParseTrades(trades, market, since, limit)
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
/**
|
||
* @method
|
||
* @name coinbase#fetchMyTrades
|
||
* @description fetch all trades made by the user
|
||
* @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getfills
|
||
* @param {string} symbol unified market symbol of the trades
|
||
* @param {int} [since] timestamp in ms of the earliest order, default is undefined
|
||
* @param {int} [limit] the maximum number of trade structures to fetch
|
||
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
* @param {int} [params.until] the latest time in ms to fetch trades for
|
||
* @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
|
||
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
|
||
*/
|
||
func (this *coinbase) FetchMyTrades(optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
symbol := GetArg(optionalArgs, 0, nil)
|
||
_ = symbol
|
||
since := GetArg(optionalArgs, 1, nil)
|
||
_ = since
|
||
limit := GetArg(optionalArgs, 2, nil)
|
||
_ = limit
|
||
params := GetArg(optionalArgs, 3, map[string]interface{} {})
|
||
_ = params
|
||
|
||
retRes38728 := (<-this.LoadMarkets())
|
||
PanicOnError(retRes38728)
|
||
var paginate interface{} = false
|
||
paginateparamsVariable := this.HandleOptionAndParams(params, "fetchMyTrades", "paginate");
|
||
paginate = GetValue(paginateparamsVariable,0);
|
||
params = GetValue(paginateparamsVariable,1)
|
||
if IsTrue(paginate) {
|
||
|
||
retRes387619 := (<-this.FetchPaginatedCallCursor("fetchMyTrades", symbol, since, limit, params, "cursor", "cursor", nil, 250))
|
||
PanicOnError(retRes387619)
|
||
ch <- retRes387619
|
||
return nil
|
||
}
|
||
var market interface{} = nil
|
||
if IsTrue(!IsEqual(symbol, nil)) {
|
||
market = this.Market(symbol)
|
||
}
|
||
var request interface{} = map[string]interface{} {}
|
||
if IsTrue(!IsEqual(market, nil)) {
|
||
AddElementToObject(request, "product_id", GetValue(market, "id"))
|
||
}
|
||
if IsTrue(!IsEqual(limit, nil)) {
|
||
AddElementToObject(request, "limit", limit)
|
||
}
|
||
if IsTrue(!IsEqual(since, nil)) {
|
||
AddElementToObject(request, "start_sequence_timestamp", this.Iso8601(since))
|
||
}
|
||
var until interface{} = this.SafeIntegerN(params, []interface{}{"until"})
|
||
if IsTrue(!IsEqual(until, nil)) {
|
||
params = this.Omit(params, []interface{}{"until"})
|
||
AddElementToObject(request, "end_sequence_timestamp", this.Iso8601(until))
|
||
}
|
||
|
||
response:= (<-this.V3PrivateGetBrokerageOrdersHistoricalFills(this.Extend(request, params)))
|
||
PanicOnError(response)
|
||
//
|
||
// {
|
||
// "fills": [
|
||
// {
|
||
// "entry_id": "b88b82cc89e326a2778874795102cbafd08dd979a2a7a3c69603fc4c23c2e010",
|
||
// "trade_id": "cdc39e45-bbd3-44ec-bf02-61742dfb16a1",
|
||
// "order_id": "813a53c5-3e39-47bb-863d-2faf685d22d8",
|
||
// "trade_time": "2023-01-18T01:37:38.091377090Z",
|
||
// "trade_type": "FILL",
|
||
// "price": "21220.64",
|
||
// "size": "0.0046830664333996",
|
||
// "commission": "0.0000280983986004",
|
||
// "product_id": "BTC-USDT",
|
||
// "sequence_timestamp": "2023-01-18T01:37:38.092520Z",
|
||
// "liquidity_indicator": "UNKNOWN_LIQUIDITY_INDICATOR",
|
||
// "size_in_quote": true,
|
||
// "user_id": "1111111-1111-1111-1111-111111111111",
|
||
// "side": "BUY"
|
||
// },
|
||
// ],
|
||
// "cursor": ""
|
||
// }
|
||
//
|
||
var trades interface{} = this.SafeList(response, "fills", []interface{}{})
|
||
var first interface{} = this.SafeDict(trades, 0)
|
||
var cursor interface{} = this.SafeString(response, "cursor")
|
||
if IsTrue(IsTrue((!IsEqual(cursor, nil))) && IsTrue((!IsEqual(cursor, "")))) {
|
||
AddElementToObject(first, "cursor", cursor)
|
||
AddElementToObject(trades, 0, first)
|
||
}
|
||
|
||
ch <- this.ParseTrades(trades, market, since, limit)
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
/**
|
||
* @method
|
||
* @name coinbase#fetchOrderBook
|
||
* @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
||
* @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getpublicproductbook
|
||
* @param {string} symbol unified symbol of the market to fetch the order book for
|
||
* @param {int} [limit] the maximum amount of order book entries to return
|
||
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
* @param {boolean} [params.usePrivate] default false, when true will use the private endpoint to fetch the order book
|
||
* @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
|
||
*/
|
||
func (this *coinbase) FetchOrderBook(symbol interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
limit := GetArg(optionalArgs, 0, nil)
|
||
_ = limit
|
||
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
||
_ = params
|
||
|
||
retRes39438 := (<-this.LoadMarkets())
|
||
PanicOnError(retRes39438)
|
||
var market interface{} = this.Market(symbol)
|
||
var request interface{} = map[string]interface{} {
|
||
"product_id": GetValue(market, "id"),
|
||
}
|
||
if IsTrue(!IsEqual(limit, nil)) {
|
||
AddElementToObject(request, "limit", limit)
|
||
}
|
||
var response interface{} = nil
|
||
var usePrivate interface{} = false
|
||
usePrivateparamsVariable := this.HandleOptionAndParams(params, "fetchOrderBook", "usePrivate", false);
|
||
usePrivate = GetValue(usePrivateparamsVariable,0);
|
||
params = GetValue(usePrivateparamsVariable,1)
|
||
if IsTrue(usePrivate) {
|
||
|
||
response = (<-this.V3PrivateGetBrokerageProductBook(this.Extend(request, params)))
|
||
PanicOnError(response)
|
||
} else {
|
||
|
||
response = (<-this.V3PublicGetBrokerageMarketProductBook(this.Extend(request, params)))
|
||
PanicOnError(response)
|
||
}
|
||
//
|
||
// {
|
||
// "pricebook": {
|
||
// "product_id": "BTC-USDT",
|
||
// "bids": [
|
||
// {
|
||
// "price": "30757.85",
|
||
// "size": "0.115"
|
||
// },
|
||
// ],
|
||
// "asks": [
|
||
// {
|
||
// "price": "30759.07",
|
||
// "size": "0.04877659"
|
||
// },
|
||
// ],
|
||
// "time": "2023-06-30T04:02:40.533606Z"
|
||
// }
|
||
// }
|
||
//
|
||
var data interface{} = this.SafeDict(response, "pricebook", map[string]interface{} {})
|
||
var time interface{} = this.SafeString(data, "time")
|
||
var timestamp interface{} = this.Parse8601(time)
|
||
|
||
ch <- this.ParseOrderBook(data, symbol, timestamp, "bids", "asks", "price", "size")
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
/**
|
||
* @method
|
||
* @name coinbase#fetchBidsAsks
|
||
* @description fetches the bid and ask price and volume for multiple markets
|
||
* @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getbestbidask
|
||
* @param {string[]} [symbols] unified symbols of the markets to fetch the bids and asks for, all markets are returned if not assigned
|
||
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
* @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
||
*/
|
||
func (this *coinbase) FetchBidsAsks(optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
symbols := GetArg(optionalArgs, 0, nil)
|
||
_ = symbols
|
||
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
||
_ = params
|
||
|
||
retRes39958 := (<-this.LoadMarkets())
|
||
PanicOnError(retRes39958)
|
||
symbols = this.MarketSymbols(symbols)
|
||
var request interface{} = map[string]interface{} {}
|
||
if IsTrue(!IsEqual(symbols, nil)) {
|
||
AddElementToObject(request, "product_ids", this.MarketIds(symbols))
|
||
}
|
||
|
||
response:= (<-this.V3PrivateGetBrokerageBestBidAsk(this.Extend(request, params)))
|
||
PanicOnError(response)
|
||
//
|
||
// {
|
||
// "pricebooks": [
|
||
// {
|
||
// "product_id": "TRAC-EUR",
|
||
// "bids": [
|
||
// {
|
||
// "price": "0.2384",
|
||
// "size": "386.1"
|
||
// }
|
||
// ],
|
||
// "asks": [
|
||
// {
|
||
// "price": "0.2406",
|
||
// "size": "672"
|
||
// }
|
||
// ],
|
||
// "time": "2023-06-30T07:15:24.656044Z"
|
||
// },
|
||
// ]
|
||
// }
|
||
//
|
||
var tickers interface{} = this.SafeList(response, "pricebooks", []interface{}{})
|
||
|
||
ch <- this.ParseTickers(tickers, symbols)
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
/**
|
||
* @method
|
||
* @name coinbase#withdraw
|
||
* @description make a withdrawal
|
||
* @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-transactions#send-money
|
||
* @param {string} code unified currency code
|
||
* @param {float} amount the amount to withdraw
|
||
* @param {string} address the address to withdraw to
|
||
* @param {string} [tag] an optional tag for the withdrawal
|
||
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
* @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
||
*/
|
||
func (this *coinbase) Withdraw(code interface{}, amount interface{}, address interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
tag := GetArg(optionalArgs, 0, nil)
|
||
_ = tag
|
||
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
||
_ = params
|
||
tagparamsVariable := this.HandleWithdrawTagAndParams(tag, params);
|
||
tag = GetValue(tagparamsVariable,0);
|
||
params = GetValue(tagparamsVariable,1)
|
||
this.CheckAddress(address)
|
||
|
||
retRes40438 := (<-this.LoadMarkets())
|
||
PanicOnError(retRes40438)
|
||
var currency interface{} = this.Currency(code)
|
||
var accountId interface{} = this.SafeString2(params, "account_id", "accountId")
|
||
params = this.Omit(params, []interface{}{"account_id", "accountId"})
|
||
if IsTrue(IsEqual(accountId, nil)) {
|
||
if IsTrue(IsEqual(code, nil)) {
|
||
panic(ArgumentsRequired(Add(this.Id, " withdraw() requires an account_id (or accountId) parameter OR a currency code argument")))
|
||
}
|
||
|
||
accountId = (<-this.FindAccountId(code, params))
|
||
PanicOnError(accountId)
|
||
if IsTrue(IsEqual(accountId, nil)) {
|
||
panic(ExchangeError(Add(Add(this.Id, " withdraw() could not find account id for "), code)))
|
||
}
|
||
}
|
||
var request interface{} = map[string]interface{} {
|
||
"account_id": accountId,
|
||
"type": "send",
|
||
"to": address,
|
||
"amount": amount,
|
||
"currency": GetValue(currency, "id"),
|
||
}
|
||
if IsTrue(!IsEqual(tag, nil)) {
|
||
AddElementToObject(request, "destination_tag", tag)
|
||
}
|
||
|
||
response:= (<-this.V2PrivatePostAccountsAccountIdTransactions(this.Extend(request, params)))
|
||
PanicOnError(response)
|
||
//
|
||
// {
|
||
// "data": {
|
||
// "id": "a1794ecf-5693-55fa-70cf-ef731748ed82",
|
||
// "type": "send",
|
||
// "status": "pending",
|
||
// "amount": {
|
||
// "amount": "-14.008308",
|
||
// "currency": "USDC"
|
||
// },
|
||
// "native_amount": {
|
||
// "amount": "-18.74",
|
||
// "currency": "CAD"
|
||
// },
|
||
// "description": null,
|
||
// "created_at": "2024-01-12T01:27:31Z",
|
||
// "updated_at": "2024-01-12T01:27:31Z",
|
||
// "resource": "transaction",
|
||
// "resource_path": "/v2/accounts/a34bgfad-ed67-538b-bffc-730c98c10da0/transactions/a1794ecf-5693-55fa-70cf-ef731748ed82",
|
||
// "instant_exchange": false,
|
||
// "network": {
|
||
// "status": "pending",
|
||
// "status_description": "Pending (est. less than 10 minutes)",
|
||
// "transaction_fee": {
|
||
// "amount": "4.008308",
|
||
// "currency": "USDC"
|
||
// },
|
||
// "transaction_amount": {
|
||
// "amount": "10.000000",
|
||
// "currency": "USDC"
|
||
// },
|
||
// "confirmations": 0
|
||
// },
|
||
// "to": {
|
||
// "resource": "ethereum_address",
|
||
// "address": "0x9...",
|
||
// "currency": "USDC",
|
||
// "address_info": {
|
||
// "address": "0x9..."
|
||
// }
|
||
// },
|
||
// "idem": "748d8591-dg9a-7831-a45b-crd61dg78762",
|
||
// "details": {
|
||
// "title": "Sent USDC",
|
||
// "subtitle": "To USDC address on Ethereum network",
|
||
// "header": "Sent 14.008308 USDC ($18.74)",
|
||
// "health": "warning"
|
||
// },
|
||
// "hide_native_amount": false
|
||
// }
|
||
// }
|
||
//
|
||
var data interface{} = this.SafeDict(response, "data", map[string]interface{} {})
|
||
|
||
ch <- this.ParseTransaction(data, currency)
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
/**
|
||
* @method
|
||
* @name coinbase#fetchDepositAddress
|
||
* @description fetch the deposit address for a currency associated with this account
|
||
* @see https://docs.cloud.coinbase.com/exchange/reference/exchangerestapi_postcoinbaseaccountaddresses
|
||
* @param {string} code unified currency code
|
||
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
* @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure}
|
||
*/
|
||
func (this *coinbase) FetchDepositAddressesByNetwork(code interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
||
_ = params
|
||
|
||
retRes41338 := (<-this.LoadMarkets())
|
||
PanicOnError(retRes41338)
|
||
var currency interface{} = this.Currency(code)
|
||
var request interface{} = nil
|
||
requestparamsVariable := (<-this.PrepareAccountRequestWithCurrencyCode(GetValue(currency, "code"), nil, params));
|
||
request = GetValue(requestparamsVariable,0);
|
||
params = GetValue(requestparamsVariable,1)
|
||
|
||
response:= (<-this.V2PrivateGetAccountsAccountIdAddresses(this.Extend(request, params)))
|
||
PanicOnError(response)
|
||
//
|
||
// {
|
||
// pagination: {
|
||
// ending_before: null,
|
||
// starting_after: null,
|
||
// previous_ending_before: null,
|
||
// next_starting_after: null,
|
||
// limit: '25',
|
||
// order: 'desc',
|
||
// previous_uri: null,
|
||
// next_uri: null
|
||
// },
|
||
// data: [
|
||
// {
|
||
// id: '64ceb5f1-5fa2-5310-a4ff-9fd46271003d',
|
||
// address: '5xjPKeAXpnhA2kHyinvdVeui6RXVdEa3B2J3SCAwiKnk',
|
||
// address_info: { address: '5xjPKeAXpnhA2kHyinvdVeui6RXVdEa3B2J3SCAwiKnk' },
|
||
// name: null,
|
||
// created_at: '2023-05-29T21:12:12Z',
|
||
// updated_at: '2023-05-29T21:12:12Z',
|
||
// network: 'solana',
|
||
// uri_scheme: 'solana',
|
||
// resource: 'address',
|
||
// resource_path: '/v2/accounts/a7b3d387-bfb8-5ce7-b8da-1f507e81cf25/addresses/64ceb5f1-5fa2-5310-a4ff-9fd46271003d',
|
||
// warnings: [
|
||
// {
|
||
// type: 'correct_address_warning',
|
||
// title: 'This is an ERC20 USDC address.',
|
||
// details: 'Only send ERC20 USD Coin (USDC) to this address.',
|
||
// image_url: 'https://www.coinbase.com/assets/addresses/global-receive-warning-a3d91807e61c717e5a38d270965003dcc025ca8a3cea40ec3d7835b7c86087fa.png',
|
||
// options: [ { text: 'I understand', style: 'primary', id: 'dismiss' } ]
|
||
// }
|
||
// ],
|
||
// qr_code_image_url: 'https://static-assets.coinbase.com/p2p/l2/asset_network_combinations/v5/usdc-solana.png',
|
||
// address_label: 'USDC address (Solana)',
|
||
// default_receive: true,
|
||
// deposit_uri: 'solana:5xjPKeAXpnhA2kHyinvdVeui6RXVdEa3B2J3SCAwiKnk?spl-token=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
|
||
// callback_url: null,
|
||
// share_address_copy: {
|
||
// line1: '5xjPKeAXpnhA2kHyinvdVeui6RXVdEa3B2J3SCAwiKnk',
|
||
// line2: 'This address can only receive USDC-SPL from Solana network. Don’t send USDC from other networks, other SPL tokens or NFTs, or it may result in a loss of funds.'
|
||
// },
|
||
// receive_subtitle: 'ERC-20',
|
||
// inline_warning: {
|
||
// text: 'This address can only receive USDC-SPL from Solana network. Don’t send USDC from other networks, other SPL tokens or NFTs, or it may result in a loss of funds.',
|
||
// tooltip: {
|
||
// title: 'USDC (Solana)',
|
||
// subtitle: 'This address can only receive USDC-SPL from Solana network.'
|
||
// }
|
||
// }
|
||
// },
|
||
// ...
|
||
// ]
|
||
// }
|
||
//
|
||
var data interface{} = this.SafeList(response, "data", []interface{}{})
|
||
var addressStructures interface{} = this.ParseDepositAddresses(data, nil, false)
|
||
|
||
ch <- this.IndexBy(addressStructures, "network")
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
func (this *coinbase) ParseDepositAddress(depositAddress interface{}, optionalArgs ...interface{}) interface{} {
|
||
//
|
||
// {
|
||
// id: '64ceb5f1-5fa2-5310-a4ff-9fd46271003d',
|
||
// address: '5xjPKeAXpnhA2kHyinvdVeui6RXVdEa3B2J3SCAwiKnk',
|
||
// address_info: {
|
||
// address: 'GCF74576I7AQ56SLMKBQAP255EGUOWCRVII3S44KEXVNJEOIFVBDMXVL',
|
||
// destination_tag: '3722061866'
|
||
// },
|
||
// name: null,
|
||
// created_at: '2023-05-29T21:12:12Z',
|
||
// updated_at: '2023-05-29T21:12:12Z',
|
||
// network: 'solana',
|
||
// uri_scheme: 'solana',
|
||
// resource: 'address',
|
||
// resource_path: '/v2/accounts/a7b3d387-bfb8-5ce7-b8da-1f507e81cf25/addresses/64ceb5f1-5fa2-5310-a4ff-9fd46271003d',
|
||
// warnings: [
|
||
// {
|
||
// type: 'correct_address_warning',
|
||
// title: 'This is an ERC20 USDC address.',
|
||
// details: 'Only send ERC20 USD Coin (USDC) to this address.',
|
||
// image_url: 'https://www.coinbase.com/assets/addresses/global-receive-warning-a3d91807e61c717e5a38d270965003dcc025ca8a3cea40ec3d7835b7c86087fa.png',
|
||
// options: [ { text: 'I understand', style: 'primary', id: 'dismiss' } ]
|
||
// }
|
||
// ],
|
||
// qr_code_image_url: 'https://static-assets.coinbase.com/p2p/l2/asset_network_combinations/v5/usdc-solana.png',
|
||
// address_label: 'USDC address (Solana)',
|
||
// default_receive: true,
|
||
// deposit_uri: 'solana:5xjPKeAXpnhA2kHyinvdVeui6RXVdEa3B2J3SCAwiKnk?spl-token=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
|
||
// callback_url: null,
|
||
// share_address_copy: {
|
||
// line1: '5xjPKeAXpnhA2kHyinvdVeui6RXVdEa3B2J3SCAwiKnk',
|
||
// line2: 'This address can only receive USDC-SPL from Solana network. Don’t send USDC from other networks, other SPL tokens or NFTs, or it may result in a loss of funds.'
|
||
// },
|
||
// receive_subtitle: 'ERC-20',
|
||
// inline_warning: {
|
||
// text: 'This address can only receive USDC-SPL from Solana network. Don’t send USDC from other networks, other SPL tokens or NFTs, or it may result in a loss of funds.',
|
||
// tooltip: {
|
||
// title: 'USDC (Solana)',
|
||
// subtitle: 'This address can only receive USDC-SPL from Solana network.'
|
||
// }
|
||
// }
|
||
// }
|
||
//
|
||
currency := GetArg(optionalArgs, 0, nil)
|
||
_ = currency
|
||
var address interface{} = this.SafeString(depositAddress, "address")
|
||
this.CheckAddress(address)
|
||
var networkId interface{} = this.SafeString(depositAddress, "network")
|
||
var code interface{} = this.SafeCurrencyCode(nil, currency)
|
||
var addressLabel interface{} = this.SafeString(depositAddress, "address_label")
|
||
var currencyId interface{} = nil
|
||
if IsTrue(!IsEqual(addressLabel, nil)) {
|
||
var splitAddressLabel interface{} = Split(addressLabel, " ")
|
||
currencyId = this.SafeString(splitAddressLabel, 0)
|
||
}
|
||
var addressInfo interface{} = this.SafeDict(depositAddress, "address_info")
|
||
return map[string]interface{} {
|
||
"info": depositAddress,
|
||
"currency": this.SafeCurrencyCode(currencyId, currency),
|
||
"network": this.NetworkIdToCode(networkId, code),
|
||
"address": address,
|
||
"tag": this.SafeString(addressInfo, "destination_tag"),
|
||
}
|
||
}
|
||
/**
|
||
* @method
|
||
* @name coinbase#deposit
|
||
* @description make a deposit
|
||
* @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-deposits#deposit-funds
|
||
* @param {string} code unified currency code
|
||
* @param {float} amount the amount to deposit
|
||
* @param {string} id the payment method id to be used for the deposit, can be retrieved from v2PrivateGetPaymentMethods
|
||
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
* @param {string} [params.accountId] the id of the account to deposit into
|
||
* @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
||
*/
|
||
func (this *coinbase) Deposit(code interface{}, amount interface{}, id interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
||
_ = params
|
||
|
||
retRes42758 := (<-this.LoadMarkets())
|
||
PanicOnError(retRes42758)
|
||
var accountId interface{} = this.SafeString2(params, "account_id", "accountId")
|
||
params = this.Omit(params, []interface{}{"account_id", "accountId"})
|
||
if IsTrue(IsEqual(accountId, nil)) {
|
||
if IsTrue(IsEqual(code, nil)) {
|
||
panic(ArgumentsRequired(Add(this.Id, " deposit() requires an account_id (or accountId) parameter OR a currency code argument")))
|
||
}
|
||
|
||
accountId = (<-this.FindAccountId(code, params))
|
||
PanicOnError(accountId)
|
||
if IsTrue(IsEqual(accountId, nil)) {
|
||
panic(ExchangeError(Add(Add(this.Id, " deposit() could not find account id for "), code)))
|
||
}
|
||
}
|
||
var request interface{} = map[string]interface{} {
|
||
"account_id": accountId,
|
||
"amount": this.NumberToString(amount),
|
||
"currency": ToUpper(code),
|
||
"payment_method": id,
|
||
}
|
||
|
||
response:= (<-this.V2PrivatePostAccountsAccountIdDeposits(this.Extend(request, params)))
|
||
PanicOnError(response)
|
||
//
|
||
// {
|
||
// "data": {
|
||
// "id": "67e0eaec-07d7-54c4-a72c-2e92826897df",
|
||
// "status": "created",
|
||
// "payment_method": {
|
||
// "id": "83562370-3e5c-51db-87da-752af5ab9559",
|
||
// "resource": "payment_method",
|
||
// "resource_path": "/v2/payment-methods/83562370-3e5c-51db-87da-752af5ab9559"
|
||
// },
|
||
// "transaction": {
|
||
// "id": "441b9494-b3f0-5b98-b9b0-4d82c21c252a",
|
||
// "resource": "transaction",
|
||
// "resource_path": "/v2/accounts/2bbf394c-193b-5b2a-9155-3b4732659ede/transactions/441b9494-b3f0-5b98-b9b0-4d82c21c252a"
|
||
// },
|
||
// "amount": {
|
||
// "amount": "10.00",
|
||
// "currency": "USD"
|
||
// },
|
||
// "subtotal": {
|
||
// "amount": "10.00",
|
||
// "currency": "USD"
|
||
// },
|
||
// "created_at": "2015-01-31T20:49:02Z",
|
||
// "updated_at": "2015-02-11T16:54:02-08:00",
|
||
// "resource": "deposit",
|
||
// "resource_path": "/v2/accounts/2bbf394c-193b-5b2a-9155-3b4732659ede/deposits/67e0eaec-07d7-54c4-a72c-2e92826897df",
|
||
// "committed": true,
|
||
// "fee": {
|
||
// "amount": "0.00",
|
||
// "currency": "USD"
|
||
// },
|
||
// "payout_at": "2015-02-18T16:54:00-08:00"
|
||
// }
|
||
// }
|
||
//
|
||
var data interface{} = this.SafeDict(response, "data", map[string]interface{} {})
|
||
|
||
ch <- this.ParseTransaction(data)
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
/**
|
||
* @method
|
||
* @name coinbase#fetchDeposit
|
||
* @description fetch information on a deposit, fiat only, for crypto transactions use fetchLedger
|
||
* @see https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-deposits#show-deposit
|
||
* @param {string} id deposit id
|
||
* @param {string} [code] unified currency code
|
||
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
* @param {string} [params.accountId] the id of the account that the funds were deposited into
|
||
* @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
|
||
*/
|
||
func (this *coinbase) FetchDeposit(id interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
code := GetArg(optionalArgs, 0, nil)
|
||
_ = code
|
||
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
||
_ = params
|
||
|
||
retRes43468 := (<-this.LoadMarkets())
|
||
PanicOnError(retRes43468)
|
||
var accountId interface{} = this.SafeString2(params, "account_id", "accountId")
|
||
params = this.Omit(params, []interface{}{"account_id", "accountId"})
|
||
if IsTrue(IsEqual(accountId, nil)) {
|
||
if IsTrue(IsEqual(code, nil)) {
|
||
panic(ArgumentsRequired(Add(this.Id, " fetchDeposit() requires an account_id (or accountId) parameter OR a currency code argument")))
|
||
}
|
||
|
||
accountId = (<-this.FindAccountId(code, params))
|
||
PanicOnError(accountId)
|
||
if IsTrue(IsEqual(accountId, nil)) {
|
||
panic(ExchangeError(Add(Add(this.Id, " fetchDeposit() could not find account id for "), code)))
|
||
}
|
||
}
|
||
var request interface{} = map[string]interface{} {
|
||
"account_id": accountId,
|
||
"deposit_id": id,
|
||
}
|
||
|
||
response:= (<-this.V2PrivateGetAccountsAccountIdDepositsDepositId(this.Extend(request, params)))
|
||
PanicOnError(response)
|
||
//
|
||
// {
|
||
// "data": {
|
||
// "id": "67e0eaec-07d7-54c4-a72c-2e92826897df",
|
||
// "status": "completed",
|
||
// "payment_method": {
|
||
// "id": "83562370-3e5c-51db-87da-752af5ab9559",
|
||
// "resource": "payment_method",
|
||
// "resource_path": "/v2/payment-methods/83562370-3e5c-51db-87da-752af5ab9559"
|
||
// },
|
||
// "transaction": {
|
||
// "id": "441b9494-b3f0-5b98-b9b0-4d82c21c252a",
|
||
// "resource": "transaction",
|
||
// "resource_path": "/v2/accounts/2bbf394c-193b-5b2a-9155-3b4732659ede/transactions/441b9494-b3f0-5b98-b9b0-4d82c21c252a"
|
||
// },
|
||
// "amount": {
|
||
// "amount": "10.00",
|
||
// "currency": "USD"
|
||
// },
|
||
// "subtotal": {
|
||
// "amount": "10.00",
|
||
// "currency": "USD"
|
||
// },
|
||
// "created_at": "2015-01-31T20:49:02Z",
|
||
// "updated_at": "2015-02-11T16:54:02-08:00",
|
||
// "resource": "deposit",
|
||
// "resource_path": "/v2/accounts/2bbf394c-193b-5b2a-9155-3b4732659ede/deposits/67e0eaec-07d7-54c4-a72c-2e92826897df",
|
||
// "committed": true,
|
||
// "fee": {
|
||
// "amount": "0.00",
|
||
// "currency": "USD"
|
||
// },
|
||
// "payout_at": "2015-02-18T16:54:00-08:00"
|
||
// }
|
||
// }
|
||
//
|
||
var data interface{} = this.SafeDict(response, "data", map[string]interface{} {})
|
||
|
||
ch <- this.ParseTransaction(data)
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
/**
|
||
* @method
|
||
* @name coinbase#fetchDepositMethodIds
|
||
* @description fetch the deposit id for a fiat currency associated with this account
|
||
* @see https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_getpaymentmethods
|
||
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
* @returns {object} an array of [deposit id structures]{@link https://docs.ccxt.com/#/?id=deposit-id-structure}
|
||
*/
|
||
func (this *coinbase) FetchDepositMethodIds(optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
||
_ = params
|
||
|
||
retRes44128 := (<-this.LoadMarkets())
|
||
PanicOnError(retRes44128)
|
||
|
||
response:= (<-this.V3PrivateGetBrokeragePaymentMethods(params))
|
||
PanicOnError(response)
|
||
//
|
||
// {
|
||
// "payment_methods": [
|
||
// {
|
||
// "id": "21b39a5d-f7b46876fb2e",
|
||
// "type": "COINBASE_FIAT_ACCOUNT",
|
||
// "name": "CAD Wallet",
|
||
// "currency": "CAD",
|
||
// "verified": true,
|
||
// "allow_buy": false,
|
||
// "allow_sell": true,
|
||
// "allow_deposit": false,
|
||
// "allow_withdraw": false,
|
||
// "created_at": "2023-06-29T19:58:46Z",
|
||
// "updated_at": "2023-10-30T20:25:01Z"
|
||
// }
|
||
// ]
|
||
// }
|
||
//
|
||
var result interface{} = this.SafeList(response, "payment_methods", []interface{}{})
|
||
|
||
ch <- this.ParseDepositMethodIds(result)
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
/**
|
||
* @method
|
||
* @name coinbase#fetchDepositMethodId
|
||
* @description fetch the deposit id for a fiat currency associated with this account
|
||
* @see https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_getpaymentmethod
|
||
* @param {string} id the deposit payment method id
|
||
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
* @returns {object} a [deposit id structure]{@link https://docs.ccxt.com/#/?id=deposit-id-structure}
|
||
*/
|
||
func (this *coinbase) FetchDepositMethodId(id interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
||
_ = params
|
||
|
||
retRes44478 := (<-this.LoadMarkets())
|
||
PanicOnError(retRes44478)
|
||
var request interface{} = map[string]interface{} {
|
||
"payment_method_id": id,
|
||
}
|
||
|
||
response:= (<-this.V3PrivateGetBrokeragePaymentMethodsPaymentMethodId(this.Extend(request, params)))
|
||
PanicOnError(response)
|
||
//
|
||
// {
|
||
// "payment_method": {
|
||
// "id": "21b39a5d-f7b46876fb2e",
|
||
// "type": "COINBASE_FIAT_ACCOUNT",
|
||
// "name": "CAD Wallet",
|
||
// "currency": "CAD",
|
||
// "verified": true,
|
||
// "allow_buy": false,
|
||
// "allow_sell": true,
|
||
// "allow_deposit": false,
|
||
// "allow_withdraw": false,
|
||
// "created_at": "2023-06-29T19:58:46Z",
|
||
// "updated_at": "2023-10-30T20:25:01Z"
|
||
// }
|
||
// }
|
||
//
|
||
var result interface{} = this.SafeDict(response, "payment_method", map[string]interface{} {})
|
||
|
||
ch <- this.ParseDepositMethodId(result)
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
func (this *coinbase) ParseDepositMethodIds(ids interface{}, optionalArgs ...interface{}) interface{} {
|
||
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
||
_ = params
|
||
var result interface{} = []interface{}{}
|
||
for i := 0; IsLessThan(i, GetArrayLength(ids)); i++ {
|
||
var id interface{} = this.Extend(this.ParseDepositMethodId(GetValue(ids, i)), params)
|
||
AppendToArray(&result,id)
|
||
}
|
||
return result
|
||
}
|
||
func (this *coinbase) ParseDepositMethodId(depositId interface{}) interface{} {
|
||
return map[string]interface{} {
|
||
"info": depositId,
|
||
"id": this.SafeString(depositId, "id"),
|
||
"currency": this.SafeString(depositId, "currency"),
|
||
"verified": this.SafeBool(depositId, "verified"),
|
||
"tag": this.SafeString(depositId, "name"),
|
||
}
|
||
}
|
||
/**
|
||
* @method
|
||
* @name coinbase#fetchConvertQuote
|
||
* @description fetch a quote for converting from one currency to another
|
||
* @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_createconvertquote
|
||
* @param {string} fromCode the currency that you want to sell and convert from
|
||
* @param {string} toCode the currency that you want to buy and convert into
|
||
* @param {float} [amount] how much you want to trade in units of the from currency
|
||
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
* @param {object} [params.trade_incentive_metadata] an object to fill in user incentive data
|
||
* @param {string} [params.trade_incentive_metadata.user_incentive_id] the id of the incentive
|
||
* @param {string} [params.trade_incentive_metadata.code_val] the code value of the incentive
|
||
* @returns {object} a [conversion structure]{@link https://docs.ccxt.com/#/?id=conversion-structure}
|
||
*/
|
||
func (this *coinbase) FetchConvertQuote(fromCode interface{}, toCode interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
amount := GetArg(optionalArgs, 0, nil)
|
||
_ = amount
|
||
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
||
_ = params
|
||
|
||
retRes45078 := (<-this.LoadMarkets())
|
||
PanicOnError(retRes45078)
|
||
var request interface{} = map[string]interface{} {
|
||
"from_account": fromCode,
|
||
"to_account": toCode,
|
||
"amount": this.NumberToString(amount),
|
||
}
|
||
|
||
response:= (<-this.V3PrivatePostBrokerageConvertQuote(this.Extend(request, params)))
|
||
PanicOnError(response)
|
||
var data interface{} = this.SafeDict(response, "trade", map[string]interface{} {})
|
||
|
||
ch <- this.ParseConversion(data)
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
/**
|
||
* @method
|
||
* @name coinbase#createConvertTrade
|
||
* @description convert from one currency to another
|
||
* @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_commitconverttrade
|
||
* @param {string} id the id of the trade that you want to make
|
||
* @param {string} fromCode the currency that you want to sell and convert from
|
||
* @param {string} toCode the currency that you want to buy and convert into
|
||
* @param {float} [amount] how much you want to trade in units of the from currency
|
||
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
* @returns {object} a [conversion structure]{@link https://docs.ccxt.com/#/?id=conversion-structure}
|
||
*/
|
||
func (this *coinbase) CreateConvertTrade(id interface{}, fromCode interface{}, toCode interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
amount := GetArg(optionalArgs, 0, nil)
|
||
_ = amount
|
||
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
||
_ = params
|
||
|
||
retRes45318 := (<-this.LoadMarkets())
|
||
PanicOnError(retRes45318)
|
||
var request interface{} = map[string]interface{} {
|
||
"trade_id": id,
|
||
"from_account": fromCode,
|
||
"to_account": toCode,
|
||
}
|
||
|
||
response:= (<-this.V3PrivatePostBrokerageConvertTradeTradeId(this.Extend(request, params)))
|
||
PanicOnError(response)
|
||
var data interface{} = this.SafeDict(response, "trade", map[string]interface{} {})
|
||
|
||
ch <- this.ParseConversion(data)
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
/**
|
||
* @method
|
||
* @name coinbase#fetchConvertTrade
|
||
* @description fetch the data for a conversion trade
|
||
* @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getconverttrade
|
||
* @param {string} id the id of the trade that you want to commit
|
||
* @param {string} code the unified currency code that was converted from
|
||
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
* @param {strng} params.toCode the unified currency code that was converted into
|
||
* @returns {object} a [conversion structure]{@link https://docs.ccxt.com/#/?id=conversion-structure}
|
||
*/
|
||
func (this *coinbase) FetchConvertTrade(id interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
code := GetArg(optionalArgs, 0, nil)
|
||
_ = code
|
||
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
||
_ = params
|
||
|
||
retRes45548 := (<-this.LoadMarkets())
|
||
PanicOnError(retRes45548)
|
||
if IsTrue(IsEqual(code, nil)) {
|
||
panic(ArgumentsRequired(Add(this.Id, " fetchConvertTrade() requires a code argument")))
|
||
}
|
||
var toCode interface{} = this.SafeString(params, "toCode")
|
||
if IsTrue(IsEqual(toCode, nil)) {
|
||
panic(ArgumentsRequired(Add(this.Id, " fetchConvertTrade() requires a toCode parameter")))
|
||
}
|
||
params = this.Omit(params, "toCode")
|
||
var request interface{} = map[string]interface{} {
|
||
"trade_id": id,
|
||
"from_account": code,
|
||
"to_account": toCode,
|
||
}
|
||
|
||
response:= (<-this.V3PrivateGetBrokerageConvertTradeTradeId(this.Extend(request, params)))
|
||
PanicOnError(response)
|
||
var data interface{} = this.SafeDict(response, "trade", map[string]interface{} {})
|
||
|
||
ch <- this.ParseConversion(data)
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
func (this *coinbase) ParseConversion(conversion interface{}, optionalArgs ...interface{}) interface{} {
|
||
fromCurrency := GetArg(optionalArgs, 0, nil)
|
||
_ = fromCurrency
|
||
toCurrency := GetArg(optionalArgs, 1, nil)
|
||
_ = toCurrency
|
||
var fromCoin interface{} = this.SafeString(conversion, "source_currency")
|
||
var fromCode interface{} = this.SafeCurrencyCode(fromCoin, fromCurrency)
|
||
var to interface{} = this.SafeString(conversion, "target_currency")
|
||
var toCode interface{} = this.SafeCurrencyCode(to, toCurrency)
|
||
var fromAmountStructure interface{} = this.SafeDict(conversion, "user_entered_amount")
|
||
var feeStructure interface{} = this.SafeDict(conversion, "total_fee")
|
||
var feeAmountStructure interface{} = this.SafeDict(feeStructure, "amount")
|
||
return map[string]interface{} {
|
||
"info": conversion,
|
||
"timestamp": nil,
|
||
"datetime": nil,
|
||
"id": this.SafeString(conversion, "id"),
|
||
"fromCurrency": fromCode,
|
||
"fromAmount": this.SafeNumber(fromAmountStructure, "value"),
|
||
"toCurrency": toCode,
|
||
"toAmount": nil,
|
||
"price": nil,
|
||
"fee": this.SafeNumber(feeAmountStructure, "value"),
|
||
}
|
||
}
|
||
/**
|
||
* @method
|
||
* @name coinbase#closePosition
|
||
* @description *futures only* closes open positions for a market
|
||
* @see https://coinbase-api.github.io/docs/#/en-us/swapV2/trade-api.html#One-Click%20Close%20All%20Positions
|
||
* @param {string} symbol Unified CCXT market symbol
|
||
* @param {string} [side] not used by coinbase
|
||
* @param {object} [params] extra parameters specific to the coinbase api endpoint
|
||
* @param {string} params.clientOrderId *mandatory* the client order id of the position to close
|
||
* @param {float} [params.size] the size of the position to close, optional
|
||
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
||
*/
|
||
func (this *coinbase) ClosePosition(symbol interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
side := GetArg(optionalArgs, 0, nil)
|
||
_ = side
|
||
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
||
_ = params
|
||
|
||
retRes46088 := (<-this.LoadMarkets())
|
||
PanicOnError(retRes46088)
|
||
var market interface{} = this.Market(symbol)
|
||
if !IsTrue(GetValue(market, "future")) {
|
||
panic(NotSupported(Add(this.Id, " closePosition() only supported for futures markets")))
|
||
}
|
||
var clientOrderId interface{} = this.SafeString2(params, "client_order_id", "clientOrderId")
|
||
params = this.Omit(params, "clientOrderId")
|
||
var request interface{} = map[string]interface{} {
|
||
"product_id": GetValue(market, "id"),
|
||
}
|
||
if IsTrue(IsEqual(clientOrderId, nil)) {
|
||
panic(ArgumentsRequired(Add(this.Id, " closePosition() requires a clientOrderId parameter")))
|
||
}
|
||
AddElementToObject(request, "client_order_id", clientOrderId)
|
||
|
||
response:= (<-this.V3PrivatePostBrokerageOrdersClosePosition(this.Extend(request, params)))
|
||
PanicOnError(response)
|
||
var order interface{} = this.SafeDict(response, "success_response", map[string]interface{} {})
|
||
|
||
ch <- this.ParseOrder(order)
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
/**
|
||
* @method
|
||
* @name coinbase#fetchPositions
|
||
* @description fetch all open positions
|
||
* @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getfcmpositions
|
||
* @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getintxpositions
|
||
* @param {string[]} [symbols] list of unified market symbols
|
||
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
* @param {string} [params.portfolio] the portfolio UUID to fetch positions for
|
||
* @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/#/?id=position-structure}
|
||
*/
|
||
func (this *coinbase) FetchPositions(optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
symbols := GetArg(optionalArgs, 0, nil)
|
||
_ = symbols
|
||
params := GetArg(optionalArgs, 1, map[string]interface{} {})
|
||
_ = params
|
||
|
||
retRes46398 := (<-this.LoadMarkets())
|
||
PanicOnError(retRes46398)
|
||
symbols = this.MarketSymbols(symbols)
|
||
var market interface{} = nil
|
||
if IsTrue(!IsEqual(symbols, nil)) {
|
||
market = this.Market(GetValue(symbols, 0))
|
||
}
|
||
var typeVar interface{} = nil
|
||
typeVarparamsVariable := this.HandleMarketTypeAndParams("fetchPositions", market, params);
|
||
typeVar = GetValue(typeVarparamsVariable,0);
|
||
params = GetValue(typeVarparamsVariable,1)
|
||
var response interface{} = nil
|
||
if IsTrue(IsEqual(typeVar, "future")) {
|
||
|
||
response = (<-this.V3PrivateGetBrokerageCfmPositions(params))
|
||
PanicOnError(response)
|
||
} else {
|
||
var portfolio interface{} = nil
|
||
portfolioparamsVariable := this.HandleOptionAndParams(params, "fetchPositions", "portfolio");
|
||
portfolio = GetValue(portfolioparamsVariable,0);
|
||
params = GetValue(portfolioparamsVariable,1)
|
||
if IsTrue(IsEqual(portfolio, nil)) {
|
||
panic(ArgumentsRequired(Add(this.Id, " fetchPositions() requires a \"portfolio\" value in params (eg: dbcb91e7-2bc9-515), or set as exchange.options[\"portfolio\"]. You can get a list of portfolios with fetchPortfolios()")))
|
||
}
|
||
var request interface{} = map[string]interface{} {
|
||
"portfolio_uuid": portfolio,
|
||
}
|
||
|
||
response = (<-this.V3PrivateGetBrokerageIntxPositionsPortfolioUuid(this.Extend(request, params)))
|
||
PanicOnError(response)
|
||
}
|
||
var positions interface{} = this.SafeList(response, "positions", []interface{}{})
|
||
|
||
ch <- this.ParsePositions(positions, symbols)
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
/**
|
||
* @method
|
||
* @name coinbase#fetchPosition
|
||
* @description fetch data on a single open contract trade position
|
||
* @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getintxposition
|
||
* @see https://docs.cloud.coinbase.com/advanced-trade/reference/retailbrokerageapi_getfcmposition
|
||
* @param {string} symbol unified market symbol of the market the position is held in, default is undefined
|
||
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
* @param {string} [params.product_id] *futures only* the product id of the position to fetch, required for futures markets only
|
||
* @param {string} [params.portfolio] *perpetual/swaps only* the portfolio UUID to fetch the position for, required for perpetual/swaps markets only
|
||
* @returns {object} a [position structure]{@link https://docs.ccxt.com/#/?id=position-structure}
|
||
*/
|
||
func (this *coinbase) FetchPosition(symbol interface{}, optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
||
_ = params
|
||
|
||
retRes46788 := (<-this.LoadMarkets())
|
||
PanicOnError(retRes46788)
|
||
var market interface{} = this.Market(symbol)
|
||
var response interface{} = nil
|
||
if IsTrue(GetValue(market, "future")) {
|
||
var productId interface{} = this.SafeString(market, "product_id")
|
||
if IsTrue(IsEqual(productId, nil)) {
|
||
panic(ArgumentsRequired(Add(this.Id, " fetchPosition() requires a \"product_id\" in params")))
|
||
}
|
||
var futureRequest interface{} = map[string]interface{} {
|
||
"product_id": productId,
|
||
}
|
||
|
||
response = (<-this.V3PrivateGetBrokerageCfmPositionsProductId(this.Extend(futureRequest, params)))
|
||
PanicOnError(response)
|
||
} else {
|
||
var portfolio interface{} = nil
|
||
portfolioparamsVariable := this.HandleOptionAndParams(params, "fetchPositions", "portfolio");
|
||
portfolio = GetValue(portfolioparamsVariable,0);
|
||
params = GetValue(portfolioparamsVariable,1)
|
||
if IsTrue(IsEqual(portfolio, nil)) {
|
||
panic(ArgumentsRequired(Add(this.Id, " fetchPosition() requires a \"portfolio\" value in params (eg: dbcb91e7-2bc9-515), or set as exchange.options[\"portfolio\"]. You can get a list of portfolios with fetchPortfolios()")))
|
||
}
|
||
var request interface{} = map[string]interface{} {
|
||
"symbol": GetValue(market, "id"),
|
||
"portfolio_uuid": portfolio,
|
||
}
|
||
|
||
response = (<-this.V3PrivateGetBrokerageIntxPositionsPortfolioUuidSymbol(this.Extend(request, params)))
|
||
PanicOnError(response)
|
||
}
|
||
var position interface{} = this.SafeDict(response, "position", map[string]interface{} {})
|
||
|
||
ch <- this.ParsePosition(position, market)
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
func (this *coinbase) ParsePosition(position interface{}, optionalArgs ...interface{}) interface{} {
|
||
//
|
||
// {
|
||
// "product_id": "1r4njf84-0-0",
|
||
// "product_uuid": "cd34c18b-3665-4ed8-9305-3db277c49fc5",
|
||
// "symbol": "ADA-PERP-INTX",
|
||
// "vwap": {
|
||
// "value": "0.6171",
|
||
// "currency": "USDC"
|
||
// },
|
||
// "position_side": "POSITION_SIDE_LONG",
|
||
// "net_size": "20",
|
||
// "buy_order_size": "0",
|
||
// "sell_order_size": "0",
|
||
// "im_contribution": "0.1",
|
||
// "unrealized_pnl": {
|
||
// "value": "0.074",
|
||
// "currency": "USDC"
|
||
// },
|
||
// "mark_price": {
|
||
// "value": "0.6208",
|
||
// "currency": "USDC"
|
||
// },
|
||
// "liquidation_price": {
|
||
// "value": "0",
|
||
// "currency": "USDC"
|
||
// },
|
||
// "leverage": "1",
|
||
// "im_notional": {
|
||
// "value": "12.342",
|
||
// "currency": "USDC"
|
||
// },
|
||
// "mm_notional": {
|
||
// "value": "0.814572",
|
||
// "currency": "USDC"
|
||
// },
|
||
// "position_notional": {
|
||
// "value": "12.342",
|
||
// "currency": "USDC"
|
||
// },
|
||
// "margin_type": "MARGIN_TYPE_CROSS",
|
||
// "liquidation_buffer": "19.677828",
|
||
// "liquidation_percentage": "4689.3506",
|
||
// "portfolio_summary": {
|
||
// "portfolio_uuid": "018ebd63-1f6d-7c8e-ada9-0761c5a2235f",
|
||
// "collateral": "20.4184",
|
||
// "position_notional": "12.342",
|
||
// "open_position_notional": "12.342",
|
||
// "pending_fees": "0",
|
||
// "borrow": "0",
|
||
// "accrued_interest": "0",
|
||
// "rolling_debt": "0",
|
||
// "portfolio_initial_margin": "0.1",
|
||
// "portfolio_im_notional": {
|
||
// "value": "12.342",
|
||
// "currency": "USDC"
|
||
// },
|
||
// "portfolio_maintenance_margin": "0.066",
|
||
// "portfolio_mm_notional": {
|
||
// "value": "0.814572",
|
||
// "currency": "USDC"
|
||
// },
|
||
// "liquidation_percentage": "4689.3506",
|
||
// "liquidation_buffer": "19.677828",
|
||
// "margin_type": "MARGIN_TYPE_CROSS",
|
||
// "margin_flags": "PORTFOLIO_MARGIN_FLAGS_UNSPECIFIED",
|
||
// "liquidation_status": "PORTFOLIO_LIQUIDATION_STATUS_NOT_LIQUIDATING",
|
||
// "unrealized_pnl": {
|
||
// "value": "0.074",
|
||
// "currency": "USDC"
|
||
// },
|
||
// "buying_power": {
|
||
// "value": "8.1504",
|
||
// "currency": "USDC"
|
||
// },
|
||
// "total_balance": {
|
||
// "value": "20.4924",
|
||
// "currency": "USDC"
|
||
// },
|
||
// "max_withdrawal": {
|
||
// "value": "8.0764",
|
||
// "currency": "USDC"
|
||
// }
|
||
// },
|
||
// "entry_vwap": {
|
||
// "value": "0.6091",
|
||
// "currency": "USDC"
|
||
// }
|
||
// }
|
||
//
|
||
market := GetArg(optionalArgs, 0, nil)
|
||
_ = market
|
||
var marketId interface{} = this.SafeString(position, "symbol", "")
|
||
market = this.SafeMarket(marketId, market)
|
||
var rawMargin interface{} = this.SafeString(position, "margin_type")
|
||
var marginMode interface{} = nil
|
||
if IsTrue(!IsEqual(rawMargin, nil)) {
|
||
marginMode = Ternary(IsTrue((IsEqual(rawMargin, "MARGIN_TYPE_CROSS"))), "cross", "isolated")
|
||
}
|
||
var notionalObject interface{} = this.SafeDict(position, "position_notional", map[string]interface{} {})
|
||
var positionSide interface{} = this.SafeString(position, "position_side")
|
||
var side interface{} = Ternary(IsTrue((IsEqual(positionSide, "POSITION_SIDE_LONG"))), "long", "short")
|
||
var unrealizedPNLObject interface{} = this.SafeDict(position, "unrealized_pnl", map[string]interface{} {})
|
||
var liquidationPriceObject interface{} = this.SafeDict(position, "liquidation_price", map[string]interface{} {})
|
||
var liquidationPrice interface{} = this.SafeNumber(liquidationPriceObject, "value")
|
||
var vwapObject interface{} = this.SafeDict(position, "vwap", map[string]interface{} {})
|
||
var summaryObject interface{} = this.SafeDict(position, "portfolio_summary", map[string]interface{} {})
|
||
return this.SafePosition(map[string]interface{} {
|
||
"info": position,
|
||
"id": this.SafeString(position, "product_id"),
|
||
"symbol": this.SafeSymbol(marketId, market),
|
||
"notional": this.SafeNumber(notionalObject, "value"),
|
||
"marginMode": marginMode,
|
||
"liquidationPrice": liquidationPrice,
|
||
"entryPrice": this.SafeNumber(vwapObject, "value"),
|
||
"unrealizedPnl": this.SafeNumber(unrealizedPNLObject, "value"),
|
||
"realizedPnl": nil,
|
||
"percentage": nil,
|
||
"contracts": this.SafeNumber(position, "net_size"),
|
||
"contractSize": GetValue(market, "contractSize"),
|
||
"markPrice": nil,
|
||
"lastPrice": nil,
|
||
"side": side,
|
||
"hedged": nil,
|
||
"timestamp": nil,
|
||
"datetime": nil,
|
||
"lastUpdateTimestamp": nil,
|
||
"maintenanceMargin": nil,
|
||
"maintenanceMarginPercentage": nil,
|
||
"collateral": this.SafeNumber(summaryObject, "collateral"),
|
||
"initialMargin": nil,
|
||
"initialMarginPercentage": nil,
|
||
"leverage": this.SafeNumber(position, "leverage"),
|
||
"marginRatio": nil,
|
||
"stopLossPrice": nil,
|
||
"takeProfitPrice": nil,
|
||
})
|
||
}
|
||
/**
|
||
* @method
|
||
* @name coinbase#fetchTradingFees
|
||
* @see https://docs.cdp.coinbase.com/advanced-trade/reference/retailbrokerageapi_gettransactionsummary/
|
||
* @description fetch the trading fees for multiple markets
|
||
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
||
* @param {string} [params.type] 'spot' or 'swap'
|
||
* @returns {object} a dictionary of [fee structures]{@link https://docs.ccxt.com/#/?id=fee-structure} indexed by market symbols
|
||
*/
|
||
func (this *coinbase) FetchTradingFees(optionalArgs ...interface{}) <- chan interface{} {
|
||
ch := make(chan interface{})
|
||
go func() interface{} {
|
||
defer close(ch)
|
||
defer ReturnPanicError(ch)
|
||
params := GetArg(optionalArgs, 0, map[string]interface{} {})
|
||
_ = params
|
||
|
||
retRes48538 := (<-this.LoadMarkets())
|
||
PanicOnError(retRes48538)
|
||
var typeVar interface{} = nil
|
||
typeVarparamsVariable := this.HandleMarketTypeAndParams("fetchTradingFees", nil, params);
|
||
typeVar = GetValue(typeVarparamsVariable,0);
|
||
params = GetValue(typeVarparamsVariable,1)
|
||
var isSpot interface{} = (IsEqual(typeVar, "spot"))
|
||
var productType interface{} = Ternary(IsTrue(isSpot), "SPOT", "FUTURE")
|
||
var request interface{} = map[string]interface{} {
|
||
"product_type": productType,
|
||
}
|
||
|
||
response:= (<-this.V3PrivateGetBrokerageTransactionSummary(this.Extend(request, params)))
|
||
PanicOnError(response)
|
||
//
|
||
// {
|
||
// total_volume: '0',
|
||
// total_fees: '0',
|
||
// fee_tier: {
|
||
// pricing_tier: 'Advanced 1',
|
||
// usd_from: '0',
|
||
// usd_to: '1000',
|
||
// taker_fee_rate: '0.008',
|
||
// maker_fee_rate: '0.006',
|
||
// aop_from: '',
|
||
// aop_to: ''
|
||
// },
|
||
// margin_rate: null,
|
||
// goods_and_services_tax: null,
|
||
// advanced_trade_only_volume: '0',
|
||
// advanced_trade_only_fees: '0',
|
||
// coinbase_pro_volume: '0',
|
||
// coinbase_pro_fees: '0',
|
||
// total_balance: '',
|
||
// has_promo_fee: false
|
||
// }
|
||
//
|
||
var data interface{} = this.SafeDict(response, "fee_tier", map[string]interface{} {})
|
||
var taker_fee interface{} = this.SafeNumber(data, "taker_fee_rate")
|
||
var marker_fee interface{} = this.SafeNumber(data, "maker_fee_rate")
|
||
var result interface{} = map[string]interface{} {}
|
||
for i := 0; IsLessThan(i, GetArrayLength(this.Symbols)); i++ {
|
||
var symbol interface{} = GetValue(this.Symbols, i)
|
||
var market interface{} = this.Market(symbol)
|
||
if IsTrue(IsTrue((IsTrue(isSpot) && IsTrue(GetValue(market, "spot")))) || IsTrue((!IsTrue(isSpot) && !IsTrue(GetValue(market, "spot"))))) {
|
||
AddElementToObject(result, symbol, map[string]interface{} {
|
||
"info": response,
|
||
"symbol": symbol,
|
||
"maker": taker_fee,
|
||
"taker": marker_fee,
|
||
"percentage": true,
|
||
})
|
||
}
|
||
}
|
||
|
||
ch <- result
|
||
return nil
|
||
|
||
}()
|
||
return ch
|
||
}
|
||
func (this *coinbase) CreateAuthToken(seconds interface{}, optionalArgs ...interface{}) interface{} {
|
||
// it may not work for v2
|
||
method := GetArg(optionalArgs, 0, nil)
|
||
_ = method
|
||
url := GetArg(optionalArgs, 1, nil)
|
||
_ = url
|
||
var uri interface{} = nil
|
||
if IsTrue(!IsEqual(url, nil)) {
|
||
uri = Add(Add(method, " "), Replace(url, "https://", ""))
|
||
var quesPos interface{} = GetIndexOf(uri, "?")
|
||
// Due to we use mb_strpos, quesPos could be false in php. In that case, the quesPos >= 0 is true
|
||
// Also it's not possible that the question mark is first character, only check > 0 here.
|
||
if IsTrue(IsGreaterThan(quesPos, 0)) {
|
||
uri = Slice(uri, 0, quesPos)
|
||
}
|
||
}
|
||
var nonce interface{} = this.RandomBytes(16)
|
||
var request interface{} = map[string]interface{} {
|
||
"aud": []interface{}{"retail_rest_api_proxy"},
|
||
"iss": "coinbase-cloud",
|
||
"nbf": seconds,
|
||
"exp": Add(seconds, 120),
|
||
"sub": this.ApiKey,
|
||
"iat": seconds,
|
||
}
|
||
if IsTrue(!IsEqual(uri, nil)) {
|
||
AddElementToObject(request, "uri", uri)
|
||
}
|
||
var token interface{} = Jwt(request, this.Encode(this.Secret), sha256, false, map[string]interface{} {
|
||
"kid": this.ApiKey,
|
||
"nonce": nonce,
|
||
"alg": "ES256",
|
||
})
|
||
return token
|
||
}
|
||
func (this *coinbase) Nonce() interface{} {
|
||
return Subtract(this.Milliseconds(), GetValue(this.Options, "timeDifference"))
|
||
}
|
||
func (this *coinbase) Sign(path interface{}, optionalArgs ...interface{}) interface{} {
|
||
api := GetArg(optionalArgs, 0, []interface{}{})
|
||
_ = api
|
||
method := GetArg(optionalArgs, 1, "GET")
|
||
_ = method
|
||
params := GetArg(optionalArgs, 2, map[string]interface{} {})
|
||
_ = params
|
||
headers := GetArg(optionalArgs, 3, nil)
|
||
_ = headers
|
||
body := GetArg(optionalArgs, 4, nil)
|
||
_ = body
|
||
var version interface{} = GetValue(api, 0)
|
||
var signed interface{} = IsEqual(GetValue(api, 1), "private")
|
||
var isV3 interface{} = IsEqual(version, "v3")
|
||
var pathPart interface{} = Ternary(IsTrue((isV3)), "api/v3", "v2")
|
||
var fullPath interface{} = Add(Add(Add("/", pathPart), "/"), this.ImplodeParams(path, params))
|
||
var query interface{} = this.Omit(params, this.ExtractParams(path))
|
||
var savedPath interface{} = fullPath
|
||
if IsTrue(IsEqual(method, "GET")) {
|
||
if IsTrue(GetArrayLength(ObjectKeys(query))) {
|
||
fullPath = Add(fullPath, Add("?", this.UrlencodeWithArrayRepeat(query)))
|
||
}
|
||
}
|
||
var url interface{} = Add(GetValue(GetValue(this.Urls, "api"), "rest"), fullPath)
|
||
if IsTrue(signed) {
|
||
var authorization interface{} = this.SafeString(this.Headers, "Authorization")
|
||
var authorizationString interface{} = nil
|
||
if IsTrue(!IsEqual(authorization, nil)) {
|
||
authorizationString = authorization
|
||
} else if IsTrue(IsTrue(this.Token) && !IsTrue(this.CheckRequiredCredentials(false))) {
|
||
authorizationString = Add("Bearer ", this.Token)
|
||
} else {
|
||
this.CheckRequiredCredentials()
|
||
var seconds interface{} = this.Seconds()
|
||
var payload interface{} = ""
|
||
if IsTrue(!IsEqual(method, "GET")) {
|
||
if IsTrue(GetArrayLength(ObjectKeys(query))) {
|
||
body = this.Json(query)
|
||
payload = body
|
||
}
|
||
} else {
|
||
if !IsTrue(isV3) {
|
||
if IsTrue(GetArrayLength(ObjectKeys(query))) {
|
||
payload = Add(payload, Add("?", this.Urlencode(query)))
|
||
}
|
||
}
|
||
}
|
||
// v3: 'GET' doesn't need payload in the signature. inside url is enough
|
||
// https://docs.cloud.coinbase.com/advanced-trade/docs/auth#example-request
|
||
// v2: 'GET' require payload in the signature
|
||
// https://docs.cloud.coinbase.com/sign-in-with-coinbase/docs/api-key-authentication
|
||
var isCloudAPiKey interface{} = IsTrue((IsGreaterThanOrEqual(GetIndexOf(this.ApiKey, "organizations/"), 0))) || IsTrue((StartsWith(this.Secret, "-----BEGIN")))
|
||
if IsTrue(isCloudAPiKey) {
|
||
if IsTrue(StartsWith(this.ApiKey, "-----BEGIN")) {
|
||
panic(ArgumentsRequired(Add(this.Id, " apiKey should contain the name (eg: organizations/3b910e93....) and not the public key")))
|
||
}
|
||
// // it may not work for v2
|
||
// let uri = method + ' ' + url.replace ('https://', '');
|
||
// const quesPos = uri.indexOf ('?');
|
||
// // Due to we use mb_strpos, quesPos could be false in php. In that case, the quesPos >= 0 is true
|
||
// // Also it's not possible that the question mark is first character, only check > 0 here.
|
||
// if (quesPos > 0) {
|
||
// uri = uri.slice (0, quesPos);
|
||
// }
|
||
// const nonce = this.randomBytes (16);
|
||
// const request: Dict = {
|
||
// 'aud': [ 'retail_rest_api_proxy' ],
|
||
// 'iss': 'coinbase-cloud',
|
||
// 'nbf': seconds,
|
||
// 'exp': seconds + 120,
|
||
// 'sub': this.apiKey,
|
||
// 'uri': uri,
|
||
// 'iat': seconds,
|
||
// };
|
||
var token interface{} = this.CreateAuthToken(seconds, method, url)
|
||
// const token = jwt (request, this.encode (this.secret), sha256, false, { 'kid': this.apiKey, 'nonce': nonce, 'alg': 'ES256' });
|
||
authorizationString = Add("Bearer ", token)
|
||
} else {
|
||
var nonce interface{} = this.Nonce()
|
||
var timestamp interface{} = this.ParseToInt(Divide(nonce, 1000))
|
||
var timestampString interface{} = ToString(timestamp)
|
||
var auth interface{} = Add(Add(Add(timestampString, method), savedPath), payload)
|
||
var signature interface{} = this.Hmac(this.Encode(auth), this.Encode(this.Secret), sha256)
|
||
headers = map[string]interface{} {
|
||
"CB-ACCESS-KEY": this.ApiKey,
|
||
"CB-ACCESS-SIGN": signature,
|
||
"CB-ACCESS-TIMESTAMP": timestampString,
|
||
"Content-Type": "application/json",
|
||
}
|
||
}
|
||
}
|
||
if IsTrue(!IsEqual(authorizationString, nil)) {
|
||
headers = map[string]interface{} {
|
||
"Authorization": authorizationString,
|
||
"Content-Type": "application/json",
|
||
}
|
||
if IsTrue(!IsEqual(method, "GET")) {
|
||
if IsTrue(GetArrayLength(ObjectKeys(query))) {
|
||
body = this.Json(query)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return map[string]interface{} {
|
||
"url": url,
|
||
"method": method,
|
||
"body": body,
|
||
"headers": headers,
|
||
}
|
||
}
|
||
func (this *coinbase) HandleErrors(code interface{}, reason interface{}, url interface{}, method interface{}, headers interface{}, body interface{}, response interface{}, requestHeaders interface{}, requestBody interface{}) interface{} {
|
||
if IsTrue(IsEqual(response, nil)) {
|
||
return nil // fallback to default error handler
|
||
}
|
||
var feedback interface{} = Add(Add(this.Id, " "), body)
|
||
//
|
||
// {"error": "invalid_request", "error_description": "The request is missing a required parameter, includes an unsupported parameter value, or is otherwise malformed."}
|
||
//
|
||
// or
|
||
//
|
||
// {
|
||
// "errors": [
|
||
// {
|
||
// "id": "not_found",
|
||
// "message": "Not found"
|
||
// }
|
||
// ]
|
||
// }
|
||
// or
|
||
// {
|
||
// "error": "UNKNOWN_FAILURE_REASON",
|
||
// "message": "",
|
||
// "error_details": "",
|
||
// "preview_failure_reason": "PREVIEW_STOP_PRICE_BELOW_LAST_TRADE_PRICE"
|
||
// }
|
||
//
|
||
var errorCode interface{} = this.SafeString(response, "error")
|
||
if IsTrue(!IsEqual(errorCode, nil)) {
|
||
var errorMessage interface{} = this.SafeString2(response, "error_description", "preview_failure_reason")
|
||
this.ThrowExactlyMatchedException(GetValue(this.Exceptions, "exact"), errorCode, feedback)
|
||
this.ThrowBroadlyMatchedException(GetValue(this.Exceptions, "broad"), errorMessage, feedback)
|
||
panic(ExchangeError(feedback))
|
||
}
|
||
var errors interface{} = this.SafeList(response, "errors")
|
||
if IsTrue(!IsEqual(errors, nil)) {
|
||
if IsTrue(IsArray(errors)) {
|
||
var numErrors interface{} = GetArrayLength(errors)
|
||
if IsTrue(IsGreaterThan(numErrors, 0)) {
|
||
errorCode = this.SafeString(GetValue(errors, 0), "id")
|
||
var errorMessage interface{} = this.SafeString(GetValue(errors, 0), "message")
|
||
if IsTrue(!IsEqual(errorCode, nil)) {
|
||
this.ThrowExactlyMatchedException(GetValue(this.Exceptions, "exact"), errorCode, feedback)
|
||
this.ThrowBroadlyMatchedException(GetValue(this.Exceptions, "broad"), errorMessage, feedback)
|
||
panic(ExchangeError(feedback))
|
||
}
|
||
}
|
||
}
|
||
}
|
||
var advancedTrade interface{} = GetValue(this.Options, "advanced")
|
||
if IsTrue(!IsTrue((InOp(response, "data"))) && IsTrue((!IsTrue(advancedTrade)))) {
|
||
panic(ExchangeError(Add(Add(this.Id, " failed due to a malformed response "), this.Json(response))))
|
||
}
|
||
return nil
|
||
}
|
||
|
||
|
||
func (this *coinbase) Init(userConfig map[string]interface{}) {
|
||
this.Exchange = Exchange{}
|
||
this.Exchange.InitParent(userConfig, this.Describe().(map[string]interface{}), this)
|
||
this.Exchange.DerivedExchange = this
|
||
}
|