2201 lines
93 KiB
Go
2201 lines
93 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 cex struct {
|
|
Exchange
|
|
|
|
}
|
|
|
|
func NewCexCore() cex {
|
|
p := cex{}
|
|
setDefaults(&p)
|
|
return p
|
|
}
|
|
|
|
func (this *cex) Describe() interface{} {
|
|
return this.DeepExtend(this.Exchange.Describe(), map[string]interface{} {
|
|
"id": "cex",
|
|
"name": "CEX.IO",
|
|
"countries": []interface{}{"GB", "EU", "CY", "RU"},
|
|
"rateLimit": 300,
|
|
"pro": true,
|
|
"has": map[string]interface{} {
|
|
"CORS": nil,
|
|
"spot": true,
|
|
"margin": false,
|
|
"swap": false,
|
|
"future": false,
|
|
"option": false,
|
|
"cancelAllOrders": true,
|
|
"cancelOrder": true,
|
|
"createOrder": true,
|
|
"createStopOrder": true,
|
|
"createTriggerOrder": true,
|
|
"fetchAccounts": true,
|
|
"fetchBalance": true,
|
|
"fetchClosedOrder": true,
|
|
"fetchClosedOrders": true,
|
|
"fetchCurrencies": true,
|
|
"fetchDepositAddress": true,
|
|
"fetchDepositsWithdrawals": true,
|
|
"fetchFundingHistory": false,
|
|
"fetchFundingRate": false,
|
|
"fetchFundingRateHistory": false,
|
|
"fetchFundingRates": false,
|
|
"fetchLedger": true,
|
|
"fetchMarkets": true,
|
|
"fetchOHLCV": true,
|
|
"fetchOpenOrder": true,
|
|
"fetchOpenOrders": true,
|
|
"fetchOrderBook": true,
|
|
"fetchTicker": true,
|
|
"fetchTickers": true,
|
|
"fetchTime": true,
|
|
"fetchTrades": true,
|
|
"fetchTradingFees": true,
|
|
"transfer": true,
|
|
},
|
|
"urls": map[string]interface{} {
|
|
"logo": "https://user-images.githubusercontent.com/1294454/27766442-8ddc33b0-5ed8-11e7-8b98-f786aef0f3c9.jpg",
|
|
"api": map[string]interface{} {
|
|
"public": "https://trade.cex.io/api/spot/rest-public",
|
|
"private": "https://trade.cex.io/api/spot/rest",
|
|
},
|
|
"www": "https://cex.io",
|
|
"doc": "https://trade.cex.io/docs/",
|
|
"fees": []interface{}{"https://cex.io/fee-schedule", "https://cex.io/limits-commissions"},
|
|
"referral": "https://cex.io/r/0/up105393824/0/",
|
|
},
|
|
"api": map[string]interface{} {
|
|
"public": map[string]interface{} {
|
|
"get": map[string]interface{} {},
|
|
"post": map[string]interface{} {
|
|
"get_server_time": 1,
|
|
"get_pairs_info": 1,
|
|
"get_currencies_info": 1,
|
|
"get_processing_info": 10,
|
|
"get_ticker": 1,
|
|
"get_trade_history": 1,
|
|
"get_order_book": 1,
|
|
"get_candles": 1,
|
|
},
|
|
},
|
|
"private": map[string]interface{} {
|
|
"get": map[string]interface{} {},
|
|
"post": map[string]interface{} {
|
|
"get_my_current_fee": 5,
|
|
"get_fee_strategy": 1,
|
|
"get_my_volume": 5,
|
|
"do_create_account": 1,
|
|
"get_my_account_status_v3": 5,
|
|
"get_my_wallet_balance": 5,
|
|
"get_my_orders": 5,
|
|
"do_my_new_order": 1,
|
|
"do_cancel_my_order": 1,
|
|
"do_cancel_all_orders": 5,
|
|
"get_order_book": 1,
|
|
"get_candles": 1,
|
|
"get_trade_history": 1,
|
|
"get_my_transaction_history": 1,
|
|
"get_my_funding_history": 5,
|
|
"do_my_internal_transfer": 1,
|
|
"get_processing_info": 10,
|
|
"get_deposit_address": 5,
|
|
"do_deposit_funds_from_wallet": 1,
|
|
"do_withdrawal_funds_to_wallet": 1,
|
|
},
|
|
},
|
|
},
|
|
"features": map[string]interface{} {
|
|
"spot": map[string]interface{} {
|
|
"sandbox": false,
|
|
"createOrder": map[string]interface{} {
|
|
"marginMode": false,
|
|
"triggerPrice": true,
|
|
"triggerPriceType": nil,
|
|
"triggerDirection": false,
|
|
"stopLossPrice": false,
|
|
"takeProfitPrice": false,
|
|
"attachedStopLossTakeProfit": nil,
|
|
"timeInForce": map[string]interface{} {
|
|
"IOC": true,
|
|
"FOK": true,
|
|
"PO": false,
|
|
"GTD": true,
|
|
},
|
|
"hedged": false,
|
|
"leverage": false,
|
|
"marketBuyRequiresPrice": false,
|
|
"marketBuyByCost": true,
|
|
"selfTradePrevention": false,
|
|
"trailing": false,
|
|
"iceberg": false,
|
|
},
|
|
"createOrders": nil,
|
|
"fetchMyTrades": nil,
|
|
"fetchOrder": nil,
|
|
"fetchOpenOrders": map[string]interface{} {
|
|
"marginMode": false,
|
|
"limit": 1000,
|
|
"trigger": false,
|
|
"trailing": false,
|
|
"symbolRequired": false,
|
|
},
|
|
"fetchOrders": nil,
|
|
"fetchClosedOrders": map[string]interface{} {
|
|
"marginMode": false,
|
|
"limit": 1000,
|
|
"daysBack": 100000,
|
|
"daysBackCanceled": 1,
|
|
"untilDays": 100000,
|
|
"trigger": false,
|
|
"trailing": false,
|
|
"symbolRequired": false,
|
|
},
|
|
"fetchOHLCV": map[string]interface{} {
|
|
"limit": 1000,
|
|
},
|
|
},
|
|
"swap": map[string]interface{} {
|
|
"linear": nil,
|
|
"inverse": nil,
|
|
},
|
|
"future": map[string]interface{} {
|
|
"linear": nil,
|
|
"inverse": nil,
|
|
},
|
|
},
|
|
"precisionMode": TICK_SIZE,
|
|
"exceptions": map[string]interface{} {
|
|
"exact": map[string]interface{} {},
|
|
"broad": map[string]interface{} {
|
|
"You have negative balance on following accounts": InsufficientFunds,
|
|
"Mandatory parameter side should be one of BUY,SELL": BadRequest,
|
|
"API orders from Main account are not allowed": BadRequest,
|
|
"check failed": BadRequest,
|
|
"Insufficient funds": InsufficientFunds,
|
|
"Get deposit address for main account is not allowed": PermissionDenied,
|
|
"Market Trigger orders are not allowed": BadRequest,
|
|
"key not passed or incorrect": AuthenticationError,
|
|
},
|
|
},
|
|
"timeframes": map[string]interface{} {
|
|
"1m": "1m",
|
|
"5m": "5m",
|
|
"15m": "15m",
|
|
"30m": "30m",
|
|
"1h": "1h",
|
|
"2h": "2h",
|
|
"4h": "4h",
|
|
"1d": "1d",
|
|
},
|
|
"options": map[string]interface{} {
|
|
"networks": map[string]interface{} {
|
|
"BTC": "bitcoin",
|
|
"ERC20": "ERC20",
|
|
"BSC20": "binancesmartchain",
|
|
"DOGE": "dogecoin",
|
|
"ALGO": "algorand",
|
|
"XLM": "stellar",
|
|
"ATOM": "cosmos",
|
|
"LTC": "litecoin",
|
|
"XRP": "ripple",
|
|
"FTM": "fantom",
|
|
"MINA": "mina",
|
|
"THETA": "theta",
|
|
"XTZ": "tezos",
|
|
"TIA": "celestia",
|
|
"CRONOS": "cronos",
|
|
"MATIC": "polygon",
|
|
"TON": "ton",
|
|
"TRC20": "tron",
|
|
"SOLANA": "solana",
|
|
"SGB": "songbird",
|
|
"DYDX": "dydx",
|
|
"DASH": "dash",
|
|
"ZIL": "zilliqa",
|
|
"EOS": "eos",
|
|
"AVALANCHEC": "avalanche",
|
|
"ETHPOW": "ethereumpow",
|
|
"NEAR": "near",
|
|
"ARB": "arbitrum",
|
|
"DOT": "polkadot",
|
|
"OPT": "optimism",
|
|
"INJ": "injective",
|
|
"ADA": "cardano",
|
|
"ONT": "ontology",
|
|
"ICP": "icp",
|
|
"KAVA": "kava",
|
|
"KSM": "kusama",
|
|
"SEI": "sei",
|
|
"NEO": "neo",
|
|
"NEO3": "neo3",
|
|
"XDC": "xdc",
|
|
},
|
|
},
|
|
})
|
|
}
|
|
/**
|
|
* @method
|
|
* @name cex#fetchCurrencies
|
|
* @description fetches all available currencies on an exchange
|
|
* @see https://trade.cex.io/docs/#rest-public-api-calls-currencies-info
|
|
* @param {dict} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {dict} an associative dictionary of currencies
|
|
*/
|
|
func (this *cex) 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
|
|
var promises interface{} = []interface{}{}
|
|
AppendToArray(&promises,this.PublicPostGetCurrenciesInfo(params))
|
|
//
|
|
// {
|
|
// "ok": "ok",
|
|
// "data": [
|
|
// {
|
|
// "currency": "ZAP",
|
|
// "fiat": false,
|
|
// "precision": "8",
|
|
// "walletPrecision": "6",
|
|
// "walletDeposit": true,
|
|
// "walletWithdrawal": true
|
|
// },
|
|
// ...
|
|
//
|
|
AppendToArray(&promises,this.PublicPostGetProcessingInfo(params))
|
|
//
|
|
// {
|
|
// "ok": "ok",
|
|
// "data": {
|
|
// "ADA": {
|
|
// "name": "Cardano",
|
|
// "blockchains": {
|
|
// "cardano": {
|
|
// "type": "coin",
|
|
// "deposit": "enabled",
|
|
// "minDeposit": "1",
|
|
// "withdrawal": "enabled",
|
|
// "minWithdrawal": "5",
|
|
// "withdrawalFee": "1",
|
|
// "withdrawalFeePercent": "0",
|
|
// "depositConfirmations": "15"
|
|
// }
|
|
// }
|
|
// },
|
|
// ...
|
|
//
|
|
|
|
responses:= (<-promiseAll(promises))
|
|
PanicOnError(responses)
|
|
var dataCurrencies interface{} = this.SafeList(GetValue(responses, 0), "data", []interface{}{})
|
|
var dataNetworks interface{} = this.SafeDict(GetValue(responses, 1), "data", map[string]interface{} {})
|
|
var currenciesIndexed interface{} = this.IndexBy(dataCurrencies, "currency")
|
|
var data interface{} = this.DeepExtend(currenciesIndexed, dataNetworks)
|
|
|
|
ch <- this.ParseCurrencies(this.ToArray(data))
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *cex) ParseCurrency(rawCurrency interface{}) interface{} {
|
|
var id interface{} = this.SafeString(rawCurrency, "currency")
|
|
var code interface{} = this.SafeCurrencyCode(id)
|
|
var typeVar interface{} = Ternary(IsTrue(this.SafeBool(rawCurrency, "fiat")), "fiat", "crypto")
|
|
var currencyDepositEnabled interface{} = this.SafeBool(rawCurrency, "walletDeposit")
|
|
var currencyWithdrawEnabled interface{} = this.SafeBool(rawCurrency, "walletWithdrawal")
|
|
var currencyPrecision interface{} = this.ParseNumber(this.ParsePrecision(this.SafeString(rawCurrency, "precision")))
|
|
var networks interface{} = map[string]interface{} {}
|
|
var rawNetworks interface{} = this.SafeDict(rawCurrency, "blockchains", map[string]interface{} {})
|
|
var keys interface{} = ObjectKeys(rawNetworks)
|
|
for j := 0; IsLessThan(j, GetArrayLength(keys)); j++ {
|
|
var networkId interface{} = GetValue(keys, j)
|
|
var rawNetwork interface{} = GetValue(rawNetworks, networkId)
|
|
var networkCode interface{} = this.NetworkIdToCode(networkId)
|
|
var deposit interface{} = IsEqual(this.SafeString(rawNetwork, "deposit"), "enabled")
|
|
var withdraw interface{} = IsEqual(this.SafeString(rawNetwork, "withdrawal"), "enabled")
|
|
AddElementToObject(networks, networkCode, map[string]interface{} {
|
|
"id": networkId,
|
|
"network": networkCode,
|
|
"margin": nil,
|
|
"deposit": deposit,
|
|
"withdraw": withdraw,
|
|
"fee": this.SafeNumber(rawNetwork, "withdrawalFee"),
|
|
"precision": currencyPrecision,
|
|
"limits": map[string]interface{} {
|
|
"deposit": map[string]interface{} {
|
|
"min": this.SafeNumber(rawNetwork, "minDeposit"),
|
|
"max": nil,
|
|
},
|
|
"withdraw": map[string]interface{} {
|
|
"min": this.SafeNumber(rawNetwork, "minWithdrawal"),
|
|
"max": nil,
|
|
},
|
|
},
|
|
"info": rawNetwork,
|
|
})
|
|
}
|
|
return this.SafeCurrencyStructure(map[string]interface{} {
|
|
"id": id,
|
|
"code": code,
|
|
"name": nil,
|
|
"type": typeVar,
|
|
"active": nil,
|
|
"deposit": currencyDepositEnabled,
|
|
"withdraw": currencyWithdrawEnabled,
|
|
"fee": nil,
|
|
"precision": currencyPrecision,
|
|
"limits": map[string]interface{} {
|
|
"amount": map[string]interface{} {
|
|
"min": nil,
|
|
"max": nil,
|
|
},
|
|
"withdraw": map[string]interface{} {
|
|
"min": nil,
|
|
"max": nil,
|
|
},
|
|
},
|
|
"networks": networks,
|
|
"info": rawCurrency,
|
|
})
|
|
}
|
|
/**
|
|
* @method
|
|
* @name cex#fetchMarkets
|
|
* @description retrieves data on all markets for ace
|
|
* @see https://trade.cex.io/docs/#rest-public-api-calls-pairs-info
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object[]} an array of objects representing market data
|
|
*/
|
|
func (this *cex) 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
|
|
|
|
response:= (<-this.PublicPostGetPairsInfo(params))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "ok": "ok",
|
|
// "data": [
|
|
// {
|
|
// "base": "AI",
|
|
// "quote": "USD",
|
|
// "baseMin": "30",
|
|
// "baseMax": "2516000",
|
|
// "baseLotSize": "0.000001",
|
|
// "quoteMin": "10",
|
|
// "quoteMax": "1000000",
|
|
// "quoteLotSize": "0.01000000",
|
|
// "basePrecision": "6",
|
|
// "quotePrecision": "8",
|
|
// "pricePrecision": "4",
|
|
// "minPrice": "0.0377",
|
|
// "maxPrice": "19.5000"
|
|
// },
|
|
// ...
|
|
//
|
|
var data interface{} = this.SafeList(response, "data", []interface{}{})
|
|
|
|
ch <- this.ParseMarkets(data)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *cex) ParseMarket(market interface{}) interface{} {
|
|
var baseId interface{} = this.SafeString(market, "base")
|
|
var base interface{} = this.SafeCurrencyCode(baseId)
|
|
var quoteId interface{} = this.SafeString(market, "quote")
|
|
var quote interface{} = this.SafeCurrencyCode(quoteId)
|
|
var id interface{} = Add(Add(base, "-"), quote) // not actual id, but for this exchange we can use this abbreviation, because e.g. tickers have hyphen in between
|
|
var symbol interface{} = Add(Add(base, "/"), quote)
|
|
return this.SafeMarketStructure(map[string]interface{} {
|
|
"id": id,
|
|
"symbol": symbol,
|
|
"base": base,
|
|
"baseId": baseId,
|
|
"quote": quote,
|
|
"quoteId": quoteId,
|
|
"settle": nil,
|
|
"settleId": nil,
|
|
"type": "spot",
|
|
"spot": true,
|
|
"margin": false,
|
|
"swap": false,
|
|
"future": false,
|
|
"option": false,
|
|
"contract": false,
|
|
"linear": nil,
|
|
"inverse": nil,
|
|
"contractSize": nil,
|
|
"expiry": nil,
|
|
"expiryDatetime": nil,
|
|
"strike": nil,
|
|
"optionType": nil,
|
|
"limits": map[string]interface{} {
|
|
"amount": map[string]interface{} {
|
|
"min": this.SafeNumber(market, "baseMin"),
|
|
"max": this.SafeNumber(market, "baseMax"),
|
|
},
|
|
"price": map[string]interface{} {
|
|
"min": this.SafeNumber(market, "minPrice"),
|
|
"max": this.SafeNumber(market, "maxPrice"),
|
|
},
|
|
"cost": map[string]interface{} {
|
|
"min": this.SafeNumber(market, "quoteMin"),
|
|
"max": this.SafeNumber(market, "quoteMax"),
|
|
},
|
|
"leverage": map[string]interface{} {
|
|
"min": nil,
|
|
"max": nil,
|
|
},
|
|
},
|
|
"precision": map[string]interface{} {
|
|
"amount": this.SafeString(market, "baseLotSize"),
|
|
"price": this.ParseNumber(this.ParsePrecision(this.SafeString(market, "pricePrecision"))),
|
|
"base": this.ParseNumber(this.ParsePrecision(this.SafeString(market, "basePrecision"))),
|
|
"quote": this.ParseNumber(this.ParsePrecision(this.SafeString(market, "quotePrecision"))),
|
|
},
|
|
"active": nil,
|
|
"created": nil,
|
|
"info": market,
|
|
})
|
|
}
|
|
/**
|
|
* @method
|
|
* @name cex#fetchTime
|
|
* @description fetches the current integer timestamp in milliseconds from the exchange server
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {int} the current integer timestamp in milliseconds from the exchange server
|
|
*/
|
|
func (this *cex) 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
|
|
|
|
response:= (<-this.PublicPostGetServerTime(params))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "ok": "ok",
|
|
// "data": {
|
|
// "timestamp": "1728472063472",
|
|
// "ISODate": "2024-10-09T11:07:43.472Z"
|
|
// }
|
|
// }
|
|
//
|
|
var data interface{} = this.SafeDict(response, "data")
|
|
var timestamp interface{} = this.SafeInteger(data, "timestamp")
|
|
|
|
ch <- timestamp
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name cex#fetchTicker
|
|
* @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
|
|
* @see https://trade.cex.io/docs/#rest-public-api-calls-ticker
|
|
* @param {string} symbol
|
|
* @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 *cex) 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
|
|
|
|
retRes4948 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes4948)
|
|
|
|
response:= (<-this.FetchTickers([]interface{}{symbol}, params))
|
|
PanicOnError(response)
|
|
|
|
ch <- this.SafeDict(response, symbol, map[string]interface{} {})
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name cex#fetchTickers
|
|
* @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
|
|
* @see https://trade.cex.io/docs/#rest-public-api-calls-ticker
|
|
* @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
|
|
* @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
|
|
*/
|
|
func (this *cex) 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
|
|
|
|
retRes5098 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes5098)
|
|
var request interface{} = map[string]interface{} {}
|
|
if IsTrue(!IsEqual(symbols, nil)) {
|
|
AddElementToObject(request, "pairs", this.MarketIds(symbols))
|
|
}
|
|
|
|
response:= (<-this.PublicPostGetTicker(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "ok": "ok",
|
|
// "data": {
|
|
// "AI-USD": {
|
|
// "bestBid": "0.3917",
|
|
// "bestAsk": "0.3949",
|
|
// "bestBidChange": "0.0035",
|
|
// "bestBidChangePercentage": "0.90",
|
|
// "bestAskChange": "0.0038",
|
|
// "bestAskChangePercentage": "0.97",
|
|
// "low": "0.3787",
|
|
// "high": "0.3925",
|
|
// "volume30d": "2945.722277",
|
|
// "lastTradeDateISO": "2024-10-11T06:18:42.077Z",
|
|
// "volume": "120.736000",
|
|
// "quoteVolume": "46.65654070",
|
|
// "lastTradeVolume": "67.914000",
|
|
// "volumeUSD": "46.65",
|
|
// "last": "0.3949",
|
|
// "lastTradePrice": "0.3925",
|
|
// "priceChange": "0.0038",
|
|
// "priceChangePercentage": "0.97"
|
|
// },
|
|
// ...
|
|
//
|
|
var data interface{} = this.SafeDict(response, "data", map[string]interface{} {})
|
|
|
|
ch <- this.ParseTickers(data, symbols)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *cex) ParseTicker(ticker interface{}, optionalArgs ...interface{}) interface{} {
|
|
market := GetArg(optionalArgs, 0, nil)
|
|
_ = market
|
|
var marketId interface{} = this.SafeString(ticker, "id")
|
|
var symbol interface{} = this.SafeSymbol(marketId, market)
|
|
return this.SafeTicker(map[string]interface{} {
|
|
"symbol": symbol,
|
|
"timestamp": nil,
|
|
"datetime": nil,
|
|
"high": this.SafeNumber(ticker, "high"),
|
|
"low": this.SafeNumber(ticker, "low"),
|
|
"bid": this.SafeNumber(ticker, "bestBid"),
|
|
"bidVolume": nil,
|
|
"ask": this.SafeNumber(ticker, "bestAsk"),
|
|
"askVolume": nil,
|
|
"vwap": nil,
|
|
"open": nil,
|
|
"close": this.SafeString(ticker, "lastTradePrice"),
|
|
"previousClose": nil,
|
|
"change": this.SafeNumber(ticker, "priceChange"),
|
|
"percentage": this.SafeNumber(ticker, "priceChangePercentage"),
|
|
"average": nil,
|
|
"baseVolume": this.SafeString(ticker, "volume"),
|
|
"quoteVolume": this.SafeString(ticker, "quoteVolume"),
|
|
"info": ticker,
|
|
}, market)
|
|
}
|
|
/**
|
|
* @method
|
|
* @name cex#fetchTrades
|
|
* @description get the list of most recent trades for a particular symbol
|
|
* @see https://trade.cex.io/docs/#rest-public-api-calls-trade-history
|
|
* @param {string} symbol unified symbol of the market to fetch trades for
|
|
* @param {int} [since] timestamp in ms of the earliest trade to fetch
|
|
* @param {int} [limit] the maximum amount of trades to fetch
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @param {int} [params.until] timestamp in ms of the latest entry
|
|
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
|
|
*/
|
|
func (this *cex) 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
|
|
|
|
retRes5848 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes5848)
|
|
var market interface{} = this.Market(symbol)
|
|
var request interface{} = map[string]interface{} {
|
|
"pair": GetValue(market, "id"),
|
|
}
|
|
if IsTrue(!IsEqual(since, nil)) {
|
|
AddElementToObject(request, "fromDateISO", this.Iso8601(since))
|
|
}
|
|
var until interface{} = nil
|
|
untilparamsVariable := this.HandleParamInteger2(params, "until", "till");
|
|
until = GetValue(untilparamsVariable,0);
|
|
params = GetValue(untilparamsVariable,1)
|
|
if IsTrue(!IsEqual(until, nil)) {
|
|
AddElementToObject(request, "toDateISO", this.Iso8601(until))
|
|
}
|
|
if IsTrue(!IsEqual(limit, nil)) {
|
|
AddElementToObject(request, "pageSize", mathMin(limit, 10000)) // has a bug, still returns more trades
|
|
}
|
|
|
|
response:= (<-this.PublicPostGetTradeHistory(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "ok": "ok",
|
|
// "data": {
|
|
// "pageSize": "10",
|
|
// "trades": [
|
|
// {
|
|
// "tradeId": "1728630559823-0",
|
|
// "dateISO": "2024-10-11T07:09:19.823Z",
|
|
// "side": "SELL",
|
|
// "price": "60879.5",
|
|
// "amount": "0.00165962"
|
|
// },
|
|
// ... followed by older trades
|
|
//
|
|
var data interface{} = this.SafeDict(response, "data", map[string]interface{} {})
|
|
var trades interface{} = this.SafeList(data, "trades", []interface{}{})
|
|
|
|
ch <- this.ParseTrades(trades, market, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *cex) ParseTrade(trade interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// public fetchTrades
|
|
//
|
|
// {
|
|
// "tradeId": "1728630559823-0",
|
|
// "dateISO": "2024-10-11T07:09:19.823Z",
|
|
// "side": "SELL",
|
|
// "price": "60879.5",
|
|
// "amount": "0.00165962"
|
|
// },
|
|
//
|
|
market := GetArg(optionalArgs, 0, nil)
|
|
_ = market
|
|
var dateStr interface{} = this.SafeString(trade, "dateISO")
|
|
var timestamp interface{} = this.Parse8601(dateStr)
|
|
market = this.SafeMarket(nil, market)
|
|
return this.SafeTrade(map[string]interface{} {
|
|
"info": trade,
|
|
"timestamp": timestamp,
|
|
"datetime": this.Iso8601(timestamp),
|
|
"symbol": GetValue(market, "symbol"),
|
|
"id": this.SafeString(trade, "tradeId"),
|
|
"order": nil,
|
|
"type": nil,
|
|
"takerOrMaker": nil,
|
|
"side": this.SafeStringLower(trade, "side"),
|
|
"price": this.SafeString(trade, "price"),
|
|
"amount": this.SafeString(trade, "amount"),
|
|
"cost": nil,
|
|
"fee": nil,
|
|
}, market)
|
|
}
|
|
/**
|
|
* @method
|
|
* @name cex#fetchOrderBook
|
|
* @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
|
|
* @see https://trade.cex.io/docs/#rest-public-api-calls-order-book
|
|
* @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
|
|
* @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
|
|
*/
|
|
func (this *cex) 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
|
|
|
|
retRes6648 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes6648)
|
|
var market interface{} = this.Market(symbol)
|
|
var request interface{} = map[string]interface{} {
|
|
"pair": GetValue(market, "id"),
|
|
}
|
|
|
|
response:= (<-this.PublicPostGetOrderBook(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "ok": "ok",
|
|
// "data": {
|
|
// "timestamp": "1728636922648",
|
|
// "currency1": "BTC",
|
|
// "currency2": "USDT",
|
|
// "bids": [
|
|
// [
|
|
// "60694.1",
|
|
// "13.12849761"
|
|
// ],
|
|
// [
|
|
// "60694.0",
|
|
// "0.71829244"
|
|
// ],
|
|
// ...
|
|
//
|
|
var orderBook interface{} = this.SafeDict(response, "data", map[string]interface{} {})
|
|
var timestamp interface{} = this.SafeInteger(orderBook, "timestamp")
|
|
|
|
ch <- this.ParseOrderBook(orderBook, GetValue(market, "symbol"), timestamp)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name cex#fetchOHLCV
|
|
* @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
* @see https://trade.cex.io/docs/#rest-public-api-calls-candles
|
|
* @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
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @param {int} [params.until] timestamp in ms of the latest entry
|
|
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
|
|
*/
|
|
func (this *cex) 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
|
|
var dataType interface{} = nil
|
|
dataTypeparamsVariable := this.HandleOptionAndParams(params, "fetchOHLCV", "dataType");
|
|
dataType = GetValue(dataTypeparamsVariable,0);
|
|
params = GetValue(dataTypeparamsVariable,1)
|
|
if IsTrue(IsEqual(dataType, nil)) {
|
|
panic(ArgumentsRequired(Add(this.Id, " fetchOHLCV requires a parameter \"dataType\" to be either \"bestBid\" or \"bestAsk\"")))
|
|
}
|
|
|
|
retRes7128 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes7128)
|
|
var market interface{} = this.Market(symbol)
|
|
var request interface{} = map[string]interface{} {
|
|
"pair": GetValue(market, "id"),
|
|
"resolution": GetValue(this.Timeframes, timeframe),
|
|
"dataType": dataType,
|
|
}
|
|
if IsTrue(!IsEqual(since, nil)) {
|
|
AddElementToObject(request, "fromISO", this.Iso8601(since))
|
|
}
|
|
var until interface{} = nil
|
|
untilparamsVariable := this.HandleParamInteger2(params, "until", "till");
|
|
until = GetValue(untilparamsVariable,0);
|
|
params = GetValue(untilparamsVariable,1)
|
|
if IsTrue(!IsEqual(until, nil)) {
|
|
AddElementToObject(request, "toISO", this.Iso8601(until))
|
|
} else if IsTrue(IsEqual(since, nil)) {
|
|
// exchange still requires that we provide one of them
|
|
AddElementToObject(request, "toISO", this.Iso8601(this.Milliseconds()))
|
|
}
|
|
if IsTrue(IsTrue(IsTrue(!IsEqual(since, nil)) && IsTrue(!IsEqual(until, nil))) && IsTrue(!IsEqual(limit, nil))) {
|
|
panic(ArgumentsRequired(Add(this.Id, " fetchOHLCV does not support fetching candles with both a limit and since/until")))
|
|
} else if IsTrue(IsTrue((IsTrue(!IsEqual(since, nil)) || IsTrue(!IsEqual(until, nil)))) && IsTrue(IsEqual(limit, nil))) {
|
|
panic(ArgumentsRequired(Add(this.Id, " fetchOHLCV requires a limit parameter when fetching candles with since or until")))
|
|
}
|
|
if IsTrue(!IsEqual(limit, nil)) {
|
|
AddElementToObject(request, "limit", limit)
|
|
}
|
|
|
|
response:= (<-this.PublicPostGetCandles(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "ok": "ok",
|
|
// "data": [
|
|
// {
|
|
// "timestamp": "1728643320000",
|
|
// "open": "61061",
|
|
// "high": "61095.1",
|
|
// "low": "61048.5",
|
|
// "close": "61087.8",
|
|
// "volume": "0",
|
|
// "resolution": "1m",
|
|
// "isClosed": true,
|
|
// "timestampISO": "2024-10-11T10:42:00.000Z"
|
|
// },
|
|
// ...
|
|
//
|
|
var data interface{} = this.SafeList(response, "data", []interface{}{})
|
|
|
|
ch <- this.ParseOHLCVs(data, market, timeframe, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *cex) ParseOHLCV(ohlcv interface{}, optionalArgs ...interface{}) interface{} {
|
|
market := GetArg(optionalArgs, 0, nil)
|
|
_ = market
|
|
return []interface{}{this.SafeInteger(ohlcv, "timestamp"), this.SafeNumber(ohlcv, "open"), this.SafeNumber(ohlcv, "high"), this.SafeNumber(ohlcv, "low"), this.SafeNumber(ohlcv, "close"), this.SafeNumber(ohlcv, "volume")}
|
|
}
|
|
/**
|
|
* @method
|
|
* @name cex#fetchTradingFees
|
|
* @description fetch the trading fees for multiple markets
|
|
* @see https://trade.cex.io/docs/#rest-public-api-calls-candles
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} a dictionary of [fee structures]{@link https://docs.ccxt.com/#/?id=fee-structure} indexed by market symbols
|
|
*/
|
|
func (this *cex) 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
|
|
|
|
retRes7808 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes7808)
|
|
|
|
response:= (<-this.PrivatePostGetMyCurrentFee(params))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "ok": "ok",
|
|
// "data": {
|
|
// "tradingFee": {
|
|
// "AI-USD": {
|
|
// "percent": "0.25"
|
|
// },
|
|
// ...
|
|
//
|
|
var data interface{} = this.SafeDict(response, "data", map[string]interface{} {})
|
|
var fees interface{} = this.SafeDict(data, "tradingFee", map[string]interface{} {})
|
|
|
|
ch <- this.ParseTradingFees(fees, true)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *cex) ParseTradingFees(response interface{}, optionalArgs ...interface{}) interface{} {
|
|
useKeyAsId := GetArg(optionalArgs, 0, false)
|
|
_ = useKeyAsId
|
|
var result interface{} = map[string]interface{} {}
|
|
var keys interface{} = ObjectKeys(response)
|
|
for i := 0; IsLessThan(i, GetArrayLength(keys)); i++ {
|
|
var key interface{} = GetValue(keys, i)
|
|
var market interface{} = nil
|
|
if IsTrue(useKeyAsId) {
|
|
market = this.SafeMarket(key)
|
|
}
|
|
var parsed interface{} = this.ParseTradingFee(GetValue(response, key), market)
|
|
AddElementToObject(result, GetValue(parsed, "symbol"), parsed)
|
|
}
|
|
for i := 0; IsLessThan(i, GetArrayLength(this.Symbols)); i++ {
|
|
var symbol interface{} = GetValue(this.Symbols, i)
|
|
if !IsTrue((InOp(result, symbol))) {
|
|
var market interface{} = this.Market(symbol)
|
|
AddElementToObject(result, symbol, this.ParseTradingFee(response, market))
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
func (this *cex) ParseTradingFee(fee interface{}, optionalArgs ...interface{}) interface{} {
|
|
market := GetArg(optionalArgs, 0, nil)
|
|
_ = market
|
|
return map[string]interface{} {
|
|
"info": fee,
|
|
"symbol": this.SafeString(market, "symbol"),
|
|
"maker": this.SafeNumber(fee, "percent"),
|
|
"taker": this.SafeNumber(fee, "percent"),
|
|
"percentage": nil,
|
|
"tierBased": nil,
|
|
}
|
|
}
|
|
func (this *cex) 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
|
|
|
|
retRes8318 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes8318)
|
|
|
|
response:= (<-this.PrivatePostGetMyAccountStatusV3(params))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "ok": "ok",
|
|
// "data": {
|
|
// "convertedCurrency": "USD",
|
|
// "balancesPerAccounts": {
|
|
// "": {
|
|
// "AI": {
|
|
// "balance": "0.000000",
|
|
// "balanceOnHold": "0.000000"
|
|
// },
|
|
// "USDT": {
|
|
// "balance": "0.00000000",
|
|
// "balanceOnHold": "0.00000000"
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
//
|
|
var data interface{} = this.SafeDict(response, "data", map[string]interface{} {})
|
|
var balances interface{} = this.SafeDict(data, "balancesPerAccounts", map[string]interface{} {})
|
|
var arrays interface{} = this.ToArray(balances)
|
|
|
|
ch <- this.ParseAccounts(arrays, params)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *cex) ParseAccount(account interface{}) interface{} {
|
|
return map[string]interface{} {
|
|
"id": nil,
|
|
"type": nil,
|
|
"code": nil,
|
|
"info": account,
|
|
}
|
|
}
|
|
/**
|
|
* @method
|
|
* @name cex#fetchBalance
|
|
* @description query for balance and get the amount of funds available for trading or funds locked in orders
|
|
* @see https://trade.cex.io/docs/#rest-private-api-calls-account-status-v3
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @param {object} [params.method] 'privatePostGetMyWalletBalance' or 'privatePostGetMyAccountStatusV3'
|
|
* @param {object} [params.account] in case 'privatePostGetMyAccountStatusV3' is chosen, this can specify the account name (default is empty string)
|
|
* @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
|
|
*/
|
|
func (this *cex) 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
|
|
var accountName interface{} = nil
|
|
accountNameparamsVariable := this.HandleParamString(params, "account", "");
|
|
accountName = GetValue(accountNameparamsVariable,0);
|
|
params = GetValue(accountNameparamsVariable,1) // default is empty string
|
|
var method interface{} = nil
|
|
methodparamsVariable := this.HandleParamString(params, "method", "privatePostGetMyWalletBalance");
|
|
method = GetValue(methodparamsVariable,0);
|
|
params = GetValue(methodparamsVariable,1)
|
|
var accountBalance interface{} = nil
|
|
if IsTrue(IsEqual(method, "privatePostGetMyAccountStatusV3")) {
|
|
|
|
response:= (<-this.PrivatePostGetMyAccountStatusV3(params))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "ok": "ok",
|
|
// "data": {
|
|
// "convertedCurrency": "USD",
|
|
// "balancesPerAccounts": {
|
|
// "": {
|
|
// "AI": {
|
|
// "balance": "0.000000",
|
|
// "balanceOnHold": "0.000000"
|
|
// },
|
|
// ....
|
|
//
|
|
var data interface{} = this.SafeDict(response, "data", map[string]interface{} {})
|
|
var balances interface{} = this.SafeDict(data, "balancesPerAccounts", map[string]interface{} {})
|
|
accountBalance = this.SafeDict(balances, accountName, map[string]interface{} {})
|
|
} else {
|
|
|
|
response:= (<-this.PrivatePostGetMyWalletBalance(params))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "ok": "ok",
|
|
// "data": {
|
|
// "AI": {
|
|
// "balance": "25.606429"
|
|
// },
|
|
// "USDT": {
|
|
// "balance": "7.935449"
|
|
// },
|
|
// ...
|
|
//
|
|
accountBalance = this.SafeDict(response, "data", map[string]interface{} {})
|
|
}
|
|
|
|
ch <- this.ParseBalance(accountBalance)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *cex) ParseBalance(response interface{}) interface{} {
|
|
var result interface{} = map[string]interface{} {
|
|
"info": response,
|
|
}
|
|
var keys interface{} = ObjectKeys(response)
|
|
for i := 0; IsLessThan(i, GetArrayLength(keys)); i++ {
|
|
var key interface{} = GetValue(keys, i)
|
|
var balance interface{} = this.SafeDict(response, key, map[string]interface{} {})
|
|
var code interface{} = this.SafeCurrencyCode(key)
|
|
var account interface{} = map[string]interface{} {
|
|
"used": this.SafeString(balance, "balanceOnHold"),
|
|
"total": this.SafeString(balance, "balance"),
|
|
}
|
|
AddElementToObject(result, code, account)
|
|
}
|
|
return this.SafeBalance(result)
|
|
}
|
|
/**
|
|
* @method
|
|
* @name cex#fetchOrders
|
|
* @description fetches information on multiple orders made by the user
|
|
* @see https://trade.cex.io/docs/#rest-private-api-calls-orders
|
|
* @param {string} status order status to fetch for
|
|
* @param {string} symbol unified market symbol of the market orders were made in
|
|
* @param {int} [since] the earliest time in ms to fetch orders for
|
|
* @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] timestamp in ms of the latest entry
|
|
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
*/
|
|
func (this *cex) 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
|
|
|
|
retRes9538 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes9538)
|
|
var request interface{} = map[string]interface{} {}
|
|
var isClosedOrders interface{} = (IsEqual(status, "closed"))
|
|
if IsTrue(isClosedOrders) {
|
|
AddElementToObject(request, "archived", true)
|
|
}
|
|
var market interface{} = nil
|
|
if IsTrue(!IsEqual(symbol, nil)) {
|
|
market = this.Market(symbol)
|
|
AddElementToObject(request, "pair", GetValue(market, "id"))
|
|
}
|
|
if IsTrue(!IsEqual(limit, nil)) {
|
|
AddElementToObject(request, "pageSize", limit)
|
|
}
|
|
if IsTrue(!IsEqual(since, nil)) {
|
|
AddElementToObject(request, "serverCreateTimestampFrom", since)
|
|
} else if IsTrue(isClosedOrders) {
|
|
// exchange requires a `since` parameter for closed orders, so set default to allowed 365
|
|
AddElementToObject(request, "serverCreateTimestampFrom", Subtract(this.Milliseconds(), Multiply(Multiply(Multiply(Multiply(364, 24), 60), 60), 1000)))
|
|
}
|
|
var until interface{} = nil
|
|
untilparamsVariable := this.HandleParamInteger2(params, "until", "till");
|
|
until = GetValue(untilparamsVariable,0);
|
|
params = GetValue(untilparamsVariable,1)
|
|
if IsTrue(!IsEqual(until, nil)) {
|
|
AddElementToObject(request, "serverCreateTimestampTo", until)
|
|
}
|
|
|
|
response:= (<-this.PrivatePostGetMyOrders(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// if called without `pair`
|
|
//
|
|
// {
|
|
// "ok": "ok",
|
|
// "data": [
|
|
// {
|
|
// "orderId": "1313003",
|
|
// "clientOrderId": "037F0AFEB93A",
|
|
// "clientId": "up421412345",
|
|
// "accountId": null,
|
|
// "status": "FILLED",
|
|
// "statusIsFinal": true,
|
|
// "currency1": "AI",
|
|
// "currency2": "USDT",
|
|
// "side": "BUY",
|
|
// "orderType": "Market",
|
|
// "timeInForce": "IOC",
|
|
// "comment": null,
|
|
// "rejectCode": null,
|
|
// "rejectReason": null,
|
|
// "initialOnHoldAmountCcy1": null,
|
|
// "initialOnHoldAmountCcy2": "10.23456700",
|
|
// "executedAmountCcy1": "25.606429",
|
|
// "executedAmountCcy2": "10.20904439",
|
|
// "requestedAmountCcy1": null,
|
|
// "requestedAmountCcy2": "10.20904439",
|
|
// "originalAmountCcy2": "10.23456700",
|
|
// "feeAmount": "0.02552261",
|
|
// "feeCurrency": "USDT",
|
|
// "price": null,
|
|
// "averagePrice": "0.3986",
|
|
// "clientCreateTimestamp": "1728474625320",
|
|
// "serverCreateTimestamp": "1728474624956",
|
|
// "lastUpdateTimestamp": "1728474628015",
|
|
// "expireTime": null,
|
|
// "effectiveTime": null
|
|
// },
|
|
// ...
|
|
//
|
|
var data interface{} = this.SafeList(response, "data", []interface{}{})
|
|
|
|
ch <- this.ParseOrders(data, market, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name cex#fetchClosedOrders
|
|
* @see https://trade.cex.io/docs/#rest-private-api-calls-orders
|
|
* @description fetches information on multiple canceled orders made by the user
|
|
* @param {string} symbol unified market symbol of the market orders were made in
|
|
* @param {int} [since] timestamp in ms of the earliest order, default is undefined
|
|
* @param {int} [limit] max number of orders 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 *cex) 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
|
|
|
|
retRes103515 := (<-this.FetchOrdersByStatus("closed", symbol, since, limit, params))
|
|
PanicOnError(retRes103515)
|
|
ch <- retRes103515
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name cex#fetchOpenOrders
|
|
* @see https://trade.cex.io/docs/#rest-private-api-calls-orders
|
|
* @description fetches information on multiple canceled orders made by the user
|
|
* @param {string} symbol unified market symbol of the market orders were made in
|
|
* @param {int} [since] timestamp in ms of the earliest order, default is undefined
|
|
* @param {int} [limit] max number of orders 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 *cex) 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
|
|
|
|
retRes105015 := (<-this.FetchOrdersByStatus("open", symbol, since, limit, params))
|
|
PanicOnError(retRes105015)
|
|
ch <- retRes105015
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name cex#fetchOpenOrder
|
|
* @description fetches information on an open order made by the user
|
|
* @see https://trade.cex.io/docs/#rest-private-api-calls-orders
|
|
* @param {string} id order id
|
|
* @param {string} [symbol] unified symbol of the market 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 *cex) FetchOpenOrder(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
|
|
|
|
retRes10648 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes10648)
|
|
var request interface{} = map[string]interface{} {
|
|
"orderId": ParseInt(id),
|
|
}
|
|
|
|
result:= (<-this.FetchOpenOrders(symbol, nil, nil, this.Extend(request, params)))
|
|
PanicOnError(result)
|
|
|
|
ch <- GetValue(result, 0)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name cex#fetchClosedOrder
|
|
* @description fetches information on an closed order made by the user
|
|
* @see https://trade.cex.io/docs/#rest-private-api-calls-orders
|
|
* @param {string} id order id
|
|
* @param {string} [symbol] unified symbol of the market 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 *cex) FetchClosedOrder(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
|
|
|
|
retRes10838 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes10838)
|
|
var request interface{} = map[string]interface{} {
|
|
"orderId": ParseInt(id),
|
|
}
|
|
|
|
result:= (<-this.FetchClosedOrders(symbol, nil, nil, this.Extend(request, params)))
|
|
PanicOnError(result)
|
|
|
|
ch <- GetValue(result, 0)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *cex) ParseOrderStatus(status interface{}) interface{} {
|
|
var statuses interface{} = map[string]interface{} {
|
|
"PENDING_NEW": "open",
|
|
"NEW": "open",
|
|
"PARTIALLY_FILLED": "open",
|
|
"FILLED": "closed",
|
|
"EXPIRED": "expired",
|
|
"REJECTED": "rejected",
|
|
"PENDING_CANCEL": "canceling",
|
|
"CANCELLED": "canceled",
|
|
}
|
|
return this.SafeString(statuses, status, status)
|
|
}
|
|
func (this *cex) ParseOrder(order interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// "orderId": "1313003",
|
|
// "clientOrderId": "037F0AFEB93A",
|
|
// "clientId": "up421412345",
|
|
// "accountId": null,
|
|
// "status": "FILLED",
|
|
// "statusIsFinal": true,
|
|
// "currency1": "AI",
|
|
// "currency2": "USDT",
|
|
// "side": "BUY",
|
|
// "orderType": "Market",
|
|
// "timeInForce": "IOC",
|
|
// "comment": null,
|
|
// "rejectCode": null,
|
|
// "rejectReason": null,
|
|
// "initialOnHoldAmountCcy1": null,
|
|
// "initialOnHoldAmountCcy2": "10.23456700",
|
|
// "executedAmountCcy1": "25.606429",
|
|
// "executedAmountCcy2": "10.20904439",
|
|
// "requestedAmountCcy1": null,
|
|
// "requestedAmountCcy2": "10.20904439",
|
|
// "originalAmountCcy2": "10.23456700",
|
|
// "feeAmount": "0.02552261",
|
|
// "feeCurrency": "USDT",
|
|
// "price": null,
|
|
// "averagePrice": "0.3986",
|
|
// "clientCreateTimestamp": "1728474625320",
|
|
// "serverCreateTimestamp": "1728474624956",
|
|
// "lastUpdateTimestamp": "1728474628015",
|
|
// "expireTime": null,
|
|
// "effectiveTime": null
|
|
//
|
|
market := GetArg(optionalArgs, 0, nil)
|
|
_ = market
|
|
var currency1 interface{} = this.SafeString(order, "currency1")
|
|
var currency2 interface{} = this.SafeString(order, "currency2")
|
|
var marketId interface{} = nil
|
|
if IsTrue(IsTrue(!IsEqual(currency1, nil)) && IsTrue(!IsEqual(currency2, nil))) {
|
|
marketId = Add(Add(currency1, "-"), currency2)
|
|
}
|
|
market = this.SafeMarket(marketId, market)
|
|
var symbol interface{} = GetValue(market, "symbol")
|
|
var status interface{} = this.ParseOrderStatus(this.SafeString(order, "status"))
|
|
var fee interface{} = map[string]interface{} {}
|
|
var feeAmount interface{} = this.SafeNumber(order, "feeAmount")
|
|
if IsTrue(!IsEqual(feeAmount, nil)) {
|
|
var currencyId interface{} = this.SafeString(order, "feeCurrency")
|
|
var feeCode interface{} = this.SafeCurrencyCode(currencyId)
|
|
AddElementToObject(fee, "currency", feeCode)
|
|
AddElementToObject(fee, "cost", feeAmount)
|
|
}
|
|
var timestamp interface{} = this.SafeInteger(order, "serverCreateTimestamp")
|
|
var requestedBase interface{} = this.SafeNumber(order, "requestedAmountCcy1")
|
|
var executedBase interface{} = this.SafeNumber(order, "executedAmountCcy1")
|
|
// const requestedQuote = this.safeNumber (order, 'requestedAmountCcy2');
|
|
var executedQuote interface{} = this.SafeNumber(order, "executedAmountCcy2")
|
|
return this.SafeOrder(map[string]interface{} {
|
|
"id": this.SafeString(order, "orderId"),
|
|
"clientOrderId": this.SafeString(order, "clientOrderId"),
|
|
"timestamp": timestamp,
|
|
"datetime": this.Iso8601(timestamp),
|
|
"lastUpdateTimestamp": this.SafeInteger(order, "lastUpdateTimestamp"),
|
|
"lastTradeTimestamp": nil,
|
|
"symbol": symbol,
|
|
"type": this.SafeStringLower(order, "orderType"),
|
|
"timeInForce": this.SafeString(order, "timeInForce"),
|
|
"postOnly": nil,
|
|
"side": this.SafeStringLower(order, "side"),
|
|
"price": this.SafeNumber(order, "price"),
|
|
"triggerPrice": this.SafeNumber(order, "stopPrice"),
|
|
"amount": requestedBase,
|
|
"cost": executedQuote,
|
|
"average": this.SafeNumber(order, "averagePrice"),
|
|
"filled": executedBase,
|
|
"remaining": nil,
|
|
"status": status,
|
|
"fee": fee,
|
|
"trades": nil,
|
|
"info": order,
|
|
}, market)
|
|
}
|
|
/**
|
|
* @method
|
|
* @name cex#createOrder
|
|
* @description create a trade order
|
|
* @see https://trade.cex.io/docs/#rest-private-api-calls-new-order
|
|
* @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 {string} [params.accountId] account-id to use (default is empty string)
|
|
* @param {float} [params.triggerPrice] the price at which a trigger order is triggered at
|
|
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
|
|
*/
|
|
func (this *cex) 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
|
|
var accountId interface{} = nil
|
|
accountIdparamsVariable := this.HandleOptionAndParams(params, "createOrder", "accountId");
|
|
accountId = GetValue(accountIdparamsVariable,0);
|
|
params = GetValue(accountIdparamsVariable,1)
|
|
if IsTrue(IsEqual(accountId, nil)) {
|
|
panic(ArgumentsRequired(Add(this.Id, " createOrder() : API trading is now allowed from main account, set params[\"accountId\"] or .options[\"createOrder\"][\"accountId\"] to the name of your sub-account")))
|
|
}
|
|
|
|
retRes12078 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes12078)
|
|
var market interface{} = this.Market(symbol)
|
|
var request interface{} = map[string]interface{} {
|
|
"clientOrderId": this.Uuid(),
|
|
"currency1": GetValue(market, "baseId"),
|
|
"currency2": GetValue(market, "quoteId"),
|
|
"accountId": accountId,
|
|
"orderType": this.Capitalize(ToLower(typeVar)),
|
|
"side": ToUpper(side),
|
|
"timestamp": this.Milliseconds(),
|
|
"amountCcy1": this.AmountToPrecision(symbol, amount),
|
|
}
|
|
var timeInForce interface{} = nil
|
|
timeInForceparamsVariable := this.HandleOptionAndParams(params, "createOrder", "timeInForce", "GTC");
|
|
timeInForce = GetValue(timeInForceparamsVariable,0);
|
|
params = GetValue(timeInForceparamsVariable,1)
|
|
if IsTrue(IsEqual(typeVar, "limit")) {
|
|
AddElementToObject(request, "price", this.PriceToPrecision(symbol, price))
|
|
AddElementToObject(request, "timeInForce", timeInForce)
|
|
}
|
|
var triggerPrice interface{} = nil
|
|
triggerPriceparamsVariable := this.HandleParamString(params, "triggerPrice");
|
|
triggerPrice = GetValue(triggerPriceparamsVariable,0);
|
|
params = GetValue(triggerPriceparamsVariable,1)
|
|
if IsTrue(!IsEqual(triggerPrice, nil)) {
|
|
AddElementToObject(request, "type", "Stop Limit")
|
|
AddElementToObject(request, "stopPrice", triggerPrice)
|
|
}
|
|
|
|
response:= (<-this.PrivatePostDoMyNewOrder(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// on success
|
|
//
|
|
// {
|
|
// "ok": "ok",
|
|
// "data": {
|
|
// "messageType": "executionReport",
|
|
// "clientId": "up132245425",
|
|
// "orderId": "1318485",
|
|
// "clientOrderId": "b5b6cd40-154c-4c1c-bd51-4a442f3d50b9",
|
|
// "accountId": "sub1",
|
|
// "status": "FILLED",
|
|
// "currency1": "LTC",
|
|
// "currency2": "USDT",
|
|
// "side": "BUY",
|
|
// "executedAmountCcy1": "0.23000000",
|
|
// "executedAmountCcy2": "15.09030000",
|
|
// "requestedAmountCcy1": "0.23000000",
|
|
// "requestedAmountCcy2": null,
|
|
// "orderType": "Market",
|
|
// "timeInForce": null,
|
|
// "comment": null,
|
|
// "executionType": "Trade",
|
|
// "executionId": "1726747124624_101_41116",
|
|
// "transactTime": "2024-10-15T15:08:12.794Z",
|
|
// "expireTime": null,
|
|
// "effectiveTime": null,
|
|
// "averagePrice": "65.61",
|
|
// "lastQuantity": "0.23000000",
|
|
// "lastAmountCcy1": "0.23000000",
|
|
// "lastAmountCcy2": "15.09030000",
|
|
// "lastPrice": "65.61",
|
|
// "feeAmount": "0.03772575",
|
|
// "feeCurrency": "USDT",
|
|
// "clientCreateTimestamp": "1729004892014",
|
|
// "serverCreateTimestamp": "1729004891628",
|
|
// "lastUpdateTimestamp": "1729004892786"
|
|
// }
|
|
// }
|
|
//
|
|
// on failure, there are extra fields
|
|
//
|
|
// "status": "REJECTED",
|
|
// "requestedAmountCcy1": null,
|
|
// "orderRejectReason": "{\\" code \\ ":405,\\" reason \\ ":\\" Either AmountCcy1(OrderQty)or AmountCcy2(CashOrderQty)should be specified for market order not both \\ "}",
|
|
// "rejectCode": 405,
|
|
// "rejectReason": "Either AmountCcy1 (OrderQty) or AmountCcy2 (CashOrderQty) should be specified for market order not both",
|
|
//
|
|
var data interface{} = this.SafeDict(response, "data")
|
|
|
|
ch <- this.ParseOrder(data, market)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name cex#cancelOrder
|
|
* @description cancels an open order
|
|
* @see https://trade.cex.io/docs/#rest-private-api-calls-cancel-order
|
|
* @param {string} id order id
|
|
* @param {string} symbol unified symbol of the market 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 *cex) 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
|
|
|
|
retRes12958 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes12958)
|
|
var request interface{} = map[string]interface{} {
|
|
"orderId": ParseInt(id),
|
|
"cancelRequestId": Add("c_", ToString((this.Milliseconds()))),
|
|
"timestamp": this.Milliseconds(),
|
|
}
|
|
|
|
response:= (<-this.PrivatePostDoCancelMyOrder(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {"ok":"ok","data":{}}
|
|
//
|
|
var data interface{} = this.SafeDict(response, "data", map[string]interface{} {})
|
|
|
|
ch <- this.ParseOrder(data)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name cex#cancelAllOrders
|
|
* @description cancel all open orders in a market
|
|
* @see https://trade.cex.io/docs/#rest-private-api-calls-cancel-all-orders
|
|
* @param {string} symbol alpaca cancelAllOrders cannot setting symbol, it will cancel all open orders
|
|
* @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 *cex) CancelAllOrders(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
|
|
|
|
retRes13198 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes13198)
|
|
|
|
response:= (<-this.PrivatePostDoCancelAllOrders(params))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "ok": "ok",
|
|
// "data": {
|
|
// "clientOrderIds": [
|
|
// "3AF77B67109F"
|
|
// ]
|
|
// }
|
|
// }
|
|
//
|
|
var data interface{} = this.SafeDict(response, "data", map[string]interface{} {})
|
|
var ids interface{} = this.SafeList(data, "clientOrderIds", []interface{}{})
|
|
var orders interface{} = []interface{}{}
|
|
for i := 0; IsLessThan(i, GetArrayLength(ids)); i++ {
|
|
var id interface{} = GetValue(ids, i)
|
|
AppendToArray(&orders,map[string]interface{} {
|
|
"clientOrderId": id,
|
|
})
|
|
}
|
|
|
|
ch <- this.ParseOrders(orders)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
/**
|
|
* @method
|
|
* @name cex#fetchLedger
|
|
* @description fetch the history of changes, actions done by the user or operations that altered the balance of the user
|
|
* @see https://trade.cex.io/docs/#rest-private-api-calls-transaction-history
|
|
* @param {string} [code] unified currency code
|
|
* @param {int} [since] timestamp in ms of the earliest ledger entry
|
|
* @param {int} [limit] max number of ledger entries to return
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @param {int} [params.until] timestamp in ms of the latest ledger entry
|
|
* @returns {object} a [ledger structure]{@link https://docs.ccxt.com/#/?id=ledger}
|
|
*/
|
|
func (this *cex) 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
|
|
|
|
retRes13548 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes13548)
|
|
var currency interface{} = nil
|
|
var request interface{} = map[string]interface{} {}
|
|
if IsTrue(!IsEqual(code, nil)) {
|
|
currency = this.Currency(code)
|
|
AddElementToObject(request, "currency", GetValue(currency, "id"))
|
|
}
|
|
if IsTrue(!IsEqual(since, nil)) {
|
|
AddElementToObject(request, "dateFrom", since)
|
|
}
|
|
if IsTrue(!IsEqual(limit, nil)) {
|
|
AddElementToObject(request, "pageSize", limit)
|
|
}
|
|
var until interface{} = nil
|
|
untilparamsVariable := this.HandleParamInteger2(params, "until", "till");
|
|
until = GetValue(untilparamsVariable,0);
|
|
params = GetValue(untilparamsVariable,1)
|
|
if IsTrue(!IsEqual(until, nil)) {
|
|
AddElementToObject(request, "dateTo", until)
|
|
}
|
|
|
|
response:= (<-this.PrivatePostGetMyTransactionHistory(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "ok": "ok",
|
|
// "data": [
|
|
// {
|
|
// "transactionId": "30367722",
|
|
// "timestamp": "2024-10-14T14:08:49.987Z",
|
|
// "accountId": "",
|
|
// "type": "withdraw",
|
|
// "amount": "-12.39060600",
|
|
// "details": "Withdraw fundingId=1235039 clientId=up421412345 walletTxId=76337154166",
|
|
// "currency": "USDT"
|
|
// },
|
|
// ...
|
|
//
|
|
var data interface{} = this.SafeList(response, "data", []interface{}{})
|
|
|
|
ch <- this.ParseLedger(data, currency, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *cex) ParseLedgerEntry(item interface{}, optionalArgs ...interface{}) interface{} {
|
|
currency := GetArg(optionalArgs, 0, nil)
|
|
_ = currency
|
|
var amount interface{} = this.SafeString(item, "amount")
|
|
var direction interface{} = nil
|
|
if IsTrue(Precise.StringLe(amount, "0")) {
|
|
direction = "out"
|
|
amount = Precise.StringMul("-1", amount)
|
|
} else {
|
|
direction = "in"
|
|
}
|
|
var currencyId interface{} = this.SafeString(item, "currency")
|
|
currency = this.SafeCurrency(currencyId, currency)
|
|
var code interface{} = this.SafeCurrencyCode(currencyId, currency)
|
|
var timestampString interface{} = this.SafeString(item, "timestamp")
|
|
var timestamp interface{} = this.Parse8601(timestampString)
|
|
var typeVar interface{} = this.SafeString(item, "type")
|
|
return this.SafeLedgerEntry(map[string]interface{} {
|
|
"info": item,
|
|
"id": this.SafeString(item, "transactionId"),
|
|
"direction": direction,
|
|
"account": this.SafeString(item, "accountId", ""),
|
|
"referenceAccount": nil,
|
|
"referenceId": nil,
|
|
"type": this.ParseLedgerEntryType(typeVar),
|
|
"currency": code,
|
|
"amount": this.ParseNumber(amount),
|
|
"timestamp": timestamp,
|
|
"datetime": this.Iso8601(timestamp),
|
|
"before": nil,
|
|
"after": nil,
|
|
"status": nil,
|
|
"fee": nil,
|
|
}, currency)
|
|
}
|
|
func (this *cex) ParseLedgerEntryType(typeVar interface{}) interface{} {
|
|
var ledgerType interface{} = map[string]interface{} {
|
|
"deposit": "deposit",
|
|
"withdraw": "withdrawal",
|
|
"commission": "fee",
|
|
}
|
|
return this.SafeString(ledgerType, typeVar, typeVar)
|
|
}
|
|
/**
|
|
* @method
|
|
* @name cex#fetchDepositsWithdrawals
|
|
* @description fetch history of deposits and withdrawals
|
|
* @see https://trade.cex.io/docs/#rest-private-api-calls-funding-history
|
|
* @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 is undefined
|
|
* @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 *cex) 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
|
|
|
|
retRes14478 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes14478)
|
|
var request interface{} = map[string]interface{} {}
|
|
var currency interface{} = nil
|
|
if IsTrue(!IsEqual(code, nil)) {
|
|
currency = this.Currency(code)
|
|
}
|
|
if IsTrue(!IsEqual(since, nil)) {
|
|
AddElementToObject(request, "dateFrom", since)
|
|
}
|
|
if IsTrue(!IsEqual(limit, nil)) {
|
|
AddElementToObject(request, "pageSize", limit)
|
|
}
|
|
var until interface{} = nil
|
|
untilparamsVariable := this.HandleParamInteger2(params, "until", "till");
|
|
until = GetValue(untilparamsVariable,0);
|
|
params = GetValue(untilparamsVariable,1)
|
|
if IsTrue(!IsEqual(until, nil)) {
|
|
AddElementToObject(request, "dateTo", until)
|
|
}
|
|
|
|
response:= (<-this.PrivatePostGetMyFundingHistory(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "ok": "ok",
|
|
// "data": [
|
|
// {
|
|
// "clientId": "up421412345",
|
|
// "accountId": "",
|
|
// "currency": "USDT",
|
|
// "direction": "withdraw",
|
|
// "amount": "12.39060600",
|
|
// "commissionAmount": "0.00000000",
|
|
// "status": "approved",
|
|
// "updatedAt": "2024-10-14T14:08:50.013Z",
|
|
// "txId": "30367718",
|
|
// "details": {}
|
|
// },
|
|
// ...
|
|
//
|
|
var data interface{} = this.SafeList(response, "data", []interface{}{})
|
|
|
|
ch <- this.ParseTransactions(data, currency, since, limit)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *cex) ParseTransaction(transaction interface{}, optionalArgs ...interface{}) interface{} {
|
|
currency := GetArg(optionalArgs, 0, nil)
|
|
_ = currency
|
|
var currencyId interface{} = this.SafeString(transaction, "currency")
|
|
var direction interface{} = this.SafeString(transaction, "direction")
|
|
var typeVar interface{} = Ternary(IsTrue((IsEqual(direction, "withdraw"))), "withdrawal", "deposit")
|
|
var code interface{} = this.SafeCurrencyCode(currencyId, currency)
|
|
var updatedAt interface{} = this.SafeString(transaction, "updatedAt")
|
|
var timestamp interface{} = this.Parse8601(updatedAt)
|
|
return map[string]interface{} {
|
|
"info": transaction,
|
|
"id": this.SafeString(transaction, "txId"),
|
|
"txid": nil,
|
|
"type": typeVar,
|
|
"currency": code,
|
|
"network": nil,
|
|
"amount": this.SafeNumber(transaction, "amount"),
|
|
"status": this.ParseTransactionStatus(this.SafeString(transaction, "status")),
|
|
"timestamp": timestamp,
|
|
"datetime": this.Iso8601(timestamp),
|
|
"address": nil,
|
|
"addressFrom": nil,
|
|
"addressTo": nil,
|
|
"tag": nil,
|
|
"tagFrom": nil,
|
|
"tagTo": nil,
|
|
"updated": nil,
|
|
"comment": nil,
|
|
"fee": map[string]interface{} {
|
|
"currency": code,
|
|
"cost": this.SafeNumber(transaction, "commissionAmount"),
|
|
},
|
|
"internal": nil,
|
|
}
|
|
}
|
|
func (this *cex) ParseTransactionStatus(status interface{}) interface{} {
|
|
var statuses interface{} = map[string]interface{} {
|
|
"rejected": "rejected",
|
|
"pending": "pending",
|
|
"approved": "ok",
|
|
}
|
|
return this.SafeString(statuses, status, status)
|
|
}
|
|
/**
|
|
* @method
|
|
* @name cex#transfer
|
|
* @description transfer currency internally between wallets on the same account
|
|
* @see https://trade.cex.io/docs/#rest-private-api-calls-internal-transfer
|
|
* @param {string} code unified currency code
|
|
* @param {float} amount amount to transfer
|
|
* @param {string} fromAccount 'SPOT', 'FUND', or 'CONTRACT'
|
|
* @param {string} toAccount 'SPOT', 'FUND', or 'CONTRACT'
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @returns {object} a [transfer structure]{@link https://docs.ccxt.com/#/?id=transfer-structure}
|
|
*/
|
|
func (this *cex) Transfer(code interface{}, amount interface{}, fromAccount interface{}, toAccount 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 transfer interface{} = nil
|
|
if IsTrue(IsTrue(!IsEqual(toAccount, "")) && IsTrue(!IsEqual(fromAccount, ""))) {
|
|
|
|
transfer = (<-this.TransferBetweenSubAccounts(code, amount, fromAccount, toAccount, params))
|
|
PanicOnError(transfer)
|
|
} else {
|
|
|
|
transfer = (<-this.TransferBetweenMainAndSubAccount(code, amount, fromAccount, toAccount, params))
|
|
PanicOnError(transfer)
|
|
}
|
|
var fillResponseFromRequest interface{} = this.HandleOption("transfer", "fillResponseFromRequest", true)
|
|
if IsTrue(fillResponseFromRequest) {
|
|
AddElementToObject(transfer, "fromAccount", fromAccount)
|
|
AddElementToObject(transfer, "toAccount", toAccount)
|
|
}
|
|
|
|
ch <- transfer
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *cex) TransferBetweenMainAndSubAccount(code interface{}, amount interface{}, fromAccount interface{}, toAccount 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
|
|
|
|
retRes15588 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes15588)
|
|
var currency interface{} = this.Currency(code)
|
|
var fromMain interface{} = (IsEqual(fromAccount, ""))
|
|
var targetAccount interface{} = Ternary(IsTrue(fromMain), toAccount, fromAccount)
|
|
var guid interface{} = this.SafeString(params, "guid", this.Uuid())
|
|
var request interface{} = map[string]interface{} {
|
|
"currency": GetValue(currency, "id"),
|
|
"amount": this.CurrencyToPrecision(code, amount),
|
|
"accountId": targetAccount,
|
|
"clientTxId": guid,
|
|
}
|
|
var response interface{} = nil
|
|
if IsTrue(fromMain) {
|
|
|
|
response = (<-this.PrivatePostDoDepositFundsFromWallet(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
} else {
|
|
|
|
response = (<-this.PrivatePostDoWithdrawalFundsToWallet(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
}
|
|
// both endpoints return the same structure, the only difference is that
|
|
// the "accountId" is filled with the "subAccount"
|
|
//
|
|
// {
|
|
// "ok": "ok",
|
|
// "data": {
|
|
// "accountId": "sub1",
|
|
// "clientTxId": "27ba8284-67cf-4386-9ec7-80b3871abd45",
|
|
// "currency": "USDT",
|
|
// "status": "approved"
|
|
// }
|
|
// }
|
|
//
|
|
var data interface{} = this.SafeDict(response, "data", map[string]interface{} {})
|
|
|
|
ch <- this.ParseTransfer(data, currency)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *cex) TransferBetweenSubAccounts(code interface{}, amount interface{}, fromAccount interface{}, toAccount 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
|
|
|
|
retRes15938 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes15938)
|
|
var currency interface{} = this.Currency(code)
|
|
var request interface{} = map[string]interface{} {
|
|
"currency": GetValue(currency, "id"),
|
|
"amount": this.CurrencyToPrecision(code, amount),
|
|
"fromAccountId": fromAccount,
|
|
"toAccountId": toAccount,
|
|
}
|
|
|
|
response:= (<-this.PrivatePostDoMyInternalTransfer(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "ok": "ok",
|
|
// "data": {
|
|
// "transactionId": "30225415"
|
|
// }
|
|
// }
|
|
//
|
|
var data interface{} = this.SafeDict(response, "data", map[string]interface{} {})
|
|
|
|
ch <- this.ParseTransfer(data, currency)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *cex) ParseTransfer(transfer interface{}, optionalArgs ...interface{}) interface{} {
|
|
//
|
|
// transferBetweenSubAccounts
|
|
//
|
|
// {
|
|
// "ok": "ok",
|
|
// "data": {
|
|
// "transactionId": "30225415"
|
|
// }
|
|
// }
|
|
//
|
|
// transfer between main/sub
|
|
//
|
|
// {
|
|
// "ok": "ok",
|
|
// "data": {
|
|
// "accountId": "sub1",
|
|
// "clientTxId": "27ba8284-67cf-4386-9ec7-80b3871abd45",
|
|
// "currency": "USDT",
|
|
// "status": "approved"
|
|
// }
|
|
// }
|
|
//
|
|
currency := GetArg(optionalArgs, 0, nil)
|
|
_ = currency
|
|
var currencyId interface{} = this.SafeString(transfer, "currency")
|
|
var currencyCode interface{} = this.SafeCurrencyCode(currencyId, currency)
|
|
return map[string]interface{} {
|
|
"info": transfer,
|
|
"id": this.SafeString2(transfer, "transactionId", "clientTxId"),
|
|
"timestamp": nil,
|
|
"datetime": nil,
|
|
"currency": currencyCode,
|
|
"amount": nil,
|
|
"fromAccount": nil,
|
|
"toAccount": nil,
|
|
"status": this.ParseTransactionStatus(this.SafeString(transfer, "status")),
|
|
}
|
|
}
|
|
/**
|
|
* @method
|
|
* @name cex#fetchDepositAddress
|
|
* @description fetch the deposit address for a currency associated with this account
|
|
* @see https://trade.cex.io/docs/#rest-private-api-calls-deposit-address
|
|
* @param {string} code unified currency code
|
|
* @param {object} [params] extra parameters specific to the exchange API endpoint
|
|
* @param {string} [params.accountId] account-id (default to empty string) to refer to (at this moment, only sub-accounts allowed by exchange)
|
|
* @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure}
|
|
*/
|
|
func (this *cex) FetchDepositAddress(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{} = nil
|
|
accountIdparamsVariable := this.HandleOptionAndParams(params, "createOrder", "accountId");
|
|
accountId = GetValue(accountIdparamsVariable,0);
|
|
params = GetValue(accountIdparamsVariable,1)
|
|
if IsTrue(IsEqual(accountId, nil)) {
|
|
panic(ArgumentsRequired(Add(this.Id, " fetchDepositAddress() : main account is not allowed to fetch deposit address from api, set params[\"accountId\"] or .options[\"createOrder\"][\"accountId\"] to the name of your sub-account")))
|
|
}
|
|
|
|
retRes16688 := (<-this.LoadMarkets())
|
|
PanicOnError(retRes16688)
|
|
var networkCode interface{} = nil
|
|
networkCodeparamsVariable := this.HandleNetworkCodeAndParams(params);
|
|
networkCode = GetValue(networkCodeparamsVariable,0);
|
|
params = GetValue(networkCodeparamsVariable,1)
|
|
var currency interface{} = this.Currency(code)
|
|
var request interface{} = map[string]interface{} {
|
|
"accountId": accountId,
|
|
"currency": GetValue(currency, "id"),
|
|
"blockchain": this.NetworkCodeToId(networkCode),
|
|
}
|
|
|
|
response:= (<-this.PrivatePostGetDepositAddress(this.Extend(request, params)))
|
|
PanicOnError(response)
|
|
//
|
|
// {
|
|
// "ok": "ok",
|
|
// "data": {
|
|
// "address": "TCr..................1AE",
|
|
// "accountId": "sub1",
|
|
// "currency": "USDT",
|
|
// "blockchain": "tron"
|
|
// }
|
|
// }
|
|
//
|
|
var data interface{} = this.SafeDict(response, "data", map[string]interface{} {})
|
|
|
|
ch <- this.ParseDepositAddress(data, currency)
|
|
return nil
|
|
|
|
}()
|
|
return ch
|
|
}
|
|
func (this *cex) ParseDepositAddress(depositAddress interface{}, optionalArgs ...interface{}) interface{} {
|
|
currency := GetArg(optionalArgs, 0, nil)
|
|
_ = currency
|
|
var address interface{} = this.SafeString(depositAddress, "address")
|
|
var currencyId interface{} = this.SafeString(depositAddress, "currency")
|
|
currency = this.SafeCurrency(currencyId, currency)
|
|
this.CheckAddress(address)
|
|
return map[string]interface{} {
|
|
"info": depositAddress,
|
|
"currency": GetValue(currency, "code"),
|
|
"network": this.NetworkIdToCode(this.SafeString(depositAddress, "blockchain")),
|
|
"address": address,
|
|
"tag": nil,
|
|
}
|
|
}
|
|
func (this *cex) Sign(path interface{}, optionalArgs ...interface{}) interface{} {
|
|
api := GetArg(optionalArgs, 0, "public")
|
|
_ = 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 url interface{} = Add(Add(GetValue(GetValue(this.Urls, "api"), api), "/"), this.ImplodeParams(path, params))
|
|
var query interface{} = this.Omit(params, this.ExtractParams(path))
|
|
if IsTrue(IsEqual(api, "public")) {
|
|
if IsTrue(IsEqual(method, "GET")) {
|
|
if IsTrue(GetArrayLength(ObjectKeys(query))) {
|
|
url = Add(url, Add("?", this.Urlencode(query)))
|
|
}
|
|
} else {
|
|
body = this.Json(query)
|
|
headers = map[string]interface{} {
|
|
"Content-Type": "application/json",
|
|
}
|
|
}
|
|
} else {
|
|
this.CheckRequiredCredentials()
|
|
var seconds interface{} = ToString(this.Seconds())
|
|
body = this.Json(query)
|
|
var auth interface{} = Add(Add(path, seconds), body)
|
|
var signature interface{} = this.Hmac(this.Encode(auth), this.Encode(this.Secret), sha256, "base64")
|
|
headers = map[string]interface{} {
|
|
"Content-Type": "application/json",
|
|
"X-AGGR-KEY": this.ApiKey,
|
|
"X-AGGR-TIMESTAMP": seconds,
|
|
"X-AGGR-SIGNATURE": signature,
|
|
}
|
|
}
|
|
return map[string]interface{} {
|
|
"url": url,
|
|
"method": method,
|
|
"body": body,
|
|
"headers": headers,
|
|
}
|
|
}
|
|
func (this *cex) HandleErrors(code interface{}, reason interface{}, url interface{}, method interface{}, headers interface{}, body interface{}, response interface{}, requestHeaders interface{}, requestBody interface{}) interface{} {
|
|
// in some cases, like from createOrder, exchange returns nested escaped JSON string:
|
|
// {"ok":"ok","data":{"messageType":"executionReport", "orderRejectReason":"{\"code\":405}"} }
|
|
// and because of `.parseJson` bug, we need extra fix
|
|
if IsTrue(IsEqual(response, nil)) {
|
|
if IsTrue(IsEqual(body, nil)) {
|
|
panic(NullResponse(Add(this.Id, " returned empty response")))
|
|
} else if IsTrue(IsEqual(GetValue(body, 0), "{")) {
|
|
var fixed interface{} = this.FixStringifiedJsonMembers(body)
|
|
response = this.ParseJson(fixed)
|
|
} else {
|
|
panic(NullResponse(Add(Add(this.Id, " returned unparsed response: "), body)))
|
|
}
|
|
}
|
|
var error interface{} = this.SafeString(response, "error")
|
|
if IsTrue(!IsEqual(error, nil)) {
|
|
var feedback interface{} = Add(Add(this.Id, " "), body)
|
|
this.ThrowExactlyMatchedException(GetValue(this.Exceptions, "exact"), error, feedback)
|
|
this.ThrowBroadlyMatchedException(GetValue(this.Exceptions, "broad"), error, feedback)
|
|
panic(ExchangeError(feedback))
|
|
}
|
|
// check errors in order-engine (the responses are not standard, so we parse here)
|
|
if IsTrue(IsGreaterThanOrEqual(GetIndexOf(url, "do_my_new_order"), 0)) {
|
|
var data interface{} = this.SafeDict(response, "data", map[string]interface{} {})
|
|
var rejectReason interface{} = this.SafeString(data, "rejectReason")
|
|
if IsTrue(!IsEqual(rejectReason, nil)) {
|
|
this.ThrowBroadlyMatchedException(GetValue(this.Exceptions, "broad"), rejectReason, rejectReason)
|
|
panic(ExchangeError(Add(Add(this.Id, " createOrder() "), rejectReason)))
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
|
|
func (this *cex) Init(userConfig map[string]interface{}) {
|
|
this.Exchange = Exchange{}
|
|
this.Exchange.InitParent(userConfig, this.Describe().(map[string]interface{}), this)
|
|
this.Exchange.DerivedExchange = this
|
|
}
|