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