UNPKG

ccxt

Version:

A JavaScript / TypeScript / Python / C# / PHP cryptocurrency trading library with support for 100+ exchanges

1,111 lines (1,109 loc) 92.4 kB
// ---------------------------------------------------------------------------- // 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 // EDIT THE CORRESPONDENT .ts FILE INSTEAD // --------------------------------------------------------------------------- import Exchange from './abstract/bittrade.js'; import { AuthenticationError, ExchangeError, PermissionDenied, ExchangeNotAvailable, OnMaintenance, InvalidOrder, OrderNotFound, InsufficientFunds, BadSymbol, BadRequest, RequestTimeout, NetworkError, ArgumentsRequired, NotSupported } from './base/errors.js'; import { Precise } from './base/Precise.js'; import { TRUNCATE, TICK_SIZE } from './base/functions/number.js'; import { sha256 } from './static_dependencies/noble-hashes/sha256.js'; // --------------------------------------------------------------------------- /** * @class bittrade * @augments Exchange */ export default class bittrade extends Exchange { describe() { return this.deepExtend(super.describe(), { 'id': 'bittrade', 'name': 'BitTrade', 'countries': ['JP'], 'rateLimit': 100, 'userAgent': this.userAgents['chrome39'], 'certified': false, 'version': 'v1', 'hostname': 'api-cloud.bittrade.co.jp', 'pro': true, 'has': { 'CORS': undefined, 'spot': true, 'margin': undefined, 'swap': false, 'future': false, 'option': false, 'cancelAllOrders': true, 'cancelOrder': true, 'cancelOrders': true, 'createMarketBuyOrderWithCost': true, 'createMarketOrderWithCost': false, 'createMarketSellOrderWithCost': false, 'createOrder': true, 'createStopLimitOrder': false, 'createStopMarketOrder': false, 'createStopOrder': false, 'fetchAccounts': true, 'fetchBalance': true, 'fetchClosedOrders': true, 'fetchCurrencies': true, 'fetchDepositAddress': false, 'fetchDepositAddressesByNetwork': false, 'fetchDeposits': true, 'fetchFundingHistory': false, 'fetchFundingRate': false, 'fetchFundingRateHistory': false, 'fetchFundingRates': false, 'fetchIndexOHLCV': false, 'fetchMarkets': true, 'fetchMarkOHLCV': false, 'fetchMyTrades': true, 'fetchOHLCV': true, 'fetchOpenOrders': true, 'fetchOrder': true, 'fetchOrderBook': true, 'fetchOrders': true, 'fetchOrderTrades': true, 'fetchPremiumIndexOHLCV': false, 'fetchTicker': true, 'fetchTickers': true, 'fetchTime': true, 'fetchTrades': true, 'fetchTradingLimits': true, 'fetchWithdrawals': true, 'withdraw': true, }, 'timeframes': { '1m': '1min', '5m': '5min', '15m': '15min', '30m': '30min', '1h': '60min', '4h': '4hour', '1d': '1day', '1w': '1week', '1M': '1mon', '1y': '1year', }, 'urls': { 'logo': 'https://user-images.githubusercontent.com/1294454/85734211-85755480-b705-11ea-8b35-0b7f1db33a2f.jpg', 'api': { 'market': 'https://{hostname}', 'public': 'https://{hostname}', 'private': 'https://{hostname}', 'v2Public': 'https://{hostname}', 'v2Private': 'https://{hostname}', }, 'www': 'https://www.bittrade.co.jp', 'referral': 'https://www.bittrade.co.jp/register/?invite_code=znnq3', 'doc': 'https://api-doc.bittrade.co.jp', 'fees': 'https://www.bittrade.co.jp/ja-jp/support/fee', }, 'api': { 'v2Public': { 'get': { 'reference/currencies': 1, 'market-status': 1, // 获取当前市场状态 }, }, 'v2Private': { 'get': { 'account/ledger': 1, 'account/withdraw/quota': 1, 'account/withdraw/address': 1, 'account/deposit/address': 1, 'account/repayment': 5, 'reference/transact-fee-rate': 1, 'account/asset-valuation': 0.2, 'point/account': 5, 'sub-user/user-list': 1, 'sub-user/user-state': 1, 'sub-user/account-list': 1, 'sub-user/deposit-address': 1, 'sub-user/query-deposit': 1, 'user/api-key': 1, 'user/uid': 1, 'algo-orders/opening': 1, 'algo-orders/history': 1, 'algo-orders/specific': 1, 'c2c/offers': 1, 'c2c/offer': 1, 'c2c/transactions': 1, 'c2c/repayment': 1, 'c2c/account': 1, 'etp/reference': 1, 'etp/transactions': 5, 'etp/transaction': 5, 'etp/rebalance': 1, 'etp/limit': 1, // 获取ETP持仓限额 }, 'post': { 'account/transfer': 1, 'account/repayment': 5, 'point/transfer': 5, 'sub-user/management': 1, 'sub-user/creation': 1, 'sub-user/tradable-market': 1, 'sub-user/transferability': 1, 'sub-user/api-key-generation': 1, 'sub-user/api-key-modification': 1, 'sub-user/api-key-deletion': 1, 'sub-user/deduct-mode': 1, 'algo-orders': 1, 'algo-orders/cancel-all-after': 1, 'algo-orders/cancellation': 1, 'c2c/offer': 1, 'c2c/cancellation': 1, 'c2c/cancel-all': 1, 'c2c/repayment': 1, 'c2c/transfer': 1, 'etp/creation': 5, 'etp/redemption': 5, 'etp/{transactId}/cancel': 10, 'etp/batch-cancel': 50, // 杠杆ETP批量撤单 }, }, 'market': { 'get': { 'history/kline': 1, 'detail/merged': 1, 'depth': 1, 'trade': 1, 'history/trade': 1, 'detail': 1, 'tickers': 1, 'etp': 1, // 获取杠杆ETP实时净值 }, }, 'public': { 'get': { 'common/symbols': 1, 'common/currencys': 1, 'common/timestamp': 1, 'common/exchange': 1, 'settings/currencys': 1, // ?language=en-US }, }, 'private': { 'get': { 'account/accounts': 0.2, 'account/accounts/{id}/balance': 0.2, 'account/accounts/{sub-uid}': 1, 'account/history': 4, 'cross-margin/loan-info': 1, 'margin/loan-info': 1, 'fee/fee-rate/get': 1, 'order/openOrders': 0.4, 'order/orders': 0.4, 'order/orders/{id}': 0.4, 'order/orders/{id}/matchresults': 0.4, 'order/orders/getClientOrder': 0.4, 'order/history': 1, 'order/matchresults': 1, // 'dw/withdraw-virtual/addresses', // 查询虚拟币提现地址(Deprecated) 'query/deposit-withdraw': 1, // 'margin/loan-info', // duplicate 'margin/loan-orders': 0.2, 'margin/accounts/balance': 0.2, 'cross-margin/loan-orders': 1, 'cross-margin/accounts/balance': 1, 'points/actions': 1, 'points/orders': 1, 'subuser/aggregate-balance': 10, 'stable-coin/exchange_rate': 1, 'stable-coin/quote': 1, }, 'post': { 'account/transfer': 1, 'futures/transfer': 1, 'order/batch-orders': 0.4, 'order/orders/place': 0.2, 'order/orders/submitCancelClientOrder': 0.2, 'order/orders/batchCancelOpenOrders': 0.4, // 'order/orders', // 创建一个新的订单请求 (仅创建订单,不执行下单) // 'order/orders/{id}/place', // 执行一个订单 (仅执行已创建的订单) 'order/orders/{id}/submitcancel': 0.2, 'order/orders/batchcancel': 0.4, // 'dw/balance/transfer', // 资产划转 'dw/withdraw/api/create': 1, // 'dw/withdraw-virtual/create', // 申请提现虚拟币 // 'dw/withdraw-virtual/{id}/place', // 确认申请虚拟币提现(Deprecated) 'dw/withdraw-virtual/{id}/cancel': 1, 'dw/transfer-in/margin': 10, 'dw/transfer-out/margin': 10, 'margin/orders': 10, 'margin/orders/{id}/repay': 10, 'cross-margin/transfer-in': 1, 'cross-margin/transfer-out': 1, 'cross-margin/orders': 1, 'cross-margin/orders/{id}/repay': 1, 'stable-coin/exchange': 1, 'subuser/transfer': 10, }, }, }, 'fees': { 'trading': { 'feeSide': 'get', 'tierBased': false, 'percentage': true, 'maker': this.parseNumber('0.002'), 'taker': this.parseNumber('0.002'), }, }, 'features': { 'spot': { 'sandbox': false, 'createOrder': { 'marginMode': false, 'triggerPrice': true, 'triggerPriceType': undefined, 'triggerDirection': false, 'stopLossPrice': false, 'takeProfitPrice': false, 'attachedStopLossTakeProfit': undefined, 'timeInForce': { 'IOC': false, 'FOK': false, 'PO': false, 'GTD': false, }, 'hedged': false, 'selfTradePrevention': false, 'trailing': false, 'leverage': false, 'marketBuyByCost': true, 'marketBuyRequiresPrice': false, 'iceberg': false, }, 'createOrders': undefined, 'fetchMyTrades': { 'marginMode': false, 'limit': 100, 'daysBack': 120, 'untilDays': 2, 'symbolRequired': false, }, 'fetchOrder': { 'marginMode': false, 'trigger': false, 'trailing': false, 'symbolRequired': false, }, 'fetchOpenOrders': { 'marginMode': false, 'limit': undefined, 'trigger': false, 'trailing': false, 'symbolRequired': false, }, 'fetchOrders': { 'marginMode': false, 'limit': undefined, 'daysBack': undefined, 'untilDays': undefined, 'trigger': false, 'trailing': false, 'symbolRequired': false, }, 'fetchClosedOrders': { 'marginMode': false, 'limit': undefined, 'daysBack': undefined, 'daysBackCanceled': undefined, 'untilDays': undefined, 'trigger': false, 'trailing': false, 'symbolRequired': false, }, 'fetchOHLCV': { 'limit': 2000, }, }, 'swap': { 'linear': undefined, 'inverse': undefined, }, 'future': { 'linear': undefined, 'inverse': undefined, }, }, 'precisionMode': TICK_SIZE, 'exceptions': { 'broad': { 'contract is restricted of closing positions on API. Please contact customer service': OnMaintenance, 'maintain': OnMaintenance, }, 'exact': { // err-code 'bad-request': BadRequest, 'base-date-limit-error': BadRequest, 'api-not-support-temp-addr': PermissionDenied, 'timeout': RequestTimeout, 'gateway-internal-error': ExchangeNotAvailable, 'account-frozen-balance-insufficient-error': InsufficientFunds, 'invalid-amount': InvalidOrder, 'order-limitorder-amount-min-error': InvalidOrder, 'order-limitorder-amount-max-error': InvalidOrder, 'order-marketorder-amount-min-error': InvalidOrder, 'order-limitorder-price-min-error': InvalidOrder, 'order-limitorder-price-max-error': InvalidOrder, 'order-holding-limit-failed': InvalidOrder, 'order-orderprice-precision-error': InvalidOrder, 'order-etp-nav-price-max-error': InvalidOrder, 'order-orderstate-error': OrderNotFound, 'order-queryorder-invalid': OrderNotFound, 'order-update-error': ExchangeNotAvailable, 'api-signature-check-failed': AuthenticationError, 'api-signature-not-valid': AuthenticationError, 'base-record-invalid': OrderNotFound, 'base-symbol-trade-disabled': BadSymbol, 'base-symbol-error': BadSymbol, 'system-maintenance': OnMaintenance, // err-msg 'invalid symbol': BadSymbol, 'symbol trade not open now': BadSymbol, 'invalid-address': BadRequest, 'base-currency-chain-error': BadRequest, 'dw-insufficient-balance': InsufficientFunds, // {"status":"error","err-code":"dw-insufficient-balance","err-msg":"Insufficient balance. You can only transfer `12.3456` at most.","data":null} }, }, 'options': { 'defaultNetwork': 'ERC20', 'networks': { 'ETH': 'erc20', 'TRX': 'trc20', 'HRC20': 'hrc20', 'HECO': 'hrc20', 'HT': 'hrc20', 'ALGO': 'algo', 'OMNI': '', }, // https://github.com/ccxt/ccxt/issues/5376 'fetchOrdersByStatesMethod': 'private_get_order_orders', 'fetchOpenOrdersMethod': 'fetch_open_orders_v1', 'createMarketBuyOrderRequiresPrice': true, 'fetchMarketsMethod': 'publicGetCommonSymbols', 'fetchBalanceMethod': 'privateGetAccountAccountsIdBalance', 'createOrderMethod': 'privatePostOrderOrdersPlace', 'currencyToPrecisionRoundingMode': TRUNCATE, 'language': 'en-US', 'broker': { 'id': 'AA03022abc', }, }, 'commonCurrencies': { // https://github.com/ccxt/ccxt/issues/6081 // https://github.com/ccxt/ccxt/issues/3365 // https://github.com/ccxt/ccxt/issues/2873 'GET': 'Themis', 'GTC': 'Game.com', 'HIT': 'HitChain', // https://github.com/ccxt/ccxt/issues/7399 // https://coinmarketcap.com/currencies/pnetwork/ // https://coinmarketcap.com/currencies/penta/markets/ // https://en.cryptonomist.ch/blog/eidoo/the-edo-to-pnt-upgrade-what-you-need-to-know-updated/ 'PNT': 'Penta', 'SBTC': 'Super Bitcoin', 'BIFI': 'Bitcoin File', // conflict with Beefy.Finance https://github.com/ccxt/ccxt/issues/8706 }, }); } /** * @method * @name bittrade#fetchTime * @description fetches the current integer timestamp in milliseconds from the exchange server * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {int} the current integer timestamp in milliseconds from the exchange server */ async fetchTime(params = {}) { const response = await this.publicGetCommonTimestamp(params); return this.safeInteger(response, 'data'); } async fetchTradingLimits(symbols = undefined, params = {}) { // this method should not be called directly, use loadTradingLimits () instead // by default it will try load withdrawal fees of all currencies (with separate requests) // however if you define symbols = [ 'ETH/BTC', 'LTC/BTC' ] in args it will only load those await this.loadMarkets(); if (symbols === undefined) { symbols = this.symbols; } const result = {}; for (let i = 0; i < symbols.length; i++) { const symbol = symbols[i]; result[symbol] = await this.fetchTradingLimitsById(this.marketId(symbol), params); } return result; } async fetchTradingLimitsById(id, params = {}) { const request = { 'symbol': id, }; const response = await this.publicGetCommonExchange(this.extend(request, params)); // // { status: "ok", // "data": { symbol: "aidocbtc", // "buy-limit-must-less-than": 1.1, // "sell-limit-must-greater-than": 0.9, // "limit-order-must-greater-than": 1, // "limit-order-must-less-than": 5000000, // "market-buy-order-must-greater-than": 0.0001, // "market-buy-order-must-less-than": 100, // "market-sell-order-must-greater-than": 1, // "market-sell-order-must-less-than": 500000, // "circuit-break-when-greater-than": 10000, // "circuit-break-when-less-than": 10, // "market-sell-order-rate-must-less-than": 0.1, // "market-buy-order-rate-must-less-than": 0.1 } } // return this.parseTradingLimits(this.safeValue(response, 'data', {})); } parseTradingLimits(limits, symbol = undefined, params = {}) { // // { symbol: "aidocbtc", // "buy-limit-must-less-than": 1.1, // "sell-limit-must-greater-than": 0.9, // "limit-order-must-greater-than": 1, // "limit-order-must-less-than": 5000000, // "market-buy-order-must-greater-than": 0.0001, // "market-buy-order-must-less-than": 100, // "market-sell-order-must-greater-than": 1, // "market-sell-order-must-less-than": 500000, // "circuit-break-when-greater-than": 10000, // "circuit-break-when-less-than": 10, // "market-sell-order-rate-must-less-than": 0.1, // "market-buy-order-rate-must-less-than": 0.1 } // return { 'info': limits, 'limits': { 'amount': { 'min': this.safeNumber(limits, 'limit-order-must-greater-than'), 'max': this.safeNumber(limits, 'limit-order-must-less-than'), }, }, }; } costToPrecision(symbol, cost) { return this.decimalToPrecision(cost, TRUNCATE, this.markets[symbol]['precision']['cost'], this.precisionMode); } /** * @method * @name bittrade#fetchMarkets * @description retrieves data on all markets for huobijp * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} an array of objects representing market data */ async fetchMarkets(params = {}) { const method = this.options['fetchMarketsMethod']; const response = await this[method](params); // // { // "status": "ok", // "data": [ // { // "base-currency": "xrp", // "quote-currency": "btc", // "price-precision": 9, // "amount-precision": 2, // "symbol-partition": "default", // "symbol": "xrpbtc", // "state": "online", // "value-precision": 8, // "min-order-amt": 1, // "max-order-amt": 5000000, // "min-order-value": 0.0001, // "limit-order-min-order-amt": 1, // "limit-order-max-order-amt": 5000000, // "limit-order-max-buy-amt": 5000000, // "limit-order-max-sell-amt": 5000000, // "sell-market-min-order-amt": 1, // "sell-market-max-order-amt": 500000, // "buy-market-max-order-value": 100, // "leverage-ratio": 5, // "super-margin-leverage-ratio": 3, // "api-trading": "enabled", // "tags": "" // } // ... // ] // } // const markets = this.safeValue(response, 'data', []); const numMarkets = markets.length; if (numMarkets < 1) { throw new NetworkError(this.id + ' fetchMarkets() returned empty response: ' + this.json(markets)); } const result = []; for (let i = 0; i < markets.length; i++) { const market = markets[i]; const baseId = this.safeString(market, 'base-currency'); const quoteId = this.safeString(market, 'quote-currency'); const base = this.safeCurrencyCode(baseId); const quote = this.safeCurrencyCode(quoteId); const state = this.safeString(market, 'state'); const leverageRatio = this.safeString(market, 'leverage-ratio', '1'); const superLeverageRatio = this.safeString(market, 'super-margin-leverage-ratio', '1'); const margin = Precise.stringGt(leverageRatio, '1') || Precise.stringGt(superLeverageRatio, '1'); const fee = (base === 'OMG') ? this.parseNumber('0') : this.parseNumber('0.002'); result.push({ 'id': baseId + quoteId, 'symbol': base + '/' + quote, 'base': base, 'quote': quote, 'settle': undefined, 'baseId': baseId, 'quoteId': quoteId, 'settleId': undefined, 'type': 'spot', 'spot': true, 'margin': margin, 'swap': false, 'future': false, 'option': false, 'active': (state === 'online'), 'contract': false, 'linear': undefined, 'inverse': undefined, 'taker': fee, 'maker': fee, 'contractSize': undefined, 'expiry': undefined, 'expiryDatetime': undefined, 'strike': undefined, 'optionType': undefined, 'precision': { 'price': this.parseNumber(this.parsePrecision(this.safeString(market, 'price-precision'))), 'amount': this.parseNumber(this.parsePrecision(this.safeString(market, 'amount-precision'))), 'cost': this.parseNumber(this.parsePrecision(this.safeString(market, 'value-precision'))), }, 'limits': { 'leverage': { 'min': this.parseNumber('1'), 'max': this.parseNumber(leverageRatio), 'superMax': this.parseNumber(superLeverageRatio), }, 'amount': { 'min': this.safeNumber(market, 'min-order-amt'), 'max': this.safeNumber(market, 'max-order-amt'), }, 'price': { 'min': undefined, 'max': undefined, }, 'cost': { 'min': this.safeNumber(market, 'min-order-value'), 'max': undefined, }, }, 'created': undefined, 'info': market, }); } return result; } parseTicker(ticker, market = undefined) { // // fetchTicker // // { // "amount": 26228.672978342216, // "open": 9078.95, // "close": 9146.86, // "high": 9155.41, // "id": 209988544334, // "count": 265846, // "low": 8988.0, // "version": 209988544334, // "ask": [ 9146.87, 0.156134 ], // "vol": 2.3822168242201668E8, // "bid": [ 9146.86, 0.080758 ], // } // // fetchTickers // { // "symbol": "bhdht", // "open": 2.3938, // "high": 2.4151, // "low": 2.3323, // "close": 2.3909, // "amount": 628.992, // "vol": 1493.71841095, // "count": 2088, // "bid": 2.3643, // "bidSize": 0.7136, // "ask": 2.4061, // "askSize": 0.4156 // } // const symbol = this.safeSymbol(undefined, market); const timestamp = this.safeInteger(ticker, 'ts'); let bid = undefined; let bidVolume = undefined; let ask = undefined; let askVolume = undefined; if ('bid' in ticker) { if (Array.isArray(ticker['bid'])) { bid = this.safeString(ticker['bid'], 0); bidVolume = this.safeString(ticker['bid'], 1); } else { bid = this.safeString(ticker, 'bid'); bidVolume = this.safeString(ticker, 'bidSize'); } } if ('ask' in ticker) { if (Array.isArray(ticker['ask'])) { ask = this.safeString(ticker['ask'], 0); askVolume = this.safeString(ticker['ask'], 1); } else { ask = this.safeString(ticker, 'ask'); askVolume = this.safeString(ticker, 'askSize'); } } const open = this.safeString(ticker, 'open'); const close = this.safeString(ticker, 'close'); const baseVolume = this.safeString(ticker, 'amount'); const quoteVolume = this.safeString(ticker, 'vol'); return this.safeTicker({ 'symbol': symbol, 'timestamp': timestamp, 'datetime': this.iso8601(timestamp), 'high': this.safeString(ticker, 'high'), 'low': this.safeString(ticker, 'low'), 'bid': bid, 'bidVolume': bidVolume, 'ask': ask, 'askVolume': askVolume, 'vwap': undefined, 'open': open, 'close': close, 'last': close, 'previousClose': undefined, 'change': undefined, 'percentage': undefined, 'average': undefined, 'baseVolume': baseVolume, 'quoteVolume': quoteVolume, 'info': ticker, }, market); } /** * @method * @name bittrade#fetchOrderBook * @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 */ async fetchOrderBook(symbol, limit = undefined, params = {}) { await this.loadMarkets(); const market = this.market(symbol); const request = { 'symbol': market['id'], 'type': 'step0', }; const response = await this.marketGetDepth(this.extend(request, params)); // // { // "status": "ok", // "ch": "market.btcusdt.depth.step0", // "ts": 1583474832790, // "tick": { // "bids": [ // [ 9100.290000000000000000, 0.200000000000000000 ], // [ 9099.820000000000000000, 0.200000000000000000 ], // [ 9099.610000000000000000, 0.205000000000000000 ], // ], // "asks": [ // [ 9100.640000000000000000, 0.005904000000000000 ], // [ 9101.010000000000000000, 0.287311000000000000 ], // [ 9101.030000000000000000, 0.012121000000000000 ], // ], // "ts":1583474832008, // "version":104999698780 // } // } // if ('tick' in response) { if (!response['tick']) { throw new BadSymbol(this.id + ' fetchOrderBook() returned empty response: ' + this.json(response)); } const tick = this.safeValue(response, 'tick'); const timestamp = this.safeInteger(tick, 'ts', this.safeInteger(response, 'ts')); const result = this.parseOrderBook(tick, symbol, timestamp); result['nonce'] = this.safeInteger(tick, 'version'); return result; } throw new ExchangeError(this.id + ' fetchOrderBook() returned unrecognized response: ' + this.json(response)); } /** * @method * @name bittrade#fetchTicker * @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} */ async fetchTicker(symbol, params = {}) { await this.loadMarkets(); const market = this.market(symbol); const request = { 'symbol': market['id'], }; const response = await this.marketGetDetailMerged(this.extend(request, params)); // // { // "status": "ok", // "ch": "market.btcusdt.detail.merged", // "ts": 1583494336669, // "tick": { // "amount": 26228.672978342216, // "open": 9078.95, // "close": 9146.86, // "high": 9155.41, // "id": 209988544334, // "count": 265846, // "low": 8988.0, // "version": 209988544334, // "ask": [ 9146.87, 0.156134 ], // "vol": 2.3822168242201668E8, // "bid": [ 9146.86, 0.080758 ], // } // } // const ticker = this.parseTicker(response['tick'], market); const timestamp = this.safeInteger(response, 'ts'); ticker['timestamp'] = timestamp; ticker['datetime'] = this.iso8601(timestamp); return ticker; } /** * @method * @name bittrade#fetchTickers * @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} */ async fetchTickers(symbols = undefined, params = {}) { await this.loadMarkets(); symbols = this.marketSymbols(symbols); const response = await this.marketGetTickers(params); const tickers = this.safeValue(response, 'data', []); const timestamp = this.safeInteger(response, 'ts'); const result = {}; for (let i = 0; i < tickers.length; i++) { const marketId = this.safeString(tickers[i], 'symbol'); const market = this.safeMarket(marketId); const symbol = market['symbol']; const ticker = this.parseTicker(tickers[i], market); ticker['timestamp'] = timestamp; ticker['datetime'] = this.iso8601(timestamp); result[symbol] = ticker; } return this.filterByArrayTickers(result, 'symbol', symbols); } parseTrade(trade, market = undefined) { // // fetchTrades (public) // // { // "amount": 0.010411000000000000, // "trade-id": 102090736910, // "ts": 1583497692182, // "id": 10500517034273194594947, // "price": 9096.050000000000000000, // "direction": "sell" // } // // fetchMyTrades (private) // // { // "symbol": "swftcbtc", // "fee-currency": "swftc", // "filled-fees": "0", // "source": "spot-api", // "id": 83789509854000, // "type": "buy-limit", // "order-id": 83711103204909, // 'filled-points': "0.005826843283532154", // "fee-deduct-currency": "ht", // 'filled-amount': "45941.53", // "price": "0.0000001401", // "created-at": 1597933260729, // "match-id": 100087455560, // "role": "maker", // "trade-id": 100050305348 // }, // const marketId = this.safeString(trade, 'symbol'); const symbol = this.safeSymbol(marketId, market); const timestamp = this.safeInteger2(trade, 'ts', 'created-at'); const order = this.safeString(trade, 'order-id'); let side = this.safeString(trade, 'direction'); let type = this.safeString(trade, 'type'); if (type !== undefined) { const typeParts = type.split('-'); side = typeParts[0]; type = typeParts[1]; } const takerOrMaker = this.safeString(trade, 'role'); const price = this.safeString(trade, 'price'); const amount = this.safeString2(trade, 'filled-amount', 'amount'); const cost = Precise.stringMul(price, amount); let fee = undefined; let feeCost = this.safeString(trade, 'filled-fees'); let feeCurrency = this.safeCurrencyCode(this.safeString(trade, 'fee-currency')); const filledPoints = this.safeString(trade, 'filled-points'); if (filledPoints !== undefined) { if ((feeCost === undefined) || (Precise.stringEq(feeCost, '0.0'))) { feeCost = filledPoints; feeCurrency = this.safeCurrencyCode(this.safeString(trade, 'fee-deduct-currency')); } } if (feeCost !== undefined) { fee = { 'cost': feeCost, 'currency': feeCurrency, }; } const tradeId = this.safeString2(trade, 'trade-id', 'tradeId'); const id = this.safeString(trade, 'id', tradeId); return this.safeTrade({ 'info': trade, 'id': id, 'symbol': symbol, 'order': order, 'timestamp': timestamp, 'datetime': this.iso8601(timestamp), 'type': type, 'side': side, 'takerOrMaker': takerOrMaker, 'price': price, 'amount': amount, 'cost': cost, 'fee': fee, }); } /** * @method * @name bittrade#fetchOrderTrades * @description fetch all the trades made from a single order * @param {string} id order id * @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 to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure} */ async fetchOrderTrades(id, symbol = undefined, since = undefined, limit = undefined, params = {}) { await this.loadMarkets(); const request = { 'id': id, }; const response = await this.privateGetOrderOrdersIdMatchresults(this.extend(request, params)); return this.parseTrades(response['data'], undefined, since, limit); } /** * @method * @name bittrade#fetchMyTrades * @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} */ async fetchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) { await this.loadMarkets(); let market = undefined; const request = {}; if (symbol !== undefined) { market = this.market(symbol); request['symbol'] = market['id']; } if (limit !== undefined) { request['size'] = limit; // 1-100 orders, default is 100 } if (since !== undefined) { request['start-time'] = since; // a date within 120 days from today // request['end-time'] = this.sum (since, 172800000); // 48 hours window } const response = await this.privateGetOrderMatchresults(this.extend(request, params)); return this.parseTrades(response['data'], market, since, limit); } /** * @method * @name bittrade#fetchTrades * @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} */ async fetchTrades(symbol, since = undefined, limit = 1000, params = {}) { await this.loadMarkets(); const market = this.market(symbol); const request = { 'symbol': market['id'], }; if (limit !== undefined) { request['size'] = Math.min(limit, 2000); } const response = await this.marketGetHistoryTrade(this.extend(request, params)); // // { // "status": "ok", // "ch": "market.btcusdt.trade.detail", // "ts": 1583497692365, // "data": [ // { // "id": 105005170342, // "ts": 1583497692182, // "data": [ // { // "amount": 0.010411000000000000, // "trade-id": 102090736910, // "ts": 1583497692182, // "id": 10500517034273194594947, // "price": 9096.050000000000000000, // "direction": "sell" // } // ] // }, // // ... // ] // } // const data = this.safeValue(response, 'data', []); let result = []; for (let i = 0; i < data.length; i++) { const trades = this.safeValue(data[i], 'data', []); for (let j = 0; j < trades.length; j++) { const trade = this.parseTrade(trades[j], market); result.push(trade); } } result = this.sortBy(result, 'timestamp'); return this.filterBySymbolSinceLimit(result, market['symbol'], since, limit); } parseOHLCV(ohlcv, market = undefined) { // // { // "amount":1.2082, // "open":0.025096, // "close":0.025095, // "high":0.025096, // "id":1591515300, // "count":6, // "low":0.025095, // "vol":0.0303205097 // } // return [ this.safeTimestamp(ohlcv, 'id'), this.safeNumber(ohlcv, 'open'), this.safeNumber(ohlcv, 'high'), this.safeNumber(ohlcv, 'low'), this.safeNumber(ohlcv, 'close'), this.safeNumber(ohlcv, 'amount'), ]; } /** * @method * @name bittrade#fetchOHLCV * @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 * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume */ async fetchOHLCV(symbol, timeframe = '1m', since = undefined, limit = 1000, params = {}) { await this.loadMarkets(); const market = this.market(symbol); const request = { 'symbol': market['id'], 'period': this.safeString(this.timeframes, timeframe, timeframe), }; if (limit !== undefined) { request['size'] = Math.min(limit, 2000); } const response = await this.marketGetHistoryKline(this.extend(request, params)); // // { // "status":"ok", // "ch":"market.ethbtc.kline.1min", // "ts":1591515374371, // "data":[ // {"amount":0.0,"open":0.025095,"close":0.025095,"high":0.025095,"id":1591515360,"count":0,"low":0.025095,"vol":0.0}, // {"amount":1.2082,"open":0.025096,"close":0.025095,"high":0.025096,"id":1591515300,"count":6,"low":0.025095,"vol":0.0303205097}, // {"amount":0.0648,"open":0.025096,"close":0.025096,"high":0.025096,"id":1591515240,"count":2,"low":0.025096,"vol":0.0016262208}, // ] // } // const data = this.safeList(response, 'data', []); return this.parseOHLCVs(data, market, timeframe, since, limit); } /** * @method * @name bittrade#fetchAccounts * @description fetch all the accounts associated with a profile * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a dictionary of [account structures]{@link https://docs.ccxt.com/#/?id=account-structure} indexed by the account type */ async fetchAccounts(params = {}) { await this.loadMarkets(); const response = await this.privateGetAccountAccounts(params); return response['data']; } /** * @method * @name bittrade#fetchCurrencies * @description fetches all available currencies on an exchange * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} an associative dictionary of currencies */ async fetchCurrencies(params = {}) { const request = { 'language': this.options['language'], }; const response = await this.publicGetSettingsCurrencys(this.extend(request, params)); // // { // "status":"ok", // "data":[ // { // "currency-addr-with-tag":false, // "fast-confirms":12, // "safe-confirms":12, // "currency-type":"eth", // "quote-currency":true, // "withdraw-enable-timestamp":1609430400000, // "deposit-enable-timestamp":1609430400000, // "currency-partition":"all", // "support-sites":["OTC","INSTITUTION","MINEPOOL"], // "withdraw-precision":6, // "visible-assets-timestamp":1508839200000, // "deposit-min-amount":"1", // "withdraw-min-amount":"10", // "show-precision":"8", // "tags":"", // "weight":23, // "full-name":"Tether USDT", // "otc-enable":1, // "visible":true, // "white-enabled":false, // "country-disabled":false, // "deposit-enabled":true, // "withdraw-enabled":true, // "name":"usdt", // "state":"online", // "display-name":"USDT", // "suspend-withdraw-desc":null, // "withdraw-desc":"Minimum withdrawal amount: 10 USDT (ERC20). !>_<!To ensure the safety of your funds, your withdrawal request will be manually reviewed if your security strategy or password is changed. Pl