ccxt-look
Version:
945 lines (938 loc) • 153 kB
JavaScript
'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,
'