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 bitopro struct { Exchange } func NewBitoproCore() bitopro { p := bitopro{} setDefaults(&p) return p } func (this *bitopro) Describe() interface{} { return this.DeepExtend(this.Exchange.Describe(), map[string]interface{} { "id": "bitopro", "name": "BitoPro", "countries": []interface{}{"TW"}, "version": "v3", "rateLimit": 100, "pro": true, "has": map[string]interface{} { "CORS": nil, "spot": true, "margin": false, "swap": false, "future": false, "option": false, "cancelAllOrders": true, "cancelOrder": true, "cancelOrders": true, "closeAllPositions": false, "closePosition": false, "createOrder": true, "createStopOrder": true, "createTriggerOrder": true, "editOrder": false, "fetchBalance": true, "fetchBorrowRateHistories": false, "fetchBorrowRateHistory": false, "fetchClosedOrders": true, "fetchCrossBorrowRate": false, "fetchCrossBorrowRates": false, "fetchCurrencies": true, "fetchDepositAddress": false, "fetchDeposits": true, "fetchDepositsWithdrawals": false, "fetchDepositWithdrawFee": "emulated", "fetchDepositWithdrawFees": true, "fetchFundingHistory": false, "fetchFundingRate": false, "fetchFundingRateHistory": false, "fetchFundingRates": false, "fetchIndexOHLCV": false, "fetchIsolatedBorrowRate": false, "fetchIsolatedBorrowRates": false, "fetchMarginMode": false, "fetchMarkets": true, "fetchMarkOHLCV": false, "fetchMyTrades": true, "fetchOHLCV": true, "fetchOpenInterestHistory": false, "fetchOpenOrders": true, "fetchOrder": true, "fetchOrderBook": true, "fetchOrders": false, "fetchOrderTrades": false, "fetchPosition": false, "fetchPositionHistory": false, "fetchPositionMode": false, "fetchPositions": false, "fetchPositionsForSymbol": false, "fetchPositionsHistory": false, "fetchPositionsRisk": false, "fetchPremiumIndexOHLCV": false, "fetchTicker": true, "fetchTickers": true, "fetchTime": false, "fetchTrades": true, "fetchTradingFee": false, "fetchTradingFees": true, "fetchTransactionFees": false, "fetchTransactions": false, "fetchTransfer": false, "fetchTransfers": false, "fetchWithdrawal": true, "fetchWithdrawals": true, "setLeverage": false, "setMarginMode": false, "transfer": false, "withdraw": true, }, "timeframes": map[string]interface{} { "1m": "1m", "5m": "5m", "15m": "15m", "30m": "30m", "1h": "1h", "3h": "3h", "6h": "6h", "12h": "12h", "1d": "1d", "1w": "1w", "1M": "1M", }, "urls": map[string]interface{} { "logo": "https://github.com/user-attachments/assets/affc6337-b95a-44bf-aacd-04f9722364f6", "api": map[string]interface{} { "rest": "https://api.bitopro.com/v3", }, "www": "https://www.bitopro.com", "doc": []interface{}{"https://github.com/bitoex/bitopro-offical-api-docs/blob/master/v3-1/rest-1/rest.md"}, "fees": "https://www.bitopro.com/fees", }, "requiredCredentials": map[string]interface{} { "apiKey": true, "secret": true, }, "api": map[string]interface{} { "public": map[string]interface{} { "get": map[string]interface{} { "order-book/{pair}": 1, "tickers": 1, "tickers/{pair}": 1, "trades/{pair}": 1, "provisioning/currencies": 1, "provisioning/trading-pairs": 1, "provisioning/limitations-and-fees": 1, "trading-history/{pair}": 1, "price/otc/{currency}": 1, }, }, "private": map[string]interface{} { "get": map[string]interface{} { "accounts/balance": 1, "orders/history": 1, "orders/all/{pair}": 1, "orders/trades/{pair}": 1, "orders/{pair}/{orderId}": 1, "wallet/withdraw/{currency}/{serial}": 1, "wallet/withdraw/{currency}/id/{id}": 1, "wallet/depositHistory/{currency}": 1, "wallet/withdrawHistory/{currency}": 1, "orders/open": 1, }, "post": map[string]interface{} { "orders/{pair}": Divide(1, 2), "orders/batch": Divide(20, 3), "wallet/withdraw/{currency}": 10, }, "put": map[string]interface{} { "orders": 5, }, "delete": map[string]interface{} { "orders/{pair}/{id}": Divide(2, 3), "orders/all": 5, "orders/{pair}": 5, }, }, }, "fees": map[string]interface{} { "trading": map[string]interface{} { "tierBased": true, "percentage": true, "maker": this.ParseNumber("0.001"), "taker": this.ParseNumber("0.002"), "tiers": map[string]interface{} { "taker": []interface{}{[]interface{}{this.ParseNumber("0"), this.ParseNumber("0.002")}, []interface{}{this.ParseNumber("3000000"), this.ParseNumber("0.00194")}, []interface{}{this.ParseNumber("5000000"), this.ParseNumber("0.0015")}, []interface{}{this.ParseNumber("30000000"), this.ParseNumber("0.0014")}, []interface{}{this.ParseNumber("300000000"), this.ParseNumber("0.0013")}, []interface{}{this.ParseNumber("550000000"), this.ParseNumber("0.0012")}, []interface{}{this.ParseNumber("1300000000"), this.ParseNumber("0.0011")}}, "maker": []interface{}{[]interface{}{this.ParseNumber("0"), this.ParseNumber("0.001")}, []interface{}{this.ParseNumber("3000000"), this.ParseNumber("0.00097")}, []interface{}{this.ParseNumber("5000000"), this.ParseNumber("0.0007")}, []interface{}{this.ParseNumber("30000000"), this.ParseNumber("0.0006")}, []interface{}{this.ParseNumber("300000000"), this.ParseNumber("0.0005")}, []interface{}{this.ParseNumber("550000000"), this.ParseNumber("0.0004")}, []interface{}{this.ParseNumber("1300000000"), this.ParseNumber("0.0003")}}, }, }, }, "options": map[string]interface{} { "networks": map[string]interface{} { "ERC20": "ERC20", "ETH": "ERC20", "TRX": "TRX", "TRC20": "TRX", "BEP20": "BSC", "BSC": "BSC", }, }, "features": map[string]interface{} { "spot": map[string]interface{} { "sandbox": false, "createOrder": map[string]interface{} { "marginMode": false, "triggerPrice": true, "triggerPriceType": nil, "triggerDirection": true, "stopLossPrice": false, "takeProfitPrice": false, "attachedStopLossTakeProfit": nil, "timeInForce": map[string]interface{} { "IOC": false, "FOK": false, "PO": true, "GTD": false, }, "hedged": false, "trailing": false, "leverage": false, "marketBuyRequiresPrice": false, "marketBuyByCost": false, "selfTradePrevention": false, "iceberg": false, }, "createOrders": nil, "fetchMyTrades": map[string]interface{} { "marginMode": false, "limit": 1000, "daysBack": 100000, "untilDays": 100000, "symbolRequired": true, }, "fetchOrder": map[string]interface{} { "marginMode": false, "trigger": false, "trailing": false, "symbolRequired": true, }, "fetchOpenOrders": map[string]interface{} { "marginMode": false, "limit": nil, "trigger": false, "trailing": false, "symbolRequired": false, }, "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": 10000, "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, }, }, "precisionMode": TICK_SIZE, "exceptions": map[string]interface{} { "exact": map[string]interface{} { "Unsupported currency.": BadRequest, "Unsupported order type": BadRequest, "Invalid body": BadRequest, "Invalid Signature": AuthenticationError, "Address not in whitelist.": BadRequest, }, "broad": map[string]interface{} { "Invalid amount": InvalidOrder, "Balance for ": InsufficientFunds, "Invalid ": BadRequest, "Wrong parameter": BadRequest, }, }, "commonCurrencies": map[string]interface{} {}, }) } /** * @method * @name bitopro#fetchCurrencies * @description fetches all available currencies on an exchange * @see https://github.com/bitoex/bitopro-offical-api-docs/blob/master/api/v3/public/get_currency_info.md * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} an associative dictionary of currencies */ func (this *bitopro) FetchCurrencies(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params response:= (<-this.PublicGetProvisioningCurrencies(params)) PanicOnError(response) var currencies interface{} = this.SafeList(response, "data", []interface{}{}) // // { // "data":[ // { // "currency":"eth", // "withdrawFee":"0.007", // "minWithdraw":"0.001", // "maxWithdraw":"1000", // "maxDailyWithdraw":"2000", // "withdraw":true, // "deposit":true, // "depositConfirmation":"12" // } // ] // } // var result interface{} = map[string]interface{} {} for i := 0; IsLessThan(i, GetArrayLength(currencies)); i++ { var currency interface{} = GetValue(currencies, i) var currencyId interface{} = this.SafeString(currency, "currency") var code interface{} = this.SafeCurrencyCode(currencyId) var deposit interface{} = this.SafeBool(currency, "deposit") var withdraw interface{} = this.SafeBool(currency, "withdraw") var fee interface{} = this.SafeNumber(currency, "withdrawFee") var withdrawMin interface{} = this.SafeNumber(currency, "minWithdraw") var withdrawMax interface{} = this.SafeNumber(currency, "maxWithdraw") var limits interface{} = map[string]interface{} { "withdraw": map[string]interface{} { "min": withdrawMin, "max": withdrawMax, }, "amount": map[string]interface{} { "min": nil, "max": nil, }, } AddElementToObject(result, code, map[string]interface{} { "id": currencyId, "code": code, "info": currency, "type": nil, "name": nil, "active": IsTrue(deposit) && IsTrue(withdraw), "deposit": deposit, "withdraw": withdraw, "fee": fee, "precision": nil, "limits": limits, }) } ch <- result return nil }() return ch } /** * @method * @name bitopro#fetchMarkets * @description retrieves data on all markets for bitopro * @see https://github.com/bitoex/bitopro-offical-api-docs/blob/master/api/v3/public/get_trading_pair_info.md * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} an array of objects representing market data */ func (this *bitopro) 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.PublicGetProvisioningTradingPairs()) PanicOnError(response) var markets interface{} = this.SafeList(response, "data", []interface{}{}) // // { // "data":[ // { // "pair":"shib_twd", // "base":"shib", // "quote":"twd", // "basePrecision":"8", // "quotePrecision":"6", // "minLimitBaseAmount":"100000", // "maxLimitBaseAmount":"5500000000", // "minMarketBuyQuoteAmount":"1000", // "orderOpenLimit":"200", // "maintain":false, // "orderBookQuotePrecision":"6", // "orderBookQuoteScaleLevel":"5" // } // ] // } // ch <- this.ParseMarkets(markets) return nil }() return ch } func (this *bitopro) ParseMarket(market interface{}) interface{} { var active interface{} = !IsTrue(this.SafeBool(market, "maintain")) var id interface{} = this.SafeString(market, "pair") var uppercaseId interface{} = ToUpper(id) var baseId interface{} = this.SafeString(market, "base") var quoteId interface{} = this.SafeString(market, "quote") var base interface{} = this.SafeCurrencyCode(baseId) var quote interface{} = this.SafeCurrencyCode(quoteId) var symbol interface{} = Add(Add(base, "/"), quote) var limits interface{} = map[string]interface{} { "amount": map[string]interface{} { "min": this.SafeNumber(market, "minLimitBaseAmount"), "max": this.SafeNumber(market, "maxLimitBaseAmount"), }, "price": map[string]interface{} { "min": nil, "max": nil, }, "cost": map[string]interface{} { "min": nil, "max": nil, }, "leverage": map[string]interface{} { "min": nil, "max": nil, }, } return map[string]interface{} { "id": id, "uppercaseId": uppercaseId, "symbol": symbol, "base": base, "quote": quote, "baseId": base, "quoteId": quote, "settle": nil, "settleId": nil, "type": "spot", "spot": true, "margin": false, "swap": false, "future": false, "option": false, "contract": false, "linear": nil, "inverse": nil, "contractSize": nil, "expiry": nil, "expiryDatetime": nil, "strike": nil, "optionType": nil, "limits": limits, "precision": map[string]interface{} { "price": this.ParseNumber(this.ParsePrecision(this.SafeString(market, "quotePrecision"))), "amount": this.ParseNumber(this.ParsePrecision(this.SafeString(market, "basePrecision"))), }, "active": active, "created": nil, "info": market, } } func (this *bitopro) ParseTicker(ticker interface{}, optionalArgs ...interface{}) interface{} { // // { // "pair":"btc_twd", // "lastPrice":"1182449.00000000", // "isBuyer":false, // "priceChange24hr":"-1.99", // "volume24hr":"9.13089740", // "high24hr":"1226097.00000000", // "low24hr":"1181000.00000000" // } // market := GetArg(optionalArgs, 0, nil) _ = market var marketId interface{} = this.SafeString(ticker, "pair") market = this.SafeMarket(marketId, market) var symbol interface{} = this.SafeString(market, "symbol") return this.SafeTicker(map[string]interface{} { "symbol": symbol, "timestamp": nil, "datetime": nil, "high": this.SafeString(ticker, "high24hr"), "low": this.SafeString(ticker, "low24hr"), "bid": nil, "bidVolume": nil, "ask": nil, "askVolume": nil, "vwap": nil, "open": nil, "close": this.SafeString(ticker, "lastPrice"), "last": this.SafeString(ticker, "lastPrice"), "previousClose": nil, "change": nil, "percentage": this.SafeString(ticker, "priceChange24hr"), "average": nil, "baseVolume": this.SafeString(ticker, "volume24hr"), "quoteVolume": nil, "info": ticker, }, market) } /** * @method * @name bitopro#fetchTicker * @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market * @see https://github.com/bitoex/bitopro-offical-api-docs/blob/master/api/v3/public/get_ticker_data.md * @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 *bitopro) 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 retRes5138 := (<-this.LoadMarkets()) PanicOnError(retRes5138) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "pair": GetValue(market, "id"), } response:= (<-this.PublicGetTickersPair(this.Extend(request, params))) PanicOnError(response) var ticker interface{} = this.SafeDict(response, "data", map[string]interface{} {}) // // { // "data":{ // "pair":"btc_twd", // "lastPrice":"1182449.00000000", // "isBuyer":false, // "priceChange24hr":"-1.99", // "volume24hr":"9.13089740", // "high24hr":"1226097.00000000", // "low24hr":"1181000.00000000" // } // } // ch <- this.ParseTicker(ticker, market) return nil }() return ch } /** * @method * @name bitopro#fetchTickers * @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market * @see https://github.com/bitoex/bitopro-offical-api-docs/blob/master/api/v3/public/get_ticker_data.md * @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 *bitopro) 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 retRes5468 := (<-this.LoadMarkets()) PanicOnError(retRes5468) response:= (<-this.PublicGetTickers()) PanicOnError(response) var tickers interface{} = this.SafeList(response, "data", []interface{}{}) // // { // "data":[ // { // "pair":"xrp_twd", // "lastPrice":"21.26110000", // "isBuyer":false, // "priceChange24hr":"-6.53", // "volume24hr":"102846.47084802", // "high24hr":"23.24460000", // "low24hr":"21.13730000" // } // ] // } // ch <- this.ParseTickers(tickers, symbols) return nil }() return ch } /** * @method * @name bitopro#fetchOrderBook * @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data * @see https://github.com/bitoex/bitopro-offical-api-docs/blob/master/api/v3/public/get_orderbook_data.md * @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 *bitopro) 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 retRes5788 := (<-this.LoadMarkets()) PanicOnError(retRes5788) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "pair": GetValue(market, "id"), } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) } response:= (<-this.PublicGetOrderBookPair(this.Extend(request, params))) PanicOnError(response) // // { // "bids":[ // { // "price":"1175271", // "amount":"0.00022804", // "count":1, // "total":"0.00022804" // } // ], // "asks":[ // { // "price":"1176906", // "amount":"0.0496", // "count":1, // "total":"0.0496" // } // ] // } // ch <- this.ParseOrderBook(response, GetValue(market, "symbol"), nil, "bids", "asks", "price", "amount") return nil }() return ch } func (this *bitopro) ParseTrade(trade interface{}, optionalArgs ...interface{}) interface{} { // // fetchTrades // { // "timestamp":1644651458, // "price":"1180785.00000000", // "amount":"0.00020000", // "isBuyer":false // } // // fetchMyTrades // { // "tradeId":"5685030251", // "orderId":"9669168142", // "price":"11821.8", // "action":"SELL", // "baseAmount":"0.01", // "quoteAmount":"118.218", // "fee":"0.236436", // "feeSymbol":"BNB", // "isTaker":true, // "timestamp":1644905714862, // "createdTimestamp":1644905714862 // } // market := GetArg(optionalArgs, 0, nil) _ = market var id interface{} = this.SafeString(trade, "tradeId") var orderId interface{} = this.SafeString(trade, "orderId") var timestamp interface{} = nil if IsTrue(IsEqual(id, nil)) { timestamp = this.SafeTimestamp(trade, "timestamp") } else { timestamp = this.SafeInteger(trade, "timestamp") } var marketId interface{} = this.SafeString(trade, "pair") market = this.SafeMarket(marketId, market) var symbol interface{} = this.SafeString(market, "symbol") var price interface{} = this.SafeString(trade, "price") var typeVar interface{} = this.SafeStringLower(trade, "type") var side interface{} = this.SafeStringLower(trade, "action") if IsTrue(IsEqual(side, nil)) { var isBuyer interface{} = this.SafeBool(trade, "isBuyer") if IsTrue(isBuyer) { side = "buy" } else { side = "sell" } } var amount interface{} = this.SafeString(trade, "amount") if IsTrue(IsEqual(amount, nil)) { amount = this.SafeString(trade, "baseAmount") } var fee interface{} = nil var feeAmount interface{} = this.SafeString(trade, "fee") var feeSymbol interface{} = this.SafeCurrencyCode(this.SafeString(trade, "feeSymbol")) if IsTrue(!IsEqual(feeAmount, nil)) { fee = map[string]interface{} { "cost": feeAmount, "currency": feeSymbol, "rate": nil, } } var isTaker interface{} = this.SafeBool(trade, "isTaker") var takerOrMaker interface{} = nil if IsTrue(!IsEqual(isTaker, nil)) { if IsTrue(isTaker) { takerOrMaker = "taker" } else { takerOrMaker = "maker" } } return this.SafeTrade(map[string]interface{} { "id": id, "info": trade, "order": orderId, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "symbol": symbol, "takerOrMaker": takerOrMaker, "type": typeVar, "side": side, "price": price, "amount": amount, "cost": nil, "fee": fee, }, market) } /** * @method * @name bitopro#fetchTrades * @description get the list of most recent trades for a particular symbol * @see https://github.com/bitoex/bitopro-offical-api-docs/blob/master/api/v3/public/get_trades_data.md * @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 *bitopro) 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 retRes7098 := (<-this.LoadMarkets()) PanicOnError(retRes7098) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "pair": GetValue(market, "id"), } response:= (<-this.PublicGetTradesPair(this.Extend(request, params))) PanicOnError(response) var trades interface{} = this.SafeList(response, "data", []interface{}{}) // // { // "data":[ // { // "timestamp":1644651458, // "price":"1180785.00000000", // "amount":"0.00020000", // "isBuyer":false // } // ] // } // ch <- this.ParseTrades(trades, market, since, limit) return nil }() return ch } /** * @method * @name bitopro#fetchTradingFees * @description fetch the trading fees for multiple markets * @see https://github.com/bitoex/bitopro-offical-api-docs/blob/master/api/v3/public/get_limitations_and_fees.md * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a dictionary of [fee structures]{@link https://docs.ccxt.com/#/?id=fee-structure} indexed by market symbols */ func (this *bitopro) FetchTradingFees(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params retRes7408 := (<-this.LoadMarkets()) PanicOnError(retRes7408) response:= (<-this.PublicGetProvisioningLimitationsAndFees(params)) PanicOnError(response) var tradingFeeRate interface{} = this.SafeDict(response, "tradingFeeRate", map[string]interface{} {}) var first interface{} = this.SafeValue(tradingFeeRate, 0) // // { // "tradingFeeRate":[ // { // "rank":0, // "twdVolumeSymbol":"\u003c", // "twdVolume":"3000000", // "bitoAmountSymbol":"\u003c", // "bitoAmount":"7500", // "makerFee":"0.001", // "takerFee":"0.002", // "makerBitoFee":"0.0008", // "takerBitoFee":"0.0016" // } // ], // "orderFeesAndLimitations":[ // { // "pair":"BTC/TWD", // "minimumOrderAmount":"0.0001", // "minimumOrderAmountBase":"BTC", // "minimumOrderNumberOfDigits":"0" // } // ], // "restrictionsOfWithdrawalFees":[ // { // "currency":"TWD", // "fee":"15", // "minimumTradingAmount":"100", // "maximumTradingAmount":"1000000", // "dailyCumulativeMaximumAmount":"2000000", // "remarks":"", // "protocol":"" // } // ], // "cryptocurrencyDepositFeeAndConfirmation":[ // { // "currency":"TWD", // "generalDepositFees":"0", // "blockchainConfirmationRequired":"" // } // ], // "ttCheckFeesAndLimitationsLevel1":[ // { // "currency":"TWD", // "redeemDailyCumulativeMaximumAmount":"", // "generateMinimumTradingAmount":"", // "generateMaximumTradingAmount":"", // "generateDailyCumulativeMaximumAmount":"" // } // ], // "ttCheckFeesAndLimitationsLevel2":[ // { // "currency":"TWD", // "redeemDailyCumulativeMaximumAmount":"20000000", // "generateMinimumTradingAmount":"30", // "generateMaximumTradingAmount":"10000000", // "generateDailyCumulativeMaximumAmount":"10000000" // } // ] // } // var result interface{} = map[string]interface{} {} var maker interface{} = this.SafeNumber(first, "makerFee") var taker interface{} = this.SafeNumber(first, "takerFee") for i := 0; IsLessThan(i, GetArrayLength(this.Symbols)); i++ { var symbol interface{} = GetValue(this.Symbols, i) AddElementToObject(result, symbol, map[string]interface{} { "info": first, "symbol": symbol, "maker": maker, "taker": taker, "percentage": true, "tierBased": true, }) } ch <- result return nil }() return ch } func (this *bitopro) ParseOHLCV(ohlcv interface{}, optionalArgs ...interface{}) interface{} { market := GetArg(optionalArgs, 0, nil) _ = market return []interface{}{this.SafeInteger(ohlcv, "timestamp"), this.SafeNumber(ohlcv, "open"), this.SafeNumber(ohlcv, "high"), this.SafeNumber(ohlcv, "low"), this.SafeNumber(ohlcv, "close"), this.SafeNumber(ohlcv, "volume")} } /** * @method * @name bitopro#fetchOHLCV * @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market * @see https://github.com/bitoex/bitopro-offical-api-docs/blob/master/api/v3/public/get_ohlc_data.md * @param {string} symbol unified symbol of the market to fetch OHLCV data for * @param {string} timeframe the length of time each candle represents * @param {int} [since] timestamp in ms of the earliest candle to fetch * @param {int} [limit] the maximum amount of candles to fetch * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume */ func (this *bitopro) 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 retRes8468 := (<-this.LoadMarkets()) PanicOnError(retRes8468) var market interface{} = this.Market(symbol) var resolution interface{} = this.SafeString(this.Timeframes, timeframe, timeframe) var request interface{} = map[string]interface{} { "pair": GetValue(market, "id"), "resolution": resolution, } // we need to have a limit argument because "to" and "from" are required if IsTrue(IsEqual(limit, nil)) { limit = 500 } else { limit = mathMin(limit, 75000) // supports slightly more than 75k candles atm, but limit here to avoid errors } var timeframeInSeconds interface{} = this.ParseTimeframe(timeframe) var alignedSince interface{} = nil if IsTrue(IsEqual(since, nil)) { AddElementToObject(request, "to", this.Seconds()) AddElementToObject(request, "from", Subtract(GetValue(request, "to"), (Multiply(limit, timeframeInSeconds)))) } else { var timeframeInMilliseconds interface{} = Multiply(timeframeInSeconds, 1000) alignedSince = Multiply(MathFloor(Divide(since, timeframeInMilliseconds)), timeframeInMilliseconds) AddElementToObject(request, "from", MathFloor(Divide(since, 1000))) AddElementToObject(request, "to", this.Sum(GetValue(request, "from"), Multiply(limit, timeframeInSeconds))) } response:= (<-this.PublicGetTradingHistoryPair(this.Extend(request, params))) PanicOnError(response) var data interface{} = this.SafeList(response, "data", []interface{}{}) // // { // "data":[ // { // "timestamp":1644581100000, // "open":"1214737", // "high":"1215110", // "low":"1214737", // "close":"1215110", // "volume":"0.08423959" // } // ] // } // var sparse interface{} = this.ParseOHLCVs(data, market, timeframe, since, limit) ch <- this.InsertMissingCandles(sparse, timeframeInSeconds, alignedSince, limit) return nil }() return ch } func (this *bitopro) InsertMissingCandles(candles interface{}, distance interface{}, since interface{}, limit interface{}) interface{} { // the exchange doesn't send zero volume candles so we emulate them instead // otherwise sending a limit arg leads to unexpected results var length interface{} = GetArrayLength(candles) if IsTrue(IsEqual(length, 0)) { return candles } var result interface{} = []interface{}{} var copyFrom interface{} = GetValue(candles, 0) var timestamp interface{} = nil if IsTrue(IsEqual(since, nil)) { timestamp = GetValue(copyFrom, 0) } else { timestamp = since } var i interface{} = 0 var candleLength interface{} = GetArrayLength(candles) var resultLength interface{} = 0 for IsTrue((IsLessThan(resultLength, limit))) && IsTrue((IsLessThan(i, candleLength))) { var candle interface{} = GetValue(candles, i) if IsTrue(IsEqual(GetValue(candle, 0), timestamp)) { AppendToArray(&result,candle) i = this.Sum(i, 1) } else { var copy interface{} = this.ArrayConcat([]interface{}{}, copyFrom) AddElementToObject(copy, 0, timestamp) // set open, high, low to close AddElementToObject(copy, 1, GetValue(copy, 4)) AddElementToObject(copy, 2, GetValue(copy, 4)) AddElementToObject(copy, 3, GetValue(copy, 4)) AddElementToObject(copy, 5, this.ParseNumber("0")) AppendToArray(&result,copy) } timestamp = this.Sum(timestamp, Multiply(distance, 1000)) resultLength = GetArrayLength(result) copyFrom = GetValue(result, Subtract(resultLength, 1)) } return result } func (this *bitopro) ParseBalance(response interface{}) interface{} { // // [{ // "currency":"twd", // "amount":"0", // "available":"0", // "stake":"0", // "tradable":true // }] // var result interface{} = map[string]interface{} { "info": response, } for i := 0; IsLessThan(i, GetArrayLength(response)); i++ { var balance interface{} = GetValue(response, i) var currencyId interface{} = this.SafeString(balance, "currency") var code interface{} = this.SafeCurrencyCode(currencyId) var amount interface{} = this.SafeString(balance, "amount") var available interface{} = this.SafeString(balance, "available") var account interface{} = map[string]interface{} { "free": available, "total": amount, } AddElementToObject(result, code, account) } return this.SafeBalance(result) } /** * @method * @name bitopro#fetchBalance * @description query for balance and get the amount of funds available for trading or funds locked in orders * @see https://github.com/bitoex/bitopro-offical-api-docs/blob/master/api/v3/private/get_account_balance.md * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure} */ func (this *bitopro) 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 retRes9678 := (<-this.LoadMarkets()) PanicOnError(retRes9678) response:= (<-this.PrivateGetAccountsBalance(params)) PanicOnError(response) var balances interface{} = this.SafeList(response, "data", []interface{}{}) // // { // "data":[ // { // "currency":"twd", // "amount":"0", // "available":"0", // "stake":"0", // "tradable":true // } // ] // } // ch <- this.ParseBalance(balances) return nil }() return ch } func (this *bitopro) ParseOrderStatus(status interface{}) interface{} { var statuses interface{} = map[string]interface{} { "-1": "open", "0": "open", "1": "open", "2": "closed", "3": "closed", "4": "canceled", "6": "canceled", } return this.SafeString(statuses, status, nil) } func (this *bitopro) ParseOrder(order interface{}, optionalArgs ...interface{}) interface{} { // // createOrder // { // "orderId": "2220595581", // "timestamp": "1644896744886", // "action": "SELL", // "amount": "0.01", // "price": "15000", // "timeInForce": "GTC" // } // // fetchOrder // { // "id":"8777138788", // "pair":"bnb_twd", // "price":"16000", // "avgExecutionPrice":"0", // "action":"SELL", // "type":"LIMIT", // "timestamp":1644899002598, // "status":4, // "originalAmount":"0.01", // "remainingAmount":"0.01", // "executedAmount":"0", // "fee":"0", // "feeSymbol":"twd", // "bitoFee":"0", // "total":"0", // "seq":"BNBTWD548774666", // "timeInForce":"GTC", // "createdTimestamp":1644898944074, // "updatedTimestamp":1644899002598 // } // market := GetArg(optionalArgs, 0, nil) _ = market var id interface{} = this.SafeString2(order, "id", "orderId") var timestamp interface{} = this.SafeInteger2(order, "timestamp", "createdTimestamp") var side interface{} = this.SafeString(order, "action") side = ToLower(side) var amount interface{} = this.SafeString2(order, "amount", "originalAmount") var price interface{} = this.SafeString(order, "price") var marketId interface{} = this.SafeString(order, "pair") market = this.SafeMarket(marketId, market, "_") var symbol interface{} = this.SafeString(market, "symbol") var orderStatus interface{} = this.SafeString(order, "status") var status interface{} = this.ParseOrderStatus(orderStatus) var typeVar interface{} = this.SafeStringLower(order, "type") var average interface{} = this.SafeString(order, "avgExecutionPrice") var filled interface{} = this.SafeString(order, "executedAmount") var remaining interface{} = this.SafeString(order, "remainingAmount") var timeInForce interface{} = this.SafeString(order, "timeInForce") var postOnly interface{} = nil if IsTrue(IsEqual(timeInForce, "POST_ONLY")) { postOnly = true } var fee interface{} = nil var feeAmount interface{} = this.SafeString(order, "fee") var feeSymbol interface{} = this.SafeCurrencyCode(this.SafeString(order, "feeSymbol")) if IsTrue(Precise.StringGt(feeAmount, "0")) { fee = map[string]interface{} { "currency": feeSymbol, "cost": feeAmount, } } return this.SafeOrder(map[string]interface{} { "id": id, "clientOrderId": nil, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "lastTradeTimestamp": this.SafeInteger(order, "updatedTimestamp"), "symbol": symbol, "type": typeVar, "timeInForce": timeInForce, "postOnly": postOnly, "side": side, "price": price, "triggerPrice": nil, "amount": amount, "cost": nil, "average": average, "filled": filled, "remaining": remaining, "status": status, "fee": fee, "trades": nil, "info": order, }, market) } /** * @method * @name bitopro#createOrder * @description create a trade order * @see https://github.com/bitoex/bitopro-offical-api-docs/blob/master/api/v3/private/create_an_order.md * @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 {object} [params.triggerPrice] the price at which a trigger order is triggered at * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *bitopro) 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 retRes11038 := (<-this.LoadMarkets()) PanicOnError(retRes11038) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "type": typeVar, "pair": GetValue(market, "id"), "action": side, "amount": this.AmountToPrecision(symbol, amount), "timestamp": this.Milliseconds(), } var orderType interface{} = ToUpper(typeVar) if IsTrue(IsEqual(orderType, "LIMIT")) { AddElementToObject(request, "price", this.PriceToPrecision(symbol, price)) } if IsTrue(IsEqual(orderType, "STOP_LIMIT")) { AddElementToObject(request, "price", this.PriceToPrecision(symbol, price)) var triggerPrice interface{} = this.SafeValue2(params, "triggerPrice", "stopPrice") params = this.Omit(params, []interface{}{"triggerPrice", "stopPrice"}) if IsTrue(IsEqual(triggerPrice, nil)) { panic(InvalidOrder(Add(Add(Add(this.Id, " createOrder() requires a triggerPrice parameter for "), orderType), " orders"))) } else { AddElementToObject(request, "stopPrice", this.PriceToPrecision(symbol, triggerPrice)) } var condition interface{} = this.SafeString(params, "condition") if IsTrue(IsEqual(condition, nil)) { panic(InvalidOrder(Add(Add(Add(this.Id, " createOrder() requires a condition parameter for "), orderType), " orders"))) } else { AddElementToObject(request, "condition", condition) } } var postOnly interface{} = this.IsPostOnly(IsEqual(orderType, "MARKET"), nil, params) if IsTrue(postOnly) { AddElementToObject(request, "timeInForce", "POST_ONLY") } response:= (<-this.PrivatePostOrdersPair(this.Extend(request, params))) PanicOnError(response) // // { // "orderId": "2220595581", // "timestamp": "1644896744886", // "action": "SELL", // "amount": "0.01", // "price": "15000", // "timeInForce": "GTC" // } // ch <- this.ParseOrder(response, market) return nil }() return ch } /** * @method * @name bitopro#cancelOrder * @description cancels an open order * @see https://github.com/bitoex/bitopro-offical-api-docs/blob/master/api/v3/private/cancel_an_order.md * @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 *bitopro) CancelOrder(id interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params if IsTrue(IsEqual(symbol, nil)) { panic(ArgumentsRequired(Add(this.Id, " cancelOrder() requires a symbol argument"))) } retRes11648 := (<-this.LoadMarkets()) PanicOnError(retRes11648) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "id": id, "pair": GetValue(market, "id"), } response:= (<-this.PrivateDeleteOrdersPairId(this.Extend(request, params))) PanicOnError(response) // // { // "orderId":"8777138788", // "action":"SELL", // "timestamp":1644899002465, // "price":"16000", // "amount":"0.01" // } // ch <- this.ParseOrder(response, market) return nil }() return ch } func (this *bitopro) ParseCancelOrders(data interface{}) interface{} { var dataKeys interface{} = ObjectKeys(data) var orders interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(dataKeys)); i++ { var marketId interface{} = GetValue(dataKeys, i) var orderIds interface{} = GetValue(data, marketId) for j := 0; IsLessThan(j, GetArrayLength(orderIds)); j++ { AppendToArray(&orders,this.SafeOrder(map[string]interface{} { "info": GetValue(orderIds, j), "id": GetValue(orderIds, j), "symbol": this.SafeSymbol(marketId), })) } } return orders } /** * @method * @name bitopro#cancelOrders * @description cancel multiple orders * @see https://github.com/bitoex/bitopro-offical-api-docs/blob/master/api/v3/private/cancel_batch_orders.md * @param {string[]} ids order ids * @param {string} symbol unified market symbol * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} an list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *bitopro) CancelOrders(ids interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params if IsTrue(IsEqual(symbol, nil)) { panic(ArgumentsRequired(Add(this.Id, " cancelOrders() requires a symbol argument"))) } retRes12148 := (<-this.LoadMarkets()) PanicOnError(retRes12148) var market interface{} = this.Market(symbol) var id interface{} = GetValue(market, "uppercaseId") var request interface{} = map[string]interface{} {} AddElementToObject(request, id, ids) response:= (<-this.PrivatePutOrders(this.Extend(request, params))) PanicOnError(response) // // { // "data":{ // "BNB_TWD":[ // "5236347105", // "359488711" // ] // } // } // var data interface{} = this.SafeDict(response, "data") ch <- this.ParseCancelOrders(data) return nil }() return ch } /** * @method * @name bitopro#cancelAllOrders * @description cancel all open orders * @see https://github.com/bitoex/bitopro-offical-api-docs/blob/master/api/v3/private/cancel_all_orders.md * @param {string} symbol unified market symbol, only orders in the market of this symbol are cancelled when symbol is not undefined * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *bitopro) CancelAllOrders(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params retRes12448 := (<-this.LoadMarkets()) PanicOnError(retRes12448) var request interface{} = map[string]interface{} {} var response interface{} = nil if IsTrue(!IsEqual(symbol, nil)) { var market interface{} = this.Market(symbol) AddElementToObject(request, "pair", GetValue(market, "id")) response = (<-this.PrivateDeleteOrdersPair(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.PrivateDeleteOrdersAll(this.Extend(request, params))) PanicOnError(response) } var data interface{} = this.SafeDict(response, "data", map[string]interface{} {}) // // { // "data":{ // "BNB_TWD":[ // "9515988421", // "4639130027" // ] // } // } // ch <- this.ParseCancelOrders(data) return nil }() return ch } /** * @method * @name bitopro#fetchOrder * @description fetches information on an order made by the user * @see https://github.com/bitoex/bitopro-offical-api-docs/blob/master/api/v3/private/get_an_order_data.md * @param {string} id the order id * @param {string} symbol unified symbol of the market the order was made in * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *bitopro) FetchOrder(id interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params if IsTrue(IsEqual(symbol, nil)) { panic(ArgumentsRequired(Add(this.Id, " fetchOrder() requires a symbol argument"))) } retRes12848 := (<-this.LoadMarkets()) PanicOnError(retRes12848) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "orderId": id, "pair": GetValue(market, "id"), } response:= (<-this.PrivateGetOrdersPairOrderId(this.Extend(request, params))) PanicOnError(response) // // { // "id":"8777138788", // "pair":"bnb_twd", // "price":"16000", // "avgExecutionPrice":"0", // "action":"SELL", // "type":"LIMIT", // "timestamp":1644899002598, // "status":4, // "originalAmount":"0.01", // "remainingAmount":"0.01", // "executedAmount":"0", // "fee":"0", // "feeSymbol":"twd", // "bitoFee":"0", // "total":"0", // "seq":"BNBTWD548774666", // "timeInForce":"GTC", // "createdTimestamp":1644898944074, // "updatedTimestamp":1644899002598 // } // ch <- this.ParseOrder(response, market) return nil }() return ch } /** * @method * @name bitopro#fetchOrders * @description fetches information on multiple orders made by the user * @see https://github.com/bitoex/bitopro-offical-api-docs/blob/master/api/v3/private/get_orders_data.md * @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 *bitopro) 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"))) } retRes13328 := (<-this.LoadMarkets()) PanicOnError(retRes13328) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "pair": GetValue(market, "id"), } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "startTimestamp", since) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) } response:= (<-this.PrivateGetOrdersAllPair(this.Extend(request, params))) PanicOnError(response) var orders interface{} = this.SafeList(response, "data", []interface{}{}) if IsTrue(IsEqual(orders, nil)) { orders = []interface{}{} } // // { // "data":[ // { // "id":"2220595581", // "pair":"bnb_twd", // "price":"15000", // "avgExecutionPrice":"0", // "action":"SELL", // "type":"LIMIT", // "createdTimestamp":1644896744886, // "updatedTimestamp":1644898706236, // "status":4, // "originalAmount":"0.01", // "remainingAmount":"0.01", // "executedAmount":"0", // "fee":"0", // "feeSymbol":"twd", // "bitoFee":"0", // "total":"0", // "seq":"BNBTWD8540871774", // "timeInForce":"GTC" // } // ] // } // ch <- this.ParseOrders(orders, market, since, limit) return nil }() return ch } /** * @method * @name bitopro#fetchOpenOrders * @description fetch all unfilled currently open orders * @see https://github.com/bitoex/bitopro-offical-api-docs/blob/master/api/v3/private/get_open_orders_data.md * @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 *bitopro) 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 retRes13938 := (<-this.LoadMarkets()) PanicOnError(retRes13938) var request interface{} = map[string]interface{} {} var market interface{} = nil if IsTrue(!IsEqual(symbol, nil)) { market = this.Market(symbol) AddElementToObject(request, "pair", GetValue(market, "id")) } response:= (<-this.PrivateGetOrdersOpen(this.Extend(request, params))) PanicOnError(response) var orders interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseOrders(orders, market, since, limit) return nil }() return ch } /** * @method * @name bitopro#fetchClosedOrders * @description fetches information on multiple closed orders made by the user * @see https://github.com/bitoex/bitopro-offical-api-docs/blob/master/api/v3/private/get_orders_data.md * @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 *bitopro) 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{} { "statusKind": "DONE", } ch <- this.FetchOrders(symbol, since, limit, this.Extend(request, params)) return nil }() return ch } /** * @method * @name bitopro#fetchMyTrades * @description fetch all trades made by the user * @see https://github.com/bitoex/bitopro-offical-api-docs/blob/master/api/v3/private/get_trades_data.md * @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 *bitopro) 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"))) } retRes14388 := (<-this.LoadMarkets()) PanicOnError(retRes14388) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "pair": GetValue(market, "id"), } response:= (<-this.PrivateGetOrdersTradesPair(this.Extend(request, params))) PanicOnError(response) var trades interface{} = this.SafeList(response, "data", []interface{}{}) // // { // "data":[ // { // "tradeId":"5685030251", // "orderId":"9669168142", // "price":"11821.8", // "action":"SELL", // "baseAmount":"0.01", // "quoteAmount":"118.218", // "fee":"0.236436", // "feeSymbol":"BNB", // "isTaker":true, // "timestamp":1644905714862, // "createdTimestamp":1644905714862 // } // ] // } // ch <- this.ParseTrades(trades, market, since, limit) return nil }() return ch } func (this *bitopro) ParseTransactionStatus(status interface{}) interface{} { var states interface{} = map[string]interface{} { "COMPLETE": "ok", "INVALID": "failed", "PROCESSING": "pending", "WAIT_PROCESS": "pending", "FAILED": "failed", "EXPIRED": "failed", "CANCELLED": "failed", "EMAIL_VERIFICATION": "pending", "WAIT_CONFIRMATION": "pending", } return this.SafeString(states, status, status) } func (this *bitopro) ParseTransaction(transaction interface{}, optionalArgs ...interface{}) interface{} { // // fetchDeposits // // { // "serial": "20220214X766799", // "timestamp": "1644833015053", // "address": "bnb1xml62k5a9dcewgc542fha75fyxdcp0zv8eqfsh", // "amount": "0.20000000", // "fee": "0.00000000", // "total": "0.20000000", // "status": "COMPLETE", // "txid": "A3CC4F6828CC752B9F3737F48B5826B9EC2857040CB5141D0CC955F7E53DB6D9", // "message": "778553959", // "protocol": "MAIN", // "id": "2905906537" // } // // fetchWithdrawals || fetchWithdraw // // { // "serial": "20220215BW14069838", // "timestamp": "1644907716044", // "address": "TKrwMaZaGiAvtXCFT41xHuusNcs4LPWS7w", // "amount": "8.00000000", // "fee": "2.00000000", // "total": "10.00000000", // "status": "COMPLETE", // "txid": "50bf250c71a582f40cf699fb58bab978437ea9bdf7259ff8072e669aab30c32b", // "protocol": "TRX", // "id": "9925310345" // } // // withdraw // // { // "serial": "20220215BW14069838", // "currency": "USDT", // "protocol": "TRX", // "address": "TKrwMaZaGiAvtXCFT41xHuusNcs4LPWS7w", // "amount": "8", // "fee": "2", // "total": "10" // } // currency := GetArg(optionalArgs, 0, nil) _ = currency var currencyId interface{} = this.SafeString(transaction, "coin") var code interface{} = this.SafeCurrencyCode(currencyId, currency) var timestamp interface{} = this.SafeInteger(transaction, "timestamp") var address interface{} = this.SafeString(transaction, "address") var tag interface{} = this.SafeString(transaction, "message") var status interface{} = this.SafeString(transaction, "status") var networkId interface{} = this.SafeString(transaction, "protocol") if IsTrue(IsEqual(networkId, "MAIN")) { networkId = code } return map[string]interface{} { "info": transaction, "id": this.SafeString(transaction, "serial"), "txid": this.SafeString(transaction, "txid"), "type": nil, "currency": code, "network": this.NetworkIdToCode(networkId), "amount": this.SafeNumber(transaction, "total"), "status": this.ParseTransactionStatus(status), "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "address": address, "addressFrom": nil, "addressTo": address, "tag": tag, "tagFrom": nil, "tagTo": tag, "updated": nil, "comment": nil, "internal": nil, "fee": map[string]interface{} { "currency": code, "cost": this.SafeNumber(transaction, "fee"), "rate": nil, }, } } /** * @method * @name bitopro#fetchDeposits * @description fetch all deposits made to an account * @see https://github.com/bitoex/bitopro-offical-api-docs/blob/master/api/v3/private/get_deposit_invoices_data.md * @param {string} code unified currency code * @param {int} [since] the earliest time in ms to fetch deposits for * @param {int} [limit] the maximum number of deposits structures to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure} */ func (this *bitopro) FetchDeposits(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) code := GetArg(optionalArgs, 0, nil) _ = code since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params if IsTrue(IsEqual(code, nil)) { panic(ArgumentsRequired(Add(this.Id, " fetchDeposits() requires the code argument"))) } retRes15808 := (<-this.LoadMarkets()) PanicOnError(retRes15808) var currency interface{} = this.SafeCurrency(code) var request interface{} = map[string]interface{} { "currency": GetValue(currency, "id"), } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "startTimestamp", since) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) } response:= (<-this.PrivateGetWalletDepositHistoryCurrency(this.Extend(request, params))) PanicOnError(response) var result interface{} = this.SafeList(response, "data", []interface{}{}) // // { // "data":[ // { // "serial":"20220214X766799", // "timestamp":"1644833015053", // "address":"bnb1xml62k5a9dcewgc542fha75fyxdcp0zv8eqfsh", // "amount":"0.20000000", // "fee":"0.00000000", // "total":"0.20000000", // "status":"COMPLETE", // "txid":"A3CC4F6828CC752B9F3737F48B5826B9EC2857040CB5141D0CC955F7E53DB6D9", // "message":"778553959", // "protocol":"MAIN", // "id":"2905906537" // } // ] // } // ch <- this.ParseTransactions(result, currency, since, limit, map[string]interface{} { "type": "deposit", }) return nil }() return ch } /** * @method * @name bitopro#fetchWithdrawals * @description fetch all withdrawals made from an account * @see https://github.com/bitoex/bitopro-offical-api-docs/blob/master/api/v3/private/get_withdraw_invoices_data.md * @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 *bitopro) FetchWithdrawals(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) code := GetArg(optionalArgs, 0, nil) _ = code since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params if IsTrue(IsEqual(code, nil)) { panic(ArgumentsRequired(Add(this.Id, " fetchWithdrawals() requires the code argument"))) } retRes16338 := (<-this.LoadMarkets()) PanicOnError(retRes16338) var currency interface{} = this.SafeCurrency(code) var request interface{} = map[string]interface{} { "currency": GetValue(currency, "id"), } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "startTimestamp", since) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) } response:= (<-this.PrivateGetWalletWithdrawHistoryCurrency(this.Extend(request, params))) PanicOnError(response) var result interface{} = this.SafeList(response, "data", []interface{}{}) // // { // "data":[ // { // "serial":"20220215BW14069838", // "timestamp":"1644907716044", // "address":"TKrwMaZaGiAvtXCFT41xHuusNcs4LPWS7w", // "amount":"8.00000000", // "fee":"2.00000000", // "total":"10.00000000", // "status":"COMPLETE", // "txid":"50bf250c71a582f40cf699fb58bab978437ea9bdf7259ff8072e669aab30c32b", // "protocol":"TRX", // "id":"9925310345" // } // ] // } // ch <- this.ParseTransactions(result, currency, since, limit, map[string]interface{} { "type": "withdrawal", }) return nil }() return ch } /** * @method * @name bitopro#fetchWithdrawal * @description fetch data on a currency withdrawal via the withdrawal id * @see https://github.com/bitoex/bitopro-offical-api-docs/blob/master/api/v3/private/get_an_withdraw_invoice_data.md * @param {string} id withdrawal id * @param {string} code unified currency code of the currency withdrawn, default is undefined * @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 *bitopro) FetchWithdrawal(id interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) code := GetArg(optionalArgs, 0, nil) _ = code params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params if IsTrue(IsEqual(code, nil)) { panic(ArgumentsRequired(Add(this.Id, " fetchWithdrawal() requires the code argument"))) } retRes16848 := (<-this.LoadMarkets()) PanicOnError(retRes16848) var currency interface{} = this.SafeCurrency(code) var request interface{} = map[string]interface{} { "serial": id, "currency": GetValue(currency, "id"), } response:= (<-this.PrivateGetWalletWithdrawCurrencySerial(this.Extend(request, params))) PanicOnError(response) var result interface{} = this.SafeDict(response, "data", map[string]interface{} {}) // // { // "data":{ // "serial":"20220215BW14069838", // "address":"TKrwMaZaGiAvtXCFT41xHuusNcs4LPWS7w", // "amount":"8.00000000", // "fee":"2.00000000", // "total":"10.00000000", // "status":"COMPLETE", // "txid":"50bf250c71a582f40cf699fb58bab978437ea9bdf7259ff8072e669aab30c32b", // "protocol":"TRX", // "id":"9925310345", // "timestamp":"1644907716044" // } // } // ch <- this.ParseTransaction(result, currency) return nil }() return ch } /** * @method * @name bitopro#withdraw * @description make a withdrawal * @see https://github.com/bitoex/bitopro-offical-api-docs/blob/master/api/v3/private/create_an_withdraw_invoice.md * @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 *bitopro) 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) retRes17258 := (<-this.LoadMarkets()) PanicOnError(retRes17258) this.CheckAddress(address) var currency interface{} = this.Currency(code) var request interface{} = map[string]interface{} { "currency": GetValue(currency, "id"), "amount": this.NumberToString(amount), "address": address, } if IsTrue(InOp(params, "network")) { var networks interface{} = this.SafeDict(this.Options, "networks", map[string]interface{} {}) var requestedNetwork interface{} = this.SafeStringUpper(params, "network") params = this.Omit(params, []interface{}{"network"}) var networkId interface{} = this.SafeString(networks, requestedNetwork) if IsTrue(IsEqual(networkId, nil)) { panic(ExchangeError(Add(Add(this.Id, " invalid network "), requestedNetwork))) } AddElementToObject(request, "protocol", networkId) } if IsTrue(!IsEqual(tag, nil)) { AddElementToObject(request, "message", tag) } response:= (<-this.PrivatePostWalletWithdrawCurrency(this.Extend(request, params))) PanicOnError(response) var result interface{} = this.SafeDict(response, "data", map[string]interface{} {}) // // { // "data":{ // "serial":"20220215BW14069838", // "currency":"USDT", // "protocol":"TRX", // "address":"TKrwMaZaGiAvtXCFT41xHuusNcs4LPWS7w", // "amount":"8", // "fee":"2", // "total":"10" // } // } // ch <- this.ParseTransaction(result, currency) return nil }() return ch } func (this *bitopro) ParseDepositWithdrawFee(fee interface{}, optionalArgs ...interface{}) interface{} { // { // "currency":"eth", // "withdrawFee":"0.007", // "minWithdraw":"0.001", // "maxWithdraw":"1000", // "maxDailyWithdraw":"2000", // "withdraw":true, // "deposit":true, // "depositConfirmation":"12" // } currency := GetArg(optionalArgs, 0, nil) _ = currency return map[string]interface{} { "info": fee, "withdraw": map[string]interface{} { "fee": this.SafeNumber(fee, "withdrawFee"), "percentage": false, }, "deposit": map[string]interface{} { "fee": nil, "percentage": nil, }, "networks": map[string]interface{} {}, } } /** * @method * @name bitopro#fetchDepositWithdrawFees * @description fetch deposit and withdraw fees * @see https://github.com/bitoex/bitopro-offical-api-docs/blob/master/api/v3/public/get_currency_info.md * @param {string[]|undefined} codes list of unified currency codes * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a list of [fee structures]{@link https://docs.ccxt.com/#/?id=fee-structure} */ func (this *bitopro) FetchDepositWithdrawFees(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) codes := GetArg(optionalArgs, 0, nil) _ = codes params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params retRes17998 := (<-this.LoadMarkets()) PanicOnError(retRes17998) response:= (<-this.PublicGetProvisioningCurrencies(params)) PanicOnError(response) // // { // "data":[ // { // "currency":"eth", // "withdrawFee":"0.007", // "minWithdraw":"0.001", // "maxWithdraw":"1000", // "maxDailyWithdraw":"2000", // "withdraw":true, // "deposit":true, // "depositConfirmation":"12" // } // ] // } // var data interface{} = this.SafeList(response, "data", []interface{}{}) ch <- this.ParseDepositWithdrawFees(data, codes, "currency") return nil }() return ch } func (this *bitopro) Sign(path interface{}, optionalArgs ...interface{}) interface{} { api := GetArg(optionalArgs, 0, "public") _ = api method := GetArg(optionalArgs, 1, "GET") _ = method params := GetArg(optionalArgs, 2, map[string]interface{} {}) _ = params headers := GetArg(optionalArgs, 3, nil) _ = headers body := GetArg(optionalArgs, 4, nil) _ = body var url interface{} = Add("/", this.ImplodeParams(path, params)) var query interface{} = this.Omit(params, this.ExtractParams(path)) if IsTrue(IsEqual(headers, nil)) { headers = map[string]interface{} {} } AddElementToObject(headers, "X-BITOPRO-API", "ccxt") if IsTrue(IsEqual(api, "private")) { this.CheckRequiredCredentials() if IsTrue(IsTrue(IsEqual(method, "POST")) || IsTrue(IsEqual(method, "PUT"))) { body = this.Json(params) var payload interface{} = this.StringToBase64(body) var signature interface{} = this.Hmac(this.Encode(payload), this.Encode(this.Secret), sha384) AddElementToObject(headers, "X-BITOPRO-APIKEY", this.ApiKey) AddElementToObject(headers, "X-BITOPRO-PAYLOAD", payload) AddElementToObject(headers, "X-BITOPRO-SIGNATURE", signature) } else if IsTrue(IsTrue(IsEqual(method, "GET")) || IsTrue(IsEqual(method, "DELETE"))) { if IsTrue(GetArrayLength(ObjectKeys(query))) { url = Add(url, Add("?", this.Urlencode(query))) } var nonce interface{} = this.Milliseconds() var rawData interface{} = map[string]interface{} { "nonce": nonce, } var data interface{} = this.Json(rawData) var payload interface{} = this.StringToBase64(data) var signature interface{} = this.Hmac(this.Encode(payload), this.Encode(this.Secret), sha384) AddElementToObject(headers, "X-BITOPRO-APIKEY", this.ApiKey) AddElementToObject(headers, "X-BITOPRO-PAYLOAD", payload) AddElementToObject(headers, "X-BITOPRO-SIGNATURE", signature) } } else if IsTrue(IsTrue(IsEqual(api, "public")) && IsTrue(IsEqual(method, "GET"))) { if IsTrue(GetArrayLength(ObjectKeys(query))) { url = Add(url, Add("?", this.Urlencode(query))) } } url = Add(GetValue(GetValue(this.Urls, "api"), "rest"), url) return map[string]interface{} { "url": url, "method": method, "body": body, "headers": headers, } } func (this *bitopro) HandleErrors(code interface{}, reason interface{}, url interface{}, method interface{}, headers interface{}, body interface{}, response interface{}, requestHeaders interface{}, requestBody interface{}) interface{} { if IsTrue(IsEqual(response, nil)) { return nil // fallback to the default error handler } if IsTrue(IsTrue(IsGreaterThanOrEqual(code, 200)) && IsTrue(IsLessThan(code, 300))) { return nil } var feedback interface{} = Add(Add(this.Id, " "), body) var error interface{} = this.SafeString(response, "error") this.ThrowExactlyMatchedException(GetValue(this.Exceptions, "exact"), error, feedback) this.ThrowBroadlyMatchedException(GetValue(this.Exceptions, "broad"), error, feedback) panic(ExchangeError(feedback)) } func (this *bitopro) Init(userConfig map[string]interface{}) { this.Exchange = Exchange{} this.Exchange.InitParent(userConfig, this.Describe().(map[string]interface{}), this) this.Exchange.DerivedExchange = this }