UNPKG

@proton/ccxt

Version:

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

1,126 lines (1,124 loc) 287 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/okx.js'; import { ExchangeError, ExchangeNotAvailable, OnMaintenance, ArgumentsRequired, BadRequest, AccountSuspended, InvalidAddress, PermissionDenied, InsufficientFunds, InvalidNonce, InvalidOrder, OrderNotFound, AuthenticationError, RequestTimeout, BadSymbol, RateLimitExceeded, NetworkError, CancelPending, NotSupported, AccountNotEnabled } from './base/errors.js'; import { Precise } from './base/Precise.js'; import { TICK_SIZE } from './base/functions/number.js'; import { sha256 } from './static_dependencies/noble-hashes/sha256.js'; // --------------------------------------------------------------------------- export default class okx extends Exchange { describe() { return this.deepExtend(super.describe(), { 'id': 'okx', 'name': 'OKX', 'countries': ['CN', 'US'], 'version': 'v5', 'rateLimit': 100, 'pro': true, 'certified': true, 'has': { 'CORS': undefined, 'spot': true, 'margin': true, 'swap': true, 'future': true, 'option': true, 'addMargin': true, 'borrowMargin': true, 'cancelAllOrders': false, 'cancelOrder': true, 'cancelOrders': true, 'createDepositAddress': false, 'createOrder': true, 'createPostOnlyOrder': true, 'createReduceOnlyOrder': true, 'createStopLimitOrder': true, 'createStopMarketOrder': true, 'createStopOrder': true, 'editOrder': true, 'fetchAccounts': true, 'fetchBalance': true, 'fetchBidsAsks': undefined, 'fetchBorrowInterest': true, 'fetchBorrowRate': true, 'fetchBorrowRateHistories': true, 'fetchBorrowRateHistory': true, 'fetchBorrowRates': true, 'fetchBorrowRatesPerSymbol': false, 'fetchCanceledOrders': true, 'fetchClosedOrder': undefined, 'fetchClosedOrders': true, 'fetchCurrencies': true, 'fetchDeposit': true, 'fetchDepositAddress': true, 'fetchDepositAddresses': false, 'fetchDepositAddressesByNetwork': true, 'fetchDeposits': true, 'fetchDepositsWithdrawals': false, 'fetchDepositWithdrawFee': 'emulated', 'fetchDepositWithdrawFees': true, 'fetchFundingHistory': true, 'fetchFundingRate': true, 'fetchFundingRateHistory': true, 'fetchFundingRates': false, 'fetchIndexOHLCV': true, 'fetchL3OrderBook': false, 'fetchLedger': true, 'fetchLedgerEntry': undefined, 'fetchLeverage': true, 'fetchLeverageTiers': false, 'fetchMarketLeverageTiers': true, 'fetchMarkets': true, 'fetchMarkOHLCV': true, 'fetchMyTrades': true, 'fetchOHLCV': true, 'fetchOpenInterest': true, 'fetchOpenInterestHistory': true, 'fetchOpenOrder': undefined, 'fetchOpenOrders': true, 'fetchOrder': true, 'fetchOrderBook': true, 'fetchOrderBooks': false, 'fetchOrders': false, 'fetchOrderTrades': true, 'fetchPermissions': undefined, 'fetchPosition': true, 'fetchPositions': true, 'fetchPositionsRisk': false, 'fetchPremiumIndexOHLCV': false, 'fetchSettlementHistory': true, 'fetchStatus': true, 'fetchTicker': true, 'fetchTickers': true, 'fetchTime': true, 'fetchTrades': true, 'fetchTradingFee': true, 'fetchTradingFees': false, 'fetchTradingLimits': false, 'fetchTransactionFee': false, 'fetchTransactionFees': false, 'fetchTransactions': false, 'fetchTransfer': true, 'fetchTransfers': true, 'fetchWithdrawal': true, 'fetchWithdrawals': true, 'fetchWithdrawalWhitelist': false, 'reduceMargin': true, 'repayMargin': true, 'setLeverage': true, 'setMargin': false, 'setMarginMode': true, 'setPositionMode': true, 'signIn': false, 'transfer': true, 'withdraw': true, }, 'timeframes': { '1m': '1m', '3m': '3m', '5m': '5m', '15m': '15m', '30m': '30m', '1h': '1H', '2h': '2H', '4h': '4H', '6h': '6H', '12h': '12H', '1d': '1D', '1w': '1W', '1M': '1M', '3M': '3M', }, 'hostname': 'www.okx.com', 'urls': { 'logo': 'https://user-images.githubusercontent.com/1294454/152485636-38b19e4a-bece-4dec-979a-5982859ffc04.jpg', 'api': { 'rest': 'https://{hostname}', }, 'www': 'https://www.okx.com', 'doc': 'https://www.okx.com/docs-v5/en/', 'fees': 'https://www.okx.com/pages/products/fees.html', 'referral': 'https://www.okx.com/join/1888677', 'test': { 'rest': 'https://{hostname}', }, }, 'api': { 'public': { 'get': { 'market/tickers': 1, 'market/ticker': 1, 'market/index-tickers': 1, 'market/books': 1, 'market/books-lite': 1.66, 'market/candles': 0.5, 'market/history-candles': 1, 'market/history-mark-price-candles': 2, 'market/history-index-candles': 2, 'market/index-candles': 1, 'market/mark-price-candles': 1, 'market/trades': 1, 'market/history-trades': 2, 'market/platform-24-volume': 10, 'market/open-oracle': 40, 'market/index-components': 1, 'market/option/instrument-family-trades': 1, // 'market/oracle', 'public/instruments': 1, 'public/instrument-tick-bands': 4, 'public/delivery-exercise-history': 0.5, 'public/open-interest': 1, 'public/funding-rate': 1, 'public/funding-rate-history': 1, 'public/price-limit': 1, 'public/opt-summary': 1, 'public/estimated-price': 2, 'public/discount-rate-interest-free-quota': 10, 'public/time': 2, 'public/liquidation-orders': 0.5, 'public/mark-price': 2, 'public/option-trades': 1, // 'public/tier', 'public/position-tiers': 2, 'public/underlying': 1, 'public/interest-rate-loan-quota': 10, 'public/vip-interest-rate-loan-quota': 10, 'rubik/stat/trading-data/support-coin': 4, 'rubik/stat/taker-volume': 4, 'rubik/stat/margin/loan-ratio': 4, // long/short 'rubik/stat/contracts/long-short-account-ratio': 4, 'rubik/stat/contracts/open-interest-volume': 4, 'rubik/stat/option/open-interest-volume': 4, // put/call 'rubik/stat/option/open-interest-volume-ratio': 4, 'rubik/stat/option/open-interest-volume-expiry': 4, 'rubik/stat/option/open-interest-volume-strike': 4, 'rubik/stat/option/taker-block-volume': 4, 'system/status': 100, 'finance/savings/lending-rate-summary': 5 / 3, 'finance/savings/lending-rate-history': 5 / 3, 'market/exchange-rate': 20, }, }, 'private': { 'get': { 'account/account-position-risk': 2, 'account/balance': 2, 'account/positions': 2, 'account/positions-history': 2, 'account/bills': 5 / 3, 'account/bills-archive': 5 / 3, 'account/config': 4, 'account/max-size': 1, 'account/max-avail-size': 1, 'account/leverage-info': 1, 'account/max-loan': 1, 'account/trade-fee': 4, 'account/interest-accrued': 4, 'account/interest-rate': 4, 'account/max-withdrawal': 1, 'account/risk-state': 2, 'account/borrow-repay-history': 4, 'account/quick-margin-borrow-repay-history': 4, 'account/interest-limits': 4, 'account/vip-interest-accrued': 4, 'account/vip-loan-order-list': 4, 'account/vip-loan-order-detail': 4, 'asset/asset-valuation': 1 / 5, 'asset/deposit-address': 5 / 3, 'asset/balances': 5 / 3, 'asset/transfer-state': 10, 'asset/transfer-record': 10, 'asset/deposit-history': 5 / 3, 'asset/withdrawal-history': 5 / 3, 'asset/deposit-withdraw-status': 20, 'asset/currencies': 5 / 3, 'asset/bills': 5 / 3, 'asset/piggy-balance': 5 / 3, 'asset/deposit-lightning': 5, 'asset/non-tradable-assets': 5 / 3, 'trade/order': 1 / 3, 'trade/orders-pending': 1, 'trade/orders-history': 0.5, 'trade/orders-history-archive': 1, 'trade/fills': 1 / 3, 'trade/fills-history': 2, 'trade/orders-algo-pending': 1, 'trade/orders-algo-history': 1, 'trade/order-algo': 1, 'account/subaccount/balances': 10, 'account/subaccount/interest-limits': 4, 'asset/subaccount/bills': 5 / 3, 'asset/subaccount/managed-subaccount-bills': 5 / 3, 'users/subaccount/list': 10, 'users/subaccount/apikey': 10, 'users/entrust-subaccount-list': 10, // broker 'broker/nd/info': 10, 'broker/nd/subaccount-info': 10, 'asset/broker/nd/subaccount-deposit-address': 4, 'asset/broker/nd/subaccount-deposit-history': 4, 'broker/nd/rebate-daily': 1, 'broker/nd/subaccount/apikey': 10, 'broker/nd/rebate-per-orders': 300, 'asset/broker/nd/subaccount-withdrawal-history': 4, // convert 'asset/convert/currencies': 5 / 3, 'asset/convert/currency-pair': 5 / 3, 'asset/convert/estimate-quote': 5, 'asset/convert/trade': 5, 'asset/convert/history': 5 / 3, // options 'account/greeks': 2, // earn 'finance/staking-defi/offers': 1, 'finance/staking-defi/orders-active': 1, 'finance/staking-defi/orders-history': 1, 'finance/savings/balance': 5 / 3, 'finance/savings/lending-history': 5 / 3, 'rfq/counterparties': 4, 'rfq/maker-instrument-settings': 4, 'rfq/rfqs': 10, 'rfq/quotes': 10, 'rfq/trades': 4, 'rfq/public-trades': 4, // copytrading 'copytrading/current-subpositions': 10, 'copytrading/subpositions-history': 10, 'copytrading/instruments': 10, 'copytrading/profit-sharing-details': 10, 'copytrading/total-profit-sharing': 10, 'copytrading/unrealized-profit-sharing-details': 10, // grid trading 'tradingBot/grid/orders-algo-pending': 1, 'tradingBot/grid/orders-algo-history': 1, 'tradingBot/grid/orders-algo-details': 1, 'tradingBot/grid/sub-orders': 1, 'tradingBot/grid/positions': 1, 'tradingBot/grid/ai-param': 1, }, 'post': { 'account/set-position-mode': 4, 'account/set-leverage': 1, 'account/position/margin-balance': 1, 'account/set-greeks': 4, 'account/set-isolated-mode': 4, 'account/set-riskOffset-type': 2, 'account/simulated_margin': 10, 'account/borrow-repay': 5 / 3, 'account/quick-margin-borrow-repay': 4, 'account/activate-option': 4, 'account/set-auto-loan': 4, 'account/subaccount/set-loan-allocation': 4, 'asset/transfer': 10, 'asset/withdrawal': 5 / 3, 'asset/withdrawal-lightning': 5, 'asset/cancel-withdrawal': 5 / 3, 'asset/convert-dust-assets': 10, 'trade/order': 1 / 3, 'trade/batch-orders': 1 / 15, 'trade/cancel-order': 1 / 3, 'trade/cancel-batch-orders': 1 / 15, 'trade/amend-order': 1 / 3, 'trade/amend-batch-orders': 1 / 3, 'trade/amend-algos': 1, 'trade/close-position': 1, 'trade/order-algo': 1, 'trade/cancel-algos': 1, 'trade/cancel-advance-algos': 1, 'users/subaccount/delete-apikey': 10, 'users/subaccount/modify-apikey': 10, 'users/subaccount/apikey': 10, 'users/subaccount/set-transfer-out': 10, 'asset/subaccount/transfer': 10, // broker 'broker/nd/create-subaccount': 10, 'broker/nd/delete-subaccount': 10, 'broker/nd/set-subaccount-level': 4, 'broker/nd/set-subaccount-fee-rate': 4, 'asset/broker/nd/subaccount-deposit-address': 4, 'broker/nd/subaccount/apikey': 10, 'broker/nd/subaccount/delete-apikey': 10, 'broker/nd/subaccount/modify-apikey': 10, 'broker/nd/rebate-per-orders': 36000, // earn 'finance/staking-defi/purchase': 3, 'finance/staking-defi/redeem': 3, 'finance/staking-defi/cancel': 3, 'finance/savings/purchase-redempt': 5 / 3, 'finance/savings/set-lending-rate': 5 / 3, 'rfq/create-rfq': 4, 'rfq/cancel-rfq': 4, 'rfq/cancel-batch-rfqs': 10, 'rfq/cancel-all-rfqs': 10, 'rfq/execute-quote': 10, 'rfq/maker-instrument-settings': 4, 'rfq/mmp-reset': 4, 'rfq/create-quote': 0.4, 'rfq/cancel-quote': 0.4, 'rfq/cancel-batch-quotes': 10, 'rfq/cancel-all-quotes': 10, // copytrading 'copytrading/algo-order': 20, 'copytrading/close-subposition': 10, 'copytrading/set-instruments': 10, // grid trading 'tradingBot/grid/order-algo': 1, 'tradingBot/grid/amend-order-algo': 1, 'tradingBot/grid/stop-order-algo': 1, 'tradingBot/grid/withdraw-income': 1, 'tradingBot/grid/compute-margin-balance': 1, 'tradingBot/grid/margin-balance': 1, }, }, }, 'fees': { 'trading': { 'taker': this.parseNumber('0.0015'), 'maker': this.parseNumber('0.0010'), }, 'spot': { 'taker': this.parseNumber('0.0015'), 'maker': this.parseNumber('0.0010'), }, 'future': { 'taker': this.parseNumber('0.0005'), 'maker': this.parseNumber('0.0002'), }, 'swap': { 'taker': this.parseNumber('0.00050'), 'maker': this.parseNumber('0.00020'), }, }, 'requiredCredentials': { 'apiKey': true, 'secret': true, 'password': true, }, 'exceptions': { 'exact': { // Public error codes from 50000-53999 // General Class '1': ExchangeError, '2': ExchangeError, '50000': BadRequest, '50001': OnMaintenance, '50002': BadRequest, '50004': RequestTimeout, '50005': ExchangeNotAvailable, '50006': BadRequest, '50007': AccountSuspended, '50008': AuthenticationError, '50009': AccountSuspended, '50010': ExchangeError, '50011': RateLimitExceeded, '50012': ExchangeError, '50013': ExchangeNotAvailable, '50014': BadRequest, '50015': ExchangeError, '50016': ExchangeError, '50017': ExchangeError, '50018': ExchangeError, '50019': ExchangeError, '50020': ExchangeError, '50021': ExchangeError, '50022': ExchangeError, '50023': ExchangeError, '50024': BadRequest, '50025': ExchangeError, '50026': ExchangeNotAvailable, '50027': PermissionDenied, '50028': ExchangeError, '50044': BadRequest, // API Class '50100': ExchangeError, '50101': AuthenticationError, '50102': InvalidNonce, '50103': AuthenticationError, '50104': AuthenticationError, '50105': AuthenticationError, '50106': AuthenticationError, '50107': AuthenticationError, '50108': ExchangeError, '50109': ExchangeError, '50110': PermissionDenied, '50111': AuthenticationError, '50112': AuthenticationError, '50113': AuthenticationError, '50114': AuthenticationError, '50115': BadRequest, // Trade Class '51000': BadRequest, '51001': BadSymbol, '51002': BadSymbol, '51003': BadRequest, '51004': InvalidOrder, '51005': InvalidOrder, '51006': InvalidOrder, '51007': InvalidOrder, '51008': InsufficientFunds, '51009': AccountSuspended, '51010': AccountNotEnabled, '51011': InvalidOrder, '51012': BadSymbol, '51014': BadSymbol, '51015': BadSymbol, '51016': InvalidOrder, '51017': ExchangeError, '51018': ExchangeError, '51019': ExchangeError, '51020': InvalidOrder, '51021': BadSymbol, '51022': BadSymbol, '51023': ExchangeError, '51024': AccountSuspended, '51025': ExchangeError, '51026': BadSymbol, '51027': BadSymbol, '51028': BadSymbol, '51029': BadSymbol, '51030': BadSymbol, '51046': InvalidOrder, '51047': InvalidOrder, '51031': InvalidOrder, '51100': InvalidOrder, '51101': InvalidOrder, '51102': InvalidOrder, '51103': InvalidOrder, '51104': InvalidOrder, '51105': InvalidOrder, '51106': InvalidOrder, '51107': InvalidOrder, '51108': InvalidOrder, '51109': InvalidOrder, '51110': InvalidOrder, '51111': BadRequest, '51112': InvalidOrder, '51113': RateLimitExceeded, '51115': InvalidOrder, '51116': InvalidOrder, '51117': InvalidOrder, '51118': InvalidOrder, '51119': InsufficientFunds, '51120': InvalidOrder, '51121': InvalidOrder, '51122': InvalidOrder, '51124': InvalidOrder, '51125': InvalidOrder, '51126': InvalidOrder, '51127': InsufficientFunds, '51128': InvalidOrder, '51129': InvalidOrder, '51130': BadSymbol, '51131': InsufficientFunds, '51132': InvalidOrder, '51133': InvalidOrder, '51134': InvalidOrder, '51135': InvalidOrder, '51136': InvalidOrder, '51137': InvalidOrder, '51138': InvalidOrder, '51139': InvalidOrder, '51156': BadRequest, '51159': BadRequest, '51162': InvalidOrder, '51163': InvalidOrder, '51166': InvalidOrder, '51201': InvalidOrder, '51202': InvalidOrder, '51203': InvalidOrder, '51204': InvalidOrder, '51205': InvalidOrder, '51250': InvalidOrder, '51251': InvalidOrder, '51252': InvalidOrder, '51253': InvalidOrder, '51254': InvalidOrder, '51255': InvalidOrder, '51256': InvalidOrder, '51257': InvalidOrder, '51258': InvalidOrder, '51259': InvalidOrder, '51260': InvalidOrder, '51261': InvalidOrder, '51262': InvalidOrder, '51263': InvalidOrder, '51264': InvalidOrder, '51265': InvalidOrder, '51267': InvalidOrder, '51268': InvalidOrder, '51269': InvalidOrder, '51270': InvalidOrder, '51271': InvalidOrder, '51272': InvalidOrder, '51273': InvalidOrder, '51274': InvalidOrder, '51275': InvalidOrder, '51276': InvalidOrder, '51277': InvalidOrder, '51278': InvalidOrder, '51279': InvalidOrder, '51280': InvalidOrder, '51321': InvalidOrder, '51322': InvalidOrder, '51323': BadRequest, '51324': BadRequest, '51325': InvalidOrder, '51327': InvalidOrder, '51328': InvalidOrder, '51329': InvalidOrder, '51330': InvalidOrder, '51400': OrderNotFound, '51401': OrderNotFound, '51402': OrderNotFound, '51403': InvalidOrder, '51404': InvalidOrder, '51405': ExchangeError, '51406': ExchangeError, '51407': BadRequest, '51408': ExchangeError, '51409': ExchangeError, '51410': CancelPending, '51500': ExchangeError, '51501': ExchangeError, '51502': InsufficientFunds, '51503': ExchangeError, '51506': ExchangeError, '51508': ExchangeError, '51509': ExchangeError, '51510': ExchangeError, '51511': ExchangeError, '51600': ExchangeError, '51601': ExchangeError, '51602': ExchangeError, '51603': OrderNotFound, '51732': AuthenticationError, '51733': AuthenticationError, '51734': AuthenticationError, '51735': ExchangeError, '51736': InsufficientFunds, // Data class '52000': ExchangeError, // SPOT/MARGIN error codes 54000-54999 '54000': ExchangeError, '54001': ExchangeError, // FUNDING error codes 58000-58999 '58000': ExchangeError, '58001': AuthenticationError, '58002': PermissionDenied, '58003': ExchangeError, '58004': AccountSuspended, '58005': ExchangeError, '58006': ExchangeError, '58007': ExchangeError, '58100': ExchangeError, '58101': AccountSuspended, '58102': RateLimitExceeded, '58103': ExchangeError, '58104': ExchangeError, '58105': ExchangeError, '58106': ExchangeError, '58107': ExchangeError, '58108': ExchangeError, '58109': ExchangeError, '58110': ExchangeError, '58111': ExchangeError, '58112': ExchangeError, '58114': ExchangeError, '58115': ExchangeError, '58116': ExchangeError, '58117': ExchangeError, '58125': BadRequest, '58126': BadRequest, '58127': BadRequest, '58128': BadRequest, '58200': ExchangeError, '58201': ExchangeError, '58202': ExchangeError, '58203': InvalidAddress, '58204': AccountSuspended, '58205': ExchangeError, '58206': ExchangeError, '58207': InvalidAddress, '58208': ExchangeError, '58209': ExchangeError, '58210': ExchangeError, '58211': ExchangeError, '58212': ExchangeError, '58213': AuthenticationError, '58221': BadRequest, '58222': BadRequest, '58224': BadRequest, '58227': BadRequest, '58228': BadRequest, '58229': InsufficientFunds, '58300': ExchangeError, '58350': InsufficientFunds, // Account error codes 59000-59999 '59000': ExchangeError, '59001': ExchangeError, '59100': ExchangeError, '59101': ExchangeError, '59102': ExchangeError, '59103': InsufficientFunds, '59104': ExchangeError, '59105': ExchangeError, '59106': ExchangeError, '59107': ExchangeError, '59108': InsufficientFunds, '59109': ExchangeError, '59128': InvalidOrder, '59200': InsufficientFunds, '59201': InsufficientFunds, '59216': BadRequest, '59300': ExchangeError, '59301': ExchangeError, '59313': ExchangeError, '59401': ExchangeError, '59500': ExchangeError, '59501': ExchangeError, '59502': ExchangeError, '59503': ExchangeError, '59504': ExchangeError, '59505': ExchangeError, '59506': ExchangeError, '59507': ExchangeError, '59508': AccountSuspended, // WebSocket error Codes from 60000-63999 '60001': AuthenticationError, '60002': AuthenticationError, '60003': AuthenticationError, '60004': AuthenticationError, '60005': AuthenticationError, '60006': InvalidNonce, '60007': AuthenticationError, '60008': AuthenticationError, '60009': AuthenticationError, '60010': AuthenticationError, '60011': AuthenticationError, '60012': BadRequest, '60013': BadRequest, '60014': RateLimitExceeded, '60015': NetworkError, '60016': ExchangeNotAvailable, '60017': BadRequest, '60018': BadRequest, '60019': BadRequest, '63999': ExchangeError, '70010': BadRequest, '70013': BadRequest, '70016': BadRequest, // Please specify your instrument settings for at least one instType. }, 'broad': { 'Internal Server Error': ExchangeNotAvailable, 'server error': ExchangeNotAvailable, // {"code":500,"data":{},"detailMsg":"","error_code":"500","error_message":"server error 1236805249","msg":"server error 1236805249"} }, }, 'httpExceptions': { '429': ExchangeNotAvailable, // https://github.com/ccxt/ccxt/issues/9612 }, 'precisionMode': TICK_SIZE, 'options': { 'sandboxMode': false, 'defaultNetwork': 'ERC20', 'networks': { 'BTC': 'Bitcoin', 'OMNI': 'Omni', 'SOL': 'Solana', 'LTC': 'Litecoin', 'MATIC': 'Polygon', 'OP': 'Optimism', 'ARB': 'Arbitrum one', 'AVAX': 'Avalanche C-Chain', }, 'networksById': { 'Bitcoin': 'BTC', 'Omni': 'OMNI', 'Solana': 'SOL', 'Litecoin': 'LTC', 'Polygon': 'MATIC', 'Optimism': 'OP', 'Arbitrum one': 'ARB', 'Avalanche C-Chain': 'AVAX', }, 'fetchOpenInterestHistory': { 'timeframes': { '5m': '5m', '1h': '1H', '8h': '8H', '1d': '1D', '5M': '5m', '1H': '1H', '8H': '8H', '1D': '1D', }, }, 'fetchOHLCV': { // 'type': 'Candles', // Candles or HistoryCandles, IndexCandles, MarkPriceCandles 'timezone': 'UTC', // UTC, HK }, 'fetchPositions': { 'method': 'privateGetAccountPositions', // privateGetAccountPositions or privateGetAccountPositionsHistory }, 'createOrder': 'privatePostTradeBatchOrders', 'createMarketBuyOrderRequiresPrice': false, 'fetchMarkets': ['spot', 'future', 'swap', 'option'], 'defaultType': 'spot', // 'fetchBalance': { // 'type': 'spot', // 'funding', 'trading', 'spot' // }, 'fetchLedger': { 'method': 'privateGetAccountBills', // privateGetAccountBills, privateGetAccountBillsArchive, privateGetAssetBills }, // 6: Funding account, 18: Trading account 'fetchOrder': { 'method': 'privateGetTradeOrder', // privateGetTradeOrdersAlgoHistory }, 'fetchOpenOrders': { 'method': 'privateGetTradeOrdersPending', // privateGetTradeOrdersAlgoPending }, 'cancelOrders': { 'method': 'privatePostTradeCancelBatchOrders', // privatePostTradeCancelAlgos }, 'fetchCanceledOrders': { 'method': 'privateGetTradeOrdersHistory', // privateGetTradeOrdersAlgoHistory }, 'fetchClosedOrders': { 'method': 'privateGetTradeOrdersHistory', // privateGetTradeOrdersAlgoHistory }, 'withdraw': { // a funding password credential is required by the exchange for the // withdraw call (not to be confused with the api password credential) 'password': undefined, 'pwd': undefined, // password or pwd both work }, 'algoOrderTypes': { 'conditional': true, 'trigger': true, 'oco': true, 'move_order_stop': true, 'iceberg': true, 'twap': true, }, 'accountsByType': { 'funding': '6', 'trading': '18', 'spot': '18', 'future': '18', 'futures': '18', 'margin': '18', 'swap': '18', 'option': '18', }, 'accountsById': { '6': 'funding', '18': 'trading', // unified trading account }, 'exchangeType': { 'spot': 'SPOT', 'margin': 'MARGIN', 'swap': 'SWAP', 'future': 'FUTURES', 'futures': 'FUTURES', 'option': 'OPTION', 'SPOT': 'SPOT', 'MARGIN': 'MARGIN', 'SWAP': 'SWAP', 'FUTURES': 'FUTURES', 'OPTION': 'OPTION', }, 'brokerId': 'e847386590ce4dBC', }, 'commonCurrencies': { // the exchange 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 }, }); } handleMarketTypeAndParams(methodName, market = undefined, params = {}) { const instType = this.safeString(params, 'instType'); params = this.omit(params, 'instType'); const type = this.safeString(params, 'type'); if ((type === undefined) && (instType !== undefined)) { params['type'] = instType; } return super.handleMarketTypeAndParams(methodName, market, params); } convertToInstrumentType(type) { const exchangeTypes = this.safeValue(this.options, 'exchangeType', {}); return this.safeString(exchangeTypes, type, type); } convertExpireDate(date) { // parse YYMMDD to timestamp const year = date.slice(0, 2); const month = date.slice(2, 4); const day = date.slice(4, 6); const reconstructedDate = '20' + year + '-' + month + '-' + day + 'T00:00:00Z'; return reconstructedDate; } createExpiredOptionMarket(symbol) { // support expired option contracts const quote = 'USD'; const optionParts = symbol.split('-'); const symbolBase = symbol.split('/'); let base = undefined; if (symbol.indexOf('/') > -1) { base = this.safeString(symbolBase, 0); } else { base = this.safeString(optionParts, 0); } const settle = base; const expiry = this.safeString(optionParts, 2); const strike = this.safeString(optionParts, 3); const optionType = this.safeString(optionParts, 4); const datetime = this.convertExpireDate(expiry); const timestamp = this.parse8601(datetime); return { 'id': base + '-' + quote + '-' + expiry + '-' + strike + '-' + optionType, 'symbol': base + '/' + quote + ':' + settle + '-' + expiry + '-' + strike + '-' + optionType, 'base': base, 'quote': quote, 'settle': settle, 'baseId': base, 'quoteId': quote, 'settleId': settle, 'active': false, 'type': 'option', 'linear': undefined, 'inverse': undefined, 'spot': false, 'swap': false, 'future': false, 'option': true, 'margin': false, 'contract': true, 'contractSize': this.parseNumber('1'), 'expiry': timestamp, 'expiryDatetime': datetime, 'optionType': (optionType === 'C') ? 'call' : 'put', 'strike': this.parseNumber(strike), 'precision': { 'amount': undefined, 'price': undefined, }, 'limits': { 'amount': { 'min': undefined, 'max': undefined, }, 'price': { 'min': undefined, 'max': undefined, }, 'cost': { 'min': undefined, 'max': undefined, }, }, 'info': undefined, }; } market(symbol) { if (this.markets === undefined) { throw new ExchangeError(this.id + ' markets not loaded'); } if (typeof symbol === 'string') { if (symbol in this.markets) { return this.markets[symbol]; } else if (symbol in this.markets_by_id) { const markets = this.markets_by_id[symbol]; return markets[0]; } else if ((symbol.indexOf('-C') > -1) || (symbol.indexOf('-P') > -1)) { return this.createExpiredOptionMarket(symbol); } } throw new BadSymbol(this.id + ' does not have market symbol ' + symbol); } safeMarket(marketId = undefined, market = undefined, delimiter = undefined, marketType = undefined) { const isOption = (marketId !== undefined) && ((marketId.indexOf('-C') > -1) || (marketId.indexOf('-P') > -1)); if (isOption && !(marketId in this.markets_by_id)) { // handle expired option contracts return this.createExpiredOptionMarket(marketId); } return super.safeMarket(marketId, market, delimiter, marketType); } async fetchStatus(params = {}) { /** * @method * @name okx#fetchStatus * @description the latest known information on the availability of the exchange API * @param {object} params extra parameters specific to the okx api endpoint * @returns {object} a [status structure]{@link https://docs.ccxt.com/#/?id=exchange-status-structure} */ const response = await this.publicGetSystemStatus(params); // // Note, if there is no maintenance around, the 'data' array is empty // // { // "code": "0", // "msg": "", // "data": [ // { // "begin": "1621328400000", // "end": "1621329000000", // "href": "https://www.okx.com/support/hc/en-us/articles/360060882172", // "scheDesc": "", // "serviceType": "1", // 0 WebSocket, 1 Spot/Margin, 2 Futures, 3 Perpetual, 4 Options, 5 Trading service // "state": "scheduled", // ongoing, completed, canceled // "system": "classic", // classic, unified // "title": "Classic Spot System Upgrade" // }, // ] // } // const data = this.safeValue(response, 'data', []); const dataLength = data.length; const update = { 'updated': undefined, 'status': (dataLength === 0) ? 'ok' : 'maintenance', 'eta': undefined, 'url': undefined, 'info': response, }; for (let i = 0; i < data.length; i++) { const event = data[i]; const state = this.safeString(event, 'state'); if (state === 'ongoing') { update['eta'] = this.safeInteger(event, 'end'); update['status'] = 'maintenance'; } } return update; } async fetchTime(params = {}) { /** * @method * @name okx#fetchTime * @description fetches the current integer timestamp in milliseconds from the exchange server * @param {object} params extra parameters specific to the okx api endpoint * @returns {int} the current integer timestamp in milliseconds from the exchange server */ const response = await this.publicGetPublicTime(params); // // { // "code": "0", // "data": [ // {"ts": "1621247923668"} // ], // "msg": "" // } // const data = this.safeValue(response, 'data', []); const first = this.safeValue(data, 0, {}); return this.safeInteger(first, 'ts'); } async fetchAccounts(params = {}) { /** * @method * @name okx#fetchAccounts * @description fetch all the accounts associated with a profile * @param {object} params extra parameters specific to the okx api endpoint * @returns {object} a dictionary of [account structures]{@link https://docs.ccxt.com/#/?id=account-structure} indexed by the account type */ const response = await this.privateGetAccountConfig(params); // // { // "code": "0", // "data": [ // { // "acctLv": "2", // "autoLoan": false, // "ctIsoMode": "automatic", // "greeksType": "PA", // "level": "Lv1", // "levelTmp": "", // "mgnIsoMode": "automatic", // "posMode": "long_short_mode", // "uid": "88018754289672195" // } // ], // "msg": "" // } // const data = this.safeValue(response, 'data', []); const result = []; for (let i = 0; i < data.length; i++) { const account = data[i]; const accountId = this.safeString(account, 'uid'); const type = this.safeString(account, 'acctLv'); result.push({ 'id': accountId, 'type': type, 'currency': undefined, 'info': account, }); } return result; } async fetchMarkets(params = {}) { /** * @method * @name okx#fetchMarkets * @description retrieves data on all markets for okx * @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 promises = []; let result = []; for (let i = 0; i < types.length; i++) { promises.push(this.fetchMarketsByType(types[i], params)); } // why not both ¯\_(ツ)_/¯ promises = await Promise.all(promises); for (let i = 0; i < promises.length; i++) { result = this.arrayConcat(result, promises[i]); } return result; } parseMarkets(markets) { const result = []; for (let i = 0; i < markets.length; i++) { result.push(this.parseMarket(markets[i])); } return result; } parseMarket(market) { // // { // "alias": "", // this_week, next_week, quarter, next_quarter // "baseCcy": "BTC", // "category": "1", // "ctMult": "", // "ctType": "", // inverse, linear // "ctVal": "", // "ctValCcy": "", // "expTime": "", // "instId": "BTC-USDT", // BTC-USD-210521, CSPR-USDT-SWAP, BTC-USD-210517-44000-C // "instType": "SPOT", // SPOT, FUTURES, SWAP, OPTION // "lever": "10", // "listTime": "1548133413000", // "lotSz": "0.00000001", // "minSz": "0.00001", // "optType": "", // "quoteCcy": "USDT", // "settleCcy": "", // "state": "live", // "stk": "", // "tickSz": "0.1", //