UNPKG

@proton/ccxt

Version:

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

1,057 lines (1,055 loc) 265 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/gate.js'; import { Precise } from './base/Precise.js'; import { TICK_SIZE } from './base/functions/number.js'; import { ExchangeError, BadRequest, ArgumentsRequired, AuthenticationError, PermissionDenied, AccountSuspended, InsufficientFunds, RateLimitExceeded, ExchangeNotAvailable, BadSymbol, InvalidOrder, OrderNotFound, NotSupported, AccountNotEnabled, OrderImmediatelyFillable, BadResponse } from './base/errors.js'; import { sha512 } from './static_dependencies/noble-hashes/sha512.js'; export default class gate extends Exchange { describe() { return this.deepExtend(super.describe(), { 'id': 'gate', 'name': 'Gate.io', 'countries': ['KR'], 'rateLimit': 10 / 3, 'version': 'v4', 'certified': true, 'pro': true, 'urls': { 'logo': 'https://user-images.githubusercontent.com/1294454/31784029-0313c702-b509-11e7-9ccc-bc0da6a0e435.jpg', 'doc': 'https://www.gate.io/docs/developers/apiv4/en/', 'www': 'https://gate.io/', 'api': { 'public': { 'wallet': 'https://api.gateio.ws/api/v4', 'futures': 'https://api.gateio.ws/api/v4', 'margin': 'https://api.gateio.ws/api/v4', 'delivery': 'https://api.gateio.ws/api/v4', 'spot': 'https://api.gateio.ws/api/v4', 'options': 'https://api.gateio.ws/api/v4', 'sub_accounts': 'https://api.gateio.ws/api/v4', 'earn': 'https://api.gateio.ws/api/v4', }, 'private': { 'withdrawals': 'https://api.gateio.ws/api/v4', 'wallet': 'https://api.gateio.ws/api/v4', 'futures': 'https://api.gateio.ws/api/v4', 'margin': 'https://api.gateio.ws/api/v4', 'delivery': 'https://api.gateio.ws/api/v4', 'spot': 'https://api.gateio.ws/api/v4', 'options': 'https://api.gateio.ws/api/v4', 'subAccounts': 'https://api.gateio.ws/api/v4', 'rebate': 'https://api.gateio.ws/api/v4', 'earn': 'https://api.gateio.ws/api/v4', }, }, 'test': { 'public': { 'futures': 'https://fx-api-testnet.gateio.ws/api/v4', 'delivery': 'https://fx-api-testnet.gateio.ws/api/v4', 'options': 'https://fx-api-testnet.gateio.ws/api/v4', }, 'private': { 'futures': 'https://fx-api-testnet.gateio.ws/api/v4', 'delivery': 'https://fx-api-testnet.gateio.ws/api/v4', 'options': 'https://fx-api-testnet.gateio.ws/api/v4', }, }, 'referral': { 'url': 'https://www.gate.io/ref/2436035', 'discount': 0.2, }, }, 'has': { 'CORS': undefined, 'spot': true, 'margin': true, 'swap': true, 'future': true, 'option': true, 'addMargin': true, 'borrowMargin': true, 'cancelAllOrders': true, 'cancelOrder': true, 'createDepositAddress': true, 'createMarketOrder': true, 'createOrder': true, 'createPostOnlyOrder': true, 'createReduceOnlyOrder': true, 'createStopLimitOrder': true, 'createStopMarketOrder': false, 'createStopOrder': true, 'editOrder': true, 'fetchBalance': true, 'fetchBorrowRate': false, 'fetchBorrowRateHistories': false, 'fetchBorrowRateHistory': false, 'fetchBorrowRates': false, 'fetchBorrowRatesPerSymbol': false, 'fetchClosedOrders': true, 'fetchCurrencies': true, 'fetchDepositAddress': true, 'fetchDeposits': true, 'fetchDepositWithdrawFee': 'emulated', 'fetchDepositWithdrawFees': true, 'fetchFundingHistory': true, 'fetchFundingRate': true, 'fetchFundingRateHistory': true, 'fetchFundingRates': true, 'fetchIndexOHLCV': true, 'fetchLedger': true, 'fetchLeverage': false, 'fetchLeverageTiers': true, 'fetchMarginMode': false, 'fetchMarketLeverageTiers': 'emulated', 'fetchMarkets': true, 'fetchMarkOHLCV': true, 'fetchMyTrades': true, 'fetchNetworkDepositAddress': true, 'fetchOHLCV': true, 'fetchOpenInterest': false, 'fetchOpenInterestHistory': true, 'fetchOpenOrders': true, 'fetchOrder': true, 'fetchOrderBook': true, 'fetchPosition': true, 'fetchPositionMode': false, 'fetchPositions': true, 'fetchPremiumIndexOHLCV': false, 'fetchSettlementHistory': true, 'fetchTicker': true, 'fetchTickers': true, 'fetchTime': false, 'fetchTrades': true, 'fetchTradingFee': true, 'fetchTradingFees': true, 'fetchTransactionFees': true, 'fetchWithdrawals': true, 'reduceMargin': true, 'repayMargin': true, 'setLeverage': true, 'setMarginMode': false, 'signIn': false, 'transfer': true, 'withdraw': true, }, 'api': { 'public': { 'wallet': { 'get': { 'currency_chains': 1.5, }, }, 'spot': { 'get': { 'currencies': 1, 'currencies/{currency}': 1, 'currency_pairs': 1, 'currency_pairs/{currency_pair}': 1, 'tickers': 1, 'order_book': 1, 'trades': 1, 'candlesticks': 1, }, }, 'margin': { 'get': { 'currency_pairs': 1, 'currency_pairs/{currency_pair}': 1, 'cross/currencies': 1, 'cross/currencies/{currency}': 1, 'funding_book': 1, }, }, 'futures': { 'get': { '{settle}/contracts': 1.5, '{settle}/contracts/{contract}': 1.5, '{settle}/order_book': 1.5, '{settle}/trades': 1.5, '{settle}/candlesticks': 1.5, '{settle}/tickers': 1.5, '{settle}/funding_rate': 1.5, '{settle}/insurance': 1.5, '{settle}/contract_stats': 1.5, '{settle}/liq_orders': 1.5, }, }, 'delivery': { 'get': { '{settle}/contracts': 1.5, '{settle}/contracts/{contract}': 1.5, '{settle}/order_book': 1.5, '{settle}/trades': 1.5, '{settle}/candlesticks': 1.5, '{settle}/tickers': 1.5, '{settle}/insurance': 1.5, }, }, 'options': { 'get': { 'underlyings': 1.5, 'expirations': 1.5, 'contracts': 1.5, 'contracts/{contract}': 1.5, 'settlements': 1.5, 'settlements/{contract}': 1.5, 'order_book': 1.5, 'tickers': 1.5, 'underlying/tickers/{underlying}': 1.5, 'candlesticks': 1.5, 'underlying/candlesticks': 1.5, 'trades': 1.5, }, }, 'earn': { 'get': { 'uni/currencies': 1.5, 'uni/currencies/{currency}': 1.5, }, }, }, 'private': { 'withdrawals': { 'post': { 'withdrawals': 3000, // 3000 = 10 seconds }, 'delete': { 'withdrawals/{withdrawal_id}': 300, }, }, 'wallet': { 'get': { 'deposit_address': 300, 'withdrawals': 300, 'deposits': 300, 'sub_account_transfers': 300, 'withdraw_status': 300, 'sub_account_balances': 300, 'fee': 300, 'total_balance': 300, }, 'post': { 'transfers': 300, 'sub_account_transfers': 300, }, }, 'subAccounts': { 'get': { 'sub_accounts': 1, 'sub_accounts/{user_id}': 1, 'sub_accounts/{user_id}/keys': 1, 'sub_accounts/{user_id}/keys/{key}': 1, }, 'post': { 'sub_accounts': 1, 'sub_accounts/{user_id}/keys': 1, 'sub_accounts/{user_id}/lock': 1, 'sub_accounts/{user_id}/unlock': 1, }, 'put': { 'sub_accounts/{user_id}/keys/{key}': 1, }, 'delete': { 'sub_accounts/{user_id}/keys/{key}': 1, }, }, 'spot': { 'get': { 'accounts': 1, 'account_book': 1, 'open_orders': 1, 'orders': 1, 'orders/{order_id}': 1, 'my_trades': 1, 'price_orders': 1, 'price_orders/{order_id}': 1, }, 'post': { 'batch_orders': 1, 'orders': 1, 'cancel_batch_orders': 1, 'price_orders': 1, }, 'delete': { 'orders': 1, 'orders/{order_id}': 1, 'price_orders': 1, 'price_orders/{order_id}': 1, }, 'patch': { 'orders/{order_id}': 1, }, }, 'margin': { 'get': { 'accounts': 1.5, 'account_book': 1.5, 'funding_accounts': 1.5, 'loans': 1.5, 'loans/{loan_id}': 1.5, 'loans/{loan_id}/repayment': 1.5, 'loan_records': 1.5, 'loan_records/{load_record_id}': 1.5, 'auto_repay': 1.5, 'transferable': 1.5, 'cross/accounts': 1.5, 'cross/account_book': 1.5, 'cross/loans': 1.5, 'cross/loans/{loan_id}': 1.5, 'cross/loans/repayments': 1.5, 'cross/transferable': 1.5, 'loan_records/{loan_record_id}': 1.5, 'borrowable': 1.5, 'cross/repayments': 1.5, 'cross/borrowable': 1.5, }, 'post': { 'loans': 1.5, 'merged_loans': 1.5, 'loans/{loan_id}/repayment': 1.5, 'auto_repay': 1.5, 'cross/loans': 1.5, 'cross/loans/repayments': 1.5, 'cross/repayments': 1.5, }, 'patch': { 'loans/{loan_id}': 1.5, 'loan_records/{loan_record_id}': 1.5, }, 'delete': { 'loans/{loan_id}': 1.5, }, }, 'futures': { 'get': { '{settle}/accounts': 1.5, '{settle}/account_book': 1.5, '{settle}/positions': 1.5, '{settle}/positions/{contract}': 1.5, '{settle}/orders': 1.5, '{settle}/orders/{order_id}': 1.5, '{settle}/my_trades': 1.5, '{settle}/my_trades_timerange': 1.5, '{settle}/position_close': 1.5, '{settle}/liquidates': 1.5, '{settle}/price_orders': 1.5, '{settle}/price_orders/{order_id}': 1.5, '{settle}/dual_comp/positions/{contract}': 1.5, '{settle}/auto_deleverages': 1.5, }, 'post': { '{settle}/positions/{contract}/margin': 1.5, '{settle}/positions/{contract}/leverage': 1.5, '{settle}/positions/{contract}/risk_limit': 1.5, '{settle}/dual_mode': 1.5, '{settle}/dual_comp/positions/{contract}': 1.5, '{settle}/dual_comp/positions/{contract}/margin': 1.5, '{settle}/dual_comp/positions/{contract}/leverage': 1.5, '{settle}/dual_comp/positions/{contract}/risk_limit': 1.5, '{settle}/orders': 1.5, '{settle}/price_orders': 1.5, }, 'delete': { '{settle}/orders': 1.5, '{settle}/orders/{order_id}': 1.5, '{settle}/price_orders': 1.5, '{settle}/price_orders/{order_id}': 1.5, }, }, 'delivery': { 'get': { '{settle}/accounts': 1.5, '{settle}/account_book': 1.5, '{settle}/positions': 1.5, '{settle}/positions/{contract}': 1.5, '{settle}/orders': 1.5, '{settle}/orders/{order_id}': 1.5, '{settle}/my_trades': 1.5, '{settle}/position_close': 1.5, '{settle}/liquidates': 1.5, '{settle}/price_orders': 1.5, '{settle}/price_orders/{order_id}': 1.5, '{settle}/settlements': 1.5, }, 'post': { '{settle}/positions/{contract}/margin': 1.5, '{settle}/positions/{contract}/leverage': 1.5, '{settle}/positions/{contract}/risk_limit': 1.5, '{settle}/orders': 1.5, '{settle}/price_orders': 1.5, }, 'delete': { '{settle}/orders': 1.5, '{settle}/orders/{order_id}': 1.5, '{settle}/price_orders': 1.5, '{settle}/price_orders/{order_id}': 1.5, }, }, 'options': { 'get': { 'accounts': 1.5, 'account_book': 1.5, 'positions': 1.5, 'positions/{contract}': 1.5, 'position_close': 1.5, 'orders': 1.5, 'orders/{order_id}': 1.5, 'my_trades': 1.5, }, 'post': { 'orders': 1.5, }, 'delete': { 'orders': 1.5, 'orders/{order_id}': 1.5, }, }, 'rebate': { 'get': { 'agency/transaction_history': 1.5, 'agency/commission_history': 1.5, }, }, 'earn': { 'get': { 'uni/lends': 1.5, 'uni/lend_records': 1.5, 'uni/interests/{currency}': 1.5, 'uni/interest_records': 1.5, }, 'post': { 'uni/lends': 1.5, }, 'patch': { 'uni/lends': 1.5, }, }, }, }, 'timeframes': { '10s': '10s', '1m': '1m', '5m': '5m', '15m': '15m', '30m': '30m', '1h': '1h', '4h': '4h', '8h': '8h', '1d': '1d', '7d': '7d', '1w': '7d', }, // copied from gatev2 'commonCurrencies': { '88MPH': 'MPH', 'AXIS': 'Axis DeFi', 'BIFI': 'Bitcoin File', 'BOX': 'DefiBox', 'BTCBEAR': 'BEAR', 'BTCBULL': 'BULL', 'BYN': 'BeyondFi', 'EGG': 'Goose Finance', 'GTC': 'Game.com', 'GTC_HT': 'Game.com HT', 'GTC_BSC': 'Game.com BSC', 'HIT': 'HitChain', 'MM': 'Million', 'MPH': 'Morpher', 'POINT': 'GatePoint', 'RAI': 'Rai Reflex Index', 'SBTC': 'Super Bitcoin', 'TNC': 'Trinity Network Credit', 'VAI': 'VAIOT', 'TRAC': 'TRACO', // conflict with OriginTrail (TRAC) }, 'requiredCredentials': { 'apiKey': true, 'secret': true, }, 'headers': { 'X-Gate-Channel-Id': 'ccxt', }, 'options': { 'sandboxMode': false, 'createOrder': { 'expiration': 86400, // for conditional orders }, 'networks': { 'ALGORAND': 'ALGO', 'ARBITRUM_NOVA': 'ARBNOVA', 'ARBITRUM_ONE': 'ARBEVM', 'AVALANCHE_C': 'AVAX_C', 'BEP20': 'BSC', 'CHILIZ': 'CHZ', 'EOS': 'EOS', 'ERC20': 'ETH', 'GATECHAIN': 'GTEVM', 'HRC20': 'HT', 'KUSAMA': 'KSMSM', 'NEAR': 'NEAR', 'OKC': 'OKT', 'OPTIMISM': 'OPETH', 'POLKADOT': 'DOTSM', 'POLYGON': 'MATIC', 'SOLANA': 'SOL', 'TRC20': 'TRX', }, 'networksById': { 'ALGO': 'ALGORAND', 'ARBEVM': 'ARBITRUM_ONE', 'ARBNOVA': 'ARBITRUM_NOVA', 'AVAX_C': 'AVALANCHE_C', 'BSC': 'BEP20', 'CHZ': 'CHILIZ', 'DOTSM': 'POLKADOT', 'EOS': 'EOS', 'ETH': 'ERC20', 'GTEVM': 'GATECHAIN', 'HT': 'HRC20', 'KSMSM': 'KUSAMA', 'MATIC': 'POLYGON', 'NEAR': 'NEAR', 'OKT': 'OKC', 'OPETH': 'OPTIMISM', 'SOL': 'SOLANA', 'TRX': 'TRC20', }, 'timeInForce': { 'GTC': 'gtc', 'IOC': 'ioc', 'PO': 'poc', 'POC': 'poc', 'FOK': 'fok', }, 'accountsByType': { 'funding': 'spot', 'spot': 'spot', 'margin': 'margin', 'cross_margin': 'cross_margin', 'cross': 'cross_margin', 'isolated': 'margin', 'swap': 'futures', 'future': 'delivery', 'futures': 'futures', 'delivery': 'delivery', 'option': 'options', 'options': 'options', }, 'defaultType': 'spot', 'swap': { 'fetchMarkets': { 'settlementCurrencies': ['usdt', 'btc'], }, }, 'future': { 'fetchMarkets': { 'settlementCurrencies': ['usdt'], }, }, }, 'precisionMode': TICK_SIZE, 'fees': { 'trading': { 'tierBased': true, 'feeSide': 'get', 'percentage': true, 'maker': this.parseNumber('0.002'), 'taker': this.parseNumber('0.002'), 'tiers': { // volume is in BTC 'maker': [ [this.parseNumber('0'), this.parseNumber('0.002')], [this.parseNumber('1.5'), this.parseNumber('0.00185')], [this.parseNumber('3'), this.parseNumber('0.00175')], [this.parseNumber('6'), this.parseNumber('0.00165')], [this.parseNumber('12.5'), this.parseNumber('0.00155')], [this.parseNumber('25'), this.parseNumber('0.00145')], [this.parseNumber('75'), this.parseNumber('0.00135')], [this.parseNumber('200'), this.parseNumber('0.00125')], [this.parseNumber('500'), this.parseNumber('0.00115')], [this.parseNumber('1250'), this.parseNumber('0.00105')], [this.parseNumber('2500'), this.parseNumber('0.00095')], [this.parseNumber('3000'), this.parseNumber('0.00085')], [this.parseNumber('6000'), this.parseNumber('0.00075')], [this.parseNumber('11000'), this.parseNumber('0.00065')], [this.parseNumber('20000'), this.parseNumber('0.00055')], [this.parseNumber('40000'), this.parseNumber('0.00055')], [this.parseNumber('75000'), this.parseNumber('0.00055')], ], 'taker': [ [this.parseNumber('0'), this.parseNumber('0.002')], [this.parseNumber('1.5'), this.parseNumber('0.00195')], [this.parseNumber('3'), this.parseNumber('0.00185')], [this.parseNumber('6'), this.parseNumber('0.00175')], [this.parseNumber('12.5'), this.parseNumber('0.00165')], [this.parseNumber('25'), this.parseNumber('0.00155')], [this.parseNumber('75'), this.parseNumber('0.00145')], [this.parseNumber('200'), this.parseNumber('0.00135')], [this.parseNumber('500'), this.parseNumber('0.00125')], [this.parseNumber('1250'), this.parseNumber('0.00115')], [this.parseNumber('2500'), this.parseNumber('0.00105')], [this.parseNumber('3000'), this.parseNumber('0.00095')], [this.parseNumber('6000'), this.parseNumber('0.00085')], [this.parseNumber('11000'), this.parseNumber('0.00075')], [this.parseNumber('20000'), this.parseNumber('0.00065')], [this.parseNumber('40000'), this.parseNumber('0.00065')], [this.parseNumber('75000'), this.parseNumber('0.00065')], ], }, }, 'swap': { 'tierBased': true, 'feeSide': 'base', 'percentage': true, 'maker': this.parseNumber('0.0'), 'taker': this.parseNumber('0.0005'), 'tiers': { 'maker': [ [this.parseNumber('0'), this.parseNumber('0.0000')], [this.parseNumber('1.5'), this.parseNumber('-0.00005')], [this.parseNumber('3'), this.parseNumber('-0.00005')], [this.parseNumber('6'), this.parseNumber('-0.00005')], [this.parseNumber('12.5'), this.parseNumber('-0.00005')], [this.parseNumber('25'), this.parseNumber('-0.00005')], [this.parseNumber('75'), this.parseNumber('-0.00005')], [this.parseNumber('200'), this.parseNumber('-0.00005')], [this.parseNumber('500'), this.parseNumber('-0.00005')], [this.parseNumber('1250'), this.parseNumber('-0.00005')], [this.parseNumber('2500'), this.parseNumber('-0.00005')], [this.parseNumber('3000'), this.parseNumber('-0.00008')], [this.parseNumber('6000'), this.parseNumber('-0.01000')], [this.parseNumber('11000'), this.parseNumber('-0.01002')], [this.parseNumber('20000'), this.parseNumber('-0.01005')], [this.parseNumber('40000'), this.parseNumber('-0.02000')], [this.parseNumber('75000'), this.parseNumber('-0.02005')], ], 'taker': [ [this.parseNumber('0'), this.parseNumber('0.00050')], [this.parseNumber('1.5'), this.parseNumber('0.00048')], [this.parseNumber('3'), this.parseNumber('0.00046')], [this.parseNumber('6'), this.parseNumber('0.00044')], [this.parseNumber('12.5'), this.parseNumber('0.00042')], [this.parseNumber('25'), this.parseNumber('0.00040')], [this.parseNumber('75'), this.parseNumber('0.00038')], [this.parseNumber('200'), this.parseNumber('0.00036')], [this.parseNumber('500'), this.parseNumber('0.00034')], [this.parseNumber('1250'), this.parseNumber('0.00032')], [this.parseNumber('2500'), this.parseNumber('0.00030')], [this.parseNumber('3000'), this.parseNumber('0.00030')], [this.parseNumber('6000'), this.parseNumber('0.00030')], [this.parseNumber('11000'), this.parseNumber('0.00030')], [this.parseNumber('20000'), this.parseNumber('0.00030')], [this.parseNumber('40000'), this.parseNumber('0.00030')], [this.parseNumber('75000'), this.parseNumber('0.00030')], ], }, }, }, // https://www.gate.io/docs/developers/apiv4/en/#label-list 'exceptions': { 'exact': { 'INVALID_PARAM_VALUE': BadRequest, 'INVALID_PROTOCOL': BadRequest, 'INVALID_ARGUMENT': BadRequest, 'INVALID_REQUEST_BODY': BadRequest, 'MISSING_REQUIRED_PARAM': ArgumentsRequired, 'BAD_REQUEST': BadRequest, 'INVALID_CONTENT_TYPE': BadRequest, 'NOT_ACCEPTABLE': BadRequest, 'METHOD_NOT_ALLOWED': BadRequest, 'NOT_FOUND': ExchangeError, 'INVALID_CREDENTIALS': AuthenticationError, 'INVALID_KEY': AuthenticationError, 'IP_FORBIDDEN': AuthenticationError, 'READ_ONLY': PermissionDenied, 'INVALID_SIGNATURE': AuthenticationError, 'MISSING_REQUIRED_HEADER': AuthenticationError, 'REQUEST_EXPIRED': AuthenticationError, 'ACCOUNT_LOCKED': AccountSuspended, 'FORBIDDEN': PermissionDenied, 'SUB_ACCOUNT_NOT_FOUND': ExchangeError, 'SUB_ACCOUNT_LOCKED': AccountSuspended, 'MARGIN_BALANCE_EXCEPTION': ExchangeError, 'MARGIN_TRANSFER_FAILED': ExchangeError, 'TOO_MUCH_FUTURES_AVAILABLE': ExchangeError, 'FUTURES_BALANCE_NOT_ENOUGH': InsufficientFunds, 'ACCOUNT_EXCEPTION': ExchangeError, 'SUB_ACCOUNT_TRANSFER_FAILED': ExchangeError, 'ADDRESS_NOT_USED': ExchangeError, 'TOO_FAST': RateLimitExceeded, 'WITHDRAWAL_OVER_LIMIT': ExchangeError, 'API_WITHDRAW_DISABLED': ExchangeNotAvailable, 'INVALID_WITHDRAW_ID': ExchangeError, 'INVALID_WITHDRAW_CANCEL_STATUS': ExchangeError, 'INVALID_PRECISION': InvalidOrder, 'INVALID_CURRENCY': BadSymbol, 'INVALID_CURRENCY_PAIR': BadSymbol, 'POC_FILL_IMMEDIATELY': OrderImmediatelyFillable, 'ORDER_NOT_FOUND': OrderNotFound, 'CLIENT_ID_NOT_FOUND': OrderNotFound, 'ORDER_CLOSED': InvalidOrder, 'ORDER_CANCELLED': InvalidOrder, 'QUANTITY_NOT_ENOUGH': InvalidOrder, 'BALANCE_NOT_ENOUGH': InsufficientFunds, 'MARGIN_NOT_SUPPORTED': InvalidOrder, 'MARGIN_BALANCE_NOT_ENOUGH': InsufficientFunds, 'AMOUNT_TOO_LITTLE': InvalidOrder, 'AMOUNT_TOO_MUCH': InvalidOrder, 'REPEATED_CREATION': InvalidOrder, 'LOAN_NOT_FOUND': OrderNotFound, 'LOAN_RECORD_NOT_FOUND': OrderNotFound, 'NO_MATCHED_LOAN': ExchangeError, 'NOT_MERGEABLE': ExchangeError, 'NO_CHANGE': ExchangeError, 'REPAY_TOO_MUCH': ExchangeError, 'TOO_MANY_CURRENCY_PAIRS': InvalidOrder, 'TOO_MANY_ORDERS': InvalidOrder, 'MIXED_ACCOUNT_TYPE': InvalidOrder, 'AUTO_BORROW_TOO_MUCH': ExchangeError, 'TRADE_RESTRICTED': InsufficientFunds, 'USER_NOT_FOUND': AccountNotEnabled, 'CONTRACT_NO_COUNTER': ExchangeError, 'CONTRACT_NOT_FOUND': BadSymbol, 'RISK_LIMIT_EXCEEDED': ExchangeError, 'INSUFFICIENT_AVAILABLE': InsufficientFunds, 'LIQUIDATE_IMMEDIATELY': InvalidOrder, 'LEVERAGE_TOO_HIGH': InvalidOrder, 'LEVERAGE_TOO_LOW': InvalidOrder, 'ORDER_NOT_OWNED': ExchangeError, 'ORDER_FINISHED': ExchangeError, 'POSITION_CROSS_MARGIN': ExchangeError, 'POSITION_IN_LIQUIDATION': ExchangeError, 'POSITION_IN_CLOSE': ExchangeError, 'POSITION_EMPTY': InvalidOrder, 'REMOVE_TOO_MUCH': ExchangeError, 'RISK_LIMIT_NOT_MULTIPLE': ExchangeError, 'RISK_LIMIT_TOO_HIGH': ExchangeError, 'RISK_LIMIT_TOO_lOW': ExchangeError, 'PRICE_TOO_DEVIATED': InvalidOrder, 'SIZE_TOO_LARGE': InvalidOrder, 'SIZE_TOO_SMALL': InvalidOrder, 'PRICE_OVER_LIQUIDATION': InvalidOrder, 'PRICE_OVER_BANKRUPT': InvalidOrder, 'ORDER_POC_IMMEDIATE': OrderImmediatelyFillable, 'INCREASE_POSITION': InvalidOrder, 'CONTRACT_IN_DELISTING': ExchangeError, 'INTERNAL': ExchangeNotAvailable, 'SERVER_ERROR': ExchangeNotAvailable, 'TOO_BUSY': ExchangeNotAvailable, 'CROSS_ACCOUNT_NOT_FOUND': ExchangeError, 'RISK_LIMIT_TOO_LOW': BadRequest, 'AUTO_TRIGGER_PRICE_LESS_LAST': InvalidOrder, 'AUTO_TRIGGER_PRICE_GREATE_LAST': InvalidOrder, // {"label":"AUTO_TRIGGER_PRICE_GREATE_LAST","message":"invalid argument: Trigger.Price must > last_price"} }, 'broad': {}, }, }); } setSandboxMode(enable) { super.setSandboxMode(enable); this.options['sandboxMode'] = enable; } async fetchMarkets(params = {}) { /** * @method * @name gate#fetchMarkets * @description retrieves data on all markets for gate * @see https://www.gate.io/docs/developers/apiv4/en/#list-all-currency-pairs-supported // spot * @see https://www.gate.io/docs/developers/apiv4/en/#list-all-supported-currency-pairs-supported-in-margin-trading // margin * @see https://www.gate.io/docs/developers/apiv4/en/#list-all-futures-contracts // swap * @see https://www.gate.io/docs/developers/apiv4/en/#list-all-futures-contracts-2 // future * @see https://www.gate.io/docs/developers/apiv4/en/#list-all-the-contracts-with-specified-underlying-and-expiration-time // option * @param {object} params extra parameters specific to the exchange api endpoint * @returns {[object]} an array of objects representing market data */ const sandboxMode = this.safeValue(this.options, 'sandboxMode', false); let rawPromises = [ this.fetchContractMarkets(params), this.fetchOptionMarkets(params), ]; if (!sandboxMode) { // gate does not have a sandbox for spot markets const mainnetOnly = [this.fetchSpotMarkets(params)]; rawPromises = this.arrayConcat(rawPromises, mainnetOnly); } const promises = await Promise.all(rawPromises); const spotMarkets = this.safeValue(promises, 0, []); const contractMarkets = this.safeValue(promises, 1, []); const optionMarkets = this.safeValue(promises, 2, []); const markets = this.arrayConcat(spotMarkets, contractMarkets); return this.arrayConcat(markets, optionMarkets); } async fetchSpotMarkets(params = {}) { const marginResponse = await this.publicMarginGetCurrencyPairs(params); const spotMarketsResponse = await this.publicSpotGetCurrencyPairs(params); const marginMarkets = this.indexBy(marginResponse, 'id'); // // Spot // // [ // { // "id": "QTUM_ETH", // "base": "QTUM", // "quote": "ETH", // "fee": "0.2", // "min_base_amount": "0.01", // "min_quote_amount": "0.001", // "amount_precision": 3, // "precision": 6, // "trade_status": "tradable", // "sell_start": 0, // "buy_start": 0 // } // ] // // Margin // // [ // { // "id": "ETH_USDT", // "base": "ETH", // "quote": "USDT", // "leverage": 3, // "min_base_amount": "0.01", // "min_quote_amount": "100", // "max_quote_amount": "1000000" // } // ] // const result = []; for (let i = 0; i < spotMarketsResponse.length; i++) { const spotMarket = spotMarketsResponse[i]; const id = this.safeString(spotMarket, 'id'); const marginMarket = this.safeValue(marginMarkets, id); const market = this.deepExtend(marginMarket, spotMarket); const [baseId, quoteId] = id.split('_'); const base = this.safeCurrencyCode(baseId); const quote = this.safeCurrencyCode(quoteId); const takerPercent = this.safeString(market, 'fee'); const makerPercent = this.safeString(market, 'maker_fee_rate', takerPercent); const amountPrecision = this.parseNumber(this.parsePrecision(this.safeString(market, 'amount_precision'))); const tradeStatus = this.safeString(market, 'trade_status'); const leverage = this.safeNumber(market, 'leverage'); const margin = leverage !== undefined; result.push({ 'id': id, 'symbol': base + '/' + quote, 'base': base, 'quote': quote, 'settle': undefined, 'baseId': baseId, 'quoteId': quoteId, 'settleId': undefined, 'type': 'spot', 'spot': true, 'margin': margin, 'swap': false, 'future': false, 'option': false, 'active': (tradeStatus === 'tradable'), 'contract': false, 'linear': undefined, 'inverse': undefined, // Fee is in %, so divide by 100 'taker': this.parseNumber(Precise.stringDiv(takerPercent, '100')), 'maker': this.parseNumber(Precise.stringDiv(makerPercent, '100')), 'contractSize': undefined, 'expiry': undefined, 'expiryDatetime': undefined, 'strike': undefined, 'optionType': undefined, 'precision': { 'amount': amountPrecision, 'price': this.parseNumber(this.parsePrecision(this.safeString(market, 'precision'))), }, 'limits': { 'leverage': { 'min': this.parseNumber('1'), 'max': this.safeNumber(market, 'leverage', 1), }, 'amount': { 'min': this.safeNumber(spotMarket, 'min_base_amount', amountPrecision), 'max': undefined, }, 'price': { 'min': undefined, 'max': undefined, }, 'cost': { 'min': this.safeNumber(market, 'min_quote_amount'), 'max': margin ? this.safeNumber(market, 'max_quote_amount') : undefined, }, }, 'info': market, }); } return result; } async fetchContractMarkets(params = {}) { const result = []; const swapSettlementCurrencies = this.getSettlementCurrencies('swap', 'fetchMarkets'); const futureSettlementCurrencies = this.getSettlementCurrencies('future', 'fetchMarkets'); for (let c = 0; c < swapSettlementCurrencies.length; c++) { const settleId = swapSettlementCurrencies[c]; const request = { 'settle': settleId, }; const response = await this.publicFuturesGetSettleContracts(this.extend(request, params)); for (let i = 0; i < response.length; i++) { const parsedMarket = this.parseContractMarket(response[i], settleId); result.push(parsedMarket); } } for (let c = 0; c < futureSettlementCurrencies.length; c++) { const settleId = futureSettlementCurrencies[c]; const request = { 'settle': settleId, }; const response = await this.publicDeliveryGetSettleContracts(this.extend(request, params)); for (let i = 0; i < response.length; i++) { const parsedMarket = this.parseContractMarket(response[i], settleId); result.push(parsedMarket); } } return result; } parseContractMarket(market, settleId) { // // Perpetual swap // // { // "name": "BTC_USDT", // "type": "direct", // "quanto_multiplier": "0.0001", // "ref_discount_rate": "0", // "order_price_deviate": "0.5", // "maintenance_rate": "0.005", // "mark_type": "index", // "last_price": "38026", // "mark_price": "37985.6", // "index_price": "37954.92", // "funding_rate_indicative": "0.000219", // "mark_price_round": "0.01", // "funding_offset": 0, // "in_delisting": false, // "risk_limit_base": "1000000", // "interest_rate": "0.0003", // "order_price_round": "0.1", // "order_size_min": 1, // "ref_rebate_rate": "0.2", // "funding_interval": 28800, // "risk_limit_step": "1000000", // "leverage_min": "1", // "leverage_max": "100", // "risk_limit_max": "8000000", // "maker_fee_rate": "-0.00025", // "taker_fee_rate": "0.00075", // "funding_rate": "0.002053", // "order_size_max": 1000000, // "funding_next_apply": 1610035200, // "short_users": 977, // "config_change_time": 1609899548, // "trade_size": 28530850594, // "position_size": 5223816, // "long_users": 455, // "funding_impact_value": "60000", // "orders_limit": 50, // "trade_id": 10851092, // "orderbook_id": 2129638396 // } // // Delivery Futures // // { // "name": "BTC_USDT_20200814", // "underlying": "BTC_USDT", // "cycle": "WEEKLY", // "type": "direct", // "quanto_multiplier": "0.0001", // "mark_type": "index", // "last_price": "9017", // "mark_price": "9019", // "index_price": "9005.3", // "basis_rate": "0.185095", // "basis_value": "13.7", // "basis_impact_value": "100000", // "settle_price": "0", // "settle_price_interval": 60, // "settle_price_duration": 1800, // "settle_fee_rate": "0.0015", // "expire_time": 1593763200, // "order_price_round": "0.1", // "mark_price_round": "0.1", // "leverage_min": "1", // "leverage_max": "100", // "maintenance_rate": "1000000", // "risk_limit_base": "140.726652109199", // "risk_limit_step": "1000000", // "risk_limit_max": "8000000", // "maker_fee_rate": "-0.00025", // "taker_fee_rate": "0.00075", // "ref_discount_rate": "0", // "ref_rebate_rate": "0.2", // "order_price_deviate": "0.5", // "order_size_min": 1, // "order_size_max": 1000000, // "orders_limit": 50, // "orderbook_id": 63, // "trade_id": 26, // "trade_size": 435, // "position_size": 130, // "config_change_time": 1593158867, // "in_delisting": false // } // const id = this.safeString(market, 'name'); const parts = id.split('_'); const baseId = this.safeString(parts, 0); const quoteId = this.safeString(parts, 1); const date = this.safeString(parts, 2); const base = this.safeCurrencyCode(baseId); const quote = this.safeCurrencyCode(quoteId); const settle = this.safeCurrencyCode(settleId); const expiry = this.safeTimestamp(market, 'expire_time'); let symbol = ''; let marketType = 'swap'; if (date !== undefined) { symbol = base + '/' + quote + ':' + settle + '-' + this.yymmdd(expiry, ''); marketType = 'future'; } else { symbol = base + '/' + quote + ':' + settle; } const priceDeviate = this.safeString(market, 'order_price_deviate'); const markPrice = this.safeString(market, 'mark_price'); const minMultiplier = Precise.stringSub('1', priceDeviate); const maxMultiplier = Precise.stringAdd('1', priceDeviate); const minPrice = Precise.stringMul(minMultiplier, markPrice); const maxPrice = Precise.stringMul(maxMultiplier, markPrice); const takerPercent = this.safeString(market, 'taker_fee_rate'); const makerPercent = this.safeString(market, 'maker_fee_rate', takerPercent); const isLinear = quote === settle; return { 'id': id, 'symbol': symbol, 'base': base, 'quote': quote, 'settle': settle, 'baseId': baseId, 'quoteId': quoteId, 'settleId': settleId, 'type': marketType, 'spot': false, 'margin': false, 'swap': marketType === 'swap', 'future': marketType === 'future', 'option': marketType === 'option', 'active': true, 'contract': true, 'linear': isLinear, 'inverse': !isLinear, 'ta