UNPKG

@proton/ccxt

Version:

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

1,125 lines (1,123 loc) 168 kB
'use strict'; var okcoin$1 = require('./abstract/okcoin.js'); var errors = require('./base/errors.js'); var Precise = require('./base/Precise.js'); var number = require('./base/functions/number.js'); var sha256 = require('./static_dependencies/noble-hashes/sha256.js'); // --------------------------------------------------------------------------- // --------------------------------------------------------------------------- class okcoin extends okcoin$1 { describe() { return this.deepExtend(super.describe(), { 'id': 'okcoin', 'name': 'OKCoin', 'countries': ['CN', 'US'], 'version': 'v3', // cheapest endpoint is 100 requests per 2 seconds // 50 requests per second => 1000 / 50 = 20ms 'rateLimit': 20, 'pro': true, 'has': { 'CORS': undefined, 'spot': true, 'margin': false, 'swap': undefined, 'future': true, 'option': undefined, 'cancelOrder': true, 'createOrder': true, 'fetchBalance': true, 'fetchClosedOrders': true, 'fetchCurrencies': true, 'fetchDepositAddress': true, 'fetchDeposits': true, 'fetchLedger': true, 'fetchMarkets': true, 'fetchMyTrades': true, 'fetchOHLCV': true, 'fetchOpenOrders': true, 'fetchOrder': true, 'fetchOrderBook': true, 'fetchOrders': undefined, 'fetchOrderTrades': true, 'fetchPosition': true, 'fetchPositions': true, 'fetchTicker': true, 'fetchTickers': true, 'fetchTime': true, 'fetchTrades': true, 'fetchTransactions': undefined, 'fetchWithdrawals': true, 'transfer': true, 'withdraw': true, }, 'timeframes': { '1m': '60', '3m': '180', '5m': '300', '15m': '900', '30m': '1800', '1h': '3600', '2h': '7200', '4h': '14400', '6h': '21600', '12h': '43200', '1d': '86400', '1w': '604800', '1M': '2678400', '3M': '8035200', '6M': '16070400', '1y': '31536000', }, 'hostname': 'okcoin.com', 'urls': { 'logo': 'https://user-images.githubusercontent.com/51840849/87295551-102fbf00-c50e-11ea-90a9-462eebba5829.jpg', 'api': { 'rest': 'https://www.{hostname}', }, 'www': 'https://www.okcoin.com', 'doc': 'https://www.okcoin.com/docs/en/', 'fees': 'https://www.okcoin.com/coin-fees', 'referral': 'https://www.okcoin.com/account/register?flag=activity&channelId=600001513', 'test': { 'rest': 'https://testnet.okex.com', }, }, 'api': { 'general': { 'get': { 'time': 8.3334, }, }, 'account': { 'get': { 'wallet': 8.3334, 'sub-account': 1000, 'asset-valuation': 1000, 'wallet/{currency}': 8.3334, 'withdrawal/history': 8.3334, 'withdrawal/history/{currency}': 8.3334, 'ledger': 5, 'deposit/address': 8.3334, 'deposit/history': 8.3334, 'deposit/history/{currency}': 8.3334, 'currencies': 8.3334, 'withdrawal/fee': 8.3334, 'deposit-lightning': 50, 'withdrawal-lightning': 50, 'fiat/deposit/detail': 5, 'fiat/deposit/details': 8.3334, 'fiat/withdraw/detail': 5, 'fiat/withdraw/details': 8.3334, 'fiat/channel': 8.3334, }, 'post': { 'transfer': 100, 'withdrawal': 8.3334, 'fiat/cancel_deposit': 1, 'fiat/deposit': 8.3334, 'fiat/withdraw': 8.3334, 'fiat/cancel_withdrawal': 1, }, }, // TODO fix signing issue in sign () // all other endpoints of the format // api/account/v3/wallet // otc endpoints actually of the format: (exchanged places) // api/v3/otc/rfq/instruments 'otc': { 'get': { 'rfq/instruments': 50, 'rfq/trade': 50, 'rfq/history': 50, }, 'post': { 'rfq/quote': 50, 'rfq/trade': 50, }, }, // TODO fix signing issue as above 'users': { 'get': { 'subaccount-info': 20, 'account-info': 20, 'subaccount/apikey': 20, }, 'post': { 'create-subaccount': 5, 'delete-subaccount': 5, 'subaccount/apikey': 50, 'subacount/delete-apikey': 20, 'subacount/modify-apikey': 20, }, }, 'earning': { 'get': { 'offers': 5, 'orders': 5, 'positions': 8.3334, }, 'post': { 'purchase': 5, 'redeem': 5, 'cancel': 5, }, }, 'spot': { 'get': { 'accounts': 5, 'accounts/{currency}': 5, 'accounts/{currency}/ledger': 5, 'orders': 10, 'orders_pending': 5, 'orders/{order_id}': 5, 'orders/{client_oid}': 5, 'trade_fee': 5, 'fills': 10, 'algo': 5, // public 'instruments': 5, 'instruments/{instrument_id}/book': 5, 'instruments/ticker': 5, 'instruments/{instrument_id}/ticker': 5, 'instruments/{instrument_id}/trades': 5, 'instruments/{instrument_id}/candles': 5, }, 'post': { 'order_algo': 2.5, 'orders': 1, 'batch_orders': 2, 'cancel_orders/{order_id}': 1, 'cancel_orders/{client_oid}': 1, 'cancel_batch_algos': 5, 'cancel_batch_orders': 5, 'amend_order/{instrument_id}': 2.5, 'amend_batch_orders': 5, }, }, 'margin': { // Margin trading closed down on February 21, 2022 'get': { 'accounts': 5, 'accounts/{instrument_id}': 5, 'accounts/{instrument_id}/ledger': 5, 'accounts/availability': 5, 'accounts/{instrument_id}/availability': 5, 'accounts/borrowed': 5, 'accounts/{instrument_id}/borrowed': 5, 'orders': 10, 'accounts/{instrument_id}/leverage': 1, 'orders/{order_id}': 5, 'orders/{client_oid}': 5, 'orders_pending': 5, 'fills': 10, // public 'instruments/{instrument_id}/mark_price': 5, }, 'post': { 'accounts/borrow': 1, 'accounts/repayment': 1, 'orders': 1, 'batch_orders': 2, 'cancel_orders': 1, 'cancel_orders/{order_id}': 1, 'cancel_orders/{client_oid}': 1, 'cancel_batch_orders': 2, 'amend_order/{instrument_id}': 2.5, 'amend_batch_orders': 5, 'accounts/{instrument_id}/leverage': 1, }, }, 'system': { 'get': { 'status': 250, }, }, 'market': { 'get': { 'oracle': 250, }, }, 'futures': { 'get': [ 'position', '{instrument_id}/position', 'accounts', 'accounts/{underlying}', 'accounts/{underlying}/leverage', 'accounts/{underlying}/ledger', 'order_algo/{instrument_id}', 'orders/{instrument_id}', 'orders/{instrument_id}/{order_id}', 'orders/{instrument_id}/{client_oid}', 'fills', 'trade_fee', 'accounts/{instrument_id}/holds', // public 'instruments', 'instruments/{instrument_id}/book', 'instruments/ticker', 'instruments/{instrument_id}/ticker', 'instruments/{instrument_id}/trades', 'instruments/{instrument_id}/candles', 'instruments/{instrument_id}/history/candles', 'instruments/{instrument_id}/index', 'rate', 'instruments/{instrument_id}/estimated_price', 'instruments/{instrument_id}/open_interest', 'instruments/{instrument_id}/price_limit', 'instruments/{instrument_id}/mark_price', 'instruments/{instrument_id}/liquidation', ], 'post': [ 'accounts/{underlying}/leverage', 'order', 'amend_order/{instrument_id}', 'orders', 'cancel_order/{instrument_id}/{order_id}', 'cancel_order/{instrument_id}/{client_oid}', 'cancel_batch_orders/{instrument_id}', 'accounts/margin_mode', 'close_position', 'cancel_all', 'order_algo', 'cancel_algos', ], }, 'swap': { 'get': [ 'position', '{instrument_id}/position', 'accounts', '{instrument_id}/accounts', 'accounts/{instrument_id}/settings', 'accounts/{instrument_id}/ledger', 'orders/{instrument_id}', 'orders/{instrument_id}/{order_id}', 'orders/{instrument_id}/{client_oid}', 'fills', 'accounts/{instrument_id}/holds', 'trade_fee', 'order_algo/{instrument_id}', // public 'instruments', 'instruments/{instrument_id}/depth', 'instruments/ticker', 'instruments/{instrument_id}/ticker', 'instruments/{instrument_id}/trades', 'instruments/{instrument_id}/candles', 'instruments/{instrument_id}/history/candles', 'instruments/{instrument_id}/index', 'rate', 'instruments/{instrument_id}/open_interest', 'instruments/{instrument_id}/price_limit', 'instruments/{instrument_id}/liquidation', 'instruments/{instrument_id}/funding_time', 'instruments/{instrument_id}/mark_price', 'instruments/{instrument_id}/historical_funding_rate', ], 'post': [ 'accounts/{instrument_id}/leverage', 'order', 'amend_order/{instrument_id}', 'orders', 'cancel_order/{instrument_id}/{order_id}', 'cancel_order/{instrument_id}/{client_oid}', 'cancel_batch_orders/{instrument_id}', 'order_algo', 'cancel_algos', 'close_position', 'cancel_all', ], }, 'option': { 'get': [ 'accounts', 'position', '{underlying}/position', 'accounts/{underlying}', 'orders/{underlying}', 'fills/{underlying}', 'accounts/{underlying}/ledger', 'trade_fee', 'orders/{underlying}/{order_id}', 'orders/{underlying}/{client_oid}', // public 'underlying', 'instruments/{underlying}', 'instruments/{underlying}/summary', 'instruments/{underlying}/summary/{instrument_id}', 'instruments/{instrument_id}/book', 'instruments/{instrument_id}/trades', 'instruments/{instrument_id}/ticker', 'instruments/{instrument_id}/candles', ], 'post': [ 'order', 'orders', 'cancel_order/{underlying}/{order_id}', 'cancel_order/{underlying}/{client_oid}', 'cancel_batch_orders/{underlying}', 'amend_order/{underlying}', 'amend_batch_orders/{underlying}', ], }, 'information': { 'get': [ '{currency}/long_short_ratio', '{currency}/volume', '{currency}/taker', '{currency}/sentiment', '{currency}/margin', ], }, 'index': { 'get': [ '{instrument_id}/constituents', ], }, }, 'fees': { 'trading': { 'taker': 0.002, 'maker': 0.001, }, 'spot': { 'taker': 0.0015, 'maker': 0.0010, }, }, 'requiredCredentials': { 'apiKey': true, 'secret': true, 'password': true, }, 'exceptions': { // http error codes // 400 Bad Request — Invalid request format // 401 Unauthorized — Invalid API Key // 403 Forbidden — You do not have access to the requested resource // 404 Not Found // 429 Client Error: Too Many Requests for url // 500 Internal Server Error — We had a problem with our server 'exact': { '1': errors.ExchangeError, // undocumented 'failure to get a peer from the ring-balancer': errors.ExchangeNotAvailable, 'Server is busy, please try again.': errors.ExchangeNotAvailable, 'An unexpected error occurred': errors.ExchangeError, 'System error': errors.ExchangeError, '4010': errors.PermissionDenied, // common // '0': ExchangeError, // 200 successful,when the order placement / cancellation / operation is successful '4001': errors.ExchangeError, '4002': errors.ExchangeError, // -------------------------------------------------------- '30001': errors.AuthenticationError, '30002': errors.AuthenticationError, '30003': errors.AuthenticationError, '30004': errors.AuthenticationError, '30005': errors.InvalidNonce, '30006': errors.AuthenticationError, '30007': errors.BadRequest, '30008': errors.RequestTimeout, '30009': errors.ExchangeError, '30010': errors.AuthenticationError, '30011': errors.PermissionDenied, '30012': errors.AuthenticationError, '30013': errors.AuthenticationError, '30014': errors.DDoSProtection, '30015': errors.AuthenticationError, '30016': errors.ExchangeError, '30017': errors.ExchangeError, '30018': errors.ExchangeError, '30019': errors.ExchangeNotAvailable, '30020': errors.BadRequest, '30021': errors.BadRequest, '30022': errors.PermissionDenied, '30023': errors.BadRequest, '30024': errors.BadSymbol, '30025': errors.BadRequest, '30026': errors.DDoSProtection, '30027': errors.AuthenticationError, '30028': errors.PermissionDenied, '30029': errors.AccountSuspended, '30030': errors.ExchangeNotAvailable, '30031': errors.BadRequest, '30032': errors.BadSymbol, '30033': errors.BadRequest, '30034': errors.ExchangeError, '30035': errors.ExchangeError, '30036': errors.ExchangeError, '30037': errors.ExchangeNotAvailable, // '30038': AuthenticationError, // { "code": 30038, "message": "user does not exist" } '30038': errors.OnMaintenance, '30044': errors.RequestTimeout, // futures '32001': errors.AccountSuspended, '32002': errors.PermissionDenied, '32003': errors.CancelPending, '32004': errors.ExchangeError, '32005': errors.InvalidOrder, '32006': errors.InvalidOrder, '32007': errors.InvalidOrder, '32008': errors.InvalidOrder, '32009': errors.InvalidOrder, '32010': errors.ExchangeError, '32011': errors.ExchangeError, '32012': errors.ExchangeError, '32013': errors.ExchangeError, '32014': errors.ExchangeError, '32015': errors.ExchangeError, '32016': errors.ExchangeError, '32017': errors.ExchangeError, '32018': errors.ExchangeError, '32019': errors.ExchangeError, '32020': errors.ExchangeError, '32021': errors.ExchangeError, '32022': errors.ExchangeError, '32023': errors.ExchangeError, '32024': errors.ExchangeError, '32025': errors.ExchangeError, '32026': errors.ExchangeError, '32027': errors.ExchangeError, '32028': errors.ExchangeError, '32029': errors.ExchangeError, '32030': errors.InvalidOrder, '32031': errors.ArgumentsRequired, '32038': errors.AuthenticationError, '32040': errors.ExchangeError, '32044': errors.ExchangeError, '32045': errors.ExchangeError, '32046': errors.ExchangeError, '32047': errors.ExchangeError, '32048': errors.InvalidOrder, '32049': errors.ExchangeError, '32050': errors.InvalidOrder, '32051': errors.InvalidOrder, '32052': errors.ExchangeError, '32053': errors.ExchangeError, '32057': errors.ExchangeError, '32054': errors.ExchangeError, '32055': errors.InvalidOrder, '32056': errors.ExchangeError, '32058': errors.ExchangeError, '32059': errors.InvalidOrder, '32060': errors.InvalidOrder, '32061': errors.InvalidOrder, '32062': errors.InvalidOrder, '32063': errors.InvalidOrder, '32064': errors.ExchangeError, '32065': errors.ExchangeError, '32066': errors.ExchangeError, '32067': errors.ExchangeError, '32068': errors.ExchangeError, '32069': errors.ExchangeError, '32070': errors.ExchangeError, '32071': errors.ExchangeError, '32072': errors.ExchangeError, '32073': errors.ExchangeError, '32074': errors.ExchangeError, '32075': errors.ExchangeError, '32076': errors.ExchangeError, '32077': errors.ExchangeError, '32078': errors.ExchangeError, '32079': errors.ExchangeError, '32080': errors.ExchangeError, '32083': errors.ExchangeError, // token and margin trading '33001': errors.PermissionDenied, '33002': errors.AccountSuspended, '33003': errors.InsufficientFunds, '33004': errors.ExchangeError, '33005': errors.ExchangeError, '33006': errors.ExchangeError, '33007': errors.ExchangeError, '33008': errors.InsufficientFunds, '33009': errors.ExchangeError, '33010': errors.ExchangeError, '33011': errors.ExchangeError, '33012': errors.ExchangeError, '33013': errors.InvalidOrder, '33014': errors.OrderNotFound, '33015': errors.InvalidOrder, '33016': errors.ExchangeError, '33017': errors.InsufficientFunds, '33018': errors.ExchangeError, '33020': errors.ExchangeError, '33021': errors.BadRequest, '33022': errors.InvalidOrder, '33023': errors.ExchangeError, '33024': errors.InvalidOrder, '33025': errors.InvalidOrder, '33026': errors.ExchangeError, '33027': errors.InvalidOrder, '33028': errors.InvalidOrder, '33029': errors.InvalidOrder, '33034': errors.ExchangeError, '33035': errors.ExchangeError, '33036': errors.ExchangeError, '33037': errors.ExchangeError, '33038': errors.ExchangeError, '33039': errors.ExchangeError, '33040': errors.ExchangeError, '33041': errors.ExchangeError, '33042': errors.ExchangeError, '33043': errors.ExchangeError, '33044': errors.ExchangeError, '33045': errors.ExchangeError, '33046': errors.ExchangeError, '33047': errors.ExchangeError, '33048': errors.ExchangeError, '33049': errors.ExchangeError, '33050': errors.ExchangeError, '33051': errors.ExchangeError, '33059': errors.BadRequest, '33060': errors.BadRequest, '33061': errors.ExchangeError, '33062': errors.ExchangeError, '33063': errors.ExchangeError, '33064': errors.ExchangeError, '33065': errors.ExchangeError, '33085': errors.InvalidOrder, // account '21009': errors.ExchangeError, '34001': errors.PermissionDenied, '34002': errors.InvalidAddress, '34003': errors.ExchangeError, '34004': errors.ExchangeError, '34005': errors.ExchangeError, '34006': errors.ExchangeError, '34007': errors.ExchangeError, '34008': errors.InsufficientFunds, '34009': errors.ExchangeError, '34010': errors.ExchangeError, '34011': errors.ExchangeError, '34012': errors.ExchangeError, '34013': errors.ExchangeError, '34014': errors.ExchangeError, '34015': errors.ExchangeError, '34016': errors.PermissionDenied, '34017': errors.AccountSuspended, '34018': errors.AuthenticationError, '34019': errors.PermissionDenied, '34020': errors.PermissionDenied, '34021': errors.InvalidAddress, '34022': errors.ExchangeError, '34023': errors.PermissionDenied, '34026': errors.RateLimitExceeded, '34036': errors.ExchangeError, '34037': errors.ExchangeError, '34038': errors.ExchangeError, '34039': errors.ExchangeError, // swap '35001': errors.ExchangeError, '35002': errors.ExchangeError, '35003': errors.ExchangeError, '35004': errors.ExchangeError, '35005': errors.AuthenticationError, '35008': errors.InvalidOrder, '35010': errors.InvalidOrder, '35012': errors.InvalidOrder, '35014': errors.InvalidOrder, '35015': errors.InvalidOrder, '35017': errors.ExchangeError, '35019': errors.InvalidOrder, '35020': errors.InvalidOrder, '35021': errors.InvalidOrder, '35022': errors.BadRequest, '35024': errors.BadRequest, '35025': errors.InsufficientFunds, '35026': errors.BadRequest, '35029': errors.OrderNotFound, '35030': errors.InvalidOrder, '35031': errors.InvalidOrder, '35032': errors.ExchangeError, '35037': errors.ExchangeError, '35039': errors.InsufficientFunds, '35040': errors.InvalidOrder, '35044': errors.ExchangeError, '35046': errors.InsufficientFunds, '35047': errors.InsufficientFunds, '35048': errors.ExchangeError, '35049': errors.InvalidOrder, '35050': errors.InvalidOrder, '35052': errors.InsufficientFunds, '35053': errors.ExchangeError, '35055': errors.InsufficientFunds, '35057': errors.ExchangeError, '35058': errors.ExchangeError, '35059': errors.BadRequest, '35060': errors.BadRequest, '35061': errors.BadRequest, '35062': errors.InvalidOrder, '35063': errors.InvalidOrder, '35064': errors.InvalidOrder, '35066': errors.InvalidOrder, '35067': errors.InvalidOrder, '35068': errors.InvalidOrder, '35069': errors.InvalidOrder, '35070': errors.InvalidOrder, '35071': errors.InvalidOrder, '35072': errors.InvalidOrder, '35073': errors.InvalidOrder, '35074': errors.InvalidOrder, '35075': errors.InvalidOrder, '35076': errors.InvalidOrder, '35077': errors.InvalidOrder, '35078': errors.InvalidOrder, '35079': errors.InvalidOrder, '35080': errors.InvalidOrder, '35081': errors.InvalidOrder, '35082': errors.InvalidOrder, '35083': errors.InvalidOrder, '35084': errors.InvalidOrder, '35085': errors.InvalidOrder, '35086': errors.InvalidOrder, '35087': errors.InvalidOrder, '35088': errors.InvalidOrder, '35089': errors.InvalidOrder, '35090': errors.ExchangeError, '35091': errors.ExchangeError, '35092': errors.ExchangeError, '35093': errors.ExchangeError, '35094': errors.ExchangeError, '35095': errors.BadRequest, '35096': errors.ExchangeError, '35097': errors.ExchangeError, '35098': errors.ExchangeError, '35099': errors.ExchangeError, '35102': errors.RateLimitExceeded, // option '36001': errors.BadRequest, '36002': errors.BadRequest, '36005': errors.ExchangeError, '36101': errors.AuthenticationError, '36102': errors.PermissionDenied, '36103': errors.PermissionDenied, '36104': errors.PermissionDenied, '36105': errors.PermissionDenied, '36106': errors.PermissionDenied, '36107': errors.PermissionDenied, '36108': errors.InsufficientFunds, '36109': errors.PermissionDenied, '36201': errors.PermissionDenied, '36202': errors.PermissionDenied, '36203': errors.InvalidOrder, '36204': errors.ExchangeError, '36205': errors.BadRequest, '36206': errors.BadRequest, '36207': errors.InvalidOrder, '36208': errors.InvalidOrder, '36209': errors.InvalidOrder, '36210': errors.InvalidOrder, '36211': errors.InvalidOrder, '36212': errors.InvalidOrder, '36213': errors.InvalidOrder, '36214': errors.ExchangeError, '36216': errors.OrderNotFound, '36217': errors.InvalidOrder, '36218': errors.InvalidOrder, '36219': errors.InvalidOrder, '36220': errors.InvalidOrder, '36221': errors.InvalidOrder, '36222': errors.InvalidOrder, '36223': errors.InvalidOrder, '36224': errors.InvalidOrder, '36225': errors.InvalidOrder, '36226': errors.InvalidOrder, '36227': errors.InvalidOrder, '36228': errors.InvalidOrder, '36229': errors.InvalidOrder, '36230': errors.InvalidOrder, // Exceeding max position limit for underlying. }, 'broad': {}, }, 'precisionMode': number.TICK_SIZE, 'options': { 'fetchOHLCV': { 'type': 'Candles', // Candles or HistoryCandles }, 'createMarketBuyOrderRequiresPrice': true, 'fetchMarkets': ['spot'], 'defaultType': 'spot', 'accountsByType': { 'spot': '1', 'funding': '6', 'main': '6', }, 'accountsById': { '1': 'spot', '6': 'funding', }, 'auth': { 'time': 'public', 'currencies': 'private', 'instruments': 'public', 'rate': 'public', '{instrument_id}/constituents': 'public', }, 'warnOnFetchCurrenciesWithoutAuthorization': false, }, 'commonCurrencies': { // OKEX refers to ERC20 version of Aeternity (AEToken) 'AE': 'AET', 'BOX': 'DefiBox', 'HOT': 'Hydro Protocol', 'HSR': 'HC', 'MAG': 'Maggie', 'SBTC': 'Super Bitcoin', 'TRADE': 'Unitrade', 'YOYO': 'YOYOW', 'WIN': 'WinToken', // https://github.com/ccxt/ccxt/issues/5701 }, }); } async fetchTime(params = {}) { /** * @method * @name okcoin#fetchTime * @description fetches the current integer timestamp in milliseconds from the exchange server * @param {object} params extra parameters specific to the okcoin api endpoint * @returns {int} the current integer timestamp in milliseconds from the exchange server */ const response = await this.generalGetTime(params); // // { // "iso": "2015-01-07T23:47:25.201Z", // "epoch": 1420674445.201 // } // return this.parse8601(this.safeString(response, 'iso')); } async fetchMarkets(params = {}) { /** * @method * @name okcoin#fetchMarkets * @description retrieves data on all markets for okcoin * @param {object} params extra parameters specific to the exchange api endpoint * @returns {[object]} an array of objects representing market data */ const types = this.safeValue(this.options, 'fetchMarkets'); let result = []; for (let i = 0; i < types.length; i++) { const markets = await this.fetchMarketsByType(types[i], params); result = this.arrayConcat(result, markets); } return result; } parseMarkets(markets) { const result = []; for (let i = 0; i < markets.length; i++) { result.push(this.parseMarket(markets[i])); } return result; } parseMarket(market) { // // spot markets // // { // base_currency: "EOS", // instrument_id: "EOS-OKB", // min_size: "0.01", // quote_currency: "OKB", // size_increment: "0.000001", // tick_size: "0.0001" // } // // futures markets // // { // instrument_id: "XRP-USD-200320", // underlying_index: "XRP", // quote_currency: "USD", // tick_size: "0.0001", // contract_val: "10", // listing: "2020-03-06", // delivery: "2020-03-20", // trade_increment: "1", // alias: "this_week", // underlying: "XRP-USD", // base_currency: "XRP", // settlement_currency: "XRP", // is_inverse: "true", // contract_val_currency: "USD", // } // // swap markets // // { // instrument_id: "BSV-USD-SWAP", // underlying_index: "BSV", // quote_currency: "USD", // coin: "BSV", // contract_val: "10", // listing: "2018-12-21T07:53:47.000Z", // delivery: "2020-03-14T08:00:00.000Z", // size_increment: "1", // tick_size: "0.01", // base_currency: "BSV", // underlying: "BSV-USD", // settlement_currency: "BSV", // is_inverse: "true", // contract_val_currency: "USD" // } // // options markets // // { // instrument_id: 'BTC-USD-200327-4000-C', // underlying: 'BTC-USD', // settlement_currency: 'BTC', // contract_val: '0.1000', // option_type: 'C', // strike: '4000', // tick_size: '0.0005', // lot_size: '1.0000', // listing: '2019-12-25T08:30:36.302Z', // delivery: '2020-03-27T08:00:00.000Z', // state: '2', // trading_start_time: '2019-12-25T08:30:36.302Z', // timestamp: '2020-03-13T08:05:09.456Z', // } // const id = this.safeString(market, 'instrument_id'); let optionType = this.safeValue(market, 'option_type'); const contractVal = this.safeNumber(market, 'contract_val'); const contract = contractVal !== undefined; const futuresAlias = this.safeString(market, 'alias'); let marketType = 'spot'; const spot = !contract; const option = (optionType !== undefined); const future = !option && (futuresAlias !== undefined); const swap = contract && !future && !option; let baseId = this.safeString(market, 'base_currency'); let quoteId = this.safeString(market, 'quote_currency'); const settleId = this.safeString(market, 'settlement_currency'); if (option) { const underlying = this.safeString(market, 'underlying'); const parts = underlying.split('-'); baseId = this.safeString(parts, 0); quoteId = this.safeString(parts, 1); marketType = 'option'; } else if (future) { baseId = this.safeString(market, 'underlying_index'); marketType = 'futures'; } else if (swap) { marketType = 'swap'; } const base = this.safeCurrencyCode(baseId); const quote = this.safeCurrencyCode(quoteId); const settle = this.safeCurrencyCode(settleId); let symbol = base + '/' + quote; let expiryDatetime = this.safeString(market, 'delivery'); let expiry = undefined; const strike = this.safeValue(market, 'strike'); if (contract) { symbol = symbol + ':' + settle; if (future || option) { if (future) { expiryDatetime += 'T00:00:00Z'; } expiry = this.parse8601(expiryDatetime); symbol = symbol + '-' + this.yymmdd(expiry); if (option) { symbol = symbol + ':' + strike + ':' + optionType; optionType = (optionType === 'C') ? 'call' : 'put'; } } } const lotSize = this.safeNumber2(market, 'lot_size', 'trade_increment'); const minPrice = this.safeString(market, 'tick_size'); const minAmountString = this.safeString2(market, 'min_size', 'base_min_size'); const minAmount = this.parseNumber(minAmountString); let minCost = undefined; if ((minAmount !== undefined) && (minPrice !== undefined)) { minCost = this.parseNumber(Precise["default"].stringMul(minPrice, minAmountString)); } const fees = this.safeValue2(this.fees, marketType, 'trading', {}); const maxLeverageString = this.safeString(market, 'max_leverage', '1'); const maxLeverage = this.parseNumber(Precise["default"].stringMax(maxLeverageString, '1')); const precisionPrice = this.parseNumber(minPrice); return this.extend(fees, { 'id': id, 'symbol': symbol, 'base': base, 'quote': quote, 'settle': settle, 'baseId': baseId, 'quoteId': quoteId, 'settleId': settleId, 'type': marketType, 'spot': spot, 'margin': false, 'swap': swap, 'future': future, 'futures': future, 'option': option, 'active': true, 'contract': contract, 'linear': contract ? (quote === settle) : undefined, 'inverse': contract ? (base === settle) : undefined, 'contractSize': contractVal, 'expiry': expiry, 'expiryDatetime': this.iso8601(expiry), 'strike': strike, 'optionType': optionType, 'precision': { 'amount': this.safeNumber(market, 'size_increment', lotSize), 'price': precisionPrice, }, 'limits': { 'leverage': { 'min': this.parseNumber('1'), 'max': this.parseNumber(maxLeverage), }, 'amount': { 'min': minAmount, 'max': undefined, }, 'price': { 'min': precisionPrice, 'max': undefined, }, 'cost': { 'min': minCost, 'max': undefined, }, }, 'info': market, }); } async fetchMarketsByType(type, params = {}) { if (type === 'option') { const underlying = await this.optionGetUnderlying(params); let result = []; for (let i = 0; i < underlying.length; i++) { const response = await this.optionGetInstrumentsUnderlying({ 'underlying': underlying[i], }); // // options markets // // [ // { // instrument_id: 'BTC-USD-200327-4000-C', // underlying: 'BTC-USD', // settlement_currency: 'BTC', // contract_val: '0.1000', // option_type: 'C', // strike: '4000', // tick_size: '0.0005', // lot_size: '1.0000', // listing: '2019-12-25T08:30:36.302Z', // delivery: '2020-03-27T08:00:00.000Z', // state: '2', // trading_start_time: '2019-12-25T08:30:36.302Z', // timestamp: '2020-03-13T08:05:09.456Z', // }, // ] // result = this.arrayConcat(result, response); } return this.parseMarkets(result); } else if ((type === 'spot') || (type === 'futures') || (type === 'swap')) { const method = type + 'GetInstruments'; const response = await this[method](params); // // spot markets // // [ // { // base_currency: "EOS", // instrument_id: "EOS-OKB", // min_size: "0.01", // quote_currency: "OKB", // size_increment: "0.000001", // tick_size: "0.0001" // } // ] // // futures markets // // [ // { // instrument_id: "XRP-USD-200320", // underlying_index: "XRP", // quote_currency: "USD", // tick_size: "0.0001", // contract_val: "10", // listing: "2020-03-06", // delivery: "2020-03-20", // trade_increment: "1", // alias: "this_week", // underlying: "XRP-USD", // base_currency: "XRP", // settlement_currency: "XRP", // is_inverse: "true", // contract_val_currency: "USD", // } // ] // // swap markets // // [ // { // instrument_id: "BSV-USD-SWAP", // underlying_index: "BSV", // quote_currency: "USD", // coin: "BSV", // contract_val: "10", // listing: "2018-12-21T07:53:47.000Z", // delivery: "2020-03-14T08:00:00.000Z", // size_increment: "1", // tick_size: "0.01", // base_currency: "BSV", // underlying: "BSV-USD", // settlement_currency: "BSV", // is_inverse: "true", // contract_val_currency: "USD" // } // ] // return this.parseMarkets(response); } else { throw new errors.NotSupported(this.id + ' fetchMarketsByType() does not support market type ' + type); } } async fetchCurrencies(params = {}) { /** * @method * @name okcoin#fetchCurrencies * @description fetches all available currencies on an exchange * @param {object} params extra parameters specific to the okcoin api endpoint * @returns {object} an associative dictionary of currencies */ // despite that their docs say these endpoints are public: // https://www.okex.com/api/account/v3/withdrawal/fee // https://www.okex.com/api/account/v3/currencies // it will still reply with { "code":30001, "message": "OK-ACCESS-KEY header is required" } // if you attempt to access it without authentication if (!this.checkRequiredCredentials(false)) { if (this.options['warnOnFetchCurrenciesWithoutAuthorization']) { throw new errors.ExchangeError(this.id + ' fetchCurrencies() is a private API endpoint that requires authentication with API keys. Set the API keys on the exchange instance or exchange.options["warnOnFetchCurrenciesWithoutAuthorization"] = false to suppress this warning message.'); } return undefined; } else { const response = await this.accountGetCurrencies(params); // // [ // { // name: '', // currency: 'BTC', // can_withdraw: '1', // can_deposit: '1', // min_withdrawal: '0.0100000000000000' // }, //