UNPKG

ccxt

Version:

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

1,164 lines (1,162 loc) • 167 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/deribit.js'; import { TICK_SIZE } from './base/functions/number.js'; import { AuthenticationError, ExchangeError, ArgumentsRequired, PermissionDenied, InvalidOrder, OrderNotFound, DDoSProtection, NotSupported, ExchangeNotAvailable, InsufficientFunds, BadRequest, InvalidAddress, OnMaintenance } from './base/errors.js'; import { Precise } from './base/Precise.js'; import { sha256 } from './static_dependencies/noble-hashes/sha256.js'; import { totp } from './base/functions/totp.js'; // --------------------------------------------------------------------------- /** * @class deribit * @augments Exchange */ export default class deribit extends Exchange { describe() { return this.deepExtend(super.describe(), { 'id': 'deribit', 'name': 'Deribit', 'countries': ['NL'], 'version': 'v2', 'userAgent': undefined, // 20 requests per second for non-matching-engine endpoints, 1000ms / 20 = 50ms between requests // 5 requests per second for matching-engine endpoints, cost = (1000ms / rateLimit) / 5 = 4 'rateLimit': 50, 'pro': true, 'has': { 'CORS': true, 'spot': false, 'margin': false, 'swap': true, 'future': true, 'option': true, 'cancelAllOrders': true, 'cancelOrder': true, 'cancelOrders': false, 'createDepositAddress': true, 'createOrder': true, 'createReduceOnlyOrder': true, 'createStopLimitOrder': true, 'createStopMarketOrder': true, 'createStopOrder': true, 'createTrailingAmountOrder': true, 'editOrder': true, 'fetchAccounts': true, 'fetchBalance': true, 'fetchBorrowRateHistories': false, 'fetchBorrowRateHistory': false, 'fetchClosedOrders': true, 'fetchCrossBorrowRate': false, 'fetchCrossBorrowRates': false, 'fetchCurrencies': true, 'fetchDeposit': false, 'fetchDepositAddress': true, 'fetchDepositAddresses': false, 'fetchDepositAddressesByNetwork': false, 'fetchDeposits': true, 'fetchDepositWithdrawFees': true, 'fetchFundingRate': true, 'fetchFundingRateHistory': true, 'fetchGreeks': true, 'fetchIndexOHLCV': false, 'fetchIsolatedBorrowRate': false, 'fetchIsolatedBorrowRates': false, 'fetchLeverageTiers': false, 'fetchLiquidations': true, 'fetchMarginMode': false, 'fetchMarkets': true, 'fetchMarkOHLCV': false, 'fetchMyLiquidations': true, 'fetchMySettlementHistory': false, 'fetchMyTrades': true, 'fetchOHLCV': true, 'fetchOpenOrders': true, 'fetchOption': true, 'fetchOptionChain': true, 'fetchOrder': true, 'fetchOrderBook': true, 'fetchOrders': false, 'fetchOrderTrades': true, 'fetchPosition': true, 'fetchPositionMode': false, 'fetchPositions': true, 'fetchPremiumIndexOHLCV': false, 'fetchStatus': true, 'fetchTicker': true, 'fetchTickers': true, 'fetchTime': true, 'fetchTrades': true, 'fetchTradingFee': false, 'fetchTradingFees': true, 'fetchTransactions': false, 'fetchTransfer': false, 'fetchTransfers': true, 'fetchUnderlyingAssets': false, 'fetchVolatilityHistory': true, 'fetchWithdrawal': false, 'fetchWithdrawals': true, 'sandbox': true, 'transfer': true, 'withdraw': true, }, 'timeframes': { '1m': '1', '3m': '3', '5m': '5', '10m': '10', '15m': '15', '30m': '30', '1h': '60', '2h': '120', '3h': '180', '6h': '360', '12h': '720', '1d': '1D', }, 'urls': { 'test': { 'rest': 'https://test.deribit.com', }, 'logo': 'https://user-images.githubusercontent.com/1294454/41933112-9e2dd65a-798b-11e8-8440-5bab2959fcb8.jpg', 'api': { 'rest': 'https://www.deribit.com', }, 'www': 'https://www.deribit.com', 'doc': [ 'https://docs.deribit.com/v2', 'https://github.com/deribit', ], 'fees': 'https://www.deribit.com/pages/information/fees', 'referral': { 'url': 'https://www.deribit.com/reg-1189.4038', 'discount': 0.1, }, }, 'api': { 'public': { 'get': { // Authentication 'auth': 1, 'exchange_token': 1, 'fork_token': 1, // Session management 'set_heartbeat': 1, 'disable_heartbeat': 1, // Supporting 'get_time': 1, 'hello': 1, 'status': 1, 'test': 1, // Subscription management 'subscribe': 1, 'unsubscribe': 1, 'unsubscribe_all': 1, // Account management 'get_announcements': 1, // Market data 'get_book_summary_by_currency': 1, 'get_book_summary_by_instrument': 1, 'get_contract_size': 1, 'get_currencies': 1, 'get_delivery_prices': 1, 'get_funding_chart_data': 1, 'get_funding_rate_history': 1, 'get_funding_rate_value': 1, 'get_historical_volatility': 1, 'get_index': 1, 'get_index_price': 1, 'get_index_price_names': 1, 'get_instrument': 1, 'get_instruments': 1, 'get_last_settlements_by_currency': 1, 'get_last_settlements_by_instrument': 1, 'get_last_trades_by_currency': 1, 'get_last_trades_by_currency_and_time': 1, 'get_last_trades_by_instrument': 1, 'get_last_trades_by_instrument_and_time': 1, 'get_mark_price_history': 1, 'get_order_book': 1, 'get_trade_volumes': 1, 'get_tradingview_chart_data': 1, 'get_volatility_index_data': 1, 'ticker': 1, }, }, 'private': { 'get': { // Authentication 'logout': 1, // Session management 'enable_cancel_on_disconnect': 1, 'disable_cancel_on_disconnect': 1, 'get_cancel_on_disconnect': 1, // Subscription management 'subscribe': 1, 'unsubscribe': 1, 'unsubscribe_all': 1, // Account management 'change_api_key_name': 1, 'change_scope_in_api_key': 1, 'change_subaccount_name': 1, 'create_api_key': 1, 'create_subaccount': 1, 'disable_api_key': 1, 'disable_tfa_for_subaccount': 1, 'enable_affiliate_program': 1, 'enable_api_key': 1, 'get_access_log': 1, 'get_account_summary': 1, 'get_account_summaries': 1, 'get_affiliate_program_info': 1, 'get_email_language': 1, 'get_new_announcements': 1, 'get_portfolio_margins': 1, 'get_position': 1, 'get_positions': 1, 'get_subaccounts': 1, 'get_subaccounts_details': 1, 'get_transaction_log': 1, 'list_api_keys': 1, 'remove_api_key': 1, 'remove_subaccount': 1, 'reset_api_key': 1, 'set_announcement_as_read': 1, 'set_api_key_as_default': 1, 'set_email_for_subaccount': 1, 'set_email_language': 1, 'set_password_for_subaccount': 1, 'toggle_notifications_from_subaccount': 1, 'toggle_subaccount_login': 1, // Block Trade 'execute_block_trade': 4, 'get_block_trade': 1, 'get_last_block_trades_by_currency': 1, 'invalidate_block_trade_signature': 1, 'verify_block_trade': 4, // Trading 'buy': 4, 'sell': 4, 'edit': 4, 'edit_by_label': 4, 'cancel': 4, 'cancel_all': 4, 'cancel_all_by_currency': 4, 'cancel_all_by_instrument': 4, 'cancel_by_label': 4, 'close_position': 4, 'get_margins': 1, 'get_mmp_config': 1, 'get_open_orders_by_currency': 1, 'get_open_orders_by_instrument': 1, 'get_order_history_by_currency': 1, 'get_order_history_by_instrument': 1, 'get_order_margin_by_ids': 1, 'get_order_state': 1, 'get_stop_order_history': 1, 'get_trigger_order_history': 1, 'get_user_trades_by_currency': 1, 'get_user_trades_by_currency_and_time': 1, 'get_user_trades_by_instrument': 1, 'get_user_trades_by_instrument_and_time': 1, 'get_user_trades_by_order': 1, 'reset_mmp': 1, 'set_mmp_config': 1, 'get_settlement_history_by_instrument': 1, 'get_settlement_history_by_currency': 1, // Wallet 'cancel_transfer_by_id': 1, 'cancel_withdrawal': 1, 'create_deposit_address': 1, 'get_current_deposit_address': 1, 'get_deposits': 1, 'get_transfers': 1, 'get_withdrawals': 1, 'submit_transfer_to_subaccount': 1, 'submit_transfer_to_user': 1, 'withdraw': 1, }, }, }, 'features': { 'default': { 'sandbox': true, 'createOrder': { 'marginMode': false, 'triggerPrice': true, // todo implement 'triggerPriceType': { 'last': true, 'mark': true, 'index': true, }, 'triggerDirection': false, 'stopLossPrice': false, 'takeProfitPrice': false, 'attachedStopLossTakeProfit': undefined, 'timeInForce': { 'IOC': true, 'FOK': true, 'PO': true, 'GTD': true, }, 'hedged': false, 'selfTradePrevention': false, 'trailing': true, 'leverage': false, 'marketBuyByCost': true, 'marketBuyRequiresPrice': false, 'iceberg': true, // todo }, 'createOrders': undefined, 'fetchMyTrades': { 'marginMode': false, 'limit': 100, 'daysBack': 100000, 'untilDays': 100000, 'symbolRequired': true, // todo }, 'fetchOrder': { 'marginMode': false, 'trigger': false, 'trailing': false, 'symbolRequired': true, // todo }, 'fetchOpenOrders': { 'marginMode': false, 'limit': undefined, 'trigger': false, 'trailing': false, 'symbolRequired': true, // todo }, 'fetchOrders': undefined, 'fetchClosedOrders': { 'marginMode': false, 'limit': 100, 'daysBack': 100000, 'daysBackCanceled': 1, 'untilDays': 100000, 'trigger': false, 'trailing': false, 'symbolRequired': true, // todo }, 'fetchOHLCV': { 'limit': 1000, // todo: recheck }, }, 'spot': { 'extends': 'default', }, 'swap': { 'linear': { 'extends': 'default', }, 'inverse': { 'extends': 'default', }, }, 'future': { 'linear': { 'extends': 'default', }, 'inverse': { 'extends': 'default', }, }, }, 'exceptions': { // 0 or absent Success, No error. '9999': PermissionDenied, '10000': AuthenticationError, '10001': ExchangeError, '10002': InvalidOrder, '10003': InvalidOrder, '10004': OrderNotFound, '10005': InvalidOrder, '10006': InvalidOrder, '10007': InvalidOrder, '10008': InvalidOrder, '10009': InsufficientFunds, '10010': OrderNotFound, '10011': InvalidOrder, '10012': InvalidOrder, '10013': PermissionDenied, '10014': PermissionDenied, '10015': PermissionDenied, '10016': PermissionDenied, '10017': PermissionDenied, '10018': PermissionDenied, '10019': PermissionDenied, '10020': ExchangeError, '10021': InvalidOrder, '10022': InvalidOrder, '10023': InvalidOrder, '10024': InvalidOrder, '10025': InvalidOrder, '10026': InvalidOrder, '10027': InvalidOrder, '10028': DDoSProtection, '10029': OrderNotFound, '10030': ExchangeError, '10031': ExchangeError, '10032': InvalidOrder, '10033': NotSupported, '10034': InvalidOrder, '10035': InvalidOrder, '10036': InvalidOrder, '10040': ExchangeNotAvailable, '10041': OnMaintenance, '10043': InvalidOrder, '10044': InvalidOrder, '10045': InvalidOrder, '10046': InvalidOrder, '10047': DDoSProtection, '10048': ExchangeError, '11008': InvalidOrder, '11029': BadRequest, '11030': ExchangeError, '11031': ExchangeError, '11035': DDoSProtection, '11036': InvalidOrder, '11037': BadRequest, '11038': InvalidOrder, '11039': InvalidOrder, '11041': InvalidOrder, '11042': PermissionDenied, '11043': BadRequest, '11044': InvalidOrder, '11045': BadRequest, '11046': BadRequest, '11047': BadRequest, '11048': ExchangeError, '11049': BadRequest, '11050': BadRequest, '11051': OnMaintenance, '11052': ExchangeError, '11053': ExchangeError, '11090': InvalidAddress, '11091': InvalidAddress, '11092': InvalidAddress, '11093': DDoSProtection, '11094': ExchangeError, '11095': ExchangeError, '11096': ExchangeError, '12000': AuthenticationError, '12001': DDoSProtection, '12002': ExchangeError, '12998': AuthenticationError, '12003': AuthenticationError, '12004': AuthenticationError, '12005': AuthenticationError, '12100': ExchangeError, '12999': AuthenticationError, '13000': AuthenticationError, '13001': AuthenticationError, '13002': PermissionDenied, '13003': AuthenticationError, '13004': AuthenticationError, '13005': AuthenticationError, '13006': AuthenticationError, '13007': AuthenticationError, '13008': ExchangeError, '13009': AuthenticationError, '13010': BadRequest, '13011': BadRequest, '13012': PermissionDenied, '13013': BadRequest, '13014': BadRequest, '13015': BadRequest, '13016': BadRequest, '13017': ExchangeError, '13018': ExchangeError, '13019': ExchangeError, '13020': ExchangeError, '13021': PermissionDenied, '13025': ExchangeError, '-32602': BadRequest, '-32601': BadRequest, '-32700': BadRequest, '-32000': BadRequest, '11054': InvalidOrder, // 'post_only_reject' post order would be filled immediately }, 'precisionMode': TICK_SIZE, 'options': { 'code': 'BTC', 'fetchBalance': { 'code': 'BTC', }, 'transfer': { 'method': 'privateGetSubmitTransferToSubaccount', // or 'privateGetSubmitTransferToUser' }, }, }); } createExpiredOptionMarket(symbol) { // support expired option contracts let quote = 'USD'; let settle = undefined; const optionParts = symbol.split('-'); const symbolBase = symbol.split('/'); let base = undefined; let expiry = undefined; if (symbol.indexOf('/') > -1) { base = this.safeString(symbolBase, 0); expiry = this.safeString(optionParts, 1); if (symbol.indexOf('USDC') > -1) { base = base + '_USDC'; } } else { base = this.safeString(optionParts, 0); expiry = this.convertMarketIdExpireDate(this.safeString(optionParts, 1)); } if (symbol.indexOf('USDC') > -1) { quote = 'USDC'; settle = 'USDC'; } else { settle = base; } let splitBase = base; if (base.indexOf('_') > -1) { const splitSymbol = base.split('_'); splitBase = this.safeString(splitSymbol, 0); } const strike = this.safeString(optionParts, 2); const optionType = this.safeString(optionParts, 3); const datetime = this.convertExpireDate(expiry); const timestamp = this.parse8601(datetime); return { 'id': base + '-' + this.convertExpireDateToMarketIdDate(expiry) + '-' + strike + '-' + optionType, 'symbol': splitBase + '/' + 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': undefined, '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, }; } safeMarket(marketId = undefined, market = undefined, delimiter = undefined, marketType = undefined) { const isOption = (marketId !== undefined) && ((marketId.endsWith('-C')) || (marketId.endsWith('-P'))); if (isOption && !(marketId in this.markets_by_id)) { // handle expired option contracts return this.createExpiredOptionMarket(marketId); } return super.safeMarket(marketId, market, delimiter, marketType); } /** * @method * @name deribit#fetchTime * @description fetches the current integer timestamp in milliseconds from the exchange server * @see https://docs.deribit.com/#public-get_time * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {int} the current integer timestamp in milliseconds from the exchange server */ async fetchTime(params = {}) { const response = await this.publicGetGetTime(params); // // { // "jsonrpc": "2.0", // "result": 1583922446019, // "usIn": 1583922446019955, // "usOut": 1583922446019956, // "usDiff": 1, // "testnet": false // } // return this.safeInteger(response, 'result'); } /** * @method * @name deribit#fetchCurrencies * @description fetches all available currencies on an exchange * @see https://docs.deribit.com/#public-get_currencies * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} an associative dictionary of currencies */ async fetchCurrencies(params = {}) { const response = await this.publicGetGetCurrencies(params); // // { // "jsonrpc": "2.0", // "result": [ // { // "withdrawal_priorities": [], // "withdrawal_fee": 0.01457324, // "min_withdrawal_fee": 0.000001, // "min_confirmations": 1, // "fee_precision": 8, // "currency_long": "Solana", // "currency": "SOL", // "coin_type": "SOL" // }, // ... // ], // "usIn": 1688652701456124, // "usOut": 1688652701456390, // "usDiff": 266, // "testnet": true // } // const data = this.safeList(response, 'result', []); const result = {}; for (let i = 0; i < data.length; i++) { const currency = data[i]; const currencyId = this.safeString(currency, 'currency'); const code = this.safeCurrencyCode(currencyId); result[code] = this.safeCurrencyStructure({ 'info': currency, 'code': code, 'id': currencyId, 'name': this.safeString(currency, 'currency_long'), 'active': undefined, 'deposit': undefined, 'withdraw': undefined, 'type': 'crypto', 'fee': this.safeNumber(currency, 'withdrawal_fee'), 'precision': this.parseNumber(this.parsePrecision(this.safeString(currency, 'fee_precision'))), 'limits': { 'amount': { 'min': undefined, 'max': undefined, }, 'withdraw': { 'min': undefined, 'max': undefined, }, 'deposit': { 'min': undefined, 'max': undefined, }, }, 'networks': undefined, }); } return result; } codeFromOptions(methodName, params = {}) { const defaultCode = this.safeValue(this.options, 'code', 'BTC'); const options = this.safeValue(this.options, methodName, {}); const code = this.safeValue(options, 'code', defaultCode); return this.safeValue(params, 'code', code); } /** * @method * @name deribit#fetchStatus * @description the latest known information on the availability of the exchange API * @see https://docs.deribit.com/#public-status * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [status structure]{@link https://docs.ccxt.com/#/?id=exchange-status-structure} */ async fetchStatus(params = {}) { const response = await this.publicGetStatus(params); // // { // "jsonrpc": "2.0", // "result": { // "locked": "false" // true, partial, false // }, // "usIn": 1650641690226788, // "usOut": 1650641690226836, // "usDiff": 48, // "testnet": false // } // const result = this.safeValue(response, 'result'); const locked = this.safeString(result, 'locked'); const updateTime = this.safeIntegerProduct(response, 'usIn', 0.001, this.milliseconds()); return { 'status': (locked === 'false') ? 'ok' : 'maintenance', 'updated': updateTime, 'eta': undefined, 'url': undefined, 'info': response, }; } /** * @method * @name deribit#fetchAccounts * @description fetch all the accounts associated with a profile * @see https://docs.deribit.com/#private-get_subaccounts * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a dictionary of [account structures]{@link https://docs.ccxt.com/#/?id=account-structure} indexed by the account type */ async fetchAccounts(params = {}) { await this.loadMarkets(); const response = await this.privateGetGetSubaccounts(params); // // { // "jsonrpc": "2.0", // "result": [{ // "username": "someusername", // "type": "main", // "system_name": "someusername", // "security_keys_enabled": false, // "security_keys_assignments": [], // "receive_notifications": false, // "login_enabled": true, // "is_password": true, // "id": "238216", // "email": "pablo@abcdef.com" // }, // { // "username": "someusername_1", // "type": "subaccount", // "system_name": "someusername_1", // "security_keys_enabled": false, // "security_keys_assignments": [], // "receive_notifications": false, // "login_enabled": false, // "is_password": false, // "id": "245499", // "email": "pablo@abcdef.com" // } // ], // "usIn": "1652736468292006", // "usOut": "1652736468292377", // "usDiff": "371", // "testnet": false // } // const result = this.safeValue(response, 'result', []); return this.parseAccounts(result); } parseAccount(account) { // // { // "username": "someusername_1", // "type": "subaccount", // "system_name": "someusername_1", // "security_keys_enabled": false, // "security_keys_assignments": [], // "receive_notifications": false, // "login_enabled": false, // "is_password": false, // "id": "245499", // "email": "pablo@abcdef.com" // } // return { 'info': account, 'id': this.safeString(account, 'id'), 'type': this.safeString(account, 'type'), 'code': undefined, }; } /** * @method * @name deribit#fetchMarkets * @description retrieves data on all markets for deribit * @see https://docs.deribit.com/#public-get_currencies * @see https://docs.deribit.com/#public-get_instruments * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} an array of objects representing market data */ async fetchMarkets(params = {}) { const instrumentsResponses = []; const result = []; const parsedMarkets = {}; let fetchAllMarkets = undefined; [fetchAllMarkets, params] = this.handleOptionAndParams(params, 'fetchMarkets', 'fetchAllMarkets', true); if (fetchAllMarkets) { const instrumentsResponse = await this.publicGetGetInstruments(params); instrumentsResponses.push(instrumentsResponse); } else { const currenciesResponse = await this.publicGetGetCurrencies(params); // // { // "jsonrpc": "2.0", // "result": [ // { // "withdrawal_priorities": [ // { value: 0.15, name: "very_low" }, // { value: 1.5, name: "very_high" }, // ], // "withdrawal_fee": 0.0005, // "min_withdrawal_fee": 0.0005, // "min_confirmations": 1, // "fee_precision": 4, // "currency_long": "Bitcoin", // "currency": "BTC", // "coin_type": "BITCOIN" // } // ], // "usIn": 1583761588590479, // "usOut": 1583761588590544, // "usDiff": 65, // "testnet": false // } // const currenciesResult = this.safeValue(currenciesResponse, 'result', []); for (let i = 0; i < currenciesResult.length; i++) { const currencyId = this.safeString(currenciesResult[i], 'currency'); const request = { 'currency': currencyId, }; const instrumentsResponse = await this.publicGetGetInstruments(this.extend(request, params)); // // { // "jsonrpc":"2.0", // "result":[ // { // "tick_size":0.0005, // "taker_commission":0.0003, // "strike":52000.0, // "settlement_period":"month", // "settlement_currency":"BTC", // "quote_currency":"BTC", // "option_type":"put", // put, call // "min_trade_amount":0.1, // "maker_commission":0.0003, // "kind":"option", // "is_active":true, // "instrument_name":"BTC-24JUN22-52000-P", // "expiration_timestamp":1656057600000, // "creation_timestamp":1648199543000, // "counter_currency":"USD", // "contract_size":1.0, // "block_trade_commission":0.0003, // "base_currency":"BTC" // }, // { // "tick_size":0.5, // "taker_commission":0.0005, // "settlement_period":"month", // month, week // "settlement_currency":"BTC", // "quote_currency":"USD", // "min_trade_amount":10.0, // "max_liquidation_commission":0.0075, // "max_leverage":50, // "maker_commission":0.0, // "kind":"future", // "is_active":true, // "instrument_name":"BTC-27MAY22", // "future_type":"reversed", // "expiration_timestamp":1653638400000, // "creation_timestamp":1648195209000, // "counter_currency":"USD", // "contract_size":10.0, // "block_trade_commission":0.0001, // "base_currency":"BTC" // }, // { // "tick_size":0.5, // "taker_commission":0.0005, // "settlement_period":"perpetual", // "settlement_currency":"BTC", // "quote_currency":"USD", // "min_trade_amount":10.0, // "max_liquidation_commission":0.0075, // "max_leverage":50, // "maker_commission":0.0, // "kind":"future", // "is_active":true, // "instrument_name":"BTC-PERPETUAL", // "future_type":"reversed", // "expiration_timestamp":32503708800000, // "creation_timestamp":1534242287000, // "counter_currency":"USD", // "contract_size":10.0, // "block_trade_commission":0.0001, // "base_currency":"BTC" // }, // ], // "usIn":1648691472831791, // "usOut":1648691472831896, // "usDiff":105, // "testnet":false // } // instrumentsResponses.push(instrumentsResponse); } } for (let i = 0; i < instrumentsResponses.length; i++) { const instrumentsResult = this.safeValue(instrumentsResponses[i], 'result', []); for (let k = 0; k < instrumentsResult.length; k++) { const market = instrumentsResult[k]; const kind = this.safeString(market, 'kind'); const isSpot = (kind === 'spot'); const id = this.safeString(market, 'instrument_name'); const baseId = this.safeString(market, 'base_currency'); const quoteId = this.safeString(market, 'counter_currency'); const settleId = this.safeString(market, 'settlement_currency'); const base = this.safeCurrencyCode(baseId); const quote = this.safeCurrencyCode(quoteId); const settle = this.safeCurrencyCode(settleId); const settlementPeriod = this.safeValue(market, 'settlement_period'); const swap = (settlementPeriod === 'perpetual'); const future = !swap && (kind.indexOf('future') >= 0); const option = (kind.indexOf('option') >= 0); const isComboMarket = kind.indexOf('combo') >= 0; const expiry = this.safeInteger(market, 'expiration_timestamp'); let strike = undefined; let optionType = undefined; let symbol = id; let type = 'swap'; if (future) { type = 'future'; } else if (option) { type = 'option'; } else if (isSpot) { type = 'spot'; } let inverse = undefined; let linear = undefined; if (isSpot) { symbol = base + '/' + quote; } else if (!isComboMarket) { symbol = base + '/' + quote + ':' + settle; if (option || future) { symbol = symbol + '-' + this.yymmdd(expiry, ''); if (option) { strike = this.safeNumber(market, 'strike'); optionType = this.safeString(market, 'option_type'); const letter = (optionType === 'call') ? 'C' : 'P'; symbol = symbol + '-' + this.numberToString(strike) + '-' + letter; } } inverse = (quote !== settle); linear = (settle === quote); } const parsedMarketValue = this.safeValue(parsedMarkets, symbol); if (parsedMarketValue) { continue; } parsedMarkets[symbol] = true; const minTradeAmount = this.safeNumber(market, 'min_trade_amount'); const tickSize = this.safeNumber(market, 'tick_size'); result.push({ 'id': id, 'symbol': symbol, 'base': base, 'quote': quote, 'settle': settle, 'baseId': baseId, 'quoteId': quoteId, 'settleId': settleId, 'type': type, 'spot': isSpot, 'margin': false, 'swap': swap, 'future': future, 'option': option, 'active': this.safeValue(market, 'is_active'), 'contract': !isSpot, 'linear': linear, 'inverse': inverse, 'taker': this.safeNumber(market, 'taker_commission'), 'maker': this.safeNumber(market, 'maker_commission'), 'contractSize': this.safeNumber(market, 'contract_size'), 'expiry': expiry, 'expiryDatetime': this.iso8601(expiry), 'strike': strike, 'optionType': optionType, 'precision': { 'amount': minTradeAmount, 'price': tickSize, }, 'limits': { 'leverage': { 'min': undefined, 'max': undefined, }, 'amount': { 'min': minTradeAmount, 'max': undefined, }, 'price': { 'min': tickSize, 'max': undefined, }, 'cost': { 'min': undefined, 'max': undefined, }, }, 'created': this.safeInteger(market, 'creation_timestamp'), 'info': market, }); } } return result; } parseBalance(balance) { const result = { 'info': balance, }; let summaries = []; if ('summaries' in balance) { summaries = this.safeList(balance, 'summaries'); } else { summaries = [balance]; } for (let i = 0; i < summaries.length; i++) { const data = summaries[i]; const currencyId = this.safeString(data, 'currency'); const currencyCode = this.safeCurrencyCode(currencyId); const account = this.account(); account['free'] = this.safeString(data, 'available_funds'); account['used'] = this.safeString(data, 'maintenance_margin'); account['total'] = this.safeString(data, 'equity'); result[currencyCode] = account; } return this.safeBalance(result); } /** * @method * @name deribit#fetchBalance * @description query for balance and get the amount of funds available for trading or funds locked in orders * @see https://docs.deribit.com/#private-get_account_summary * @see https://docs.deribit.com/#private-get_account_summaries * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.code] unified currency code of the currency for the balance, if defined 'privateGetGetAccountSummary' will be used, otherwise 'privateGetGetAccountSummaries' will be used * @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure} */ async fetchBalance(params = {}) { await this.loadMarkets(); const code = this.safeString(params, 'code'); params = this.omit(params, 'code'); const request = {}; if (code !== undefined) { request['currency'] = this.currencyId(code); } let response = undefined; if (code === undefined) { response = await this.privateGetGetAccountSummaries(params); } else { response = await this.privateGetGetAccountSummary(this.extend(request, params)); } // // { // "jsonrpc": "2.0", // "result": { // "total_pl": 0, // "session_upl": 0, // "session_rpl": 0, // "session_funding": 0, // "portfolio_margining_enabled": false, // "options_vega": 0, // "options_theta": 0, // "options_session_upl": 0, // "options_session_rpl": 0, // "options_pl": 0, // "options_gamma": 0, // "options_delta": 0, // "margin_balance": 0.00062359, // "maintenance_margin": 0, // "limits": { // "non_matching_engine_burst": 300, // "non_matching_engine": 200, // "matching_engine_burst": 20, // "matching_engine": 2 // }, // "initial_margin": 0, // "futures_session_upl": 0, // "futures_session_rpl": 0, // "futures_pl": 0, // "equity": 0.00062359, // "deposit_address": "13tUtNsJSZa1F5GeCmwBywVrymHpZispzw", // "delta_total": 0, // "currency": "BTC", // "balance": 0.00062359, // "available_withdrawal_funds": 0.00062359, // "available_funds": 0.00062359 // }, // "usIn": 1583775838115975, // "usOut": 1583775838116520, // "usDiff": 545, // "testnet": false // } // const result = this.safeDict(response, 'result', {}); return this.parseBalance(result); } /** * @method * @name deribit#createDepositAddress * @description create a currency deposit address * @see https://docs.deribit.com/#private-create_deposit_address * @param {string} code unified currency code of the currency for the deposit address * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure} */ async createDepositAddress(code, params = {}) { await this.loadMarkets(); const currency = this.currency(code); const request = { 'currency': currency['id'], }; const response = await this.privateGetCreateDepositAddress(this.extend(request, params)); // // { // "jsonrpc": "2.0", // "id": 7538, // "result": { // "address": "2N8udZGBc1hLRCFsU9kGwMPpmYUwMFTuCwB", // "creation_timestamp": 1550575165170, // "currency": "BTC", // "type": "deposit" // } // } // const result = this.safeValue(response, 'result', {}); const address = this.safeString(result, 'address'); this.checkAddress(address); return { 'currency': code, 'address': address, 'tag': undefined, 'network': undefined, 'info': response, }; } /** * @method * @name deribit#fetchDepositAddress * @description fetch the deposit address for a currency associated with this account * @see https://docs.deribit.com/#private-get_current_deposit_address * @param {string} code unified currency code * @param