@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
JavaScript
'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'
// },
//