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 tokocrypto struct { Exchange } func NewTokocryptoCore() tokocrypto { p := tokocrypto{} setDefaults(&p) return p } func (this *tokocrypto) Describe() interface{} { return this.DeepExtend(this.Exchange.Describe(), map[string]interface{} { "id": "tokocrypto", "name": "Tokocrypto", "countries": []interface{}{"ID"}, "certified": false, "pro": false, "version": "v1", "has": map[string]interface{} { "CORS": nil, "spot": true, "margin": true, "swap": false, "future": false, "option": false, "addMargin": nil, "borrowMargin": nil, "cancelAllOrders": false, "cancelOrder": true, "cancelOrders": nil, "createDepositAddress": false, "createMarketBuyOrderWithCost": true, "createMarketOrderWithCost": false, "createMarketSellOrderWithCost": false, "createOrder": true, "createReduceOnlyOrder": nil, "createStopLimitOrder": true, "createStopMarketOrder": true, "createStopOrder": true, "fetchAccounts": false, "fetchBalance": true, "fetchBidsAsks": true, "fetchBorrowInterest": nil, "fetchBorrowRateHistories": nil, "fetchBorrowRateHistory": nil, "fetchCanceledOrders": false, "fetchClosedOrder": false, "fetchClosedOrders": "emulated", "fetchCrossBorrowRate": false, "fetchCrossBorrowRates": false, "fetchCurrencies": false, "fetchDeposit": false, "fetchDepositAddress": true, "fetchDepositAddresses": false, "fetchDepositAddressesByNetwork": false, "fetchDeposits": true, "fetchDepositsWithdrawals": false, "fetchFundingHistory": false, "fetchFundingRate": false, "fetchFundingRateHistory": false, "fetchFundingRates": false, "fetchIndexOHLCV": false, "fetchIsolatedBorrowRate": false, "fetchIsolatedBorrowRates": false, "fetchL3OrderBook": false, "fetchLedger": nil, "fetchLeverage": false, "fetchLeverageTiers": false, "fetchMarketLeverageTiers": "emulated", "fetchMarkets": true, "fetchMarkOHLCV": false, "fetchMyTrades": true, "fetchOHLCV": true, "fetchOpenInterestHistory": false, "fetchOpenOrder": false, "fetchOpenOrders": true, "fetchOrder": true, "fetchOrderBook": true, "fetchOrderBooks": false, "fetchOrders": true, "fetchOrderTrades": false, "fetchPosition": false, "fetchPositions": false, "fetchPositionsRisk": false, "fetchPremiumIndexOHLCV": false, "fetchStatus": false, "fetchTicker": false, "fetchTickers": false, "fetchTime": true, "fetchTrades": true, "fetchTradingFee": false, "fetchTradingFees": false, "fetchTradingLimits": false, "fetchTransactionFee": false, "fetchTransactionFees": false, "fetchTransactions": false, "fetchTransfers": false, "fetchWithdrawal": false, "fetchWithdrawals": true, "fetchWithdrawalWhitelist": false, "reduceMargin": false, "repayCrossMargin": false, "repayIsolatedMargin": false, "setLeverage": false, "setMargin": false, "setMarginMode": false, "setPositionMode": false, "signIn": false, "transfer": false, "withdraw": true, }, "timeframes": map[string]interface{} { "1m": "1m", "3m": "3m", "5m": "5m", "15m": "15m", "30m": "30m", "1h": "1h", "2h": "2h", "4h": "4h", "6h": "6h", "8h": "8h", "12h": "12h", "1d": "1d", "3d": "3d", "1w": "1w", "1M": "1M", }, "urls": map[string]interface{} { "logo": "https://user-images.githubusercontent.com/1294454/183870484-d3398d0c-f6a1-4cce-91b8-d58792308716.jpg", "api": map[string]interface{} { "rest": map[string]interface{} { "public": "https://www.tokocrypto.com", "binance": "https://api.binance.com/api/v3", "private": "https://www.tokocrypto.com", }, }, "www": "https://tokocrypto.com", "doc": "https://www.tokocrypto.com/apidocs/", "fees": "https://www.tokocrypto.com/fees/newschedule", }, "api": map[string]interface{} { "binance": map[string]interface{} { "get": map[string]interface{} { "ping": 1, "time": 1, "depth": map[string]interface{} { "cost": 1, "byLimit": []interface{}{[]interface{}{100, 1}, []interface{}{500, 5}, []interface{}{1000, 10}, []interface{}{5000, 50}}, }, "trades": 1, "aggTrades": 1, "historicalTrades": 5, "klines": 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, }, "exchangeInfo": 10, }, "put": map[string]interface{} { "userDataStream": 1, }, "post": map[string]interface{} { "userDataStream": 1, }, "delete": map[string]interface{} { "userDataStream": 1, }, }, "public": map[string]interface{} { "get": map[string]interface{} { "open/v1/common/time": 1, "open/v1/common/symbols": 1, "open/v1/market/depth": 1, "open/v1/market/trades": 1, "open/v1/market/agg-trades": 1, "open/v1/market/klines": 1, }, }, "private": map[string]interface{} { "get": map[string]interface{} { "open/v1/orders/detail": 1, "open/v1/orders": 1, "open/v1/account/spot": 1, "open/v1/account/spot/asset": 1, "open/v1/orders/trades": 1, "open/v1/withdraws": 1, "open/v1/deposits": 1, "open/v1/deposits/address": 1, }, "post": map[string]interface{} { "open/v1/orders": 1, "open/v1/orders/cancel": 1, "open/v1/orders/oco": 1, "open/v1/withdraws": 1, "open/v1/user-data-stream": 1, }, }, }, "fees": map[string]interface{} { "trading": map[string]interface{} { "tierBased": true, "percentage": true, "taker": this.ParseNumber("0.0075"), "maker": this.ParseNumber("0.0075"), }, }, "precisionMode": TICK_SIZE, "options": map[string]interface{} { "createMarketBuyOrderRequiresPrice": true, "defaultTimeInForce": "GTC", "hasAlreadyAuthenticatedSuccessfully": false, "warnOnFetchOpenOrdersWithoutSymbol": true, "recvWindow": Multiply(5, 1000), "timeDifference": 0, "adjustForTimeDifference": false, "newOrderRespType": map[string]interface{} { "market": "FULL", "limit": "FULL", }, "quoteOrderQty": false, "networks": map[string]interface{} { "ERC20": "ETH", "TRC20": "TRX", "BEP2": "BNB", "BEP20": "BSC", "OMNI": "OMNI", "EOS": "EOS", "SPL": "SOL", }, "reverseNetworks": map[string]interface{} { "tronscan.org": "TRC20", "etherscan.io": "ERC20", "bscscan.com": "BSC", "explorer.binance.org": "BEP2", "bithomp.com": "XRP", "bloks.io": "EOS", "stellar.expert": "XLM", "blockchair.com/bitcoin": "BTC", "blockchair.com/bitcoin-cash": "BCH", "blockchair.com/ecash": "XEC", "explorer.litecoin.net": "LTC", "explorer.avax.network": "AVAX", "solscan.io": "SOL", "polkadot.subscan.io": "DOT", "dashboard.internetcomputer.org": "ICP", "explorer.chiliz.com": "CHZ", "cardanoscan.io": "ADA", "mainnet.theoan.com": "AION", "algoexplorer.io": "ALGO", "explorer.ambrosus.com": "AMB", "viewblock.io/zilliqa": "ZIL", "viewblock.io/arweave": "AR", "explorer.ark.io": "ARK", "atomscan.com": "ATOM", "www.mintscan.io": "CTK", "explorer.bitcoindiamond.org": "BCD", "btgexplorer.com": "BTG", "bts.ai": "BTS", "explorer.celo.org": "CELO", "explorer.nervos.org": "CKB", "cerebro.cortexlabs.ai": "CTXC", "chainz.cryptoid.info": "VIA", "explorer.dcrdata.org": "DCR", "digiexplorer.info": "DGB", "dock.subscan.io": "DOCK", "dogechain.info": "DOGE", "explorer.elrond.com": "EGLD", "blockscout.com": "ETC", "explore-fetchhub.fetch.ai": "FET", "filfox.info": "FIL", "fio.bloks.io": "FIO", "explorer.firo.org": "FIRO", "neoscan.io": "NEO", "ftmscan.com": "FTM", "explorer.gochain.io": "GO", "block.gxb.io": "GXS", "hash-hash.info": "HBAR", "www.hiveblockexplorer.com": "HIVE", "explorer.helium.com": "HNT", "tracker.icon.foundation": "ICX", "www.iostabc.com": "IOST", "explorer.iota.org": "IOTA", "iotexscan.io": "IOTX", "irishub.iobscan.io": "IRIS", "kava.mintscan.io": "KAVA", "scope.klaytn.com": "KLAY", "kmdexplorer.io": "KMD", "kusama.subscan.io": "KSM", "explorer.lto.network": "LTO", "polygonscan.com": "POLYGON", "explorer.ont.io": "ONT", "minaexplorer.com": "MINA", "nanolooker.com": "NANO", "explorer.nebulas.io": "NAS", "explorer.nbs.plus": "NBS", "explorer.nebl.io": "NEBL", "nulscan.io": "NULS", "nxscan.com": "NXS", "explorer.harmony.one": "ONE", "explorer.poa.network": "POA", "qtum.info": "QTUM", "explorer.rsk.co": "RSK", "www.oasisscan.com": "ROSE", "ravencoin.network": "RVN", "sc.tokenview.com": "SC", "secretnodes.com": "SCRT", "explorer.skycoin.com": "SKY", "steemscan.com": "STEEM", "explorer.stacks.co": "STX", "www.thetascan.io": "THETA", "scan.tomochain.com": "TOMO", "explore.vechain.org": "VET", "explorer.vite.net": "VITE", "www.wanscan.org": "WAN", "wavesexplorer.com": "WAVES", "wax.eosx.io": "WAXP", "waltonchain.pro": "WTC", "chain.nem.ninja": "XEM", "verge-blockchain.info": "XVG", "explorer.yoyow.org": "YOYOW", "explorer.zcha.in": "ZEC", "explorer.zensystem.io": "ZEN", }, "impliedNetworks": map[string]interface{} { "ETH": map[string]interface{} { "ERC20": "ETH", }, "TRX": map[string]interface{} { "TRC20": "TRX", }, }, "legalMoney": map[string]interface{} { "MXN": true, "UGX": true, "SEK": true, "CHF": true, "VND": true, "AED": true, "DKK": true, "KZT": true, "HUF": true, "PEN": true, "PHP": true, "USD": true, "TRY": true, "EUR": true, "NGN": true, "PLN": true, "BRL": true, "ZAR": true, "KES": true, "ARS": true, "RUB": true, "AUD": true, "NOK": true, "CZK": true, "GBP": true, "UAH": true, "GHS": true, "HKD": true, "CAD": true, "INR": true, "JPY": true, "NZD": true, }, }, "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, "This action disabled is on this account.": AccountSuspended, "-1000": ExchangeNotAvailable, "-1001": ExchangeNotAvailable, "-1002": AuthenticationError, "-1003": RateLimitExceeded, "-1004": DDoSProtection, "-1005": PermissionDenied, "-1006": BadResponse, "-1007": RequestTimeout, "-1010": BadResponse, "-1011": PermissionDenied, "-1013": InvalidOrder, "-1014": InvalidOrder, "-1015": RateLimitExceeded, "-1016": ExchangeNotAvailable, "-1020": BadRequest, "-1021": InvalidNonce, "-1022": AuthenticationError, "-1023": BadRequest, "-1099": AuthenticationError, "-1100": BadRequest, "-1101": BadRequest, "-1102": BadRequest, "-1103": BadRequest, "-1104": BadRequest, "-1105": BadRequest, "-1106": BadRequest, "-1108": BadRequest, "-1109": AuthenticationError, "-1110": BadRequest, "-1111": BadRequest, "-1112": InvalidOrder, "-1113": BadRequest, "-1114": BadRequest, "-1115": BadRequest, "-1116": BadRequest, "-1117": BadRequest, "-1118": BadRequest, "-1119": BadRequest, "-1120": BadRequest, "-1121": BadSymbol, "-1125": AuthenticationError, "-1127": BadRequest, "-1128": BadRequest, "-1130": BadRequest, "-1131": BadRequest, "-1136": BadRequest, "-2008": AuthenticationError, "-2010": ExchangeError, "-2011": OrderNotFound, "-2013": OrderNotFound, "-2014": AuthenticationError, "-2015": AuthenticationError, "-2016": BadRequest, "-2018": InsufficientFunds, "-2019": InsufficientFunds, "-2020": OrderNotFillable, "-2021": OrderImmediatelyFillable, "-2022": InvalidOrder, "-2023": InsufficientFunds, "-2024": InsufficientFunds, "-2025": InvalidOrder, "-2026": InvalidOrder, "-2027": InvalidOrder, "-2028": InsufficientFunds, "-3000": ExchangeError, "-3001": AuthenticationError, "-3002": BadSymbol, "-3003": BadRequest, "-3004": ExchangeError, "-3005": InsufficientFunds, "-3006": InsufficientFunds, "-3007": ExchangeError, "-3008": InsufficientFunds, "-3009": BadRequest, "-3010": ExchangeError, "-3011": BadRequest, "-3012": ExchangeError, "-3013": BadRequest, "-3014": AccountSuspended, "-3015": ExchangeError, "-3016": BadRequest, "-3017": ExchangeError, "-3018": AccountSuspended, "-3019": AccountSuspended, "-3020": InsufficientFunds, "-3021": BadRequest, "-3022": AccountSuspended, "-3023": BadRequest, "-3024": ExchangeError, "-3025": BadRequest, "-3026": BadRequest, "-3027": BadSymbol, "-3028": BadSymbol, "-3029": ExchangeError, "-3036": AccountSuspended, "-3037": ExchangeError, "-3038": BadRequest, "-3041": InsufficientFunds, "-3042": BadRequest, "-3043": BadRequest, "-3044": DDoSProtection, "-3045": ExchangeError, "-3999": ExchangeError, "-4001": BadRequest, "-4002": BadRequest, "-4003": BadRequest, "-4004": AuthenticationError, "-4005": RateLimitExceeded, "-4006": BadRequest, "-4007": BadRequest, "-4008": BadRequest, "-4010": BadRequest, "-4011": BadRequest, "-4012": BadRequest, "-4013": AuthenticationError, "-4014": PermissionDenied, "-4015": ExchangeError, "-4016": PermissionDenied, "-4017": PermissionDenied, "-4018": BadSymbol, "-4019": BadSymbol, "-4021": BadRequest, "-4022": BadRequest, "-4023": ExchangeError, "-4024": InsufficientFunds, "-4025": InsufficientFunds, "-4026": InsufficientFunds, "-4027": ExchangeError, "-4028": BadRequest, "-4029": BadRequest, "-4030": ExchangeError, "-4031": ExchangeError, "-4032": ExchangeError, "-4033": BadRequest, "-4034": ExchangeError, "-4035": PermissionDenied, "-4036": BadRequest, "-4037": ExchangeError, "-4038": ExchangeError, "-4039": BadRequest, "-4040": BadRequest, "-4041": ExchangeError, "-4042": ExchangeError, "-4043": BadRequest, "-4044": BadRequest, "-4045": ExchangeError, "-4046": AuthenticationError, "-4047": BadRequest, "-5001": BadRequest, "-5002": InsufficientFunds, "-5003": InsufficientFunds, "-5004": BadRequest, "-5005": InsufficientFunds, "-5006": BadRequest, "-5007": BadRequest, "-5008": InsufficientFunds, "-5009": BadRequest, "-5010": ExchangeError, "-5011": BadRequest, "-5012": ExchangeError, "-5013": InsufficientFunds, "-5021": BadRequest, "-6001": BadRequest, "-6003": BadRequest, "-6004": ExchangeError, "-6005": InvalidOrder, "-6006": BadRequest, "-6007": BadRequest, "-6008": BadRequest, "-6009": RateLimitExceeded, "-6011": BadRequest, "-6012": InsufficientFunds, "-6013": ExchangeError, "-6014": BadRequest, "-6015": BadRequest, "-6016": BadRequest, "-6017": BadRequest, "-6018": BadRequest, "-6019": AuthenticationError, "-6020": BadRequest, "-7001": BadRequest, "-7002": BadRequest, "-9000": InsufficientFunds, "-10017": BadRequest, "-11008": InsufficientFunds, "-12014": RateLimitExceeded, "-13000": BadRequest, "-13001": BadRequest, "-13002": BadRequest, "-13003": BadRequest, "-13004": BadRequest, "-13005": BadRequest, "-13006": InvalidOrder, "-13007": AuthenticationError, "-21001": BadRequest, "-21002": BadRequest, "-21003": BadRequest, "100001003": BadRequest, "2202": InsufficientFunds, "3210": InvalidOrder, "3203": InvalidOrder, "3211": InvalidOrder, "3207": InvalidOrder, "3218": OrderNotFound, }, "broad": map[string]interface{} { "has no operation privilege": PermissionDenied, "MAX_POSITION": InvalidOrder, }, }, "features": map[string]interface{} { "spot": map[string]interface{} { "sandbox": false, "createOrder": map[string]interface{} { "marginMode": false, "triggerPrice": true, "triggerDirection": false, "triggerPriceType": 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, "marketBuyByCost": true, "marketBuyRequiresPrice": true, "selfTradePrevention": true, "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": false, }, "fetchOpenOrders": map[string]interface{} { "marginMode": false, "limit": 1000, "trigger": false, "trailing": false, "symbolRequired": true, }, "fetchOrders": map[string]interface{} { "marginMode": false, "limit": 1000, "daysBack": 100000, "untilDays": 100000, "trigger": false, "trailing": false, "symbolRequired": true, }, "fetchClosedOrders": map[string]interface{} { "marginMode": false, "limit": 1000, "daysBack": 100000, "daysBackCanceled": 1, "untilDays": 100000, "trigger": false, "trailing": false, "symbolRequired": true, }, "fetchOHLCV": map[string]interface{} { "limit": 1000, }, }, "swap": map[string]interface{} { "linear": nil, "inverse": nil, }, "future": map[string]interface{} { "linear": nil, "inverse": nil, }, }, }) } func (this *tokocrypto) Nonce() interface{} { return Subtract(this.Milliseconds(), GetValue(this.Options, "timeDifference")) } /** * @method * @name tokocrypto#fetchTime * @see https://www.tokocrypto.com/apidocs/#check-server-time * @description fetches the current integer timestamp in milliseconds from the exchange server * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {int} the current integer timestamp in milliseconds from the exchange server */ func (this *tokocrypto) 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.PublicGetOpenV1CommonTime(params)) PanicOnError(response) // // { // "code": 0, // "msg": "Success", // "data": null, // "timestamp": 1737378074159 // } // ch <- this.SafeInteger(response, "timestamp") return nil }() return ch } /** * @method * @name tokocrypto#fetchMarkets * @see https://www.tokocrypto.com/apidocs/#get-all-supported-trading-symbol * @description retrieves data on all markets for tokocrypto * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} an array of objects representing market data */ func (this *tokocrypto) FetchMarkets(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params response:= (<-this.PublicGetOpenV1CommonSymbols(params)) PanicOnError(response) // // { // "code":0, // "msg":"Success", // "data":{ // "list":[ // { // "type":1, // "symbol":"1INCH_BTC", // "baseAsset":"1INCH", // "basePrecision":8, // "quoteAsset":"BTC", // "quotePrecision":8, // "filters":[ // {"filterType":"PRICE_FILTER","minPrice":"0.00000001","maxPrice":"1000.00000000","tickSize":"0.00000001","applyToMarket":false}, // {"filterType":"PERCENT_PRICE","multiplierUp":5,"multiplierDown":0.2,"avgPriceMins":"5","applyToMarket":false}, // {"filterType":"LOT_SIZE","minQty":"0.10000000","maxQty":"90000000.00000000","stepSize":"0.10000000","applyToMarket":false}, // {"filterType":"MIN_NOTIONAL","avgPriceMins":"5","minNotional":"0.00010000","applyToMarket":true}, // {"filterType":"ICEBERG_PARTS","applyToMarket":false,"limit":"10"}, // {"filterType":"MARKET_LOT_SIZE","minQty":"0.00000000","maxQty":"79460.14117231","stepSize":"0.00000000","applyToMarket":false}, // {"filterType":"TRAILING_DELTA","applyToMarket":false}, // {"filterType":"MAX_NUM_ORDERS","applyToMarket":false}, // {"filterType":"MAX_NUM_ALGO_ORDERS","applyToMarket":false,"maxNumAlgoOrders":"5"} // ], // "orderTypes":["LIMIT","LIMIT_MAKER","MARKET","STOP_LOSS_LIMIT","TAKE_PROFIT_LIMIT"], // "icebergEnable":1, // "ocoEnable":1, // "spotTradingEnable":1, // "marginTradingEnable":1, // "permissions":["SPOT","MARGIN"] // }, // ] // }, // "timestamp":1659492212507 // } // if IsTrue(GetValue(this.Options, "adjustForTimeDifference")) { retRes75112 := (<-this.LoadTimeDifference()) PanicOnError(retRes75112) } var data interface{} = this.SafeValue(response, "data", map[string]interface{} {}) var list interface{} = this.SafeValue(data, "list", []interface{}{}) var result interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(list)); i++ { var market interface{} = GetValue(list, i) var baseId interface{} = this.SafeString(market, "baseAsset") var quoteId interface{} = this.SafeString(market, "quoteAsset") var id interface{} = this.SafeString(market, "symbol") var lowercaseId interface{} = this.SafeStringLower(market, "symbol") var settleId interface{} = this.SafeString(market, "marginAsset") var base interface{} = this.SafeCurrencyCode(baseId) var quote interface{} = this.SafeCurrencyCode(quoteId) var settle interface{} = this.SafeCurrencyCode(settleId) var symbol interface{} = Add(Add(base, "/"), quote) var filters interface{} = this.SafeValue(market, "filters", []interface{}{}) var filtersByType interface{} = this.IndexBy(filters, "filterType") var status interface{} = this.SafeString(market, "spotTradingEnable") var active interface{} = (IsEqual(status, "1")) var permissions interface{} = this.SafeValue(market, "permissions", []interface{}{}) for j := 0; IsLessThan(j, GetArrayLength(permissions)); j++ { if IsTrue(IsEqual(GetValue(permissions, j), "TRD_GRP_003")) { active = false break } } var isMarginTradingAllowed interface{} = this.SafeBool(market, "isMarginTradingAllowed", false) var entry interface{} = map[string]interface{} { "id": id, "lowercaseId": lowercaseId, "symbol": symbol, "base": base, "quote": quote, "settle": settle, "baseId": baseId, "quoteId": quoteId, "settleId": settleId, "type": "spot", "spot": true, "margin": isMarginTradingAllowed, "swap": false, "future": false, "delivery": false, "option": false, "active": active, "contract": false, "linear": nil, "inverse": nil, "contractSize": nil, "expiry": nil, "expiryDatetime": nil, "strike": nil, "optionType": nil, "precision": map[string]interface{} { "amount": this.ParseNumber(this.ParsePrecision(this.SafeString(market, "quantityPrecision"))), "price": this.ParseNumber(this.ParsePrecision(this.SafeString(market, "pricePrecision"))), "base": this.ParseNumber(this.ParsePrecision(this.SafeString(market, "baseAssetPrecision"))), "quote": this.ParseNumber(this.ParsePrecision(this.SafeString(market, "quotePrecision"))), }, "limits": map[string]interface{} { "leverage": map[string]interface{} { "min": nil, "max": nil, }, "amount": map[string]interface{} { "min": nil, "max": nil, }, "price": map[string]interface{} { "min": nil, "max": nil, }, "cost": map[string]interface{} { "min": nil, "max": nil, }, }, "created": nil, "info": market, } if IsTrue(InOp(filtersByType, "PRICE_FILTER")) { var filter interface{} = this.SafeValue(filtersByType, "PRICE_FILTER", map[string]interface{} {}) AddElementToObject(GetValue(entry, "precision"), "price", this.SafeNumber(filter, "tickSize")) // PRICE_FILTER reports zero values for maxPrice // since they updated filter types in November 2018 // https://github.com/ccxt/ccxt/issues/4286 // therefore limits['price']['max'] doesn't have any meaningful value except undefined AddElementToObject(GetValue(entry, "limits"), "price", map[string]interface{} { "min": this.SafeNumber(filter, "minPrice"), "max": this.SafeNumber(filter, "maxPrice"), }) AddElementToObject(GetValue(entry, "precision"), "price", GetValue(filter, "tickSize")) } if IsTrue(InOp(filtersByType, "LOT_SIZE")) { var filter interface{} = this.SafeValue(filtersByType, "LOT_SIZE", map[string]interface{} {}) AddElementToObject(GetValue(entry, "precision"), "amount", this.SafeNumber(filter, "stepSize")) AddElementToObject(GetValue(entry, "limits"), "amount", map[string]interface{} { "min": this.SafeNumber(filter, "minQty"), "max": this.SafeNumber(filter, "maxQty"), }) } if IsTrue(InOp(filtersByType, "MARKET_LOT_SIZE")) { var filter interface{} = this.SafeValue(filtersByType, "MARKET_LOT_SIZE", map[string]interface{} {}) AddElementToObject(GetValue(entry, "limits"), "market", map[string]interface{} { "min": this.SafeNumber(filter, "minQty"), "max": this.SafeNumber(filter, "maxQty"), }) } if IsTrue(InOp(filtersByType, "MIN_NOTIONAL")) { var filter interface{} = this.SafeValue(filtersByType, "MIN_NOTIONAL", map[string]interface{} {}) AddElementToObject(GetValue(GetValue(entry, "limits"), "cost"), "min", this.SafeNumber2(filter, "minNotional", "notional")) } AppendToArray(&result,entry) } ch <- result return nil }() return ch } /** * @method * @name tokocrypto#fetchOrderBook * @see https://www.tokocrypto.com/apidocs/#order-book * @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data * @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 *tokocrypto) 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 retRes8808 := (<-this.LoadMarkets()) PanicOnError(retRes8808) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} {} if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) // default 100, max 5000, see https://github.com/binance/binance-spot-api-docs/blob/master/rest-api.md#order-book } var response interface{} = nil if IsTrue(IsEqual(GetValue(market, "quote"), "USDT")) { AddElementToObject(request, "symbol", Add(GetValue(market, "baseId"), GetValue(market, "quoteId"))) response = (<-this.BinanceGetDepth(this.Extend(request, params))) PanicOnError(response) } else { AddElementToObject(request, "symbol", GetValue(market, "id")) response = (<-this.PublicGetOpenV1MarketDepth(this.Extend(request, params))) PanicOnError(response) } // // future // // { // "lastUpdateId":333598053905, // "E":1618631511986, // "T":1618631511964, // "bids":[ // ["2493.56","20.189"], // ["2493.54","1.000"], // ["2493.51","0.005"] // ], // "asks":[ // ["2493.57","0.877"], // ["2493.62","0.063"], // ["2493.71","12.054"], // ] // } // type not 1 // { // "code":0, // "msg":"Success", // "data":{ // "lastUpdateId":3204783, // "bids":[], // "asks": [] // }, // "timestamp":1692262634599 // } var data interface{} = this.SafeValue(response, "data", response) var timestamp interface{} = this.SafeInteger2(response, "T", "timestamp") var orderbook interface{} = this.ParseOrderBook(data, symbol, timestamp) AddElementToObject(orderbook, "nonce", this.SafeInteger(data, "lastUpdateId")) ch <- orderbook return nil }() return ch } func (this *tokocrypto) ParseTrade(trade interface{}, optionalArgs ...interface{}) interface{} { // // aggregate trades // https://github.com/binance-exchange/binance-official-api-docs/blob/master/rest-api.md#compressedaggregate-trades-list // // { // "a": 26129, // Aggregate tradeId // "p": "0.01633102", // Price // "q": "4.70443515", // Quantity // "f": 27781, // First tradeId // "l": 27781, // Last tradeId // "T": 1498793709153, // Timestamp // "m": true, // Was the buyer the maker? // "M": true // Was the trade the best price match? // } // // recent public trades and old public trades // https://github.com/binance-exchange/binance-official-api-docs/blob/master/rest-api.md#recent-trades-list // https://github.com/binance-exchange/binance-official-api-docs/blob/master/rest-api.md#old-trade-lookup-market_data // // { // "id": 28457, // "price": "4.00000100", // "qty": "12.00000000", // "time": 1499865549590, // "isBuyerMaker": true, // "isBestMatch": true // } // // private trades // https://github.com/binance-exchange/binance-official-api-docs/blob/master/rest-api.md#account-trade-list-user_data // // { // "symbol": "BNBBTC", // "id": 28457, // "orderId": 100234, // "price": "4.00000100", // "qty": "12.00000000", // "commission": "10.10000000", // "commissionAsset": "BNB", // "time": 1499865549590, // "isBuyer": true, // "isMaker": false, // "isBestMatch": true // } // // futures trades // https://binance-docs.github.io/apidocs/futures/en/#account-trade-list-user_data // // { // "accountId": 20, // "buyer": False, // "commission": "-0.07819010", // "commissionAsset": "USDT", // "counterPartyId": 653, // "id": 698759, // "maker": False, // "orderId": 25851813, // "price": "7819.01", // "qty": "0.002", // "quoteQty": "0.01563", // "realizedPnl": "-0.91539999", // "side": "SELL", // "symbol": "BTCUSDT", // "time": 1569514978020 // } // { // "symbol": "BTCUSDT", // "id": 477128891, // "orderId": 13809777875, // "side": "SELL", // "price": "38479.55", // "qty": "0.001", // "realizedPnl": "-0.00009534", // "marginAsset": "USDT", // "quoteQty": "38.47955", // "commission": "-0.00076959", // "commissionAsset": "USDT", // "time": 1612733566708, // "positionSide": "BOTH", // "maker": true, // "buyer": false // } // // { respType: FULL } // // { // "price": "4000.00000000", // "qty": "1.00000000", // "commission": "4.00000000", // "commissionAsset": "USDT", // "tradeId": "1234", // } // market := GetArg(optionalArgs, 0, nil) _ = market var timestamp interface{} = this.SafeInteger2(trade, "T", "time") var price interface{} = this.SafeString2(trade, "p", "price") var amount interface{} = this.SafeString2(trade, "q", "qty") var cost interface{} = this.SafeString2(trade, "quoteQty", "baseQty") // inverse futures var marketId interface{} = this.SafeString(trade, "symbol") var symbol interface{} = this.SafeSymbol(marketId, market) var id interface{} = this.SafeString2(trade, "t", "a") id = this.SafeString2(trade, "id", "tradeId", id) var side interface{} = nil var orderId interface{} = this.SafeString(trade, "orderId") var buyerMaker interface{} = this.SafeValue2(trade, "m", "isBuyerMaker") var takerOrMaker interface{} = nil if IsTrue(!IsEqual(buyerMaker, nil)) { side = Ternary(IsTrue(buyerMaker), "sell", "buy") // this is reversed intentionally takerOrMaker = "taker" } else if IsTrue(InOp(trade, "side")) { side = this.SafeStringLower(trade, "side") } else { if IsTrue(InOp(trade, "isBuyer")) { side = Ternary(IsTrue(GetValue(trade, "isBuyer")), "buy", "sell") // this is a true side } } var fee interface{} = nil if IsTrue(InOp(trade, "commission")) { fee = map[string]interface{} { "cost": this.SafeString(trade, "commission"), "currency": this.SafeCurrencyCode(this.SafeString(trade, "commissionAsset")), } } if IsTrue(InOp(trade, "isMaker")) { takerOrMaker = Ternary(IsTrue(GetValue(trade, "isMaker")), "maker", "taker") } if IsTrue(InOp(trade, "maker")) { takerOrMaker = Ternary(IsTrue(GetValue(trade, "maker")), "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": price, "amount": amount, "cost": cost, "fee": fee, }, market) } /** * @method * @name tokocrypto#fetchTrades * @see https://www.tokocrypto.com/apidocs/#recent-trades-list * @see https://www.tokocrypto.com/apidocs/#compressedaggregate-trades-list * @description get the list of most recent trades for a particular symbol * @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 *tokocrypto) 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 retRes10898 := (<-this.LoadMarkets()) PanicOnError(retRes10898) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "symbol": this.GetMarketIdByType(market), } if IsTrue(!IsEqual(GetValue(market, "quote"), "USDT")) { if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) } var responseInner interface{} = this.PublicGetOpenV1MarketTrades(this.Extend(request, params)) // // { // "code": 0, // "msg": "success", // "data": { // "list": [ // { // "id": 28457, // "price": "4.00000100", // "qty": "12.00000000", // "time": 1499865549590, // "isBuyerMaker": true, // "isBestMatch": true // } // ] // }, // "timestamp": 1571921637091 // } // var data interface{} = this.SafeDict(responseInner, "data", map[string]interface{} {}) var list interface{} = this.SafeList(data, "list", []interface{}{}) ch <- this.ParseTrades(list, market, since, limit) return nil } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) // default = 500, maximum = 1000 } var defaultMethod interface{} = "binanceGetTrades" var method interface{} = this.SafeString(this.Options, "fetchTradesMethod", defaultMethod) var response interface{} = nil if IsTrue(IsTrue((IsEqual(method, "binanceGetAggTrades"))) && IsTrue((!IsEqual(since, nil)))) { AddElementToObject(request, "startTime", since) // https://github.com/ccxt/ccxt/issues/6400 // https://github.com/binance-exchange/binance-official-api-docs/blob/master/rest-api.md#compressedaggregate-trades-list AddElementToObject(request, "endTime", this.Sum(since, 3600000)) response = (<-this.BinanceGetAggTrades(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.BinanceGetTrades(this.Extend(request, params))) PanicOnError(response) } // // Caveats: // - default limit (500) applies only if no other parameters set, trades up // to the maximum limit may be returned to satisfy other parameters // - if both limit and time window is set and time window contains more // trades than the limit then the last trades from the window are returned // - 'tradeId' accepted and returned by this method is "aggregate" trade id // which is different from actual trade id // - setting both fromId and time window results in error // // aggregate trades // // [ // { // "a": 26129, // Aggregate tradeId // "p": "0.01633102", // Price // "q": "4.70443515", // Quantity // "f": 27781, // First tradeId // "l": 27781, // Last tradeId // "T": 1498793709153, // Timestamp // "m": true, // Was the buyer the maker? // "M": true // Was the trade the best price match? // } // ] // // recent public trades and historical public trades // // [ // { // "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 *tokocrypto) ParseTicker(ticker interface{}, optionalArgs ...interface{}) interface{} { // // { // "symbol": "ETHBTC", // "priceChange": "0.00068700", // "priceChangePercent": "2.075", // "weightedAvgPrice": "0.03342681", // "prevClosePrice": "0.03310300", // "lastPrice": "0.03378900", // "lastQty": "0.07700000", // "bidPrice": "0.03378900", // "bidQty": "7.16800000", // "askPrice": "0.03379000", // "askQty": "24.00000000", // "openPrice": "0.03310200", // "highPrice": "0.03388900", // "lowPrice": "0.03306900", // "volume": "205478.41000000", // "quoteVolume": "6868.48826294", // "openTime": 1601469986932, // "closeTime": 1601556386932, // "firstId": 196098772, // "lastId": 196186315, // "count": 87544 // } // // coinm // { // "baseVolume": "214549.95171161", // "closeTime": "1621965286847", // "count": "1283779", // "firstId": "152560106", // "highPrice": "39938.3", // "lastId": "153843955", // "lastPrice": "37993.4", // "lastQty": "1", // "lowPrice": "36457.2", // "openPrice": "37783.4", // "openTime": "1621878840000", // "pair": "BTCUSD", // "priceChange": "210.0", // "priceChangePercent": "0.556", // "symbol": "BTCUSD_PERP", // "volume": "81990451", // "weightedAvgPrice": "38215.08713747" // } // market := GetArg(optionalArgs, 0, nil) _ = market var timestamp interface{} = this.SafeInteger(ticker, "closeTime") var marketId interface{} = this.SafeString(ticker, "symbol") var symbol interface{} = this.SafeSymbol(marketId, market) var last interface{} = this.SafeString(ticker, "lastPrice") var isCoinm interface{} = (InOp(ticker, "baseVolume")) var baseVolume interface{} = nil var quoteVolume interface{} = nil if IsTrue(isCoinm) { baseVolume = this.SafeString(ticker, "baseVolume") quoteVolume = this.SafeString(ticker, "volume") } else { baseVolume = this.SafeString(ticker, "volume") quoteVolume = this.SafeString(ticker, "quoteVolume") } return this.SafeTicker(map[string]interface{} { "symbol": symbol, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "high": this.SafeString(ticker, "highPrice"), "low": this.SafeString(ticker, "lowPrice"), "bid": this.SafeString(ticker, "bidPrice"), "bidVolume": this.SafeString(ticker, "bidQty"), "ask": this.SafeString(ticker, "askPrice"), "askVolume": this.SafeString(ticker, "askQty"), "vwap": this.SafeString(ticker, "weightedAvgPrice"), "open": this.SafeString(ticker, "openPrice"), "close": last, "last": last, "previousClose": this.SafeString(ticker, "prevClosePrice"), "change": this.SafeString(ticker, "priceChange"), "percentage": this.SafeString(ticker, "priceChangePercent"), "average": nil, "baseVolume": baseVolume, "quoteVolume": quoteVolume, "info": ticker, }, market) } /** * @method * @name tokocrypto#fetchTickers * @see https://binance-docs.github.io/apidocs/spot/en/#24hr-ticker-price-change-statistics * @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market * @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 *tokocrypto) 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 retRes12778 := (<-this.LoadMarkets()) PanicOnError(retRes12778) response:= (<-this.BinanceGetTicker24hr(params)) PanicOnError(response) ch <- this.ParseTickers(response, symbols) return nil }() return ch } func (this *tokocrypto) GetMarketIdByType(market interface{}) interface{} { if IsTrue(IsEqual(GetValue(market, "quote"), "USDT")) { return Add(GetValue(market, "baseId"), GetValue(market, "quoteId")) } return GetValue(market, "id") } /** * @method * @name tokocrypto#fetchTicker * @see https://binance-docs.github.io/apidocs/spot/en/#24hr-ticker-price-change-statistics * @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market * @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 *tokocrypto) 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 retRes12998 := (<-this.LoadMarkets()) PanicOnError(retRes12998) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "symbol": Add(GetValue(market, "baseId"), GetValue(market, "quoteId")), } response:= (<-this.BinanceGetTicker24hr(this.Extend(request, params))) PanicOnError(response) if IsTrue(IsArray(response)) { var firstTicker interface{} = this.SafeDict(response, 0, map[string]interface{} {}) ch <- this.ParseTicker(firstTicker, market) return nil } ch <- this.ParseTicker(response, market) return nil }() return ch } /** * @method * @name tokocrypto#fetchBidsAsks * @see https://binance-docs.github.io/apidocs/spot/en/#symbol-order-book-ticker * @description fetches the bid and ask price and volume for multiple markets * @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 *tokocrypto) 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 retRes13228 := (<-this.LoadMarkets()) PanicOnError(retRes13228) response:= (<-this.BinanceGetTickerBookTicker(params)) PanicOnError(response) ch <- this.ParseTickers(response, symbols) return nil }() return ch } func (this *tokocrypto) ParseOHLCV(ohlcv interface{}, optionalArgs ...interface{}) interface{} { // when api method = publicGetKlines || fapiPublicGetKlines || dapiPublicGetKlines // [ // 1591478520000, // open time // "0.02501300", // open // "0.02501800", // high // "0.02500000", // low // "0.02500000", // close // "22.19000000", // volume // 1591478579999, // close time // "0.55490906", // quote asset volume // 40, // number of trades // "10.92900000", // taker buy base asset volume // "0.27336462", // taker buy quote asset volume // "0" // ignore // ] // // when api method = fapiPublicGetMarkPriceKlines || fapiPublicGetIndexPriceKlines // [ // [ // 1591256460000, // Open time // "9653.29201333", // Open // "9654.56401333", // High // "9653.07367333", // Low // "9653.07367333", // Close (or latest price) // "0", // Ignore // 1591256519999, // Close time // "0", // Ignore // 60, // Number of bisic data // "0", // Ignore // "0", // Ignore // "0" // Ignore // ] // ] // market := GetArg(optionalArgs, 0, nil) _ = market return []interface{}{this.SafeInteger(ohlcv, 0), this.SafeNumber(ohlcv, 1), this.SafeNumber(ohlcv, 2), this.SafeNumber(ohlcv, 3), this.SafeNumber(ohlcv, 4), this.SafeNumber(ohlcv, 5)} } /** * @method * @name tokocrypto#fetchOHLCV * @see https://binance-docs.github.io/apidocs/spot/en/#kline-candlestick-data * @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market * @param {string} symbol unified symbol of the market to fetch OHLCV data for * @param {string} timeframe the length of time each candle represents * @param {int} [since] timestamp in ms of the earliest candle to fetch * @param {int} [limit] the maximum amount of candles to fetch * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.price] "mark" or "index" for mark price and index price candles * @param {int} [params.until] timestamp in ms of the latest candle to fetch * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume */ func (this *tokocrypto) 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 retRes13878 := (<-this.LoadMarkets()) PanicOnError(retRes13878) var market interface{} = this.Market(symbol) // binance docs say that the default limit 500, max 1500 for futures, max 1000 for spot markets // the reality is that the time range wider than 500 candles won't work right var defaultLimit interface{} = 500 var maxLimit interface{} = 1500 var price interface{} = this.SafeString(params, "price") var until interface{} = this.SafeInteger(params, "until") params = this.Omit(params, []interface{}{"price", "until"}) limit = Ternary(IsTrue((IsEqual(limit, nil))), defaultLimit, mathMin(limit, maxLimit)) var request interface{} = map[string]interface{} { "interval": this.SafeString(this.Timeframes, timeframe, timeframe), "limit": limit, } if IsTrue(IsEqual(price, "index")) { AddElementToObject(request, "pair", GetValue(market, "id")) // Index price takes this argument instead of symbol } else { AddElementToObject(request, "symbol", this.GetMarketIdByType(market)) } // const duration = this.parseTimeframe (timeframe); if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "startTime", since) } if IsTrue(!IsEqual(until, nil)) { AddElementToObject(request, "endTime", until) } var response interface{} = nil if IsTrue(IsEqual(GetValue(market, "quote"), "USDT")) { response = (<-this.BinanceGetKlines(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.PublicGetOpenV1MarketKlines(this.Extend(request, params))) PanicOnError(response) } // // [ // [1591478520000,"0.02501300","0.02501800","0.02500000","0.02500000","22.19000000",1591478579999,"0.55490906",40,"10.92900000","0.27336462","0"], // [1591478580000,"0.02499600","0.02500900","0.02499400","0.02500300","21.34700000",1591478639999,"0.53370468",24,"7.53800000","0.18850725","0"], // [1591478640000,"0.02500800","0.02501100","0.02500300","0.02500800","154.14200000",1591478699999,"3.85405839",97,"5.32300000","0.13312641","0"], // ] // var data interface{} = this.SafeList(response, "data", response) ch <- this.ParseOHLCVs(data, market, timeframe, since, limit) return nil }() return ch } /** * @method * @name tokocrypto#fetchBalance * @see https://www.tokocrypto.com/apidocs/#account-information-signed * @description query for balance and get the amount of funds available for trading or funds locked in orders * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.type] 'future', 'delivery', 'savings', 'funding', or 'spot' * @param {string} [params.marginMode] 'cross' or 'isolated', for margin trading, uses this.options.defaultMarginMode if not passed, defaults to undefined/None/null * @param {string[]|undefined} [params.symbols] unified market symbols, only used in isolated margin mode * @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure} */ func (this *tokocrypto) 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 retRes14428 := (<-this.LoadMarkets()) PanicOnError(retRes14428) var defaultType interface{} = this.SafeString2(this.Options, "fetchBalance", "defaultType", "spot") var typeVar interface{} = this.SafeString(params, "type", defaultType) var defaultMarginMode interface{} = this.SafeString2(this.Options, "marginMode", "defaultMarginMode") var marginMode interface{} = this.SafeStringLower(params, "marginMode", defaultMarginMode) var request interface{} = map[string]interface{} {} response:= (<-this.PrivateGetOpenV1AccountSpot(this.Extend(request, params))) PanicOnError(response) // // spot // // { // "code":0, // "msg":"Success", // "data":{ // "makerCommission":"0.00100000", // "takerCommission":"0.00100000", // "buyerCommission":"0.00000000", // "sellerCommission":"0.00000000", // "canTrade":1, // "canWithdraw":1, // "canDeposit":1, // "status":1, // "accountAssets":[ // {"asset":"1INCH","free":"0","locked":"0"}, // {"asset":"AAVE","free":"0","locked":"0"}, // {"asset":"ACA","free":"0","locked":"0"} // ], // }, // "timestamp":1659666786943 // } // ch <- this.ParseBalanceCustom(response, typeVar, marginMode) return nil }() return ch } func (this *tokocrypto) ParseBalanceCustom(response interface{}, optionalArgs ...interface{}) interface{} { typeVar := GetArg(optionalArgs, 0, nil) _ = typeVar marginMode := GetArg(optionalArgs, 1, nil) _ = marginMode var timestamp interface{} = this.SafeInteger(response, "updateTime") var result interface{} = map[string]interface{} { "info": response, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), } var data interface{} = this.SafeValue(response, "data", map[string]interface{} {}) var balances interface{} = this.SafeValue(data, "accountAssets", []interface{}{}) for i := 0; IsLessThan(i, GetArrayLength(balances)); i++ { var balance interface{} = GetValue(balances, i) var currencyId interface{} = this.SafeString(balance, "asset") var code interface{} = this.SafeCurrencyCode(currencyId) var account interface{} = this.Account() AddElementToObject(account, "free", this.SafeString(balance, "free")) AddElementToObject(account, "used", this.SafeString(balance, "locked")) AddElementToObject(result, code, account) } return this.SafeBalance(result) } func (this *tokocrypto) ParseOrderStatus(status interface{}) interface{} { var statuses interface{} = map[string]interface{} { "-2": "open", "0": "open", "1": "open", "2": "closed", "3": "canceled", "4": "canceling", "5": "rejected", "6": "expired", "NEW": "open", "PARTIALLY_FILLED": "open", "FILLED": "closed", "CANCELED": "canceled", "PENDING_CANCEL": "canceling", "REJECTED": "rejected", "EXPIRED": "expired", } return this.SafeString(statuses, status, status) } func (this *tokocrypto) ParseOrder(order interface{}, optionalArgs ...interface{}) interface{} { // // 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 // } // createOrder // { // "orderId": "145265071", // "bOrderListId": "0", // "clientId": "49c09c3c2cd54419a59c05441f517b3c", // "bOrderId": "35247529", // "symbol": "USDT_BIDR", // "symbolType": "1", // "side": "0", // "type": "1", // "price": "11915", // "origQty": "2", // "origQuoteQty": "23830.00", // "executedQty": "0.00000000", // "executedPrice": "0", // "executedQuoteQty": "0.00", // "timeInForce": "1", // "stopPrice": "0", // "icebergQty": "0", // "status": "0", // "createTime": "1662711074372" // } // // createOrder with { "newOrderRespType": "FULL" } // // { // "symbol": "BTCUSDT", // "orderId": 5403233939, // "orderListId": -1, // "clientOrderId": "x-R4BD3S825e669e75b6c14f69a2c43e", // "transactTime": 1617151923742, // "price": "0.00000000", // "origQty": "0.00050000", // "executedQty": "0.00050000", // "cummulativeQuoteQty": "29.47081500", // "status": "FILLED", // "timeInForce": "GTC", // "type": "MARKET", // "side": "BUY", // "fills": [ // { // "price": "58941.63000000", // "qty": "0.00050000", // "commission": "0.00007050", // "commissionAsset": "BNB", // "tradeId": 737466631 // } // ] // } // // delivery // // { // "orderId": "18742727411", // "symbol": "ETHUSD_PERP", // "pair": "ETHUSD", // "status": "FILLED", // "clientOrderId": "x-xcKtGhcu3e2d1503fdd543b3b02419", // "price": "0", // "avgPrice": "4522.14", // "origQty": "1", // "executedQty": "1", // "cumBase": "0.00221134", // "timeInForce": "GTC", // "type": "MARKET", // "reduceOnly": false, // "closePosition": false, // "side": "SELL", // "positionSide": "BOTH", // "stopPrice": "0", // "workingType": "CONTRACT_PRICE", // "priceProtect": false, // "origType": "MARKET", // "time": "1636061952660", // "updateTime": "1636061952660" // } // market := GetArg(optionalArgs, 0, nil) _ = market var status interface{} = this.ParseOrderStatus(this.SafeString(order, "status")) var marketId interface{} = this.SafeString(order, "symbol") var symbol interface{} = this.SafeSymbol(marketId, market) var filled interface{} = this.SafeString(order, "executedQty", "0") var timestamp interface{} = this.SafeInteger(order, "createTime") var average interface{} = this.SafeString(order, "avgPrice") var price interface{} = this.SafeString2(order, "price", "executedPrice") var amount interface{} = this.SafeString(order, "origQty") // - Spot/Margin market: cummulativeQuoteQty // Note this is not the actual cost, since Binance futures uses leverage to calculate margins. var cost interface{} = this.SafeStringN(order, []interface{}{"cummulativeQuoteQty", "cumQuote", "executedQuoteQty", "cumBase"}) var id interface{} = this.SafeString(order, "orderId") var typeVar interface{} = this.ParseOrderType(this.SafeStringLower(order, "type")) var side interface{} = this.SafeStringLower(order, "side") if IsTrue(IsEqual(side, "0")) { side = "buy" } else if IsTrue(IsEqual(side, "1")) { side = "sell" } var fills interface{} = this.SafeValue(order, "fills", []interface{}{}) var clientOrderId interface{} = this.SafeString2(order, "clientOrderId", "clientId") var timeInForce interface{} = this.SafeString(order, "timeInForce") if IsTrue(IsEqual(timeInForce, "GTX")) { // GTX means "Good Till Crossing" and is an equivalent way of saying Post Only timeInForce = "PO" } var postOnly interface{} = IsTrue((IsEqual(typeVar, "limit_maker"))) || IsTrue((IsEqual(timeInForce, "PO"))) return this.SafeOrder(map[string]interface{} { "info": order, "id": id, "clientOrderId": clientOrderId, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "lastTradeTimestamp": nil, "symbol": symbol, "type": typeVar, "timeInForce": timeInForce, "postOnly": postOnly, "reduceOnly": this.SafeValue(order, "reduceOnly"), "side": side, "price": price, "triggerPrice": this.ParseNumber(this.OmitZero(this.SafeString(order, "stopPrice"))), "amount": amount, "cost": cost, "average": average, "filled": filled, "remaining": nil, "status": status, "fee": nil, "trades": fills, }, market) } func (this *tokocrypto) ParseOrderType(status interface{}) interface{} { var statuses interface{} = map[string]interface{} { "2": "market", "1": "limit", "4": "limit", "7": "limit", } return this.SafeString(statuses, status, status) } /** * @method * @name tokocrypto#createOrder * @description create a trade order * @see https://www.tokocrypto.com/apidocs/#new-order--signed * @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] the price at which a trigger order would be triggered * @param {float} [params.cost] for spot market buy orders, 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 *tokocrypto) 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 retRes16968 := (<-this.LoadMarkets()) PanicOnError(retRes16968) var market interface{} = this.Market(symbol) var clientOrderId interface{} = this.SafeString2(params, "clientOrderId", "clientId") var postOnly interface{} = this.SafeBool(params, "postOnly", false) // only supported for spot/margin api if IsTrue(postOnly) { typeVar = "LIMIT_MAKER" } params = this.Omit(params, []interface{}{"clientId", "clientOrderId"}) var initialUppercaseType interface{} = ToUpper(typeVar) var uppercaseType interface{} = initialUppercaseType var triggerPrice interface{} = this.SafeValue2(params, "triggerPrice", "stopPrice") if IsTrue(!IsEqual(triggerPrice, nil)) { params = this.Omit(params, []interface{}{"triggerPrice", "stopPrice"}) if IsTrue(IsEqual(uppercaseType, "MARKET")) { uppercaseType = "STOP_LOSS" } else if IsTrue(IsEqual(uppercaseType, "LIMIT")) { uppercaseType = "STOP_LOSS_LIMIT" } } var validOrderTypes interface{} = this.SafeValue(GetValue(market, "info"), "orderTypes") if !IsTrue(this.InArray(uppercaseType, validOrderTypes)) { if IsTrue(!IsEqual(initialUppercaseType, uppercaseType)) { panic(InvalidOrder(Add(Add(Add(Add(Add(this.Id, " triggerPrice parameter is not allowed for "), symbol), " "), typeVar), " orders"))) } else { panic(InvalidOrder(Add(Add(Add(Add(Add(this.Id, " "), typeVar), " is not a valid order type for the "), symbol), " market"))) } } var reverseOrderTypeMapping interface{} = map[string]interface{} { "LIMIT": 1, "MARKET": 2, "STOP_LOSS": 3, "STOP_LOSS_LIMIT": 4, "TAKE_PROFIT": 5, "TAKE_PROFIT_LIMIT": 6, "LIMIT_MAKER": 7, } var request interface{} = map[string]interface{} { "symbol": Add(Add(GetValue(market, "baseId"), "_"), GetValue(market, "quoteId")), "type": this.SafeString(reverseOrderTypeMapping, uppercaseType), } if IsTrue(IsEqual(side, "buy")) { AddElementToObject(request, "side", 0) } else if IsTrue(IsEqual(side, "sell")) { AddElementToObject(request, "side", 1) } if IsTrue(IsEqual(clientOrderId, nil)) { var broker interface{} = this.SafeValue(this.Options, "broker") if IsTrue(!IsEqual(broker, nil)) { var brokerId interface{} = this.SafeString(broker, "marketType") if IsTrue(!IsEqual(brokerId, nil)) { AddElementToObject(request, "clientId", Add(brokerId, this.Uuid22())) } } } else { AddElementToObject(request, "clientId", clientOrderId) } // additional required fields depending on the order type var priceIsRequired interface{} = false var triggerPriceIsRequired interface{} = false var quantityIsRequired interface{} = false // // spot/margin // // LIMIT timeInForce, quantity, price // MARKET quantity or quoteOrderQty // STOP_LOSS quantity, stopPrice // STOP_LOSS_LIMIT timeInForce, quantity, price, stopPrice // TAKE_PROFIT quantity, stopPrice // TAKE_PROFIT_LIMIT timeInForce, quantity, price, stopPrice // LIMIT_MAKER quantity, price // if IsTrue(IsEqual(uppercaseType, "MARKET")) { if IsTrue(IsEqual(side, "buy")) { var precision interface{} = GetValue(GetValue(market, "precision"), "price") var quoteAmount interface{} = nil var createMarketBuyOrderRequiresPrice interface{} = true createMarketBuyOrderRequiresPriceparamsVariable := this.HandleOptionAndParams(params, "createOrder", "createMarketBuyOrderRequiresPrice", true); createMarketBuyOrderRequiresPrice = GetValue(createMarketBuyOrderRequiresPriceparamsVariable,0); params = GetValue(createMarketBuyOrderRequiresPriceparamsVariable,1) var cost interface{} = this.SafeNumber2(params, "cost", "quoteOrderQty") params = this.Omit(params, []interface{}{"cost", "quoteOrderQty"}) if IsTrue(!IsEqual(cost, nil)) { quoteAmount = cost } else if IsTrue(createMarketBuyOrderRequiresPrice) { if IsTrue(IsEqual(price, nil)) { panic(InvalidOrder(Add(this.Id, " createOrder() requires the price argument for market buy orders to calculate the total cost to spend (amount * price), alternatively set the createMarketBuyOrderRequiresPrice option or param to false and pass the cost to spend (quote quantity) in the amount argument"))) } else { var amountString interface{} = this.NumberToString(amount) var priceString interface{} = this.NumberToString(price) quoteAmount = Precise.StringMul(amountString, priceString) } } else { quoteAmount = amount } AddElementToObject(request, "quoteOrderQty", this.DecimalToPrecision(quoteAmount, TRUNCATE, precision, this.PrecisionMode)) } else { quantityIsRequired = true } } else if IsTrue(IsEqual(uppercaseType, "LIMIT")) { priceIsRequired = true quantityIsRequired = true } else if IsTrue(IsTrue((IsEqual(uppercaseType, "STOP_LOSS"))) || IsTrue((IsEqual(uppercaseType, "TAKE_PROFIT")))) { triggerPriceIsRequired = true quantityIsRequired = true if IsTrue(IsTrue(GetValue(market, "linear")) || IsTrue(GetValue(market, "inverse"))) { priceIsRequired = true } } else if IsTrue(IsTrue((IsEqual(uppercaseType, "STOP_LOSS_LIMIT"))) || IsTrue((IsEqual(uppercaseType, "TAKE_PROFIT_LIMIT")))) { quantityIsRequired = true triggerPriceIsRequired = true priceIsRequired = true } else if IsTrue(IsEqual(uppercaseType, "LIMIT_MAKER")) { priceIsRequired = true quantityIsRequired = true } if IsTrue(quantityIsRequired) { AddElementToObject(request, "quantity", this.AmountToPrecision(symbol, amount)) } if IsTrue(priceIsRequired) { if IsTrue(IsEqual(price, nil)) { panic(InvalidOrder(Add(Add(Add(this.Id, " createOrder() requires a price argument for a "), typeVar), " order"))) } AddElementToObject(request, "price", this.PriceToPrecision(symbol, price)) } if IsTrue(triggerPriceIsRequired) { if IsTrue(IsEqual(triggerPrice, nil)) { panic(InvalidOrder(Add(Add(Add(this.Id, " createOrder() requires a triggerPrice extra param for a "), typeVar), " order"))) } else { AddElementToObject(request, "stopPrice", this.PriceToPrecision(symbol, triggerPrice)) } } response:= (<-this.PrivatePostOpenV1Orders(this.Extend(request, params))) PanicOnError(response) // // { // "code": 0, // "msg": "Success", // "data": { // "orderId": 145264846, // "bOrderListId": 0, // "clientId": "4ee2ab5e55e74b358eaf98079c670d17", // "bOrderId": 35247499, // "symbol": "USDT_BIDR", // "symbolType": 1, // "side": 0, // "type": 1, // "price": "11915", // "origQty": "2", // "origQuoteQty": "23830.00", // "executedQty": "0.00000000", // "executedPrice": "0", // "executedQuoteQty": "0.00", // "timeInForce": 1, // "stopPrice": 0, // "icebergQty": "0", // "status": 0, // "createTime": 1662710994848 // }, // "timestamp": 1662710994975 // } // var rawOrder interface{} = this.SafeDict(response, "data", map[string]interface{} {}) ch <- this.ParseOrder(rawOrder, market) return nil }() return ch } /** * @method * @name tokocrypto#fetchOrder * @see https://www.tokocrypto.com/apidocs/#query-order-signed * @description fetches information on an order made by the user * @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 *tokocrypto) 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 var request interface{} = map[string]interface{} { "orderId": id, } response:= (<-this.PrivateGetOpenV1Orders(this.Extend(request, params))) PanicOnError(response) // // { // "code": 0, // "msg": "Success", // "data": { // "list": [{ // "orderId": "145221985", // "clientId": "201515331fd64d03aedbe687a38152e3", // "bOrderId": "35239632", // "bOrderListId": "0", // "symbol": "USDT_BIDR", // "symbolType": 1, // "side": 0, // "type": 1, // "price": "11907", // "origQty": "2", // "origQuoteQty": "23814", // "executedQty": "0", // "executedPrice": "0", // "executedQuoteQty": "0", // "timeInForce": 1, // "stopPrice": "0", // "icebergQty": "0", // "status": 0, // "createTime": 1662699360000 // }] // }, // "timestamp": 1662710056523 // } // var data interface{} = this.SafeValue(response, "data", map[string]interface{} {}) var list interface{} = this.SafeValue(data, "list", []interface{}{}) var rawOrder interface{} = this.SafeDict(list, 0, map[string]interface{} {}) ch <- this.ParseOrder(rawOrder) return nil }() return ch } /** * @method * @name tokocrypto#fetchOrders * @see https://www.tokocrypto.com/apidocs/#all-orders-signed * @description fetches information on multiple orders made by the user * @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 *tokocrypto) FetchOrders(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params if IsTrue(IsEqual(symbol, nil)) { panic(ArgumentsRequired(Add(this.Id, " fetchOrders() requires a symbol argument"))) } retRes19258 := (<-this.LoadMarkets()) PanicOnError(retRes19258) var market interface{} = this.Market(symbol) 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) } response:= (<-this.PrivateGetOpenV1Orders(this.Extend(request, params))) PanicOnError(response) // // { // "code": 0, // "msg": "success", // "data": { // "list": [ // { // "orderId": "4", // order id // "bOrderId": "100001", // binance order id // "bOrderListId": -1, // Unless part of an OCO, the value will always be -1. // "clientId": "1aa4f99ad7bc4fab903395afd25d0597", // client custom order id // "symbol": "ADA_USDT", // "symbolType": 1, // "side": 1, // "type": 1, // "price": "0.1", // "origQty": "10", // "origQuoteQty": "1", // "executedQty": "0", // "executedPrice": "0", // "executedQuoteQty": "0", // "timeInForce": 1, // "stopPrice": "0.0000000000000000", // "icebergQty": "0.0000000000000000", // "status": 0, // "isWorking": 0, // "createTime": 1572692016811 // } // ] // }, // "timestamp": 1572860756458 // } // var data interface{} = this.SafeValue(response, "data", map[string]interface{} {}) var orders interface{} = this.SafeList(data, "list", []interface{}{}) ch <- this.ParseOrders(orders, market, since, limit) return nil }() return ch } /** * @method * @name tokocrypto#fetchOpenOrders * @see https://www.tokocrypto.com/apidocs/#all-orders-signed * @description fetch all unfilled currently open orders * @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 orders 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 *tokocrypto) 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 var request interface{} = map[string]interface{} { "type": 1, } // -1 = all, 1 = open, 2 = closed retRes199515 := (<-this.FetchOrders(symbol, since, limit, this.Extend(request, params))) PanicOnError(retRes199515) ch <- retRes199515 return nil }() return ch } /** * @method * @name tokocrypto#fetchClosedOrders * @see https://www.tokocrypto.com/apidocs/#all-orders-signed * @description fetches information on multiple closed orders made by the user * @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 *tokocrypto) 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 var request interface{} = map[string]interface{} { "type": 2, } // -1 = all, 1 = open, 2 = closed retRes201115 := (<-this.FetchOrders(symbol, since, limit, this.Extend(request, params))) PanicOnError(retRes201115) ch <- retRes201115 return nil }() return ch } /** * @method * @name tokocrypto#cancelOrder * @see https://www.tokocrypto.com/apidocs/#cancel-order-signed * @description cancels an open order * @param {string} id order id * @param {string} symbol unified symbol of the market the order was made in * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *tokocrypto) 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 var request interface{} = map[string]interface{} { "orderId": id, } response:= (<-this.PrivatePostOpenV1OrdersCancel(this.Extend(request, params))) PanicOnError(response) // // { // "code": 0, // "msg": "Success", // "data": { // "orderId": "145221985", // "bOrderListId": "0", // "clientId": "201515331fd64d03aedbe687a38152e3", // "bOrderId": "35239632", // "symbol": "USDT_BIDR", // "symbolType": 1, // "type": 1, // "side": 0, // "price": "11907.0000000000000000", // "origQty": "2.0000000000000000", // "origQuoteQty": "23814.0000000000000000", // "executedPrice": "0.0000000000000000", // "executedQty": "0.00000000", // "executedQuoteQty": "0.00", // "timeInForce": 1, // "stopPrice": "0.0000000000000000", // "icebergQty": "0.0000000000000000", // "status": 3 // }, // "timestamp": 1662710683634 // } // var rawOrder interface{} = this.SafeDict(response, "data", map[string]interface{} {}) ch <- this.ParseOrder(rawOrder) return nil }() return ch } /** * @method * @name tokocrypto#fetchMyTrades * @see https://www.tokocrypto.com/apidocs/#account-trade-list-signed * @description fetch all trades made by the user * @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 *tokocrypto) 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 if IsTrue(IsEqual(symbol, nil)) { panic(ArgumentsRequired(Add(this.Id, " fetchMyTrades() requires a symbol argument"))) } retRes20758 := (<-this.LoadMarkets()) PanicOnError(retRes20758) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "symbol": GetValue(market, "id"), } var endTime interface{} = this.SafeInteger2(params, "until", "endTime") if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "startTime", since) } if IsTrue(!IsEqual(endTime, nil)) { AddElementToObject(request, "endTime", endTime) params = this.Omit(params, []interface{}{"endTime", "until"}) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) } response:= (<-this.PrivateGetOpenV1OrdersTrades(this.Extend(request, params))) PanicOnError(response) // // { // "code": 0, // "msg": "success", // "data": { // "list": [ // { // "tradeId": "3", // "orderId": "2", // "symbol": "ADA_USDT", // "price": "0.04398", // "qty": "250", // "quoteQty": "10.995", // "commission": "0.25", // "commissionAsset": "ADA", // "isBuyer": 1, // "isMaker": 0, // "isBestMatch": 1, // "time": "1572920872276" // } // ] // }, // "timestamp": 1573723498893 // } // var data interface{} = this.SafeValue(response, "data", map[string]interface{} {}) var trades interface{} = this.SafeList(data, "list", []interface{}{}) ch <- this.ParseTrades(trades, market, since, limit) return nil }() return ch } /** * @method * @name tokocrypto#fetchDepositAddress * @description fetch the deposit address for a currency associated with this account * @see https://www.tokocrypto.com/apidocs/#deposit-address-signed * @param {string} code unified currency code * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure} */ func (this *tokocrypto) FetchDepositAddress(code interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params retRes21328 := (<-this.LoadMarkets()) PanicOnError(retRes21328) var currency interface{} = this.Currency(code) var request interface{} = map[string]interface{} { "asset": GetValue(currency, "id"), } var networks interface{} = this.SafeValue(this.Options, "networks", map[string]interface{} {}) var network interface{} = this.SafeStringUpper(params, "network") // this line allows the user to specify either ERC20 or ETH network = this.SafeString(networks, network, network) // handle ERC20>ETH alias if IsTrue(!IsEqual(network, nil)) { AddElementToObject(request, "network", network) params = this.Omit(params, "network") } // has support for the 'network' parameter // https://binance-docs.github.io/apidocs/spot/en/#deposit-address-supporting-network-user_data response:= (<-this.PrivateGetOpenV1DepositsAddress(this.Extend(request, params))) PanicOnError(response) // // { // "code":0, // "msg":"Success", // "data":{ // "uid":"182395", // "asset":"USDT", // "network":"ETH", // "address":"0x101a925704f6ff13295ab8dd7a60988d116aaedf", // "addressTag":"", // "status":1 // }, // "timestamp":1660685915746 // } // var data interface{} = this.SafeValue(response, "data", map[string]interface{} {}) var address interface{} = this.SafeString(data, "address") var tag interface{} = this.SafeString(data, "addressTag", "") if IsTrue(IsEqual(GetLength(tag), 0)) { tag = nil } this.CheckAddress(address) ch <- map[string]interface{} { "info": response, "currency": code, "network": this.SafeString(data, "network"), "address": address, "tag": tag, } return nil }() return ch } /** * @method * @name tokocrypto#fetchDeposits * @see https://www.tokocrypto.com/apidocs/#deposit-history-signed * @description fetch all deposits made to an account * @param {string} code unified currency code * @param {int} [since] the earliest time in ms to fetch deposits for * @param {int} [limit] the maximum number of deposits structures to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {int} [params.until] the latest time in ms to fetch deposits for * @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure} */ func (this *tokocrypto) 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 retRes21928 := (<-this.LoadMarkets()) PanicOnError(retRes21928) var currency interface{} = nil var request interface{} = map[string]interface{} {} var until interface{} = this.SafeInteger(params, "until") if IsTrue(!IsEqual(code, nil)) { currency = this.Currency(code) AddElementToObject(request, "coin", GetValue(currency, "id")) } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "startTime", since) // max 3 months range https://github.com/ccxt/ccxt/issues/6495 var endTime interface{} = this.Sum(since, 7776000000) if IsTrue(!IsEqual(until, nil)) { endTime = mathMin(endTime, until) } AddElementToObject(request, "endTime", endTime) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) } response:= (<-this.PrivateGetOpenV1Deposits(this.Extend(request, params))) PanicOnError(response) // // { // "code":0, // "msg":"Success", // "data":{ // "list":[ // { // "id":5167969, // "asset":"BIDR", // "network":"BSC", // "address":"0x101a925704f6ff13295ab8dd7a60988d116aaedf", // "addressTag":"", // "txId":"113409337867", // "amount":"15000", // "transferType":1, // "status":1, // "insertTime":"1659429390000" // }, // ] // }, // "timestamp":1659758865998 // } // var data interface{} = this.SafeValue(response, "data", map[string]interface{} {}) var deposits interface{} = this.SafeList(data, "list", []interface{}{}) ch <- this.ParseTransactions(deposits, currency, since, limit) return nil }() return ch } /** * @method * @name tokocrypto#fetchWithdrawals * @see https://www.tokocrypto.com/apidocs/#withdraw-signed * @description fetch all withdrawals made from an account * @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 *tokocrypto) 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 retRes22538 := (<-this.LoadMarkets()) PanicOnError(retRes22538) var request interface{} = map[string]interface{} {} var currency interface{} = nil if IsTrue(!IsEqual(code, nil)) { currency = this.Currency(code) AddElementToObject(request, "coin", GetValue(currency, "id")) } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "startTime", since) // max 3 months range https://github.com/ccxt/ccxt/issues/6495 AddElementToObject(request, "endTime", this.Sum(since, 7776000000)) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) } response:= (<-this.PrivateGetOpenV1Withdraws(this.Extend(request, params))) PanicOnError(response) // // { // "code":0, // "msg":"Success", // "data":{ // "list":[ // { // "id":4245859, // "clientId":"198", // "asset":"BIDR", // "network":"BSC", // "address":"0xff1c75149cc492e7d5566145b859fcafc900b6e9", // "addressTag":"", // "amount":"10000", // "fee":"0", // "txId":"113501794501", // "transferType":1, // "status":10, // "createTime":1659521314413 // } // ] // }, // "timestamp":1659759062187 // } // var data interface{} = this.SafeValue(response, "data", map[string]interface{} {}) var withdrawals interface{} = this.SafeList(data, "list", []interface{}{}) ch <- this.ParseTransactions(withdrawals, currency, since, limit) return nil }() return ch } func (this *tokocrypto) 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", "1": "canceled", "2": "pending", "3": "failed", "4": "pending", "5": "failed", "10": "ok", }, } var statuses interface{} = this.SafeValue(statusesByType, typeVar, map[string]interface{} {}) return this.SafeString(statuses, status, status) } func (this *tokocrypto) ParseTransaction(transaction interface{}, optionalArgs ...interface{}) interface{} { // // fetchDeposits // // { // "id": 5167969, // "asset": "BIDR", // "network": "BSC", // "address": "0x101a925704f6ff13295ab8dd7a60988d116aaedf", // "addressTag": "", // "txId": "113409337867", // "amount": "15000", // "transferType": 1, // "status": 1, // "insertTime": "1659429390000" // } // // fetchWithdrawals // // { // "id": 4245859, // "clientId": "198", // "asset": "BIDR", // "network": "BSC", // "address": "0xff1c75149cc492e7d5566145b859fcafc900b6e9", // "addressTag": "", // "amount": "10000", // "fee": "0", // "txId": "113501794501", // "transferType": 1, // "status": 10, // "createTime": 1659521314413 // } // // withdraw // // { // "code": 0, // "msg": "成功", // "data": { // "withdrawId":"12" // }, // "timestamp": 1571745049095 // } // currency := GetArg(optionalArgs, 0, nil) _ = currency var address interface{} = this.SafeString(transaction, "address") var tag interface{} = this.SafeString(transaction, "addressTag") // set but unused if IsTrue(!IsEqual(tag, nil)) { if IsTrue(IsLessThan(GetLength(tag), 1)) { tag = nil } } var txid interface{} = this.SafeString(transaction, "txId") if IsTrue(IsTrue((!IsEqual(txid, nil))) && IsTrue((IsGreaterThanOrEqual(GetIndexOf(txid, "Internal transfer "), 0)))) { txid = Slice(txid, 18, nil) } var currencyId interface{} = this.SafeString2(transaction, "coin", "fiatCurrency") var code interface{} = this.SafeCurrencyCode(currencyId, currency) var timestamp interface{} = nil var insertTime interface{} = this.SafeInteger(transaction, "insertTime") var createTime interface{} = this.SafeInteger2(transaction, "createTime", "timestamp") var typeVar interface{} = this.SafeString(transaction, "type") if IsTrue(IsEqual(typeVar, nil)) { if IsTrue(IsTrue((!IsEqual(insertTime, nil))) && IsTrue((IsEqual(createTime, nil)))) { typeVar = "deposit" timestamp = insertTime } else if IsTrue(IsTrue((IsEqual(insertTime, nil))) && IsTrue((!IsEqual(createTime, nil)))) { typeVar = "withdrawal" timestamp = createTime } } var feeCost interface{} = this.SafeNumber2(transaction, "transactionFee", "totalFee") var fee interface{} = map[string]interface{} { "currency": nil, "cost": nil, "rate": nil, } if IsTrue(!IsEqual(feeCost, nil)) { AddElementToObject(fee, "currency", code) AddElementToObject(fee, "cost", feeCost) } var internalRaw interface{} = this.SafeInteger(transaction, "transferType") var internal interface{} = false if IsTrue(!IsEqual(internalRaw, nil)) { internal = true } var id interface{} = this.SafeString(transaction, "id") if IsTrue(IsEqual(id, nil)) { var data interface{} = this.SafeValue(transaction, "data", map[string]interface{} {}) id = this.SafeString(data, "withdrawId") typeVar = "withdrawal" } return map[string]interface{} { "info": transaction, "id": id, "txid": txid, "type": typeVar, "currency": code, "network": this.SafeString(transaction, "network"), "amount": this.SafeNumber(transaction, "amount"), "status": this.ParseTransactionStatusByType(this.SafeString(transaction, "status"), typeVar), "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "address": address, "addressFrom": nil, "addressTo": address, "tag": tag, "tagFrom": nil, "tagTo": tag, "updated": this.SafeInteger2(transaction, "successTime", "updateTime"), "comment": nil, "internal": internal, "fee": fee, } } /** * @method * @name tokocrypto#withdraw * @see https://www.tokocrypto.com/apidocs/#withdraw-signed * @description make a withdrawal * @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 *tokocrypto) 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) retRes24498 := (<-this.LoadMarkets()) PanicOnError(retRes24498) this.CheckAddress(address) var currency interface{} = this.Currency(code) var request interface{} = map[string]interface{} { "asset": GetValue(currency, "id"), "address": address, "amount": this.NumberToString(amount), } if IsTrue(!IsEqual(tag, nil)) { AddElementToObject(request, "addressTag", tag) } networkCodequeryVariable := this.HandleNetworkCodeAndParams(params); networkCode := GetValue(networkCodequeryVariable,0); query := GetValue(networkCodequeryVariable,1) var networkId interface{} = this.NetworkCodeToId(networkCode) if IsTrue(!IsEqual(networkId, nil)) { AddElementToObject(request, "network", ToUpper(networkId)) } response:= (<-this.PrivatePostOpenV1Withdraws(this.Extend(request, query))) PanicOnError(response) // // { // "code": 0, // "msg": "成功", // "data": { // "withdrawId":"12" // }, // "timestamp": 1571745049095 // } // ch <- this.ParseTransaction(response, currency) return nil }() return ch } func (this *tokocrypto) 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 if !IsTrue((InOp(GetValue(GetValue(this.Urls, "api"), "rest"), api))) { panic(NotSupported(Add(Add(Add(this.Id, " does not have a testnet/sandbox URL for "), api), " endpoints"))) } var url interface{} = GetValue(GetValue(GetValue(this.Urls, "api"), "rest"), api) url = Add(url, Add("/", path)) if IsTrue(IsEqual(api, "wapi")) { url = Add(url, ".html") } var userDataStream interface{} = IsTrue((IsEqual(path, "userDataStream"))) || IsTrue((IsEqual(path, "listenKey"))) if IsTrue(userDataStream) { if IsTrue(this.ApiKey) { // v1 special case for userDataStream headers = map[string]interface{} { "X-MBX-APIKEY": this.ApiKey, "Content-Type": "application/x-www-form-urlencoded", } if IsTrue(!IsEqual(method, "GET")) { body = this.Urlencode(params) } } else { panic(AuthenticationError(Add(this.Id, " userDataStream endpoint requires `apiKey` credential"))) } } else if IsTrue(IsTrue(IsTrue(IsTrue(IsTrue(IsTrue(IsTrue(IsTrue((IsEqual(api, "private"))) || IsTrue((IsTrue(IsEqual(api, "sapi")) && IsTrue(!IsEqual(path, "system/status"))))) || IsTrue((IsEqual(api, "sapiV3")))) || IsTrue((IsTrue(IsEqual(api, "wapi")) && IsTrue(!IsEqual(path, "systemStatus"))))) || IsTrue((IsEqual(api, "dapiPrivate")))) || IsTrue((IsEqual(api, "dapiPrivateV2")))) || IsTrue((IsEqual(api, "fapiPrivate")))) || IsTrue((IsEqual(api, "fapiPrivateV2")))) { this.CheckRequiredCredentials() var query interface{} = nil var defaultRecvWindow interface{} = this.SafeInteger(this.Options, "recvWindow") var extendedParams interface{} = this.Extend(map[string]interface{} { "timestamp": this.Nonce(), }, params) if IsTrue(!IsEqual(defaultRecvWindow, nil)) { AddElementToObject(extendedParams, "recvWindow", defaultRecvWindow) } var recvWindow interface{} = this.SafeInteger(params, "recvWindow") if IsTrue(!IsEqual(recvWindow, nil)) { AddElementToObject(extendedParams, "recvWindow", recvWindow) } if IsTrue(IsTrue((IsEqual(api, "sapi"))) && IsTrue((IsEqual(path, "asset/dust")))) { query = this.UrlencodeWithArrayRepeat(extendedParams) } else if IsTrue(IsTrue(IsTrue(IsTrue((IsEqual(path, "batchOrders"))) || IsTrue((IsGreaterThanOrEqual(GetIndexOf(path, "sub-account"), 0)))) || IsTrue((IsEqual(path, "capital/withdraw/apply")))) || IsTrue((IsGreaterThanOrEqual(GetIndexOf(path, "staking"), 0)))) { query = this.Rawencode(extendedParams) } else { query = this.Urlencode(extendedParams) } 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(IsTrue((IsEqual(method, "GET"))) || IsTrue((IsEqual(method, "DELETE")))) || IsTrue((IsEqual(api, "wapi")))) { url = Add(url, Add("?", query)) } else { body = query AddElementToObject(headers, "Content-Type", "application/x-www-form-urlencoded") } } 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 *tokocrypto) 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 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 *tokocrypto) (ret_ interface{}) { defer func() { if e := recover(); e != nil { if e == "break" { return } ret_ = func(this *tokocrypto) 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, " "), body))) } var feedback interface{} = Add(Add(this.Id, " "), body) if IsTrue(IsEqual(message, "No need to change margin type.")) { panic(MarginModeAlreadySet(feedback)) } 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 *tokocrypto) 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, "noCoin"))) && !IsTrue((InOp(params, "coin")))) { return GetValue(config, "noCoin") } else if IsTrue(IsTrue((InOp(config, "noSymbol"))) && !IsTrue((InOp(params, "symbol")))) { return GetValue(config, "noSymbol") } else if IsTrue(IsTrue((InOp(config, "noPoolId"))) && !IsTrue((InOp(params, "poolId")))) { return GetValue(config, "noPoolId") } 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.SafeInteger(config, "cost", 1) } func (this *tokocrypto) Init(userConfig map[string]interface{}) { this.Exchange = Exchange{} this.Exchange.InitParent(userConfig, this.Describe().(map[string]interface{}), this) this.Exchange.DerivedExchange = this }