ccxt
Version:
1,164 lines (1,162 loc) • 167 kB
JavaScript
// ----------------------------------------------------------------------------
// PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
// https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
// EDIT THE CORRESPONDENT .ts FILE INSTEAD
// ---------------------------------------------------------------------------
import Exchange from './abstract/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