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 bitrue struct { Exchange } func NewBitrueCore() bitrue { p := bitrue{} setDefaults(&p) return p } func (this *bitrue) Describe() interface{} { return this.DeepExtend(this.Exchange.Describe(), map[string]interface{} { "id": "bitrue", "name": "Bitrue", "countries": []interface{}{"SG"}, "rateLimit": 1000, "certified": false, "version": "v1", "pro": true, "has": map[string]interface{} { "CORS": nil, "spot": true, "margin": false, "swap": true, "future": false, "option": false, "cancelAllOrders": true, "cancelOrder": true, "createMarketBuyOrderWithCost": true, "createMarketOrderWithCost": false, "createMarketSellOrderWithCost": false, "createOrder": true, "createStopLimitOrder": true, "createStopMarketOrder": true, "createStopOrder": true, "fetchBalance": true, "fetchBidsAsks": true, "fetchBorrowRateHistories": false, "fetchBorrowRateHistory": false, "fetchClosedOrders": true, "fetchCrossBorrowRate": false, "fetchCrossBorrowRates": false, "fetchCurrencies": true, "fetchDepositAddress": false, "fetchDeposits": true, "fetchDepositsWithdrawals": false, "fetchDepositWithdrawFee": "emulated", "fetchDepositWithdrawFees": true, "fetchFundingHistory": false, "fetchFundingRate": false, "fetchFundingRateHistory": false, "fetchFundingRates": false, "fetchIsolatedBorrowRate": false, "fetchIsolatedBorrowRates": false, "fetchMarginMode": false, "fetchMarkets": true, "fetchMyTrades": true, "fetchOHLCV": true, "fetchOpenOrders": true, "fetchOrder": true, "fetchOrderBook": true, "fetchOrders": false, "fetchPositionMode": false, "fetchStatus": true, "fetchTicker": true, "fetchTickers": true, "fetchTime": true, "fetchTrades": true, "fetchTradingFee": false, "fetchTradingFees": false, "fetchTransactionFees": false, "fetchTransactions": false, "fetchTransfers": true, "fetchWithdrawals": true, "setLeverage": true, "setMargin": true, "transfer": true, "withdraw": true, }, "timeframes": map[string]interface{} { "1m": "1m", "5m": "5m", "15m": "15m", "30m": "30m", "1h": "1H", "2h": "2H", "4h": "4H", "1d": "1D", "1w": "1W", }, "urls": map[string]interface{} { "logo": "https://github.com/user-attachments/assets/67abe346-1273-461a-bd7c-42fa32907c8e", "api": map[string]interface{} { "spot": "https://www.bitrue.com/api", "fapi": "https://fapi.bitrue.com/fapi", "dapi": "https://fapi.bitrue.com/dapi", "kline": "https://www.bitrue.com/kline-api", }, "www": "https://www.bitrue.com", "referral": "https://www.bitrue.com/affiliate/landing?cn=600000&inviteCode=EZWETQE", "doc": []interface{}{"https://github.com/Bitrue-exchange/bitrue-official-api-docs", "https://www.bitrue.com/api-docs"}, "fees": "https://bitrue.zendesk.com/hc/en-001/articles/4405479952537", }, "api": map[string]interface{} { "spot": map[string]interface{} { "kline": map[string]interface{} { "public": map[string]interface{} { "get": map[string]interface{} { "public.json": 1, "public{currency}.json": 1, }, }, }, "v1": map[string]interface{} { "public": map[string]interface{} { "get": map[string]interface{} { "ping": 1, "time": 1, "exchangeInfo": 1, "depth": map[string]interface{} { "cost": 1, "byLimit": []interface{}{[]interface{}{100, 1}, []interface{}{500, 5}, []interface{}{1000, 10}}, }, "trades": 1, "historicalTrades": 5, "aggTrades": 1, "ticker/24hr": map[string]interface{} { "cost": 1, "noSymbol": 40, }, "ticker/price": map[string]interface{} { "cost": 1, "noSymbol": 2, }, "ticker/bookTicker": map[string]interface{} { "cost": 1, "noSymbol": 2, }, "market/kline": 1, }, }, "private": map[string]interface{} { "get": map[string]interface{} { "order": 1, "openOrders": 1, "allOrders": 5, "account": 5, "myTrades": map[string]interface{} { "cost": 5, "noSymbol": 40, }, "etf/net-value/{symbol}": 1, "withdraw/history": 1, "deposit/history": 1, }, "post": map[string]interface{} { "order": 4, "withdraw/commit": 1, }, "delete": map[string]interface{} { "order": 1, }, }, }, "v2": map[string]interface{} { "private": map[string]interface{} { "get": map[string]interface{} { "myTrades": 5, }, }, }, }, "fapi": map[string]interface{} { "v1": map[string]interface{} { "public": map[string]interface{} { "get": map[string]interface{} { "ping": 1, "time": 1, "contracts": 1, "depth": 1, "ticker": 1, "klines": 1, }, }, }, "v2": map[string]interface{} { "private": map[string]interface{} { "get": map[string]interface{} { "myTrades": 1, "openOrders": 1, "order": 1, "account": 1, "leverageBracket": 1, "commissionRate": 1, "futures_transfer_history": 1, "forceOrdersHistory": 1, }, "post": map[string]interface{} { "positionMargin": 1, "level_edit": 1, "cancel": 1, "order": 1, "allOpenOrders": 1, "futures_transfer": 1, }, }, }, }, "dapi": map[string]interface{} { "v1": map[string]interface{} { "public": map[string]interface{} { "get": map[string]interface{} { "ping": 1, "time": 1, "contracts": 1, "depth": 1, "ticker": 1, "klines": 1, }, }, }, "v2": map[string]interface{} { "private": map[string]interface{} { "get": map[string]interface{} { "myTrades": 1, "openOrders": 1, "order": 1, "account": 1, "leverageBracket": 1, "commissionRate": 1, "futures_transfer_history": 1, "forceOrdersHistory": 1, }, "post": map[string]interface{} { "positionMargin": 1, "level_edit": 1, "cancel": 1, "order": 1, "allOpenOrders": 1, "futures_transfer": 1, }, }, }, }, }, "fees": map[string]interface{} { "trading": map[string]interface{} { "feeSide": "get", "tierBased": false, "percentage": true, "taker": this.ParseNumber("0.00098"), "maker": this.ParseNumber("0.00098"), }, "future": map[string]interface{} { "trading": map[string]interface{} { "feeSide": "quote", "tierBased": true, "percentage": true, "taker": this.ParseNumber("0.000400"), "maker": this.ParseNumber("0.000200"), "tiers": map[string]interface{} { "taker": []interface{}{[]interface{}{this.ParseNumber("0"), this.ParseNumber("0.000400")}, []interface{}{this.ParseNumber("250"), this.ParseNumber("0.000400")}, []interface{}{this.ParseNumber("2500"), this.ParseNumber("0.000350")}, []interface{}{this.ParseNumber("7500"), this.ParseNumber("0.000320")}, []interface{}{this.ParseNumber("22500"), this.ParseNumber("0.000300")}, []interface{}{this.ParseNumber("50000"), this.ParseNumber("0.000270")}, []interface{}{this.ParseNumber("100000"), this.ParseNumber("0.000250")}, []interface{}{this.ParseNumber("200000"), this.ParseNumber("0.000220")}, []interface{}{this.ParseNumber("400000"), this.ParseNumber("0.000200")}, []interface{}{this.ParseNumber("750000"), this.ParseNumber("0.000170")}}, "maker": []interface{}{[]interface{}{this.ParseNumber("0"), this.ParseNumber("0.000200")}, []interface{}{this.ParseNumber("250"), this.ParseNumber("0.000160")}, []interface{}{this.ParseNumber("2500"), this.ParseNumber("0.000140")}, []interface{}{this.ParseNumber("7500"), this.ParseNumber("0.000120")}, []interface{}{this.ParseNumber("22500"), this.ParseNumber("0.000100")}, []interface{}{this.ParseNumber("50000"), this.ParseNumber("0.000080")}, []interface{}{this.ParseNumber("100000"), this.ParseNumber("0.000060")}, []interface{}{this.ParseNumber("200000"), this.ParseNumber("0.000040")}, []interface{}{this.ParseNumber("400000"), this.ParseNumber("0.000020")}, []interface{}{this.ParseNumber("750000"), this.ParseNumber("0")}}, }, }, }, "delivery": map[string]interface{} { "trading": map[string]interface{} { "feeSide": "base", "tierBased": true, "percentage": true, "taker": this.ParseNumber("0.000500"), "maker": this.ParseNumber("0.000100"), "tiers": map[string]interface{} { "taker": []interface{}{[]interface{}{this.ParseNumber("0"), this.ParseNumber("0.000500")}, []interface{}{this.ParseNumber("250"), this.ParseNumber("0.000450")}, []interface{}{this.ParseNumber("2500"), this.ParseNumber("0.000400")}, []interface{}{this.ParseNumber("7500"), this.ParseNumber("0.000300")}, []interface{}{this.ParseNumber("22500"), this.ParseNumber("0.000250")}, []interface{}{this.ParseNumber("50000"), this.ParseNumber("0.000240")}, []interface{}{this.ParseNumber("100000"), this.ParseNumber("0.000240")}, []interface{}{this.ParseNumber("200000"), this.ParseNumber("0.000240")}, []interface{}{this.ParseNumber("400000"), this.ParseNumber("0.000240")}, []interface{}{this.ParseNumber("750000"), this.ParseNumber("0.000240")}}, "maker": []interface{}{[]interface{}{this.ParseNumber("0"), this.ParseNumber("0.000100")}, []interface{}{this.ParseNumber("250"), this.ParseNumber("0.000080")}, []interface{}{this.ParseNumber("2500"), this.ParseNumber("0.000050")}, []interface{}{this.ParseNumber("7500"), this.ParseNumber("0.0000030")}, []interface{}{this.ParseNumber("22500"), this.ParseNumber("0")}, []interface{}{this.ParseNumber("50000"), this.ParseNumber("-0.000050")}, []interface{}{this.ParseNumber("100000"), this.ParseNumber("-0.000060")}, []interface{}{this.ParseNumber("200000"), this.ParseNumber("-0.000070")}, []interface{}{this.ParseNumber("400000"), this.ParseNumber("-0.000080")}, []interface{}{this.ParseNumber("750000"), this.ParseNumber("-0.000090")}}, }, }, }, }, "options": map[string]interface{} { "createMarketBuyOrderRequiresPrice": true, "fetchMarkets": []interface{}{"spot", "linear", "inverse"}, "fetchMyTradesMethod": "v2PrivateGetMyTrades", "hasAlreadyAuthenticatedSuccessfully": false, "currencyToPrecisionRoundingMode": TRUNCATE, "recvWindow": Multiply(5, 1000), "timeDifference": 0, "adjustForTimeDifference": false, "parseOrderToPrecision": false, "newOrderRespType": map[string]interface{} { "market": "FULL", "limit": "FULL", }, "networks": map[string]interface{} { "ERC20": "ETH", "TRC20": "TRX", "AETERNITY": "Aeternity", "AION": "AION", "ALGO": "Algorand", "ASK": "ASK", "ATOM": "ATOM", "AVAXC": "AVAX C-Chain", "BCH": "BCH", "BEP2": "BEP2", "BEP20": "BEP20", "Bitcoin": "Bitcoin", "BRP20": "BRP20", "ADA": "Cardano", "CASINOCOIN": "CasinoCoin", "CASINOCOIN-XRPL": "CasinoCoin XRPL", "CONTENTOS": "Contentos", "DASH": "Dash", "DECOIN": "Decoin", "DFI": "DeFiChain", "DGB": "DGB", "DIVI": "Divi", "DOGE": "dogecoin", "EOS": "EOS", "ETC": "ETC", "FILECOIN": "Filecoin", "FREETON": "FREETON", "HBAR": "HBAR", "HEDERA": "Hedera Hashgraph", "HRC20": "HRC20", "ICON": "ICON", "ICP": "ICP", "IGNIS": "Ignis", "INTERNETCOMPUTER": "Internet Computer", "IOTA": "IOTA", "KAVA": "KAVA", "KSM": "KSM", "LTC": "LiteCoin", "LUNA": "Luna", "MATIC": "MATIC", "MOBILECOIN": "Mobile Coin", "MONACOIN": "MonaCoin", "XMR": "Monero", "NEM": "NEM", "NEP5": "NEP5", "OMNI": "OMNI", "PAC": "PAC", "DOT": "Polkadot", "RAVEN": "Ravencoin", "SAFEX": "Safex", "SOL": "SOLANA", "SGB": "Songbird", "XML": "Stellar Lumens", "XYM": "Symbol", "XTZ": "Tezos", "theta": "theta", "THETA": "THETA", "VECHAIN": "VeChain", "WANCHAIN": "Wanchain", "XINFIN": "XinFin Network", "XRP": "XRP", "XRPL": "XRPL", "ZIL": "ZIL", }, "defaultType": "spot", "timeframes": map[string]interface{} { "spot": map[string]interface{} { "1m": "1m", "5m": "5m", "15m": "15m", "30m": "30m", "1h": "1H", "2h": "2H", "4h": "4H", "12h": "12H", "1d": "1D", "1w": "1W", }, "future": map[string]interface{} { "1m": "1min", "5m": "5min", "15m": "15min", "30m": "30min", "1h": "1h", "1d": "1day", "1w": "1week", "1M": "1month", }, }, "accountsByType": map[string]interface{} { "spot": "wallet", "future": "contract", "swap": "contract", "funding": "wallet", "fund": "wallet", "contract": "contract", }, }, "commonCurrencies": map[string]interface{} { "MIM": "MIM Swarm", }, "precisionMode": TICK_SIZE, "features": map[string]interface{} { "default": map[string]interface{} { "sandbox": false, "createOrder": map[string]interface{} { "marginMode": false, "triggerPrice": true, "triggerPriceType": nil, "triggerDirection": nil, "stopLossPrice": false, "takeProfitPrice": false, "attachedStopLossTakeProfit": nil, "timeInForce": map[string]interface{} { "IOC": true, "FOK": true, "PO": true, "GTD": false, }, "hedged": false, "trailing": false, "leverage": false, "marketBuyRequiresPrice": true, "marketBuyByCost": true, "selfTradePrevention": false, "iceberg": true, }, "createOrders": nil, "fetchMyTrades": map[string]interface{} { "marginMode": false, "limit": 1000, "daysBack": 100000, "untilDays": 100000, "symbolRequired": true, }, "fetchOrder": map[string]interface{} { "marginMode": false, "trigger": false, "trailing": false, "symbolRequired": true, }, "fetchOpenOrders": map[string]interface{} { "marginMode": false, "limit": nil, "trigger": false, "trailing": false, "symbolRequired": true, }, "fetchOrders": nil, "fetchClosedOrders": map[string]interface{} { "marginMode": false, "limit": 1000, "daysBack": 90, "daysBackCanceled": 1, "untilDays": 90, "trigger": false, "trailing": false, "symbolRequired": true, }, "fetchOHLCV": map[string]interface{} { "limit": 1440, }, }, "spot": map[string]interface{} { "extends": "default", }, "forDerivatives": map[string]interface{} { "extends": "default", "createOrder": map[string]interface{} { "marginMode": true, "leverage": true, "marketBuyRequiresPrice": false, "marketBuyByCost": false, }, "fetchOHLCV": map[string]interface{} { "limit": 300, }, "fetchClosedOrders": nil, }, "swap": map[string]interface{} { "linear": map[string]interface{} { "extends": "forDerivatives", }, "inverse": map[string]interface{} { "extends": "forDerivatives", }, }, "future": map[string]interface{} { "linear": nil, "inverse": nil, }, }, "exceptions": map[string]interface{} { "exact": map[string]interface{} { "System is under maintenance.": OnMaintenance, "System abnormality": ExchangeError, "You are not authorized to execute this request.": PermissionDenied, "API key does not exist": AuthenticationError, "Order would trigger immediately.": OrderImmediatelyFillable, "Stop price would trigger immediately.": OrderImmediatelyFillable, "Order would immediately match and take.": OrderImmediatelyFillable, "Account has insufficient balance for requested action.": InsufficientFunds, "Rest API trading is not enabled.": ExchangeNotAvailable, "You don\\'t have permission.": PermissionDenied, "Market is closed.": ExchangeNotAvailable, "Too many requests. Please try again later.": DDoSProtection, "-1000": ExchangeNotAvailable, "-1001": ExchangeNotAvailable, "-1002": AuthenticationError, "-1003": RateLimitExceeded, "-1013": InvalidOrder, "-1015": RateLimitExceeded, "-1016": ExchangeNotAvailable, "-1020": BadRequest, "-1021": InvalidNonce, "-1022": AuthenticationError, "-1100": BadRequest, "-1101": BadRequest, "-1102": BadRequest, "-1103": BadRequest, "-1104": BadRequest, "-1105": BadRequest, "-1106": BadRequest, "-1111": BadRequest, "-1112": InvalidOrder, "-1114": BadRequest, "-1115": BadRequest, "-1116": BadRequest, "-1117": BadRequest, "-1166": InvalidOrder, "-1118": BadRequest, "-1119": BadRequest, "-1120": BadRequest, "-1121": BadSymbol, "-1125": AuthenticationError, "-1127": BadRequest, "-1128": BadRequest, "-1130": BadRequest, "-1131": BadRequest, "-1160": InvalidOrder, "-1156": InvalidOrder, "-2008": AuthenticationError, "-2010": ExchangeError, "-2011": OrderNotFound, "-2013": OrderNotFound, "-2014": AuthenticationError, "-2015": AuthenticationError, "-2017": InsufficientFunds, "-2019": InsufficientFunds, "-3005": InsufficientFunds, "-3006": InsufficientFunds, "-3008": InsufficientFunds, "-3010": ExchangeError, "-3015": ExchangeError, "-3022": AccountSuspended, "-4028": BadRequest, "-3020": InsufficientFunds, "-3041": InsufficientFunds, "-5013": InsufficientFunds, "-11008": InsufficientFunds, "-4051": InsufficientFunds, }, "broad": map[string]interface{} { "Insufficient account balance": InsufficientFunds, "has no operation privilege": PermissionDenied, "MAX_POSITION": InvalidOrder, }, }, }) } func (this *bitrue) Nonce() interface{} { return Subtract(this.Milliseconds(), GetValue(this.Options, "timeDifference")) } /** * @method * @name bitrue#fetchStatus * @description the latest known information on the availability of the exchange API * @see https://github.com/Bitrue-exchange/Spot-official-api-docs#test-connectivity * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [status structure]{@link https://docs.ccxt.com/#/?id=exchange-status-structure} */ func (this *bitrue) FetchStatus(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.SpotV1PublicGetPing(params)) PanicOnError(response) // // empty means working status. // // {} // var keys interface{} = ObjectKeys(response) var keysLength interface{} = GetArrayLength(keys) var formattedStatus interface{} = Ternary(IsTrue(keysLength), "maintenance", "ok") ch <- map[string]interface{} { "status": formattedStatus, "updated": nil, "eta": nil, "url": nil, "info": response, } return nil }() return ch } /** * @method * @name bitrue#fetchTime * @description fetches the current integer timestamp in milliseconds from the exchange server * @see https://github.com/Bitrue-exchange/Spot-official-api-docs#check-server-time * @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 *bitrue) 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.SpotV1PublicGetTime(params)) PanicOnError(response) // // { // "serverTime":1635467280514 // } // ch <- this.SafeInteger(response, "serverTime") return nil }() return ch } /** * @method * @name bitrue#fetchCurrencies * @description fetches all available currencies on an exchange * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} an associative dictionary of currencies */ func (this *bitrue) 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.SpotV1PublicGetExchangeInfo(params)) PanicOnError(response) // // { // "timezone":"CTT", // "serverTime":1635464889117, // "rateLimits":[ // {"rateLimitType":"REQUESTS_WEIGHT","interval":"MINUTES","limit":6000}, // {"rateLimitType":"ORDERS","interval":"SECONDS","limit":150}, // {"rateLimitType":"ORDERS","interval":"DAYS","limit":288000}, // ], // "exchangeFilters":[], // "symbols":[ // { // "symbol":"SHABTC", // "status":"TRADING", // "baseAsset":"sha", // "baseAssetPrecision":0, // "quoteAsset":"btc", // "quotePrecision":10, // "orderTypes":["MARKET","LIMIT"], // "icebergAllowed":false, // "filters":[ // {"filterType":"PRICE_FILTER","minPrice":"0.00000001349","maxPrice":"0.00000017537","priceScale":10}, // {"filterType":"LOT_SIZE","minQty":"1.0","minVal":"0.00020","maxQty":"1000000000","volumeScale":0}, // ], // "defaultPrice":"0.0000006100", // }, // ], // "coins":[ // { // "coin": "near", // "coinFulName": "NEAR Protocol", // "chains": [ "BEP20", ], // "chainDetail": [ // { // "chain": "BEP20", // "enableWithdraw": true, // "enableDeposit": true, // "withdrawFee": "0.2000", // "minWithdraw": "5.0000", // "maxWithdraw": "1000000000000000.0000", // }, // ], // }, // ], // } // var result interface{} = map[string]interface{} {} var coins interface{} = this.SafeList(response, "coins", []interface{}{}) for i := 0; IsLessThan(i, GetArrayLength(coins)); i++ { var currency interface{} = GetValue(coins, i) var id interface{} = this.SafeString(currency, "coin") var name interface{} = this.SafeString(currency, "coinFulName") var code interface{} = this.SafeCurrencyCode(id) var deposit interface{} = nil var withdraw interface{} = nil var minWithdrawString interface{} = nil var maxWithdrawString interface{} = nil var minWithdrawFeeString interface{} = nil var networkDetails interface{} = this.SafeList(currency, "chainDetail", []interface{}{}) var networks interface{} = map[string]interface{} {} for j := 0; IsLessThan(j, GetArrayLength(networkDetails)); j++ { var entry interface{} = GetValue(networkDetails, j) var networkId interface{} = this.SafeString(entry, "chain") var network interface{} = this.NetworkIdToCode(networkId, code) var enableDeposit interface{} = this.SafeBool(entry, "enableDeposit") deposit = Ternary(IsTrue((enableDeposit)), enableDeposit, deposit) var enableWithdraw interface{} = this.SafeBool(entry, "enableWithdraw") withdraw = Ternary(IsTrue((enableWithdraw)), enableWithdraw, withdraw) var networkWithdrawFeeString interface{} = this.SafeString(entry, "withdrawFee") if IsTrue(!IsEqual(networkWithdrawFeeString, nil)) { minWithdrawFeeString = Ternary(IsTrue((IsEqual(minWithdrawFeeString, nil))), networkWithdrawFeeString, Precise.StringMin(networkWithdrawFeeString, minWithdrawFeeString)) } var networkMinWithdrawString interface{} = this.SafeString(entry, "minWithdraw") if IsTrue(!IsEqual(networkMinWithdrawString, nil)) { minWithdrawString = Ternary(IsTrue((IsEqual(minWithdrawString, nil))), networkMinWithdrawString, Precise.StringMin(networkMinWithdrawString, minWithdrawString)) } var networkMaxWithdrawString interface{} = this.SafeString(entry, "maxWithdraw") if IsTrue(!IsEqual(networkMaxWithdrawString, nil)) { maxWithdrawString = Ternary(IsTrue((IsEqual(maxWithdrawString, nil))), networkMaxWithdrawString, Precise.StringMax(networkMaxWithdrawString, maxWithdrawString)) } AddElementToObject(networks, network, map[string]interface{} { "info": entry, "id": networkId, "network": network, "deposit": enableDeposit, "withdraw": enableWithdraw, "active": IsTrue(enableDeposit) && IsTrue(enableWithdraw), "fee": this.ParseNumber(networkWithdrawFeeString), "precision": nil, "limits": map[string]interface{} { "withdraw": map[string]interface{} { "min": this.ParseNumber(networkMinWithdrawString), "max": this.ParseNumber(networkMaxWithdrawString), }, }, }) } AddElementToObject(result, code, map[string]interface{} { "id": id, "name": name, "code": code, "precision": nil, "info": currency, "active": IsTrue(deposit) && IsTrue(withdraw), "deposit": deposit, "withdraw": withdraw, "networks": networks, "fee": this.ParseNumber(minWithdrawFeeString), "limits": map[string]interface{} { "withdraw": map[string]interface{} { "min": this.ParseNumber(minWithdrawString), "max": this.ParseNumber(maxWithdrawString), }, }, }) } ch <- result return nil }() return ch } /** * @method * @name bitrue#fetchMarkets * @description retrieves data on all markets for bitrue * @see https://github.com/Bitrue-exchange/Spot-official-api-docs#exchangeInfo_endpoint * @see https://www.bitrue.com/api-docs#current-open-contract * @see https://www.bitrue.com/api_docs_includes_file/delivery.html#current-open-contract * @param {object} [params] extra parameters specific to the exchange api endpoint * @returns {object[]} an array of objects representing market data */ func (this *bitrue) 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 var promisesRaw interface{} = []interface{}{} var fetchMarkets interface{} = this.SafeValue(this.Options, "fetchMarkets", []interface{}{"spot", "linear", "inverse"}) for i := 0; IsLessThan(i, GetArrayLength(fetchMarkets)); i++ { var marketType interface{} = GetValue(fetchMarkets, i) if IsTrue(IsEqual(marketType, "spot")) { AppendToArray(&promisesRaw,this.SpotV1PublicGetExchangeInfo(params)) } else if IsTrue(IsEqual(marketType, "linear")) { AppendToArray(&promisesRaw,this.FapiV1PublicGetContracts(params)) } else if IsTrue(IsEqual(marketType, "inverse")) { AppendToArray(&promisesRaw,this.DapiV1PublicGetContracts(params)) } else { panic(ExchangeError(Add(Add(Add(this.Id, " fetchMarkets() this.options fetchMarkets \""), marketType), "\" is not a supported market type"))) } } promises:= (<-promiseAll(promisesRaw)) PanicOnError(promises) var spotMarkets interface{} = this.SafeValue(this.SafeValue(promises, 0), "symbols", []interface{}{}) var futureMarkets interface{} = this.SafeValue(promises, 1) var deliveryMarkets interface{} = this.SafeValue(promises, 2) var markets interface{} = spotMarkets markets = this.ArrayConcat(markets, futureMarkets) markets = this.ArrayConcat(markets, deliveryMarkets) // // spot // // { // "timezone":"CTT", // "serverTime":1635464889117, // "rateLimits":[ // {"rateLimitType":"REQUESTS_WEIGHT","interval":"MINUTES","limit":6000}, // {"rateLimitType":"ORDERS","interval":"SECONDS","limit":150}, // {"rateLimitType":"ORDERS","interval":"DAYS","limit":288000}, // ], // "exchangeFilters":[], // "symbols":[ // { // "symbol":"SHABTC", // "status":"TRADING", // "baseAsset":"sha", // "baseAssetPrecision":0, // "quoteAsset":"btc", // "quotePrecision":10, // "orderTypes":["MARKET","LIMIT"], // "icebergAllowed":false, // "filters":[ // {"filterType":"PRICE_FILTER","minPrice":"0.00000001349","maxPrice":"0.00000017537","priceScale":10}, // {"filterType":"LOT_SIZE","minQty":"1.0","minVal":"0.00020","maxQty":"1000000000","volumeScale":0}, // ], // "defaultPrice":"0.0000006100", // }, // ], // "coins":[ // { // "coin":"sbr", // "coinFulName":"Saber", // "enableWithdraw":true, // "enableDeposit":true, // "chains":["SOLANA"], // "withdrawFee":"2.0", // "minWithdraw":"5.0", // "maxWithdraw":"1000000000000000", // }, // ], // } // // swap / delivery // // [ // { // "symbol": "H-HT-USDT", // "pricePrecision": 8, // "side": 1, // "maxMarketVolume": 100000, // "multiplier": 6, // "minOrderVolume": 1, // "maxMarketMoney": 10000000, // "type": "H", // E: perpetual contract, S: test contract, others are mixed contract // "maxLimitVolume": 1000000, // "maxValidOrder": 20, // "multiplierCoin": "HT", // "minOrderMoney": 0.001, // "maxLimitMoney": 1000000, // "status": 1 // } // ] // if IsTrue(GetValue(this.Options, "adjustForTimeDifference")) { retRes88712 := (<-this.LoadTimeDifference()) PanicOnError(retRes88712) } ch <- this.ParseMarkets(markets) return nil }() return ch } func (this *bitrue) ParseMarket(market interface{}) interface{} { var id interface{} = this.SafeString(market, "symbol") var lowercaseId interface{} = this.SafeStringLower(market, "symbol") var side interface{} = this.SafeInteger(market, "side") // 1 linear, 0 inverse, undefined spot var typeVar interface{} = nil var isLinear interface{} = nil var isInverse interface{} = nil if IsTrue(IsEqual(side, nil)) { typeVar = "spot" } else { typeVar = "swap" isLinear = (IsEqual(side, 1)) isInverse = (IsEqual(side, 0)) } var isContract interface{} = (!IsEqual(typeVar, "spot")) var baseId interface{} = this.SafeString(market, "baseAsset") var quoteId interface{} = this.SafeString(market, "quoteAsset") var settleId interface{} = nil var settle interface{} = nil if IsTrue(isContract) { var symbolSplit interface{} = Split(id, "-") baseId = this.SafeString(symbolSplit, 1) quoteId = this.SafeString(symbolSplit, 2) if IsTrue(isLinear) { settleId = quoteId } else { settleId = baseId } settle = this.SafeCurrencyCode(settleId) } var base interface{} = this.SafeCurrencyCode(baseId) var quote interface{} = this.SafeCurrencyCode(quoteId) var symbol interface{} = Add(Add(base, "/"), quote) if IsTrue(!IsEqual(settle, nil)) { symbol = Add(symbol, Add(":", settle)) } var filters interface{} = this.SafeList(market, "filters", []interface{}{}) var filtersByType interface{} = this.IndexBy(filters, "filterType") var status interface{} = this.SafeString(market, "status") var priceFilter interface{} = this.SafeDict(filtersByType, "PRICE_FILTER", map[string]interface{} {}) var amountFilter interface{} = this.SafeDict(filtersByType, "LOT_SIZE", map[string]interface{} {}) var defaultPricePrecision interface{} = this.SafeString(market, "pricePrecision") var defaultAmountPrecision interface{} = this.SafeString(market, "quantityPrecision") var pricePrecision interface{} = this.SafeString(priceFilter, "priceScale", defaultPricePrecision) var amountPrecision interface{} = this.SafeString(amountFilter, "volumeScale", defaultAmountPrecision) var multiplier interface{} = this.SafeString(market, "multiplier") var maxQuantity interface{} = this.SafeNumber(amountFilter, "maxQty") if IsTrue(IsEqual(maxQuantity, nil)) { maxQuantity = this.SafeNumber(market, "maxValidOrder") } var minCost interface{} = this.SafeNumber(amountFilter, "minVal") if IsTrue(IsEqual(minCost, nil)) { minCost = this.SafeNumber(market, "minOrderMoney") } return map[string]interface{} { "id": id, "lowercaseId": lowercaseId, "symbol": symbol, "base": base, "quote": quote, "settle": settle, "baseId": baseId, "quoteId": quoteId, "settleId": settleId, "type": typeVar, "spot": (IsEqual(typeVar, "spot")), "margin": false, "swap": isContract, "future": false, "option": false, "active": (IsEqual(status, "TRADING")), "contract": isContract, "linear": isLinear, "inverse": isInverse, "contractSize": this.ParseNumber(Precise.StringAbs(multiplier)), "expiry": nil, "expiryDatetime": nil, "strike": nil, "optionType": nil, "precision": map[string]interface{} { "amount": this.ParseNumber(this.ParsePrecision(amountPrecision)), "price": this.ParseNumber(this.ParsePrecision(pricePrecision)), }, "limits": map[string]interface{} { "leverage": map[string]interface{} { "min": nil, "max": nil, }, "amount": map[string]interface{} { "min": this.SafeNumber(amountFilter, "minQty"), "max": maxQuantity, }, "price": map[string]interface{} { "min": this.SafeNumber(priceFilter, "minPrice"), "max": this.SafeNumber(priceFilter, "maxPrice"), }, "cost": map[string]interface{} { "min": minCost, "max": nil, }, }, "created": nil, "info": market, } } func (this *bitrue) ParseBalance(response interface{}) interface{} { // // spot // // { // "makerCommission":0, // "takerCommission":0, // "buyerCommission":0, // "sellerCommission":0, // "updateTime":null, // "balances":[ // {"asset":"sbr","free":"0","locked":"0"}, // {"asset":"ksm","free":"0","locked":"0"}, // {"asset":"neo3s","free":"0","locked":"0"}, // ], // "canTrade":false, // "canWithdraw":false, // "canDeposit":false // } // // swap // // { // "account":[ // { // "marginCoin":"USDT", // "coinPrecious":4, // "accountNormal":1010.4043400372839856, // "accountLock":2.9827889600000006, // "partPositionNormal":0, // "totalPositionNormal":0, // "achievedAmount":0, // "unrealizedAmount":0, // "totalMarginRate":0, // "totalEquity":1010.4043400372839856, // "partEquity":0, // "totalCost":0, // "sumMarginRate":0, // "sumOpenRealizedAmount":0, // "canUseTrialFund":0, // "sumMaintenanceMargin":null, // "futureModel":null, // "positionVos":[] // } // ] // } // var result interface{} = map[string]interface{} { "info": response, } var timestamp interface{} = this.SafeInteger(response, "updateTime") var balances interface{} = this.SafeValue2(response, "balances", "account", []interface{}{}) for i := 0; IsLessThan(i, GetArrayLength(balances)); i++ { var balance interface{} = GetValue(balances, i) var currencyId interface{} = this.SafeString2(balance, "asset", "marginCoin") var code interface{} = this.SafeCurrencyCode(currencyId) var account interface{} = this.Account() AddElementToObject(account, "free", this.SafeString2(balance, "free", "accountNormal")) AddElementToObject(account, "used", this.SafeString2(balance, "locked", "accountLock")) AddElementToObject(result, code, account) } AddElementToObject(result, "timestamp", timestamp) AddElementToObject(result, "datetime", this.Iso8601(timestamp)) return this.SafeBalance(result) } /** * @method * @name bitrue#fetchBalance * @description query for balance and get the amount of funds available for trading or funds locked in orders * @see https://github.com/Bitrue-exchange/Spot-official-api-docs#account-information-user_data * @see https://www.bitrue.com/api-docs#account-information-v2-user_data-hmac-sha256 * @see https://www.bitrue.com/api_docs_includes_file/delivery.html#account-information-v2-user_data-hmac-sha256 * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.type] 'future', 'delivery', 'spot', 'swap' * @param {string} [params.subType] 'linear', 'inverse' * @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure} */ func (this *bitrue) 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 retRes10778 := (<-this.LoadMarkets()) PanicOnError(retRes10778) var typeVar interface{} = nil typeVarparamsVariable := this.HandleMarketTypeAndParams("fetchBalance", nil, params); typeVar = GetValue(typeVarparamsVariable,0); params = GetValue(typeVarparamsVariable,1) var subType interface{} = nil subTypeparamsVariable := this.HandleSubTypeAndParams("fetchBalance", nil, params); subType = GetValue(subTypeparamsVariable,0); params = GetValue(subTypeparamsVariable,1) var response interface{} = nil var result interface{} = nil if IsTrue(IsEqual(typeVar, "swap")) { if IsTrue(IsTrue(!IsEqual(subType, nil)) && IsTrue(IsEqual(subType, "inverse"))) { response = (<-this.DapiV2PrivateGetAccount(params)) PanicOnError(response) result = this.SafeDict(response, "data", map[string]interface{} {}) } else { response = (<-this.FapiV2PrivateGetAccount(params)) PanicOnError(response) result = this.SafeDict(response, "data", map[string]interface{} {}) } } else { response = (<-this.SpotV1PrivateGetAccount(params)) PanicOnError(response) result = response } ch <- this.ParseBalance(result) return nil }() return ch } /** * @method * @name bitrue#fetchOrderBook * @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data * @see https://github.com/Bitrue-exchange/Spot-official-api-docs#order-book * @see https://www.bitrue.com/api-docs#order-book * @see https://www.bitrue.com/api_docs_includes_file/delivery.html#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 *bitrue) 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 retRes11898 := (<-this.LoadMarkets()) PanicOnError(retRes11898) var market interface{} = this.Market(symbol) var response interface{} = nil if IsTrue(GetValue(market, "swap")) { var request interface{} = map[string]interface{} { "contractName": GetValue(market, "id"), } if IsTrue(!IsEqual(limit, nil)) { if IsTrue(IsGreaterThan(limit, 100)) { limit = 100 } AddElementToObject(request, "limit", limit) // default 100, max 100, see https://www.bitrue.com/api-docs#order-book } if IsTrue(GetValue(market, "linear")) { response = (<-this.FapiV1PublicGetDepth(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(GetValue(market, "inverse")) { response = (<-this.DapiV1PublicGetDepth(this.Extend(request, params))) PanicOnError(response) } } else if IsTrue(GetValue(market, "spot")) { var request interface{} = map[string]interface{} { "symbol": GetValue(market, "id"), } if IsTrue(!IsEqual(limit, nil)) { if IsTrue(IsGreaterThan(limit, 1000)) { limit = 1000 } AddElementToObject(request, "limit", limit) // default 100, max 1000, see https://github.com/Bitrue-exchange/bitrue-official-api-docs#order-book } response = (<-this.SpotV1PublicGetDepth(this.Extend(request, params))) PanicOnError(response) } else { panic(NotSupported(Add(this.Id, " fetchOrderBook only support spot & swap markets"))) } // // spot // // { // "lastUpdateId":1635474910177, // "bids":[ // ["61436.84","0.05",[]], // ["61435.77","0.0124",[]], // ["61434.88","0.012",[]], // ], // "asks":[ // ["61452.46","0.0001",[]], // ["61452.47","0.0597",[]], // ["61452.76","0.0713",[]], // ] // } // // swap // // { // "asks": [[34916.5, 2582], [34916.6, 2193], [34916.7, 2629], [34916.8, 3478], [34916.9, 2718]], // "bids": [[34916.4, 92065], [34916.3, 25703], [34916.2, 37259], [34916.1, 26446], [34916, 44456]], // "time": 1699338305000 // } // var timestamp interface{} = this.SafeInteger(response, "time") var orderbook interface{} = this.ParseOrderBook(response, symbol, timestamp) AddElementToObject(orderbook, "nonce", this.SafeInteger(response, "lastUpdateId")) ch <- orderbook return nil }() return ch } func (this *bitrue) ParseTicker(ticker interface{}, optionalArgs ...interface{}) interface{} { // // fetchBidsAsks // // { // "symbol": "LTCBTC", // "bidPrice": "4.00000000", // "bidQty": "431.00000000", // "askPrice": "4.00000200", // "askQty": "9.00000000" // } // // fetchTicker // // { // "symbol": "BNBBTC", // "priceChange": "0.000248", // "priceChangePercent": "3.5500", // "weightedAvgPrice": null, // "prevClosePrice": null, // "lastPrice": "0.007226", // "lastQty": null, // "bidPrice": "0.007208", // "askPrice": "0.007240", // "openPrice": "0.006978", // "highPrice": "0.007295", // "lowPrice": "0.006935", // "volume": "11749.86", // "quoteVolume": "84.1066211", // "openTime": 0, // "closeTime": 0, // "firstId": 0, // "lastId": 0, // "count": 0 // } // market := GetArg(optionalArgs, 0, nil) _ = market var symbol interface{} = this.SafeSymbol(nil, market) var last interface{} = this.SafeString2(ticker, "lastPrice", "last") var timestamp interface{} = this.SafeInteger(ticker, "time") var percentage interface{} = nil if IsTrue(GetValue(market, "swap")) { percentage = Precise.StringMul(this.SafeString(ticker, "rose"), "100") } else { percentage = this.SafeString(ticker, "priceChangePercent") } return this.SafeTicker(map[string]interface{} { "symbol": symbol, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "high": this.SafeString2(ticker, "highPrice", "high"), "low": this.SafeString2(ticker, "lowPrice", "low"), "bid": this.SafeString2(ticker, "bidPrice", "buy"), "bidVolume": this.SafeString(ticker, "bidQty"), "ask": this.SafeString2(ticker, "askPrice", "sell"), "askVolume": this.SafeString(ticker, "askQty"), "vwap": this.SafeString(ticker, "weightedAvgPrice"), "open": this.SafeString(ticker, "openPrice"), "close": last, "last": last, "previousClose": nil, "change": this.SafeString(ticker, "priceChange"), "percentage": percentage, "average": nil, "baseVolume": this.SafeString2(ticker, "volume", "vol"), "quoteVolume": this.SafeString(ticker, "quoteVolume"), "info": ticker, }, market) } /** * @method * @name bitrue#fetchTicker * @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market * @see https://github.com/Bitrue-exchange/Spot-official-api-docs#24hr-ticker-price-change-statistics * @see https://www.bitrue.com/api-docs#ticker * @see https://www.bitrue.com/api_docs_includes_file/delivery.html#ticker * @param {string} symbol unified symbol of the market to fetch the ticker for * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure} */ func (this *bitrue) 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 retRes13338 := (<-this.LoadMarkets()) PanicOnError(retRes13338) var market interface{} = this.Market(symbol) var response interface{} = nil var data interface{} = nil if IsTrue(GetValue(market, "swap")) { var request interface{} = map[string]interface{} { "contractName": GetValue(market, "id"), } if IsTrue(GetValue(market, "linear")) { response = (<-this.FapiV1PublicGetTicker(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(GetValue(market, "inverse")) { response = (<-this.DapiV1PublicGetTicker(this.Extend(request, params))) PanicOnError(response) } data = response } else if IsTrue(GetValue(market, "spot")) { var request interface{} = map[string]interface{} { "symbol": GetValue(market, "id"), } response = (<-this.SpotV1PublicGetTicker24hr(this.Extend(request, params))) PanicOnError(response) data = this.SafeDict(response, 0, map[string]interface{} {}) } else { panic(NotSupported(Add(this.Id, " fetchTicker only support spot & swap markets"))) } // // spot // // [{ // symbol: 'BTCUSDT', // priceChange: '105.20', // priceChangePercent: '0.3000', // weightedAvgPrice: null, // prevClosePrice: null, // lastPrice: '34905.21', // lastQty: null, // bidPrice: '34905.21', // askPrice: '34905.22', // openPrice: '34800.01', // highPrice: '35276.33', // lowPrice: '34787.51', // volume: '12549.6481', // quoteVolume: '439390492.917', // openTime: '0', // closeTime: '0', // firstId: '0', // lastId: '0', // count: '0' // }] // // swap // // { // "high": "35296", // "vol": "779308354", // "last": "34884.1", // "low": "34806.7", // "buy": 34883.9, // "sell": 34884, // "rose": "-0.0027957315", // "time": 1699348013000 // } // ch <- this.ParseTicker(data, market) return nil }() return ch } /** * @method * @name bitrue#fetchOHLCV * @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market * @see https://www.bitrue.com/api_docs_includes_file/spot/index.html#kline-data * @see https://www.bitrue.com/api_docs_includes_file/futures/index.html#kline-candlestick-data * @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 * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume */ func (this *bitrue) 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 retRes14118 := (<-this.LoadMarkets()) PanicOnError(retRes14118) var market interface{} = this.Market(symbol) var timeframes interface{} = this.SafeDict(this.Options, "timeframes", map[string]interface{} {}) var response interface{} = nil var data interface{} = nil if IsTrue(GetValue(market, "swap")) { var timeframesFuture interface{} = this.SafeDict(timeframes, "future", map[string]interface{} {}) var request interface{} = map[string]interface{} { "contractName": GetValue(market, "id"), "interval": this.SafeString(timeframesFuture, timeframe, "1min"), } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) } if IsTrue(GetValue(market, "linear")) { response = (<-this.FapiV1PublicGetKlines(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(GetValue(market, "inverse")) { response = (<-this.DapiV1PublicGetKlines(this.Extend(request, params))) PanicOnError(response) } data = response } else if IsTrue(GetValue(market, "spot")) { var timeframesSpot interface{} = this.SafeDict(timeframes, "spot", map[string]interface{} {}) var request interface{} = map[string]interface{} { "symbol": GetValue(market, "id"), "scale": this.SafeString(timeframesSpot, timeframe, "1m"), } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "fromIdx", since) } response = (<-this.SpotV1PublicGetMarketKline(this.Extend(request, params))) PanicOnError(response) data = this.SafeList(response, "data", []interface{}{}) } else { panic(NotSupported(Add(this.Id, " fetchOHLCV only support spot & swap markets"))) } // // spot // // { // "symbol":"BTCUSDT", // "scale":"KLINE_1MIN", // "data":[ // { // "i":"1660825020", // "a":"93458.778", // "v":"3.9774", // "c":"23494.99", // "h":"23509.63", // "l":"23491.93", // "o":"23508.34" // } // ] // } // // swap // // [ // { // "high": "35360.7", // "vol": "110288", // "low": "35347.9", // "idx": 1699411680000, // "close": "35347.9", // "open": "35349.4" // } // ] // ch <- this.ParseOHLCVs(data, market, timeframe, since, limit) return nil }() return ch } func (this *bitrue) ParseOHLCV(ohlcv interface{}, optionalArgs ...interface{}) interface{} { // // spot // // { // "i":"1660825020", // "a":"93458.778", // "v":"3.9774", // "c":"23494.99", // "h":"23509.63", // "l":"23491.93", // "o":"23508.34" // } // // swap // // { // "high": "35360.7", // "vol": "110288", // "low": "35347.9", // "idx": 1699411680000, // "close": "35347.9", // "open": "35349.4" // } // market := GetArg(optionalArgs, 0, nil) _ = market var timestamp interface{} = this.SafeTimestamp(ohlcv, "i") if IsTrue(IsEqual(timestamp, nil)) { timestamp = this.SafeInteger(ohlcv, "idx") } return []interface{}{timestamp, this.SafeNumber2(ohlcv, "o", "open"), this.SafeNumber2(ohlcv, "h", "high"), this.SafeNumber2(ohlcv, "l", "low"), this.SafeNumber2(ohlcv, "c", "close"), this.SafeNumber2(ohlcv, "v", "vol")} } /** * @method * @name bitrue#fetchBidsAsks * @description fetches the bid and ask price and volume for multiple markets * @see https://github.com/Bitrue-exchange/Spot-official-api-docs#symbol-order-book-ticker * @see https://www.bitrue.com/api-docs#ticker * @see https://www.bitrue.com/api_docs_includes_file/delivery.html#ticker * @param {string[]|undefined} 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 *bitrue) 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 retRes15368 := (<-this.LoadMarkets()) PanicOnError(retRes15368) symbols = this.MarketSymbols(symbols, nil, false) var first interface{} = this.SafeString(symbols, 0) var market interface{} = this.Market(first) var response interface{} = nil if IsTrue(GetValue(market, "swap")) { var request interface{} = map[string]interface{} { "contractName": GetValue(market, "id"), } if IsTrue(GetValue(market, "linear")) { response = (<-this.FapiV1PublicGetTicker(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(GetValue(market, "inverse")) { response = (<-this.DapiV1PublicGetTicker(this.Extend(request, params))) PanicOnError(response) } } else if IsTrue(GetValue(market, "spot")) { var request interface{} = map[string]interface{} { "symbol": GetValue(market, "id"), } response = (<-this.SpotV1PublicGetTickerBookTicker(this.Extend(request, params))) PanicOnError(response) } else { panic(NotSupported(Add(this.Id, " fetchBidsAsks only support spot & swap markets"))) } // // spot // // { // "symbol": "LTCBTC", // "bidPrice": "4.00000000", // "bidQty": "431.00000000", // "askPrice": "4.00000200", // "askQty": "9.00000000" // } // // swap // // { // "high": "35296", // "vol": "779308354", // "last": "34884.1", // "low": "34806.7", // "buy": 34883.9, // "sell": 34884, // "rose": "-0.0027957315", // "time": 1699348013000 // } // var data interface{} = map[string]interface{} {} AddElementToObject(data, GetValue(market, "id"), response) ch <- this.ParseTickers(data, symbols) return nil }() return ch } /** * @method * @name bitrue#fetchTickers * @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market * @see https://github.com/Bitrue-exchange/Spot-official-api-docs#24hr-ticker-price-change-statistics * @see https://www.bitrue.com/api-docs#ticker * @see https://www.bitrue.com/api_docs_includes_file/delivery.html#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 *bitrue) 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 retRes15998 := (<-this.LoadMarkets()) PanicOnError(retRes15998) symbols = this.MarketSymbols(symbols) var response interface{} = nil var data interface{} = nil var request interface{} = map[string]interface{} {} var typeVar interface{} = nil if IsTrue(!IsEqual(symbols, nil)) { var first interface{} = this.SafeString(symbols, 0) var market interface{} = this.Market(first) if IsTrue(GetValue(market, "swap")) { panic(NotSupported(Add(this.Id, " fetchTickers does not support swap markets, please use fetchTicker instead"))) } else if IsTrue(GetValue(market, "spot")) { response = (<-this.SpotV1PublicGetTicker24hr(this.Extend(request, params))) PanicOnError(response) data = response } else { panic(NotSupported(Add(this.Id, " fetchTickers only support spot & swap markets"))) } } else { typeVarparamsVariable := this.HandleMarketTypeAndParams("fetchTickers", nil, params); typeVar = GetValue(typeVarparamsVariable,0); params = GetValue(typeVarparamsVariable,1) if IsTrue(!IsEqual(typeVar, "spot")) { panic(NotSupported(Add(this.Id, " fetchTickers only support spot when symbols are not proved"))) } response = (<-this.SpotV1PublicGetTicker24hr(this.Extend(request, params))) PanicOnError(response) data = response } // // spot // // [{ // symbol: 'BTCUSDT', // priceChange: '105.20', // priceChangePercent: '0.3000', // weightedAvgPrice: null, // prevClosePrice: null, // lastPrice: '34905.21', // lastQty: null, // bidPrice: '34905.21', // askPrice: '34905.22', // openPrice: '34800.01', // highPrice: '35276.33', // lowPrice: '34787.51', // volume: '12549.6481', // quoteVolume: '439390492.917', // openTime: '0', // closeTime: '0', // firstId: '0', // lastId: '0', // count: '0' // }] // // swap // // { // "high": "35296", // "vol": "779308354", // "last": "34884.1", // "low": "34806.7", // "buy": 34883.9, // "sell": 34884, // "rose": "-0.0027957315", // "time": 1699348013000 // } // // the exchange returns market ids with an underscore from the tickers endpoint // the market ids do not have an underscore, so it has to be removed // https://github.com/ccxt/ccxt/issues/13856 var tickers interface{} = map[string]interface{} {} for i := 0; IsLessThan(i, GetArrayLength(data)); i++ { var ticker interface{} = this.SafeDict(data, i, map[string]interface{} {}) var market interface{} = this.Market(this.SafeValue(ticker, "symbol")) AddElementToObject(tickers, GetValue(market, "id"), ticker) } ch <- this.ParseTickers(tickers, symbols) return nil }() return ch } func (this *bitrue) ParseTrade(trade interface{}, optionalArgs ...interface{}) interface{} { // // fetchTrades // // { // "id": 28457, // "price": "4.00000100", // "qty": "12.00000000", // "time": 1499865549590, // Actual timestamp of trade // "isBuyerMaker": true, // "isBestMatch": true // } // // fetchTrades - spot // // { // "symbol":"USDCUSDT", // "id":20725156, // "orderId":2880918576, // "origClientOrderId":null, // "price":"0.9996000000000000", // "qty":"100.0000000000000000", // "commission":null, // "commissionAssert":null, // "time":1635558511000, // "isBuyer":false, // "isMaker":false, // "isBestMatch":true // } // // fetchTrades - future // // { // "tradeId":12, // "price":0.9, // "qty":1, // "amount":9, // "contractName":"E-SAND-USDT", // "side":"BUY", // "fee":"0.0018", // "bidId":1558124009467904992, // "askId":1558124043827644908, // "bidUserId":10294, // "askUserId":10467, // "isBuyer":true, // "isMaker":true, // "ctime":1678426306000 // } // market := GetArg(optionalArgs, 0, nil) _ = market var timestamp interface{} = this.SafeInteger2(trade, "ctime", "time") var priceString interface{} = this.SafeString(trade, "price") var amountString interface{} = this.SafeString(trade, "qty") var marketId interface{} = this.SafeString2(trade, "symbol", "contractName") var symbol interface{} = this.SafeSymbol(marketId, market) var orderId interface{} = this.SafeString(trade, "orderId") var id interface{} = this.SafeString2(trade, "id", "tradeId") var side interface{} = nil var buyerMaker interface{} = this.SafeBool(trade, "isBuyerMaker") // ignore "m" until Bitrue fixes api var isBuyer interface{} = this.SafeBool(trade, "isBuyer") if IsTrue(!IsEqual(buyerMaker, nil)) { side = Ternary(IsTrue(buyerMaker), "sell", "buy") } if IsTrue(!IsEqual(isBuyer, nil)) { side = Ternary(IsTrue(isBuyer), "buy", "sell") // this is a true side } var fee interface{} = nil if IsTrue(InOp(trade, "commission")) { fee = map[string]interface{} { "cost": this.SafeString2(trade, "commission", "fee"), "currency": this.SafeCurrencyCode(this.SafeString(trade, "commissionAssert")), } } var takerOrMaker interface{} = nil var isMaker interface{} = this.SafeBool(trade, "isMaker") if IsTrue(!IsEqual(isMaker, nil)) { takerOrMaker = Ternary(IsTrue(isMaker), "maker", "taker") } return this.SafeTrade(map[string]interface{} { "info": trade, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "symbol": symbol, "id": id, "order": orderId, "type": nil, "side": side, "takerOrMaker": takerOrMaker, "price": priceString, "amount": amountString, "cost": nil, "fee": fee, }, market) } /** * @method * @name bitrue#fetchTrades * @description get the list of most recent trades for a particular symbol * @see https://github.com/Bitrue-exchange/Spot-official-api-docs#recent-trades-list * @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 * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades} */ func (this *bitrue) 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 retRes17808 := (<-this.LoadMarkets()) PanicOnError(retRes17808) var market interface{} = this.Market(symbol) var response interface{} = nil if IsTrue(GetValue(market, "spot")) { var request interface{} = map[string]interface{} { "symbol": GetValue(market, "id"), } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) // default 100, max 1000 } response = (<-this.SpotV1PublicGetTrades(this.Extend(request, params))) PanicOnError(response) } else { panic(NotSupported(Add(this.Id, " fetchTrades only support spot markets"))) } // // spot // // [ // { // "id": 28457, // "price": "4.00000100", // "qty": "12.00000000", // "time": 1499865549590, // "isBuyerMaker": true, // "isBestMatch": true // } // ] // ch <- this.ParseTrades(response, market, since, limit) return nil }() return ch } func (this *bitrue) ParseOrderStatus(status interface{}) interface{} { var statuses interface{} = map[string]interface{} { "INIT": "open", "PENDING_CREATE": "open", "NEW": "open", "PARTIALLY_FILLED": "open", "FILLED": "closed", "CANCELED": "canceled", "PENDING_CANCEL": "canceling", "REJECTED": "rejected", "EXPIRED": "expired", } return this.SafeString(statuses, status, status) } func (this *bitrue) ParseOrder(order interface{}, optionalArgs ...interface{}) interface{} { // // createOrder - spot // // { // "symbol":"USDCUSDT", // "orderId":2878854881, // "clientOrderId":"", // "transactTime":1635551031276 // } // // createOrder - future // // { // "orderId":1690615676032452985, // } // // fetchOrders - spot // // { // "symbol":"USDCUSDT", // "orderId":"2878854881", // "clientOrderId":"", // "price":"1.1000000000000000", // "origQty":"100.0000000000000000", // "executedQty":"0.0000000000000000", // "cummulativeQuoteQty":"0.0000000000000000", // "status":"NEW", // "timeInForce":"", // "type":"LIMIT", // "side":"SELL", // "stopPrice":"", // "icebergQty":"", // "time":1635551031000, // "updateTime":1635551031000, // "isWorking":false // } // // fetchOrders - future // // { // "orderId":1917641, // "price":100, // "origQty":10, // "origAmount":10, // "executedQty":1, // "avgPrice":10000, // "status":"INIT", // "type":"LIMIT", // "side":"BUY", // "action":"OPEN", // "transactTime":1686716571425 // "clientOrderId":4949299210 // } // market := GetArg(optionalArgs, 0, nil) _ = market var status interface{} = this.ParseOrderStatus(this.SafeString2(order, "status", "orderStatus")) var marketId interface{} = this.SafeString(order, "symbol") var symbol interface{} = this.SafeSymbol(marketId, market) var filled interface{} = this.SafeString(order, "executedQty") var timestamp interface{} = nil var lastTradeTimestamp interface{} = nil if IsTrue(InOp(order, "time")) { timestamp = this.SafeInteger(order, "time") } else if IsTrue(InOp(order, "transactTime")) { timestamp = this.SafeInteger(order, "transactTime") } else if IsTrue(InOp(order, "updateTime")) { if IsTrue(IsEqual(status, "open")) { if IsTrue(Precise.StringGt(filled, "0")) { lastTradeTimestamp = this.SafeInteger(order, "updateTime") } else { timestamp = this.SafeInteger(order, "updateTime") } } } var average interface{} = this.SafeString(order, "avgPrice") var price interface{} = this.SafeString(order, "price") var amount interface{} = this.SafeString(order, "origQty") // - Spot/Margin market: cummulativeQuoteQty // - Futures market: cumQuote. // Note this is not the actual cost, since Binance futures uses leverage to calculate margins. var cost interface{} = this.SafeString2(order, "cummulativeQuoteQty", "cumQuote") var id interface{} = this.SafeString(order, "orderId") var typeVar interface{} = this.SafeStringLower(order, "type") var side interface{} = this.SafeStringLower(order, "side") var fills interface{} = this.SafeList(order, "fills", []interface{}{}) var clientOrderId interface{} = this.SafeString(order, "clientOrderId") var timeInForce interface{} = this.SafeString(order, "timeInForce") var postOnly interface{} = IsTrue(IsTrue((IsEqual(typeVar, "limit_maker"))) || IsTrue((IsEqual(timeInForce, "GTX")))) || IsTrue((IsEqual(typeVar, "post_only"))) if IsTrue(IsEqual(typeVar, "limit_maker")) { typeVar = "limit" } var triggerPrice interface{} = this.ParseNumber(this.OmitZero(this.SafeString(order, "stopPrice"))) return this.SafeOrder(map[string]interface{} { "info": order, "id": id, "clientOrderId": clientOrderId, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "lastTradeTimestamp": lastTradeTimestamp, "symbol": symbol, "type": typeVar, "timeInForce": timeInForce, "postOnly": postOnly, "side": side, "price": price, "triggerPrice": triggerPrice, "amount": amount, "cost": cost, "average": average, "filled": filled, "remaining": nil, "status": status, "fee": nil, "trades": fills, }, market) } /** * @method * @name bitrue#createMarketBuyOrderWithCost * @description create a market buy order by providing the symbol and cost * @see https://www.bitrue.com/api-docs#new-order-trade-hmac-sha256 * @see https://www.bitrue.com/api_docs_includes_file/delivery.html#new-order-trade-hmac-sha256 * @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 *bitrue) 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 retRes19568 := (<-this.LoadMarkets()) PanicOnError(retRes19568) var market interface{} = this.Market(symbol) if !IsTrue(GetValue(market, "swap")) { panic(NotSupported(Add(this.Id, " createMarketBuyOrderWithCost() supports swap orders only"))) } AddElementToObject(params, "createMarketBuyOrderRequiresPrice", false) retRes196215 := (<-this.CreateOrder(symbol, "market", "buy", cost, nil, params)) PanicOnError(retRes196215) ch <- retRes196215 return nil }() return ch } /** * @method * @name bitrue#createOrder * @description create a trade order * @see https://www.bitrue.com/api_docs_includes_file/spot/index.html#new-order-trade * @see https://www.bitrue.com/api_docs_includes_file/futures/index.html#new-order-trade-hmac-sha256 * @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 {float} [params.triggerPrice] *spot only* the price at which a trigger order is triggered at * @param {string} [params.clientOrderId] a unique id for the order, automatically generated if not sent * @param {decimal} [params.leverage] in future order, the leverage value of the order should consistent with the user contract configuration, default is 1 * @param {string} [params.timeInForce] 'fok', 'ioc' or 'po' * @param {bool} [params.postOnly] default false * @param {bool} [params.reduceOnly] default false * EXCHANGE SPECIFIC PARAMETERS * @param {decimal} [params.icebergQty] * @param {long} [params.recvWindow] * @param {float} [params.cost] *swap market buy only* the quote quantity that can be used as an alternative for the amount * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *bitrue) 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 retRes19908 := (<-this.LoadMarkets()) PanicOnError(retRes19908) var market interface{} = this.Market(symbol) var response interface{} = nil var data interface{} = nil var uppercaseType interface{} = ToUpper(typeVar) var request interface{} = map[string]interface{} { "side": ToUpper(side), "type": uppercaseType, } if IsTrue(IsEqual(uppercaseType, "LIMIT")) { if IsTrue(IsEqual(price, nil)) { panic(InvalidOrder(Add(this.Id, " createOrder() requires a price argument"))) } AddElementToObject(request, "price", this.PriceToPrecision(symbol, price)) } if IsTrue(GetValue(market, "swap")) { var isMarket interface{} = IsEqual(uppercaseType, "MARKET") var timeInForce interface{} = this.SafeStringLower(params, "timeInForce") var postOnly interface{} = this.IsPostOnly(isMarket, nil, params) if IsTrue(postOnly) { AddElementToObject(request, "type", "POST_ONLY") } else if IsTrue(IsEqual(timeInForce, "fok")) { AddElementToObject(request, "type", "FOK") } else if IsTrue(IsEqual(timeInForce, "ioc")) { AddElementToObject(request, "type", "IOC") } AddElementToObject(request, "contractName", GetValue(market, "id")) var createMarketBuyOrderRequiresPrice interface{} = true createMarketBuyOrderRequiresPriceparamsVariable := this.HandleOptionAndParams(params, "createOrder", "createMarketBuyOrderRequiresPrice", true); createMarketBuyOrderRequiresPrice = GetValue(createMarketBuyOrderRequiresPriceparamsVariable,0); params = GetValue(createMarketBuyOrderRequiresPriceparamsVariable,1) if IsTrue(IsTrue(IsTrue(isMarket) && IsTrue((IsEqual(side, "buy")))) && IsTrue(createMarketBuyOrderRequiresPrice)) { var cost interface{} = this.SafeString(params, "cost") params = this.Omit(params, "cost") if IsTrue(IsTrue(IsEqual(price, nil)) && IsTrue(IsEqual(cost, nil))) { panic(InvalidOrder(Add(this.Id, " createOrder() requires the price argument with swap market buy orders to calculate total order cost (amount to spend), where cost = amount * price. Supply a price argument to createOrder() call if you want the cost to be calculated for you from price and amount, or, alternatively, add .options[\"createMarketBuyOrderRequiresPrice\"] = false to supply the cost in the amount argument (the exchange-specific behaviour)"))) } else { var amountString interface{} = this.NumberToString(amount) var priceString interface{} = this.NumberToString(price) var quoteAmount interface{} = Precise.StringMul(amountString, priceString) var requestAmount interface{} = Ternary(IsTrue((!IsEqual(cost, nil))), cost, quoteAmount) AddElementToObject(request, "amount", this.CostToPrecision(symbol, requestAmount)) AddElementToObject(request, "volume", this.CostToPrecision(symbol, requestAmount)) } } else { AddElementToObject(request, "amount", this.ParseToNumeric(amount)) AddElementToObject(request, "volume", this.ParseToNumeric(amount)) } AddElementToObject(request, "positionType", 1) var reduceOnly interface{} = this.SafeValue2(params, "reduceOnly", "reduce_only") AddElementToObject(request, "open", Ternary(IsTrue(reduceOnly), "CLOSE", "OPEN")) var leverage interface{} = this.SafeString(params, "leverage", "1") AddElementToObject(request, "leverage", this.ParseToNumeric(leverage)) params = this.Omit(params, []interface{}{"leverage", "reduceOnly", "reduce_only", "timeInForce"}) if IsTrue(GetValue(market, "linear")) { response = (<-this.FapiV2PrivatePostOrder(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(GetValue(market, "inverse")) { response = (<-this.DapiV2PrivatePostOrder(this.Extend(request, params))) PanicOnError(response) } data = this.SafeDict(response, "data", map[string]interface{} {}) } else if IsTrue(GetValue(market, "spot")) { AddElementToObject(request, "symbol", GetValue(market, "id")) AddElementToObject(request, "quantity", this.AmountToPrecision(symbol, amount)) var validOrderTypes interface{} = this.SafeValue(GetValue(market, "info"), "orderTypes") if !IsTrue(this.InArray(uppercaseType, validOrderTypes)) { panic(InvalidOrder(Add(Add(Add(Add(this.Id, " "), typeVar), " is not a valid order type in market "), symbol))) } var clientOrderId interface{} = this.SafeString2(params, "newClientOrderId", "clientOrderId") if IsTrue(!IsEqual(clientOrderId, nil)) { params = this.Omit(params, []interface{}{"newClientOrderId", "clientOrderId"}) AddElementToObject(request, "newClientOrderId", clientOrderId) } var triggerPrice interface{} = this.SafeValue2(params, "triggerPrice", "stopPrice") if IsTrue(!IsEqual(triggerPrice, nil)) { params = this.Omit(params, []interface{}{"triggerPrice", "stopPrice"}) AddElementToObject(request, "stopPrice", this.PriceToPrecision(symbol, triggerPrice)) } response = (<-this.SpotV1PrivatePostOrder(this.Extend(request, params))) PanicOnError(response) data = response } else { panic(NotSupported(Add(this.Id, " createOrder only support spot & swap markets"))) } // // spot // // { // "symbol": "BTCUSDT", // "orderId": 307650651173648896, // "orderIdStr": "307650651173648896", // "clientOrderId": "6gCrw2kRUAF9CvJDGP16IP", // "transactTime": 1507725176595 // } // // swap // // { // "code": "0", // "msg": "Success", // "data": { // "orderId": 1690615676032452985 // } // } // ch <- this.ParseOrder(data, market) return nil }() return ch } /** * @method * @name bitrue#fetchOrder * @description fetches information on an order made by the user * @see https://www.bitrue.com/api_docs_includes_file/spot/index.html#query-order-user_data * @see https://www.bitrue.com/api_docs_includes_file/futures/index.html#query-order-user_data-hmac-sha256 * @param {string} id the 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 *bitrue) 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 if IsTrue(IsEqual(symbol, nil)) { panic(ArgumentsRequired(Add(this.Id, " fetchOrder() requires a symbol argument"))) } retRes21148 := (<-this.LoadMarkets()) PanicOnError(retRes21148) var market interface{} = this.Market(symbol) var origClientOrderId interface{} = this.SafeValue2(params, "origClientOrderId", "clientOrderId") params = this.Omit(params, []interface{}{"origClientOrderId", "clientOrderId"}) var response interface{} = nil var data interface{} = nil var request interface{} = map[string]interface{} {} if IsTrue(IsEqual(origClientOrderId, nil)) { AddElementToObject(request, "orderId", id) } else { if IsTrue(GetValue(market, "swap")) { AddElementToObject(request, "clientOrderId", origClientOrderId) } else { AddElementToObject(request, "origClientOrderId", origClientOrderId) } } if IsTrue(GetValue(market, "swap")) { AddElementToObject(request, "contractName", GetValue(market, "id")) if IsTrue(GetValue(market, "linear")) { response = (<-this.FapiV2PrivateGetOrder(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(GetValue(market, "inverse")) { response = (<-this.DapiV2PrivateGetOrder(this.Extend(request, params))) PanicOnError(response) } data = this.SafeDict(response, "data", map[string]interface{} {}) } else if IsTrue(GetValue(market, "spot")) { AddElementToObject(request, "orderId", id) // spot market id is mandatory AddElementToObject(request, "symbol", GetValue(market, "id")) response = (<-this.SpotV1PrivateGetOrder(this.Extend(request, params))) PanicOnError(response) data = response } else { panic(NotSupported(Add(this.Id, " fetchOrder only support spot & swap markets"))) } // // spot // // { // "symbol": "LTCBTC", // "orderId": 1, // "clientOrderId": "myOrder1", // "price": "0.1", // "origQty": "1.0", // "executedQty": "0.0", // "cummulativeQuoteQty": "0.0", // "status": "NEW", // "timeInForce": "GTC", // "type": "LIMIT", // "side": "BUY", // "stopPrice": "0.0", // "icebergQty": "0.0", // "time": 1499827319559, // "updateTime": 1499827319559, // "isWorking": true // } // // swap // // { // "code":0, // "msg":"success", // "data":{ // "orderId":1917641, // "price":100, // "origQty":10, // "origAmount":10, // "executedQty":1, // "avgPrice":10000, // "status":"INIT", // "type":"LIMIT", // "side":"BUY", // "action":"OPEN", // "transactTime":1686716571425 // "clientOrderId":4949299210 // } // } // ch <- this.ParseOrder(data, market) return nil }() return ch } /** * @method * @name bitrue#fetchClosedOrders * @description fetches information on multiple closed orders made by the user * @see https://www.bitrue.com/api_docs_includes_file/spot/index.html#all-orders-user_data * @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 * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *bitrue) 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 if IsTrue(IsEqual(symbol, nil)) { panic(ArgumentsRequired(Add(this.Id, " fetchClosedOrders() requires a symbol argument"))) } retRes22078 := (<-this.LoadMarkets()) PanicOnError(retRes22078) var market interface{} = this.Market(symbol) if !IsTrue(GetValue(market, "spot")) { panic(NotSupported(Add(this.Id, " fetchClosedOrders only support spot markets"))) } var request interface{} = map[string]interface{} { "symbol": GetValue(market, "id"), } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "startTime", since) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) // default 100, max 1000 } response:= (<-this.SpotV1PrivateGetAllOrders(this.Extend(request, params))) PanicOnError(response) // // [ // { // "symbol": "LTCBTC", // "orderId": 1, // "clientOrderId": "myOrder1", // "price": "0.1", // "origQty": "1.0", // "executedQty": "0.0", // "cummulativeQuoteQty": "0.0", // "status": "NEW", // "timeInForce": "GTC", // "type": "LIMIT", // "side": "BUY", // "stopPrice": "0.0", // "icebergQty": "0.0", // "time": 1499827319559, // "updateTime": 1499827319559, // "isWorking": true // } // ] // ch <- this.ParseOrders(response, market, since, limit) return nil }() return ch } /** * @method * @name bitrue#fetchOpenOrders * @description fetch all unfilled currently open orders * @see https://www.bitrue.com/api_docs_includes_file/spot/index.html#current-open-orders-user_data * @see https://www.bitrue.com/api_docs_includes_file/futures/index.html#cancel-all-open-orders-trade-hmac-sha256 * @param {string} symbol unified market symbol * @param {int} [since] the earliest time in ms to fetch open orders for * @param {int} [limit] the maximum number of open order structures to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *bitrue) 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 if IsTrue(IsEqual(symbol, nil)) { panic(ArgumentsRequired(Add(this.Id, " fetchOpenOrders() requires a symbol argument"))) } retRes22678 := (<-this.LoadMarkets()) PanicOnError(retRes22678) var market interface{} = this.Market(symbol) var response interface{} = nil var data interface{} = nil var request interface{} = map[string]interface{} {} if IsTrue(GetValue(market, "swap")) { AddElementToObject(request, "contractName", GetValue(market, "id")) if IsTrue(GetValue(market, "linear")) { response = (<-this.FapiV2PrivateGetOpenOrders(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(GetValue(market, "inverse")) { response = (<-this.DapiV2PrivateGetOpenOrders(this.Extend(request, params))) PanicOnError(response) } data = this.SafeList(response, "data", []interface{}{}) } else if IsTrue(GetValue(market, "spot")) { AddElementToObject(request, "symbol", GetValue(market, "id")) response = (<-this.SpotV1PrivateGetOpenOrders(this.Extend(request, params))) PanicOnError(response) data = response } else { panic(NotSupported(Add(this.Id, " fetchOpenOrders only support spot & swap markets"))) } // // spot // // [ // { // "symbol":"USDCUSDT", // "orderId":"2878854881", // "clientOrderId":"", // "price":"1.1000000000000000", // "origQty":"100.0000000000000000", // "executedQty":"0.0000000000000000", // "cummulativeQuoteQty":"0.0000000000000000", // "status":"NEW", // "timeInForce":"", // "type":"LIMIT", // "side":"SELL", // "stopPrice":"", // "icebergQty":"", // "time":1635551031000, // "updateTime":1635551031000, // "isWorking":false // } // ] // // swap // // { // "code": "0", // "msg": "Success", // "data": [{ // "orderId": 1917641, // "clientOrderId": "2488514315", // "price": 100, // "origQty": 10, // "origAmount": 10, // "executedQty": 1, // "avgPrice": 12451, // "status": "INIT", // "type": "LIMIT", // "side": "BUY", // "action": "OPEN", // "transactTime": 1686717303975 // } // ] // } // ch <- this.ParseOrders(data, market, since, limit) return nil }() return ch } /** * @method * @name bitrue#cancelOrder * @description cancels an open order * @see https://github.com/Bitrue-exchange/Spot-official-api-docs#cancel-order-trade * @see https://www.bitrue.com/api-docs#cancel-order-trade-hmac-sha256 * @see https://www.bitrue.com/api_docs_includes_file/delivery.html#cancel-order-trade-hmac-sha256 * @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 *bitrue) 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 if IsTrue(IsEqual(symbol, nil)) { panic(ArgumentsRequired(Add(this.Id, " cancelOrder() requires a symbol argument"))) } retRes23528 := (<-this.LoadMarkets()) PanicOnError(retRes23528) var market interface{} = this.Market(symbol) var origClientOrderId interface{} = this.SafeValue2(params, "origClientOrderId", "clientOrderId") params = this.Omit(params, []interface{}{"origClientOrderId", "clientOrderId"}) var response interface{} = nil var data interface{} = nil var request interface{} = map[string]interface{} {} if IsTrue(IsEqual(origClientOrderId, nil)) { AddElementToObject(request, "orderId", id) } else { if IsTrue(GetValue(market, "swap")) { AddElementToObject(request, "clientOrderId", origClientOrderId) } else { AddElementToObject(request, "origClientOrderId", origClientOrderId) } } if IsTrue(GetValue(market, "swap")) { AddElementToObject(request, "contractName", GetValue(market, "id")) if IsTrue(GetValue(market, "linear")) { response = (<-this.FapiV2PrivatePostCancel(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(GetValue(market, "inverse")) { response = (<-this.DapiV2PrivatePostCancel(this.Extend(request, params))) PanicOnError(response) } data = this.SafeDict(response, "data", map[string]interface{} {}) } else if IsTrue(GetValue(market, "spot")) { AddElementToObject(request, "symbol", GetValue(market, "id")) response = (<-this.SpotV1PrivateDeleteOrder(this.Extend(request, params))) PanicOnError(response) data = response } else { panic(NotSupported(Add(this.Id, " cancelOrder only support spot & swap markets"))) } // // spot // // { // "symbol": "LTCBTC", // "origClientOrderId": "myOrder1", // "orderId": 1, // "clientOrderId": "cancelMyOrder1" // } // // swap // // { // "code": "0", // "msg": "Success", // "data": { // "orderId": 1690615847831143159 // } // } // ch <- this.ParseOrder(data, market) return nil }() return ch } /** * @method * @name bitrue#cancelAllOrders * @description cancel all open orders in a market * @see https://www.bitrue.com/api-docs#cancel-all-open-orders-trade-hmac-sha256 * @see https://www.bitrue.com/api_docs_includes_file/delivery.html#cancel-all-open-orders-trade-hmac-sha256 * @param {string} symbol unified market symbol of the market to cancel orders in * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.marginMode] 'cross' or 'isolated', for spot margin trading * @returns {object[]} a list of [order structures]{@link https://github.com/ccxt/ccxt/wiki/Manual#order-structure} */ func (this *bitrue) 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 retRes24188 := (<-this.LoadMarkets()) PanicOnError(retRes24188) var market interface{} = this.Market(symbol) var response interface{} = nil var data interface{} = nil if IsTrue(GetValue(market, "swap")) { var request interface{} = map[string]interface{} { "contractName": GetValue(market, "id"), } if IsTrue(GetValue(market, "linear")) { response = (<-this.FapiV2PrivatePostAllOpenOrders(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(GetValue(market, "inverse")) { response = (<-this.DapiV2PrivatePostAllOpenOrders(this.Extend(request, params))) PanicOnError(response) } data = this.SafeList(response, "data", []interface{}{}) } else { panic(NotSupported(Add(this.Id, " cancelAllOrders only support future markets"))) } // // swap // // { // 'code': '0', // 'msg': 'Success', // 'data': null // } // ch <- this.ParseOrders(data, market) return nil }() return ch } /** * @method * @name bitrue#fetchMyTrades * @description fetch all trades made by the user * @see https://www.bitrue.com/api_docs_includes_file/spot/index.html#account-trade-list-user_data * @see https://www.bitrue.com/api_docs_includes_file/futures/index.html#account-trade-list-user_data-hmac-sha256 * @param {string} symbol unified market symbol * @param {int} [since] the earliest time in ms to fetch trades for * @param {int} [limit] the maximum number of trades structures to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure} */ func (this *bitrue) 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 retRes24608 := (<-this.LoadMarkets()) PanicOnError(retRes24608) if IsTrue(IsEqual(symbol, nil)) { panic(ArgumentsRequired(Add(this.Id, " fetchMyTrades() requires a symbol argument"))) } var market interface{} = this.Market(symbol) var response interface{} = nil var data interface{} = nil var request interface{} = map[string]interface{} {} if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "startTime", since) } if IsTrue(!IsEqual(limit, nil)) { if IsTrue(IsGreaterThan(limit, 1000)) { limit = 1000 } AddElementToObject(request, "limit", limit) } if IsTrue(GetValue(market, "swap")) { AddElementToObject(request, "contractName", GetValue(market, "id")) if IsTrue(GetValue(market, "linear")) { response = (<-this.FapiV2PrivateGetMyTrades(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(GetValue(market, "inverse")) { response = (<-this.DapiV2PrivateGetMyTrades(this.Extend(request, params))) PanicOnError(response) } data = this.SafeList(response, "data", []interface{}{}) } else if IsTrue(GetValue(market, "spot")) { AddElementToObject(request, "symbol", GetValue(market, "id")) response = (<-this.SpotV2PrivateGetMyTrades(this.Extend(request, params))) PanicOnError(response) data = response } else { panic(NotSupported(Add(this.Id, " fetchMyTrades only support spot & swap markets"))) } // // spot // // [ // { // "symbol":"USDCUSDT", // "id":20725156, // "orderId":2880918576, // "origClientOrderId":null, // "price":"0.9996000000000000", // "qty":"100.0000000000000000", // "commission":null, // "commissionAssert":null, // "time":1635558511000, // "isBuyer":false, // "isMaker":false, // "isBestMatch":true // } // ] // // swap // // { // "code":"0", // "msg":"Success", // "data":[ // { // "tradeId":12, // "price":0.9, // "qty":1, // "amount":9, // "contractName":"E-SAND-USDT", // "side":"BUY", // "fee":"0.0018", // "bidId":1558124009467904992, // "askId":1558124043827644908, // "bidUserId":10294, // "askUserId":10467, // "isBuyer":true, // "isMaker":true, // "ctime":1678426306000 // } // ] // } // ch <- this.ParseTrades(data, market, since, limit) return nil }() return ch } /** * @method * @name bitrue#fetchDeposits * @description fetch all deposits made to an account * @see https://github.com/Bitrue-exchange/Spot-official-api-docs#deposit-history--withdraw_data * @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 * @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure} */ func (this *bitrue) 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 if IsTrue(IsEqual(code, nil)) { panic(ArgumentsRequired(Add(this.Id, " fetchDeposits() requires a code argument"))) } retRes25558 := (<-this.LoadMarkets()) PanicOnError(retRes25558) var currency interface{} = this.Currency(code) var request interface{} = map[string]interface{} { "coin": GetValue(currency, "id"), "status": 1, } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "startTime", since) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) } response:= (<-this.SpotV1PrivateGetDepositHistory(this.Extend(request, params))) PanicOnError(response) // // { // "code":200, // "msg":"succ", // "data":[ // { // "id":2659137, // "symbol":"USDC", // "amount":"200.0000000000000000", // "fee":"0.0E-15", // "createdAt":1635503169000, // "updatedAt":1635503202000, // "addressFrom":"0x2faf487a4414fe77e2327f0bf4ae2a264a776ad2", // "addressTo":"0x190ceccb1f8bfbec1749180f0ba8922b488d865b", // "txid":"0x9970aec41099ac385568859517308707bc7d716df8dabae7b52f5b17351c3ed0", // "confirmations":5, // "status":0, // "tagType":null, // }, // { // "id":2659137, // "symbol": "XRP", // "amount": "20.0000000000000000", // "fee": "0.0E-15", // "createdAt": 1544669393000, // "updatedAt": 1544669413000, // "addressFrom": "", // "addressTo": "raLPjTYeGezfdb6crXZzcC8RkLBEwbBHJ5_18113641", // "txid": "515B23E1F9864D3AF7F5B4C4FCBED784BAE861854FAB95F4031922B6AAEFC7AC", // "confirmations": 7, // "status": 1, // "tagType": "Tag" // } // ] // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseTransactions(data, currency, since, limit) return nil }() return ch } /** * @method * @name bitrue#fetchWithdrawals * @description fetch all withdrawals made from an account * @see https://github.com/Bitrue-exchange/Spot-official-api-docs#withdraw-history--withdraw_data * @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 * @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure} */ func (this *bitrue) 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 if IsTrue(IsEqual(code, nil)) { panic(ArgumentsRequired(Add(this.Id, " fetchWithdrawals() requires a code argument"))) } retRes26288 := (<-this.LoadMarkets()) PanicOnError(retRes26288) var currency interface{} = this.Currency(code) var request interface{} = map[string]interface{} { "coin": GetValue(currency, "id"), "status": 5, } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "startTime", since) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) } response:= (<-this.SpotV1PrivateGetWithdrawHistory(this.Extend(request, params))) PanicOnError(response) // // { // "code": 200, // "msg": "succ", // "data": [ // { // "id": 183745, // "symbol": "usdt_erc20", // "amount": "8.4000000000000000", // "fee": "1.6000000000000000", // "payAmount": "0.0000000000000000", // "createdAt": 1595336441000, // "updatedAt": 1595336576000, // "addressFrom": "", // "addressTo": "0x2edfae3878d7b6db70ce4abed177ab2636f60c83", // "txid": "", // "confirmations": 0, // "status": 6, // "tagType": null // } // ] // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseTransactions(data, currency) return nil }() return ch } func (this *bitrue) ParseTransactionStatusByType(status interface{}, optionalArgs ...interface{}) interface{} { typeVar := GetArg(optionalArgs, 0, nil) _ = typeVar var statusesByType interface{} = map[string]interface{} { "deposit": map[string]interface{} { "0": "pending", "1": "ok", }, "withdrawal": map[string]interface{} { "0": "pending", "5": "ok", "6": "canceled", }, } var statuses interface{} = this.SafeDict(statusesByType, typeVar, map[string]interface{} {}) return this.SafeString(statuses, status, status) } func (this *bitrue) ParseTransaction(transaction interface{}, optionalArgs ...interface{}) interface{} { // // fetchDeposits // // { // "symbol": "XRP", // "amount": "261.3361000000000000", // "fee": "0.0E-15", // "createdAt": 1548816979000, // "updatedAt": 1548816999000, // "addressFrom": "", // "addressTo": "raLPjTYeGezfdb6crXZzcC8RkLBEwbBHJ5_18113641", // "txid": "86D6EB68A7A28938BCE06BD348F8C07DEF500C5F7FE92069EF8C0551CE0F2C7D", // "confirmations": 8, // "status": 1, // "tagType": "Tag" // }, // { // "symbol": "XRP", // "amount": "20.0000000000000000", // "fee": "0.0E-15", // "createdAt": 1544669393000, // "updatedAt": 1544669413000, // "addressFrom": "", // "addressTo": "raLPjTYeGezfdb6crXZzcC8RkLBEwbBHJ5_18113641", // "txid": "515B23E1F9864D3AF7F5B4C4FCBED784BAE861854FAB95F4031922B6AAEFC7AC", // "confirmations": 7, // "status": 1, // "tagType": "Tag" // } // // fetchWithdrawals // // { // "id": 183745, // "symbol": "usdt_erc20", // "amount": "8.4000000000000000", // "fee": "1.6000000000000000", // "payAmount": "0.0000000000000000", // "createdAt": 1595336441000, // "updatedAt": 1595336576000, // "addressFrom": "", // "addressTo": "0x2edfae3878d7b6db70ce4abed177ab2636f60c83", // "txid": "", // "confirmations": 0, // "status": 6, // "tagType": null // } // // withdraw // // { // "msg": null, // "amount": 1000, // "fee": 1, // "ctime": null, // "coin": "usdt_erc20", // "withdrawId": 1156423, // "addressTo": "0x2edfae3878d7b6db70ce4abed177ab2636f60c83" // } // currency := GetArg(optionalArgs, 0, nil) _ = currency var id interface{} = this.SafeString2(transaction, "id", "withdrawId") var tagType interface{} = this.SafeString(transaction, "tagType") var addressTo interface{} = this.SafeString(transaction, "addressTo") var addressFrom interface{} = this.SafeString(transaction, "addressFrom") var tagTo interface{} = nil var tagFrom interface{} = nil if IsTrue(!IsEqual(tagType, nil)) { if IsTrue(!IsEqual(addressTo, nil)) { var parts interface{} = Split(addressTo, "_") addressTo = this.SafeString(parts, 0) tagTo = this.SafeString(parts, 1) } if IsTrue(!IsEqual(addressFrom, nil)) { var parts interface{} = Split(addressFrom, "_") addressFrom = this.SafeString(parts, 0) tagFrom = this.SafeString(parts, 1) } } var txid interface{} = this.SafeString(transaction, "txid") var timestamp interface{} = this.SafeInteger(transaction, "createdAt") var updated interface{} = this.SafeInteger(transaction, "updatedAt") var payAmount interface{} = (InOp(transaction, "payAmount")) var ctime interface{} = (InOp(transaction, "ctime")) var typeVar interface{} = Ternary(IsTrue((IsTrue(payAmount) || IsTrue(ctime))), "withdrawal", "deposit") var status interface{} = this.ParseTransactionStatusByType(this.SafeString(transaction, "status"), typeVar) var amount interface{} = this.SafeNumber(transaction, "amount") var network interface{} = nil var currencyId interface{} = this.SafeString2(transaction, "symbol", "coin") if IsTrue(!IsEqual(currencyId, nil)) { var parts interface{} = Split(currencyId, "_") currencyId = this.SafeString(parts, 0) var networkId interface{} = this.SafeString(parts, 1) if IsTrue(!IsEqual(networkId, nil)) { network = ToUpper(networkId) } } var code interface{} = this.SafeCurrencyCode(currencyId, currency) var feeCost interface{} = this.SafeNumber(transaction, "fee") var fee interface{} = nil if IsTrue(!IsEqual(feeCost, nil)) { fee = map[string]interface{} { "currency": code, "cost": feeCost, } } return map[string]interface{} { "info": transaction, "id": id, "txid": txid, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "network": network, "address": addressTo, "addressTo": addressTo, "addressFrom": addressFrom, "tag": tagTo, "tagTo": tagTo, "tagFrom": tagFrom, "type": typeVar, "amount": amount, "currency": code, "status": status, "updated": updated, "internal": false, "comment": nil, "fee": fee, } } /** * @method * @name bitrue#withdraw * @description make a withdrawal * @see https://github.com/Bitrue-exchange/Spot-official-api-docs#withdraw-commit--withdraw_data * @param {string} code unified currency code * @param {float} amount the amount to withdraw * @param {string} address the address to withdraw to * @param {string} tag * @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 *bitrue) 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) retRes28318 := (<-this.LoadMarkets()) PanicOnError(retRes28318) var currency interface{} = this.Currency(code) var request interface{} = map[string]interface{} { "coin": GetValue(currency, "id"), "amount": amount, "addressTo": address, } var networkCode interface{} = nil networkCodeparamsVariable := this.HandleNetworkCodeAndParams(params); networkCode = GetValue(networkCodeparamsVariable,0); params = GetValue(networkCodeparamsVariable,1) if IsTrue(!IsEqual(networkCode, nil)) { AddElementToObject(request, "chainName", this.NetworkCodeToId(networkCode)) } if IsTrue(!IsEqual(tag, nil)) { AddElementToObject(request, "tag", tag) } response:= (<-this.SpotV1PrivatePostWithdrawCommit(this.Extend(request, params))) PanicOnError(response) // // { // "code": 200, // "msg": "succ", // "data": { // "msg": null, // "amount": 1000, // "fee": 1, // "ctime": null, // "coin": "usdt_erc20", // "withdrawId": 1156423, // "addressTo": "0x2edfae3878d7b6db70ce4abed177ab2636f60c83" // } // } // var data interface{} = this.SafeDict(response, "data", map[string]interface{} {}) ch <- this.ParseTransaction(data, currency) return nil }() return ch } func (this *bitrue) ParseDepositWithdrawFee(fee interface{}, optionalArgs ...interface{}) interface{} { // // { // "coin": "adx", // "coinFulName": "Ambire AdEx", // "chains": [ "BSC" ], // "chainDetail": [ [Object] ] // } // currency := GetArg(optionalArgs, 0, nil) _ = currency var chainDetails interface{} = this.SafeList(fee, "chainDetail", []interface{}{}) var chainDetailLength interface{} = GetArrayLength(chainDetails) var result interface{} = map[string]interface{} { "info": fee, "withdraw": map[string]interface{} { "fee": nil, "percentage": nil, }, "deposit": map[string]interface{} { "fee": nil, "percentage": nil, }, "networks": map[string]interface{} {}, } if IsTrue(!IsEqual(chainDetailLength, 0)) { for i := 0; IsLessThan(i, chainDetailLength); i++ { var chainDetail interface{} = GetValue(chainDetails, i) var networkId interface{} = this.SafeString(chainDetail, "chain") var currencyCode interface{} = this.SafeString(currency, "code") var networkCode interface{} = this.NetworkIdToCode(networkId, currencyCode) AddElementToObject(GetValue(result, "networks"), networkCode, map[string]interface{} { "deposit": map[string]interface{} { "fee": nil, "percentage": nil, }, "withdraw": map[string]interface{} { "fee": this.SafeNumber(chainDetail, "withdrawFee"), "percentage": false, }, }) if IsTrue(IsEqual(chainDetailLength, 1)) { AddElementToObject(GetValue(result, "withdraw"), "fee", this.SafeNumber(chainDetail, "withdrawFee")) AddElementToObject(GetValue(result, "withdraw"), "percentage", false) } } } return result } /** * @method * @name bitrue#fetchDepositWithdrawFees * @description fetch deposit and withdraw fees * @see https://github.com/Bitrue-exchange/Spot-official-api-docs#exchangeInfo_endpoint * @param {string[]|undefined} codes list of unified currency codes * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a list of [fee structures]{@link https://docs.ccxt.com/#/?id=fee-structure} */ func (this *bitrue) FetchDepositWithdrawFees(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) codes := GetArg(optionalArgs, 0, nil) _ = codes params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params retRes29228 := (<-this.LoadMarkets()) PanicOnError(retRes29228) response:= (<-this.SpotV1PublicGetExchangeInfo(params)) PanicOnError(response) var coins interface{} = this.SafeList(response, "coins") ch <- this.ParseDepositWithdrawFees(coins, codes, "coin") return nil }() return ch } func (this *bitrue) ParseTransfer(transfer interface{}, optionalArgs ...interface{}) interface{} { // // fetchTransfers // // { // 'transferType': 'wallet_to_contract', // 'symbol': 'USDT', // 'amount': 1.0, // 'status': 1, // 'ctime': 1685404575000 // } // // transfer // // {} // currency := GetArg(optionalArgs, 0, nil) _ = currency var transferType interface{} = this.SafeString(transfer, "transferType") var fromAccount interface{} = nil var toAccount interface{} = nil if IsTrue(!IsEqual(transferType, nil)) { var accountSplit interface{} = Split(transferType, "_to_") fromAccount = this.SafeString(accountSplit, 0) toAccount = this.SafeString(accountSplit, 1) } var timestamp interface{} = this.SafeInteger(transfer, "ctime") return map[string]interface{} { "info": transfer, "id": nil, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "currency": this.SafeString(currency, "code"), "amount": this.SafeNumber(transfer, "amount"), "fromAccount": fromAccount, "toAccount": toAccount, "status": "ok", } } /** * @method * @name bitrue#fetchTransfers * @description fetch a history of internal transfers made on an account * @see https://www.bitrue.com/api-docs#get-future-account-transfer-history-list-user_data-hmac-sha256 * @see https://www.bitrue.com/api_docs_includes_file/delivery.html#get-future-account-transfer-history-list-user_data-hmac-sha256 * @param {string} code unified currency code of the currency transferred * @param {int} [since] the earliest time in ms to fetch transfers for * @param {int} [limit] the maximum number of transfers 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 transfers for * @param {string} [params.type] transfer type wallet_to_contract or contract_to_wallet * @returns {object[]} a list of [transfer structures]{@link https://github.com/ccxt/ccxt/wiki/Manual#transfer-structure} */ func (this *bitrue) FetchTransfers(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 retRes29818 := (<-this.LoadMarkets()) PanicOnError(retRes29818) var typeVar interface{} = this.SafeString2(params, "type", "transferType") var request interface{} = map[string]interface{} { "transferType": typeVar, } var currency interface{} = nil if IsTrue(!IsEqual(code, nil)) { currency = this.Currency(code) AddElementToObject(request, "coinSymbol", GetValue(currency, "id")) } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "beginTime", since) } if IsTrue(!IsEqual(limit, nil)) { if IsTrue(IsGreaterThan(limit, 200)) { limit = 200 } AddElementToObject(request, "limit", limit) } var until interface{} = this.SafeInteger(params, "until") if IsTrue(!IsEqual(until, nil)) { params = this.Omit(params, "until") AddElementToObject(request, "endTime", until) } response:= (<-this.FapiV2PrivateGetFuturesTransferHistory(this.Extend(request, params))) PanicOnError(response) // // { // 'code': '0', // 'msg': 'Success', // 'data': [{ // 'transferType': 'wallet_to_contract', // 'symbol': 'USDT', // 'amount': 1.0, // 'status': 1, // 'ctime': 1685404575000 // }] // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseTransfers(data, currency, since, limit) return nil }() return ch } /** * @method * @name bitrue#transfer * @description transfer currency internally between wallets on the same account * @see https://www.bitrue.com/api-docs#new-future-account-transfer-user_data-hmac-sha256 * @see https://www.bitrue.com/api_docs_includes_file/delivery.html#user-commission-rate-user_data-hmac-sha256 * @param {string} code unified currency code * @param {float} amount amount to transfer * @param {string} fromAccount account to transfer from * @param {string} toAccount account to transfer to * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [transfer structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#transfer-structure} */ func (this *bitrue) 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 retRes30378 := (<-this.LoadMarkets()) PanicOnError(retRes30378) var currency interface{} = this.Currency(code) var accountTypes interface{} = this.SafeDict(this.Options, "accountsByType", map[string]interface{} {}) var fromId interface{} = this.SafeString(accountTypes, fromAccount, fromAccount) var toId interface{} = this.SafeString(accountTypes, toAccount, toAccount) var request interface{} = map[string]interface{} { "coinSymbol": GetValue(currency, "id"), "amount": this.CurrencyToPrecision(code, amount), "transferType": Add(Add(fromId, "_to_"), toId), } response:= (<-this.FapiV2PrivatePostFuturesTransfer(this.Extend(request, params))) PanicOnError(response) // // { // 'code': '0', // 'msg': 'Success', // 'data': null // } // var data interface{} = this.SafeDict(response, "data", map[string]interface{} {}) ch <- this.ParseTransfer(data, currency) return nil }() return ch } /** * @method * @name bitrue#setLeverage * @description set the level of leverage for a market * @see https://www.bitrue.com/api-docs#change-initial-leverage-trade-hmac-sha256 * @see https://www.bitrue.com/api_docs_includes_file/delivery.html#change-initial-leverage-trade-hmac-sha256 * @param {float} leverage the rate of leverage * @param {string} symbol unified market symbol * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} response from the exchange */ func (this *bitrue) SetLeverage(leverage 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 if IsTrue(IsEqual(symbol, nil)) { panic(ArgumentsRequired(Add(this.Id, " setLeverage() requires a symbol argument"))) } if IsTrue(IsTrue((IsLessThan(leverage, 1))) || IsTrue((IsGreaterThan(leverage, 125)))) { panic(BadRequest(Add(this.Id, " leverage should be between 1 and 125"))) } retRes30778 := (<-this.LoadMarkets()) PanicOnError(retRes30778) var market interface{} = this.Market(symbol) var response interface{} = nil var request interface{} = map[string]interface{} { "contractName": GetValue(market, "id"), "leverage": leverage, } if !IsTrue(GetValue(market, "swap")) { panic(NotSupported(Add(this.Id, " setLeverage only support swap markets"))) } if IsTrue(GetValue(market, "linear")) { response = (<-this.FapiV2PrivatePostLevelEdit(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(GetValue(market, "inverse")) { response = (<-this.DapiV2PrivatePostLevelEdit(this.Extend(request, params))) PanicOnError(response) } ch <- response return nil }() return ch } func (this *bitrue) ParseMarginModification(data interface{}, optionalArgs ...interface{}) interface{} { // // setMargin // // { // "code": 0, // "msg": "success" // "data": null // } // market := GetArg(optionalArgs, 0, nil) _ = market return map[string]interface{} { "info": data, "symbol": GetValue(market, "symbol"), "type": nil, "marginMode": "isolated", "amount": nil, "total": nil, "code": nil, "status": nil, "timestamp": nil, "datetime": nil, } } /** * @method * @name bitrue#setMargin * @description Either adds or reduces margin in an isolated position in order to set the margin to a specific value * @see https://www.bitrue.com/api-docs#modify-isolated-position-margin-trade-hmac-sha256 * @see https://www.bitrue.com/api_docs_includes_file/delivery.html#modify-isolated-position-margin-trade-hmac-sha256 * @param {string} symbol unified market symbol of the market to set margin in * @param {float} amount the amount to set the margin to * @param {object} [params] parameters specific to the exchange API endpoint * @returns {object} A [margin structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#add-margin-structure} */ func (this *bitrue) SetMargin(symbol interface{}, amount 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 retRes31318 := (<-this.LoadMarkets()) PanicOnError(retRes31318) var market interface{} = this.Market(symbol) if !IsTrue(GetValue(market, "swap")) { panic(NotSupported(Add(this.Id, " setMargin only support swap markets"))) } var response interface{} = nil var request interface{} = map[string]interface{} { "contractName": GetValue(market, "id"), "amount": this.ParseToNumeric(amount), } if IsTrue(GetValue(market, "linear")) { response = (<-this.FapiV2PrivatePostPositionMargin(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(GetValue(market, "inverse")) { response = (<-this.DapiV2PrivatePostPositionMargin(this.Extend(request, params))) PanicOnError(response) } // // { // "code": 0, // "msg": "success" // "data": null // } // ch <- this.ParseMarginModification(response, market) return nil }() return ch } func (this *bitrue) 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 typeVar interface{} = this.SafeString(api, 0) var version interface{} = this.SafeString(api, 1) var access interface{} = this.SafeString(api, 2) var url interface{} = nil if IsTrue(IsTrue((IsTrue(IsEqual(typeVar, "api")) && IsTrue(IsEqual(version, "kline")))) || IsTrue((IsTrue(IsEqual(typeVar, "open")) && IsTrue(IsGreaterThanOrEqual(GetIndexOf(path, "listenKey"), 0))))) { url = GetValue(GetValue(this.Urls, "api"), typeVar) } else { url = Add(Add(GetValue(GetValue(this.Urls, "api"), typeVar), "/"), version) } url = Add(Add(url, "/"), this.ImplodeParams(path, params)) params = this.Omit(params, this.ExtractParams(path)) if IsTrue(IsEqual(access, "private")) { this.CheckRequiredCredentials() var recvWindow interface{} = this.SafeInteger(this.Options, "recvWindow", 5000) if IsTrue(IsTrue(IsEqual(typeVar, "spot")) || IsTrue(IsEqual(typeVar, "open"))) { var query interface{} = this.Urlencode(this.Extend(map[string]interface{} { "timestamp": this.Nonce(), "recvWindow": recvWindow, }, params)) var signature interface{} = this.Hmac(this.Encode(query), this.Encode(this.Secret), sha256) query = Add(query, Add(Add("&", "signature="), signature)) headers = map[string]interface{} { "X-MBX-APIKEY": this.ApiKey, } if IsTrue(IsTrue((IsEqual(method, "GET"))) || IsTrue((IsEqual(method, "DELETE")))) { url = Add(url, Add("?", query)) } else { body = query AddElementToObject(headers, "Content-Type", "application/x-www-form-urlencoded") } } else { var timestamp interface{} = ToString(this.Nonce()) var signPath interface{} = nil if IsTrue(IsEqual(typeVar, "fapi")) { signPath = "/fapi" } else if IsTrue(IsEqual(typeVar, "dapi")) { signPath = "/dapi" } signPath = Add(Add(Add(Add(signPath, "/"), version), "/"), path) var signMessage interface{} = Add(Add(timestamp, method), signPath) if IsTrue(IsEqual(method, "GET")) { var keys interface{} = ObjectKeys(params) var keysLength interface{} = GetArrayLength(keys) if IsTrue(IsGreaterThan(keysLength, 0)) { signMessage = Add(signMessage, Add("?", this.Urlencode(params))) } var signature interface{} = this.Hmac(this.Encode(signMessage), this.Encode(this.Secret), sha256) headers = map[string]interface{} { "X-CH-APIKEY": this.ApiKey, "X-CH-SIGN": signature, "X-CH-TS": timestamp, } url = Add(url, Add("?", this.Urlencode(params))) } else { var query interface{} = this.Extend(map[string]interface{} { "recvWindow": recvWindow, }, params) body = this.Json(query) signMessage = Add(signMessage, body) var signature interface{} = this.Hmac(this.Encode(signMessage), this.Encode(this.Secret), sha256) headers = map[string]interface{} { "Content-Type": "application/json", "X-CH-APIKEY": this.ApiKey, "X-CH-SIGN": signature, "X-CH-TS": timestamp, } } } } else { if IsTrue(GetArrayLength(ObjectKeys(params))) { url = Add(url, Add("?", this.Urlencode(params))) } } return map[string]interface{} { "url": url, "method": method, "body": body, "headers": headers, } } func (this *bitrue) HandleErrors(code interface{}, reason interface{}, url interface{}, method interface{}, headers interface{}, body interface{}, response interface{}, requestHeaders interface{}, requestBody interface{}) interface{} { if IsTrue(IsTrue((IsEqual(code, 418))) || IsTrue((IsEqual(code, 429)))) { panic(DDoSProtection(Add(Add(Add(Add(Add(Add(this.Id, " "), ToString(code)), " "), reason), " "), body))) } // error response in a form: { "code": -1013, "msg": "Invalid quantity." } // following block cointains legacy checks against message patterns in "msg" property // will switch "code" checks eventually, when we know all of them if IsTrue(IsGreaterThanOrEqual(code, 400)) { if IsTrue(IsGreaterThanOrEqual(GetIndexOf(body, "Price * QTY is zero or less"), 0)) { panic(InvalidOrder(Add(Add(this.Id, " order cost = amount * price is zero or less "), body))) } if IsTrue(IsGreaterThanOrEqual(GetIndexOf(body, "LOT_SIZE"), 0)) { panic(InvalidOrder(Add(Add(this.Id, " order amount should be evenly divisible by lot size "), body))) } if IsTrue(IsGreaterThanOrEqual(GetIndexOf(body, "PRICE_FILTER"), 0)) { panic(InvalidOrder(Add(Add(this.Id, " order price is invalid, i.e. exceeds allowed price precision, exceeds min price or max price limits or is invalid float value in general, use this.priceToPrecision (symbol, amount) "), body))) } } if IsTrue(IsEqual(response, nil)) { return nil // fallback to default error handler } // check success value for wapi endpoints // response in format {'msg': 'The coin does not exist.', 'success': true/false} var success interface{} = this.SafeBool(response, "success", true) if !IsTrue(success) { var messageInner interface{} = this.SafeString(response, "msg") var parsedMessage interface{} = nil if IsTrue(!IsEqual(messageInner, nil)) { { ret__ := func(this *bitrue) (ret_ interface{}) { defer func() { if e := recover(); e != nil { if e == "break" { return } ret_ = func(this *bitrue) interface{} { // catch block: // do nothing parsedMessage = nil return nil }(this) } }() // try block: parsedMessage = JsonParse(messageInner) return nil }(this) if ret__ != nil { return ret__ } } if IsTrue(!IsEqual(parsedMessage, nil)) { response = parsedMessage } } } var message interface{} = this.SafeString(response, "msg") if IsTrue(!IsEqual(message, nil)) { this.ThrowExactlyMatchedException(GetValue(this.Exceptions, "exact"), message, Add(Add(this.Id, " "), message)) this.ThrowBroadlyMatchedException(GetValue(this.Exceptions, "broad"), message, Add(Add(this.Id, " "), message)) } // checks against error codes var error interface{} = this.SafeString(response, "code") if IsTrue(!IsEqual(error, nil)) { // https://github.com/ccxt/ccxt/issues/6501 // https://github.com/ccxt/ccxt/issues/7742 if IsTrue(IsTrue((IsEqual(error, "200"))) || IsTrue(Precise.StringEquals(error, "0"))) { return nil } // a workaround for {"code":-2015,"msg":"Invalid API-key, IP, or permissions for action."} // despite that their message is very confusing, it is raised by Binance // on a temporary ban, the API key is valid, but disabled for a while if IsTrue(IsTrue((IsEqual(error, "-2015"))) && IsTrue(GetValue(this.Options, "hasAlreadyAuthenticatedSuccessfully"))) { panic(DDoSProtection(Add(Add(this.Id, " temporary banned: "), body))) } var feedback interface{} = Add(Add(this.Id, " "), body) this.ThrowExactlyMatchedException(GetValue(this.Exceptions, "exact"), error, feedback) panic(ExchangeError(feedback)) } if !IsTrue(success) { panic(ExchangeError(Add(Add(this.Id, " "), body))) } return nil } func (this *bitrue) CalculateRateLimiterCost(api interface{}, method interface{}, path interface{}, params interface{}, optionalArgs ...interface{}) interface{} { config := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = config if IsTrue(IsTrue((InOp(config, "noSymbol"))) && !IsTrue((InOp(params, "symbol")))) { return GetValue(config, "noSymbol") } else if IsTrue(IsTrue((InOp(config, "byLimit"))) && IsTrue((InOp(params, "limit")))) { var limit interface{} = GetValue(params, "limit") var byLimit interface{} = GetValue(config, "byLimit") for i := 0; IsLessThan(i, GetArrayLength(byLimit)); i++ { var entry interface{} = GetValue(byLimit, i) if IsTrue(IsLessThanOrEqual(limit, GetValue(entry, 0))) { return GetValue(entry, 1) } } } return this.SafeValue(config, "cost", 1) } func (this *bitrue) Init(userConfig map[string]interface{}) { this.Exchange = Exchange{} this.Exchange.InitParent(userConfig, this.Describe().(map[string]interface{}), this) this.Exchange.DerivedExchange = this }