UNPKG

ccxt-look

Version:

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

945 lines (938 loc) 153 kB
'use strict'; // --------------------------------------------------------------------------- const Exchange = require ('./base/Exchange'); const { TICK_SIZE } = require ('./base/functions/number'); const { AuthenticationError, ExchangeError, ArgumentsRequired, PermissionDenied, InvalidOrder, OrderNotFound, InsufficientFunds, BadRequest, RateLimitExceeded, InvalidNonce } = require ('./base/errors'); const Precise = require ('./base/Precise'); // --------------------------------------------------------------------------- module.exports = class bybit extends Exchange { describe () { return this.deepExtend (super.describe (), { 'id': 'bybit', 'name': 'Bybit', 'countries': [ 'VG' ], // British Virgin Islands 'version': 'v2', 'userAgent': undefined, // 50 requests per second for GET requests, 1000ms / 50 = 20ms between requests // 20 requests per second for POST requests, cost = 50 / 20 = 2.5 'rateLimit': 20, 'hostname': 'bybit.com', // bybit.com, bytick.com 'has': { 'CORS': true, 'spot': true, 'margin': false, 'swap': true, 'future': true, 'option': undefined, 'cancelAllOrders': true, 'cancelOrder': true, 'createOrder': true, 'createStopLimitOrder': true, 'createStopMarketOrder': true, 'createStopOrder': true, 'editOrder': true, 'fetchBalance': true, 'fetchBorrowRate': false, 'fetchBorrowRates': false, 'fetchClosedOrders': true, 'fetchDeposits': true, 'fetchFundingRate': true, 'fetchFundingRateHistory': false, 'fetchIndexOHLCV': true, 'fetchLedger': true, 'fetchMarketLeverageTiers': true, 'fetchMarkets': true, 'fetchMarkOHLCV': true, 'fetchMyTrades': true, 'fetchOHLCV': true, 'fetchOpenOrders': true, 'fetchOrder': true, 'fetchOrderBook': true, 'fetchOrders': true, 'fetchOrderTrades': true, 'fetchPositions': true, 'fetchPremiumIndexOHLCV': true, 'fetchTicker': true, 'fetchTickers': true, 'fetchTime': true, 'fetchTrades': true, 'fetchTradingFee': false, 'fetchTradingFees': false, 'fetchTransactions': undefined, 'fetchWithdrawals': true, 'setLeverage': true, 'setMarginMode': true, }, 'timeframes': { '1m': '1', '3m': '3', '5m': '5', '15m': '15', '30m': '30', '1h': '60', '2h': '120', '4h': '240', '6h': '360', '12h': '720', '1d': 'D', '1w': 'W', '1M': 'M', '1y': 'Y', }, 'urls': { 'test': { 'spot': 'https://api-testnet.{hostname}', 'futures': 'https://api-testnet.{hostname}', 'v2': 'https://api-testnet.{hostname}', 'public': 'https://api-testnet.{hostname}', 'private': 'https://api-testnet.{hostname}', }, 'logo': 'https://user-images.githubusercontent.com/51840849/76547799-daff5b80-649e-11ea-87fb-3be9bac08954.jpg', 'api': { 'spot': 'https://api.{hostname}', 'futures': 'https://api.{hostname}', 'v2': 'https://api.{hostname}', 'public': 'https://api.{hostname}', 'private': 'https://api.{hostname}', }, 'www': 'https://www.bybit.com', 'doc': [ 'https://bybit-exchange.github.io/docs/inverse/', 'https://bybit-exchange.github.io/docs/linear/', 'https://github.com/bybit-exchange', ], 'fees': 'https://help.bybit.com/hc/en-us/articles/360039261154', 'referral': 'https://www.bybit.com/app/register?ref=X7Prm', }, 'api': { // outdated endpoints ----------------------------------------- 'spot': { 'public': { 'get': [ 'symbols', ], }, 'quote': { 'get': [ 'depth', 'depth/merged', 'trades', 'kline', 'ticker/24hr', 'ticker/price', 'ticker/book_ticker', ], }, 'private': { 'get': [ 'order', 'open-orders', 'history-orders', 'myTrades', 'account', 'time', ], 'post': [ 'order', ], 'delete': [ 'order', 'order/fast', ], }, 'order': { 'delete': [ 'batch-cancel', 'batch-fast-cancel', 'batch-cancel-by-ids', ], }, }, 'futures': { 'private': { 'get': [ 'order/list', 'order', 'stop-order/list', 'stop-order', 'position/list', 'execution/list', 'trade/closed-pnl/list', ], 'post': [ 'order/create', 'order/cancel', 'order/cancelAll', 'order/replace', 'stop-order/create', 'stop-order/cancel', 'stop-order/cancelAll', 'stop-order/replace', 'position/change-position-margin', 'position/trading-stop', 'position/leverage/save', 'position/switch-mode', 'position/switch-isolated', 'position/risk-limit', ], }, }, 'v2': { 'public': { 'get': [ 'orderBook/L2', 'kline/list', 'tickers', 'trading-records', 'symbols', 'liq-records', 'mark-price-kline', 'index-price-kline', 'premium-index-kline', 'open-interest', 'big-deal', 'account-ratio', 'time', 'announcement', 'funding/prev-funding-rate', 'risk-limit/list', ], }, 'private': { 'get': [ 'order/list', 'order', 'stop-order/list', 'stop-order', 'position/list', 'position/fee-rate', 'execution/list', 'trade/closed-pnl/list', 'funding/prev-funding-rate', 'funding/prev-funding', 'funding/predicted-funding', 'account/api-key', 'account/lcp', 'wallet/balance', 'wallet/fund/records', 'wallet/withdraw/list', 'exchange-order/list', ], 'post': [ 'order/create', 'order/cancel', 'order/cancelAll', 'order/replace', 'stop-order/create', 'stop-order/cancel', 'stop-order/cancelAll', 'stop-order/replace', 'position/change-position-margin', 'position/trading-stop', 'position/leverage/save', 'position/switch-mode', 'position/switch-isolated', 'position/risk-limit', ], }, }, // new endpoints ------------------------------------------ 'public': { 'get': { // inverse swap 'v2/public/orderBook/L2': 1, 'v2/public/kline/list': 3, 'v2/public/tickers': 1, 'v2/public/trading-records': 1, 'v2/public/symbols': 1, 'v2/public/mark-price-kline': 3, 'v2/public/index-price-kline': 3, 'v2/public/premium-index-kline': 2, 'v2/public/open-interest': 1, 'v2/public/big-deal': 1, 'v2/public/account-ratio': 1, 'v2/public/funding-rate': 1, 'v2/public/elite-ratio': 1, // linear swap USDT 'public/linear/kline': 3, 'public/linear/recent-trading-records': 1, 'public/linear/funding/prev-funding-rate': 1, 'public/linear/mark-price-kline': 1, 'public/linear/index-price-kline': 1, 'public/linear/premium-index-kline': 1, // spot 'spot/v1/time': 1, 'spot/v1/symbols': 1, 'spot/quote/v1/depth': 1, 'spot/quote/v1/depth/merged': 1, 'spot/quote/v1/trades': 1, 'spot/quote/v1/kline': 1, 'spot/quote/v1/ticker/24hr': 1, 'spot/quote/v1/ticker/price': 1, 'spot/quote/v1/ticker/book_ticker': 1, // data 'v2/public/time': 1, 'v2/public/announcement': 1, // USDC endpoints are testnet only as of 2022 Jan 11 ---------- // option USDC (testnet only) 'option/usdc/openapi/public/v1/order-book': 1, 'option/usdc/openapi/public/v1/symbols': 1, 'option/usdc/openapi/public/v1/tick': 1, 'option/usdc/openapi/public/v1/delivery-price': 1, 'option/usdc/openapi/public/v1/query-trade-latest': 1, // perpetual swap USDC (testnet only) 'perpetual/usdc/openapi/public/v1/order-book': 1, 'perpetual/usdc/openapi/public/v1/symbols': 1, 'perpetual/usdc/openapi/public/v1/tick': 1, 'perpetual/usdc/openapi/public/v1/kline/list': 1, 'perpetual/usdc/openapi/public/v1/mark-price-kline': 1, 'perpetual/usdc/openapi/public/v1/index-price-kline': 1, 'perpetual/usdc/openapi/public/v1/premium-index-kline': 1, 'perpetual/usdc/openapi/public/v1/open-interest': 1, 'perpetual/usdc/openapi/public/v1/big-deal': 1, 'perpetual/usdc/openapi/public/v1/account-ratio': 1, }, // outdated endpoints-------------------------------------- 'linear': { 'get': [ 'kline', 'recent-trading-records', 'funding/prev-funding-rate', 'mark-price-kline', 'index-price-kline', 'premium-index-kline', 'risk-limit', ], }, }, // new endpoints ------------------------------------------ 'private': { 'get': { // inverse swap 'v2/private/order/list': 5, 'v2/private/order': 5, 'v2/private/stop-order/list': 5, 'v2/private/stop-order': 1, 'v2/private/position/list': 25, 'v2/private/position/fee-rate': 40, 'v2/private/execution/list': 25, 'v2/private/trade/closed-pnl/list': 1, 'v2/public/risk-limit/list': 1, // TODO check 'v2/public/funding/prev-funding-rate': 25, // TODO check 'v2/private/funding/prev-funding': 25, 'v2/private/funding/predicted-funding': 25, 'v2/private/account/api-key': 5, 'v2/private/account/lcp': 1, 'v2/private/wallet/balance': 25, // 120 per minute = 2 per second => cost = 50 / 2 = 25 'v2/private/wallet/fund/records': 25, 'v2/private/wallet/withdraw/list': 25, 'v2/private/exchange-order/list': 1, // linear swap USDT 'private/linear/order/list': 5, // 600 per minute = 10 per second => cost = 50 / 10 = 5 'private/linear/order/search': 5, 'private/linear/stop-order/list': 5, 'private/linear/stop-order/search': 5, 'private/linear/position/list': 25, 'private/linear/trade/execution/list': 25, 'private/linear/trade/closed-pnl/list': 25, 'public/linear/risk-limit': 1, 'private/linear/funding/predicted-funding': 25, 'private/linear/funding/prev-funding': 25, // inverse futures 'futures/private/order/list': 5, 'futures/private/order': 5, 'futures/private/stop-order/list': 5, 'futures/private/stop-order': 5, 'futures/private/position/list': 25, 'futures/private/execution/list': 25, 'futures/private/trade/closed-pnl/list': 1, // spot 'spot/v1/account': 2.5, 'spot/v1/order': 2.5, 'spot/v1/open-orders': 2.5, 'spot/v1/history-orders': 2.5, 'spot/v1/myTrades': 2.5, // account 'asset/v1/private/transfer/list': 50, // 60 per minute = 1 per second => cost = 50 / 1 = 50 'asset/v1/private/sub-member/transfer/list': 50, 'asset/v1/private/sub-member/member-ids': 50, }, 'post': { // inverse swap 'v2/private/order/create': 30, 'v2/private/order/cancel': 30, 'v2/private/order/cancelAll': 300, // 100 per minute + 'consumes 10 requests' 'v2/private/order/replace': 30, 'v2/private/stop-order/create': 30, 'v2/private/stop-order/cancel': 30, 'v2/private/stop-order/cancelAll': 300, 'v2/private/stop-order/replace': 30, 'v2/private/position/change-position-margin': 40, 'v2/private/position/trading-stop': 40, 'v2/private/position/leverage/save': 40, 'v2/private/tpsl/switch-mode': 40, 'v2/private/position/switch-isolated': 2.5, 'v2/private/position/risk-limit': 2.5, 'v2/private/position/switch-mode': 2.5, // linear swap USDT 'private/linear/order/create': 30, // 100 per minute = 1.666 per second => cost = 50 / 1.6666 = 30 'private/linear/order/cancel': 30, 'private/linear/order/cancel-all': 300, // 100 per minute + 'consumes 10 requests' 'private/linear/order/replace': 30, 'private/linear/stop-order/create': 30, 'private/linear/stop-order/cancel': 30, 'private/linear/stop-order/cancel-all': 300, 'private/linear/stop-order/replace': 30, 'private/linear/position/set-auto-add-margin': 40, 'private/linear/position/switch-isolated': 40, 'private/linear/position/switch-mode': 40, 'private/linear/tpsl/switch-mode': 2.5, 'private/linear/position/add-margin': 40, 'private/linear/position/set-leverage': 40, // 75 per minute = 1.25 per second => cost = 50 / 1.25 = 40 'private/linear/position/trading-stop': 40, 'private/linear/position/set-risk': 2.5, // inverse futures 'futures/private/order/create': 30, 'futures/private/order/cancel': 30, 'futures/private/order/cancelAll': 30, 'futures/private/order/replace': 30, 'futures/private/stop-order/create': 30, 'futures/private/stop-order/cancel': 30, 'futures/private/stop-order/cancelAll': 30, 'futures/private/stop-order/replace': 30, 'futures/private/position/change-position-margin': 40, 'futures/private/position/trading-stop': 40, 'futures/private/position/leverage/save': 40, 'futures/private/position/switch-mode': 40, 'futures/private/tpsl/switch-mode': 40, 'futures/private/position/switch-isolated': 40, 'futures/private/position/risk-limit': 2.5, // spot 'spot/v1/order': 2.5, // account 'asset/v1/private/transfer': 150, // 20 per minute = 0.333 per second => cost = 50 / 0.3333 = 150 'asset/v1/private/sub-member/transfer': 150, // USDC endpoints are testnet only as of 2022 Jan 11 ---------- // option USDC (testnet only) 'option/usdc/openapi/private/v1/place-order': 2.5, 'option/usdc/openapi/private/v1/batch-place-order': 2.5, 'option/usdc/openapi/private/v1/replace-order': 2.5, 'option/usdc/openapi/private/v1/batch-replace-orders': 2.5, 'option/usdc/openapi/private/v1/cancel-order': 2.5, 'option/usdc/openapi/private/v1/batch-cancel-orders': 2.5, 'option/usdc/openapi/private/v1/cancel-all': 2.5, 'option/usdc/openapi/private/v1/query-active-orders': 2.5, 'option/usdc/openapi/private/v1/query-order-history': 2.5, 'option/usdc/openapi/private/v1/execution-list': 2.5, 'option/usdc/openapi/private/v1/query-transaction-log': 2.5, 'option/usdc/openapi/private/v1/query-wallet-balance': 2.5, 'option/usdc/openapi/private/v1/query-asset-info': 2.5, 'option/usdc/openapi/private/v1/query-margin-info': 2.5, 'option/usdc/openapi/private/v1/query-position': 2.5, 'option/usdc/openapi/private/v1/query-delivery-list': 2.5, 'option/usdc/openapi/private/v1/query-position-exp-date': 2.5, 'option/usdc/openapi/private/v1/mmp-modify': 2.5, 'option/usdc/openapi/private/v1/mmp-reset': 2.5, // perpetual swap USDC (testnet only) 'perpetual/usdc/openapi/private/v1/place-order': 2.5, 'perpetual/usdc/openapi/private/v1/replace-order': 2.5, 'perpetual/usdc/openapi/private/v1/cancel-order': 2.5, 'perpetual/usdc/openapi/private/v1/cancel-all': 2.5, 'perpetual/usdc/openapi/private/v1/position/leverage/save': 2.5, 'option/usdc/openapi/private/v1/session-settlement': 2.5, 'perpetual/usdc/openapi/public/v1/risk-limit/list': 2.5, 'perpetual/usdc/openapi/private/v1/position/set-risk-limit': 2.5, }, 'delete': { // spot 'spot/v1/order': 2.5, 'spot/v1/order/fast': 2.5, 'spot/order/batch-cancel': 2.5, 'spot/order/batch-fast-cancel': 2.5, 'spot/order/batch-cancel-by-ids': 2.5, }, // outdated endpoints ------------------------------------- 'linear': { 'get': [ 'order/list', 'order/search', 'stop-order/list', 'stop-order/search', 'position/list', 'trade/execution/list', 'trade/closed-pnl/list', 'funding/predicted-funding', 'funding/prev-funding', ], 'post': [ 'order/create', 'order/cancel', 'order/cancel-all', 'order/replace', 'stop-order/create', 'stop-order/cancel', 'stop-order/cancel-all', 'stop-order/replace', 'position/set-auto-add-margin', 'position/switch-isolated', 'position/switch-mode', 'tpsl/switch-mode', 'position/add-margin', 'position/set-leverage', 'position/trading-stop', 'position/set-risk', ], }, }, }, 'httpExceptions': { '403': RateLimitExceeded, // Forbidden -- You request too many times }, 'exceptions': { 'exact': { '-2015': AuthenticationError, // Invalid API-key, IP, or permissions for action. '10001': BadRequest, // parameter error '10002': InvalidNonce, // request expired, check your timestamp and recv_window '10003': AuthenticationError, // Invalid apikey '10004': AuthenticationError, // invalid sign '10005': PermissionDenied, // permission denied for current apikey '10006': RateLimitExceeded, // too many requests '10007': AuthenticationError, // api_key not found in your request parameters '10010': PermissionDenied, // request ip mismatch '10017': BadRequest, // request path not found or request method is invalid '10018': RateLimitExceeded, // exceed ip rate limit '20001': OrderNotFound, // Order not exists '20003': InvalidOrder, // missing parameter side '20004': InvalidOrder, // invalid parameter side '20005': InvalidOrder, // missing parameter symbol '20006': InvalidOrder, // invalid parameter symbol '20007': InvalidOrder, // missing parameter order_type '20008': InvalidOrder, // invalid parameter order_type '20009': InvalidOrder, // missing parameter qty '20010': InvalidOrder, // qty must be greater than 0 '20011': InvalidOrder, // qty must be an integer '20012': InvalidOrder, // qty must be greater than zero and less than 1 million '20013': InvalidOrder, // missing parameter price '20014': InvalidOrder, // price must be greater than 0 '20015': InvalidOrder, // missing parameter time_in_force '20016': InvalidOrder, // invalid value for parameter time_in_force '20017': InvalidOrder, // missing parameter order_id '20018': InvalidOrder, // invalid date format '20019': InvalidOrder, // missing parameter stop_px '20020': InvalidOrder, // missing parameter base_price '20021': InvalidOrder, // missing parameter stop_order_id '20022': BadRequest, // missing parameter leverage '20023': BadRequest, // leverage must be a number '20031': BadRequest, // leverage must be greater than zero '20070': BadRequest, // missing parameter margin '20071': BadRequest, // margin must be greater than zero '20084': BadRequest, // order_id or order_link_id is required '30001': BadRequest, // order_link_id is repeated '30003': InvalidOrder, // qty must be more than the minimum allowed '30004': InvalidOrder, // qty must be less than the maximum allowed '30005': InvalidOrder, // price exceeds maximum allowed '30007': InvalidOrder, // price exceeds minimum allowed '30008': InvalidOrder, // invalid order_type '30009': ExchangeError, // no position found '30010': InsufficientFunds, // insufficient wallet balance '30011': PermissionDenied, // operation not allowed as position is undergoing liquidation '30012': PermissionDenied, // operation not allowed as position is undergoing ADL '30013': PermissionDenied, // position is in liq or adl status '30014': InvalidOrder, // invalid closing order, qty should not greater than size '30015': InvalidOrder, // invalid closing order, side should be opposite '30016': ExchangeError, // TS and SL must be cancelled first while closing position '30017': InvalidOrder, // estimated fill price cannot be lower than current Buy liq_price '30018': InvalidOrder, // estimated fill price cannot be higher than current Sell liq_price '30019': InvalidOrder, // cannot attach TP/SL params for non-zero position when placing non-opening position order '30020': InvalidOrder, // position already has TP/SL params '30021': InvalidOrder, // cannot afford estimated position_margin '30022': InvalidOrder, // estimated buy liq_price cannot be higher than current mark_price '30023': InvalidOrder, // estimated sell liq_price cannot be lower than current mark_price '30024': InvalidOrder, // cannot set TP/SL/TS for zero-position '30025': InvalidOrder, // trigger price should bigger than 10% of last price '30026': InvalidOrder, // price too high '30027': InvalidOrder, // price set for Take profit should be higher than Last Traded Price '30028': InvalidOrder, // price set for Stop loss should be between Liquidation price and Last Traded Price '30029': InvalidOrder, // price set for Stop loss should be between Last Traded Price and Liquidation price '30030': InvalidOrder, // price set for Take profit should be lower than Last Traded Price '30031': InsufficientFunds, // insufficient available balance for order cost '30032': InvalidOrder, // order has been filled or cancelled '30033': RateLimitExceeded, // The number of stop orders exceeds maximum limit allowed '30034': OrderNotFound, // no order found '30035': RateLimitExceeded, // too fast to cancel '30036': ExchangeError, // the expected position value after order execution exceeds the current risk limit '30037': InvalidOrder, // order already cancelled '30041': ExchangeError, // no position found '30042': InsufficientFunds, // insufficient wallet balance '30043': InvalidOrder, // operation not allowed as position is undergoing liquidation '30044': InvalidOrder, // operation not allowed as position is undergoing AD '30045': InvalidOrder, // operation not allowed as position is not normal status '30049': InsufficientFunds, // insufficient available balance '30050': ExchangeError, // any adjustments made will trigger immediate liquidation '30051': ExchangeError, // due to risk limit, cannot adjust leverage '30052': ExchangeError, // leverage can not less than 1 '30054': ExchangeError, // position margin is invalid '30057': ExchangeError, // requested quantity of contracts exceeds risk limit '30063': ExchangeError, // reduce-only rule not satisfied '30067': InsufficientFunds, // insufficient available balance '30068': ExchangeError, // exit value must be positive '30074': InvalidOrder, // can't create the stop order, because you expect the order will be triggered when the LastPrice(or IndexPrice、 MarkPrice, determined by trigger_by) is raising to stop_px, but the LastPrice(or IndexPrice、 MarkPrice) is already equal to or greater than stop_px, please adjust base_price or stop_px '30075': InvalidOrder, // can't create the stop order, because you expect the order will be triggered when the LastPrice(or IndexPrice、 MarkPrice, determined by trigger_by) is falling to stop_px, but the LastPrice(or IndexPrice、 MarkPrice) is already equal to or less than stop_px, please adjust base_price or stop_px '30078': ExchangeError, // {"ret_code":30078,"ret_msg":"","ext_code":"","ext_info":"","result":null,"time_now":"1644853040.916000","rate_limit_status":73,"rate_limit_reset_ms":1644853040912,"rate_limit":75} // '30084': BadRequest, // Isolated not modified, see handleErrors below '33004': AuthenticationError, // apikey already expired '34026': ExchangeError, // the limit is no change '130021': InsufficientFunds, // {"ret_code":130021,"ret_msg":"orderfix price failed for CannotAffordOrderCost.","ext_code":"","ext_info":"","result":null,"time_now":"1644588250.204878","rate_limit_status":98,"rate_limit_reset_ms":1644588250200,"rate_limit":100} }, 'broad': { 'unknown orderInfo': OrderNotFound, // {"ret_code":-1,"ret_msg":"unknown orderInfo","ext_code":"","ext_info":"","result":null,"time_now":"1584030414.005545","rate_limit_status":99,"rate_limit_reset_ms":1584030414003,"rate_limit":100} 'invalid api_key': AuthenticationError, // {"ret_code":10003,"ret_msg":"invalid api_key","ext_code":"","ext_info":"","result":null,"time_now":"1599547085.415797"} }, }, 'precisionMode': TICK_SIZE, 'options': { 'marketTypes': { 'BTC/USDT': 'linear', 'ETH/USDT': 'linear', 'BNB/USDT': 'linear', 'ADA/USDT': 'linear', 'DOGE/USDT': 'linear', 'XRP/USDT': 'linear', 'DOT/USDT': 'linear', 'UNI/USDT': 'linear', 'BCH/USDT': 'linear', 'LTC/USDT': 'linear', 'SOL/USDT': 'linear', 'LINK/USDT': 'linear', 'MATIC/USDT': 'linear', 'ETC/USDT': 'linear', 'FIL/USDT': 'linear', 'EOS/USDT': 'linear', 'AAVE/USDT': 'linear', 'XTZ/USDT': 'linear', 'SUSHI/USDT': 'linear', 'XEM/USDT': 'linear', 'BTC/USD': 'inverse', 'ETH/USD': 'inverse', 'EOS/USD': 'inverse', 'XRP/USD': 'inverse', }, 'defaultType': 'linear', // linear, inverse, futures // // ^ // | // | this will be replaced with the following soon | // | // v // // 'defaultType': 'swap', // swap, spot, future, option 'code': 'BTC', 'cancelAllOrders': { // 'method': 'v2PrivatePostOrderCancelAll', // v2PrivatePostStopOrderCancelAll }, 'recvWindow': 5 * 1000, // 5 sec default 'timeDifference': 0, // the difference between system clock and exchange server clock 'adjustForTimeDifference': false, // controls the adjustment logic upon instantiation }, 'fees': { 'trading': { 'tierBased': false, 'percentage': true, 'taker': 0.00075, 'maker': -0.00025, }, 'funding': { 'tierBased': false, 'percentage': false, 'withdraw': {}, 'deposit': {}, }, }, }); } nonce () { return this.milliseconds () - this.options['timeDifference']; } async fetchTime (params = {}) { const response = await this.publicGetV2PublicTime (params); // // { // ret_code: 0, // ret_msg: 'OK', // ext_code: '', // ext_info: '', // result: {}, // time_now: '1583933682.448826' // } // return this.safeTimestamp (response, 'time_now'); } async fetchMarkets (params = {}) { if (this.options['adjustForTimeDifference']) { await this.loadTimeDifference (); } const response = await this.publicGetV2PublicSymbols (params); // // linear swaps and inverse swaps and futures // const swapsResponse = await this.publicGetV2PublicSymbols (params); // // { // "ret_code":0, // "ret_msg":"OK", // "ext_code":"", // "ext_info":"", // "result":[ // // inverse swap // { // "name":"BTCUSD", // "alias":"BTCUSD", // "status":"Trading", // "base_currency":"BTC", // "quote_currency":"USD", // "price_scale":2, // "taker_fee":"0.00075", // "maker_fee":"-0.00025", // "leverage_filter":{"min_leverage":1,"max_leverage":100,"leverage_step":"0.01"}, // "price_filter":{"min_price":"0.5","max_price":"999999","tick_size":"0.5"}, // "lot_size_filter":{"max_trading_qty":1000000,"min_trading_qty":1,"qty_step":1} // }, // // linear swap // { // "name":"BTCUSDT", // "alias":"BTCUSDT", // "status":"Trading", // "base_currency":"BTC", // "quote_currency":"USDT", // "price_scale":2, // "taker_fee":"0.00075", // "maker_fee":"-0.00025", // "leverage_filter":{"min_leverage":1,"max_leverage":100,"leverage_step":"0.01"}, // "price_filter":{"min_price":"0.5","max_price":"999999","tick_size":"0.5"}, // "lot_size_filter":{"max_trading_qty":100,"min_trading_qty":0.001, "qty_step":0.001} // }, // // inverse futures // { // "name":"BTCUSDM22", // "alias":"BTCUSD0624", // "status":"Trading", // "base_currency":"BTC", // "quote_currency":"USD", // "price_scale":2, // "taker_fee":"0.00075", // "maker_fee":"-0.00025", // "leverage_filter":{"min_leverage":1,"max_leverage":100,"leverage_step":"0.01"}, // "price_filter":{"min_price":"0.5","max_price":"999999","tick_size":"0.5"}, // "lot_size_filter":{"max_trading_qty":1000000,"min_trading_qty":1,"qty_step":1} // }, // { // "name":"BTCUSDH22", // "alias":"BTCUSD0325", // "status":"Trading", // "base_currency":"BTC", // "quote_currency":"USD", // "price_scale":2, // "taker_fee":"0.00075", // "maker_fee":"-0.00025", // "leverage_filter":{"min_leverage":1,"max_leverage":100,"leverage_step":"0.01"} // "price_filter":{"min_price":"0.5","max_price":"999999","tick_size":"0.5"}, // "lot_size_filter":{"max_trading_qty":1000000,"min_trading_qty":1,"qty_step":1} // } // ], // "time_now":"1642369942.072113" // } // // spot markets // const spotResponse = await this.publicGetSpotV1Symbols (params); // // { // "ret_code":0, // "ret_msg":"", // "ext_code":null, // "ext_info":null, // "result":[ // { // "name":"BTCUSDT", // "alias":"BTCUSDT", // "baseCurrency":"BTC", // "quoteCurrency":"USDT", // "basePrecision":"0.000001", // "quotePrecision":"0.00000001", // "minTradeQuantity":"0.000158", // "minTradeAmount":"10", // "maxTradeQuantity":"4", // "maxTradeAmount":"100000", // "minPricePrecision":"0.01", // "category":1, // "showStatus":true // }, // ] // } // // USDC linear options response // const linearOptionsResponse = await this.publicGetOptionUsdcOpenapiPublicV1Symbols (params); // // { // "retCode":0, // "retMsg":"success", // "result":{ // "resultTotalSize":424, // "cursor":"0%2C500", // "dataList":[ // { // "symbol":"BTC-24JUN22-300000-C", // "status":"ONLINE", // "baseCoin":"BTC", // "quoteCoin":"USD", // "settleCoin":"USDC", // "takerFee":"0.0003", // "makerFee":"0.0003", // "minLeverage":"", // "maxLeverage":"", // "leverageStep":"", // "minOrderPrice":"0.5", // "maxOrderPrice":"10000000", // "minOrderSize":"0.01", // "maxOrderSize":"200", // "tickSize":"0.5", // "minOrderSizeIncrement":"0.01", // "basicDeliveryFeeRate":"0.00015", // "deliveryTime":"1656057600000" // }, // { // "symbol":"BTC-24JUN22-300000-P", // "status":"ONLINE", // "baseCoin":"BTC", // "quoteCoin":"USD", // "settleCoin":"USDC", // "takerFee":"0.0003", // "makerFee":"0.0003", // "minLeverage":"", // "maxLeverage":"", // "leverageStep":"", // "minOrderPrice":"0.5", // "maxOrderPrice":"10000000", // "minOrderSize":"0.01", // "maxOrderSize":"200", // "tickSize":"0.5", // "minOrderSizeIncrement":"0.01", // "basicDeliveryFeeRate":"0.00015", // "deliveryTime":"1656057600000" // }, // ] // } // } // // USDC linear perpetual swaps // const usdcLinearPerpetualSwaps = await this.publicGetPerpetualUsdcOpenapiPublicV1Symbols (params); // // { // "retCode":0, // "retMsg":"", // "result":[ // { // "symbol":"BTCPERP", // "status":"ONLINE", // "baseCoin":"BTC", // "quoteCoin":"USD", // "takerFeeRate":"0.00075", // "makerFeeRate":"-0.00025", // "minLeverage":"1", // "maxLeverage":"100", // "leverageStep":"0.01", // "minPrice":"0.50", // "maxPrice":"999999.00", // "tickSize":"0.50", // "maxTradingQty":"5.000", // "minTradingQty":"0.001", // "qtyStep":"0.001", // "deliveryFeeRate":"", // "deliveryTime":"0" // } // ] // } // const markets = this.safeValue (response, 'result', []); const options = this.safeValue (this.options, 'fetchMarkets', {}); const linearQuoteCurrencies = this.safeValue (options, 'linear', { 'USDT': true }); const result = []; for (let i = 0; i < markets.length; i++) { const market = markets[i]; const id = this.safeString2 (market, 'name', 'symbol'); const baseId = this.safeString2 (market, 'base_currency', 'baseCoin'); const quoteId = this.safeString2 (market, 'quote_currency', 'quoteCoin'); let settleId = this.safeString (market, 'settleCoin'); const base = this.safeCurrencyCode (baseId); const quote = this.safeCurrencyCode (quoteId); let settle = this.safeCurrencyCode (settleId); const linear = (quote in linearQuoteCurrencies); let symbol = base + '/' + quote; const baseQuote = base + quote; let type = 'swap'; if (baseQuote !== id) { type = 'future'; } const lotSizeFilter = this.safeValue (market, 'lot_size_filter', {}); const priceFilter = this.safeValue (market, 'price_filter', {}); const leverage = this.safeValue (market, 'leverage_filter', {}); const status = this.safeString (market, 'status'); let active = undefined; if (status !== undefined) { active = (status === 'Trading'); } const swap = (type === 'swap'); const future = (type === 'future'); const option = (type === 'option'); const contract = swap || future || option; let expiry = undefined; let expiryDatetime = undefined; let strike = undefined; let optionType = undefined; if (contract) { if (settle === undefined) { settleId = linear ? quoteId : baseId; settle = this.safeCurrencyCode (settleId); } symbol = symbol + ':' + settle; if (future) { const alias = this.safeString (market, 'alias'); const shortDate = alias.slice (-4); const date = this.iso8601 (this.milliseconds ()); const splitDate = date.split ('-'); const year = splitDate[0]; const expiryMonth = shortDate.slice (0, 2); const expiryDay = shortDate.slice (2, 4); expiryDatetime = year + '-' + expiryMonth + '-' + expiryDay + 'T00:00:00Z'; expiry = this.parse8601 (expiryDatetime); symbol = symbol + '-' + this.yymmdd (expiry); } else if (option) { expiry = this.safeInteger (market, 'deliveryTime'); expiryDatetime = this.iso8601 (expiry); const splitId = this.split (id, '-'); strike = this.safeString (splitId, 2); const optionLetter = this.safeString (splitId, 3); symbol = symbol + '-' + this.yymmdd (expiry) + ':' + strike + ':' + optionLetter; if (optionLetter === 'P') { optionType = 'put'; } else if (optionLetter === 'C') { optionType = 'call'; } } } result.push ({ 'id': id, 'symbol': symbol, 'base': base, 'quote': quote, 'settle': settle, 'baseId': baseId, 'quoteId': quoteId, 'settleId': settleId, 'type': type, 'spot': (type === 'spot'), 'margin': undefined, // todo 'swap': swap, 'future': future, 'futures': future, // Deprecated, use future 'option': option, 'active': active, '