ccxt
Version:
1,084 lines (1,082 loc) • 163 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/delta.js';
import { ExchangeError, InsufficientFunds, BadRequest, BadSymbol, InvalidOrder, AuthenticationError, OrderNotFound, ExchangeNotAvailable, ArgumentsRequired } from './base/errors.js';
import { TICK_SIZE } from './base/functions/number.js';
import { Precise } from './base/Precise.js';
import { sha256 } from './static_dependencies/noble-hashes/sha256.js';
// ---------------------------------------------------------------------------
/**
* @class delta
* @augments Exchange
*/
export default class delta extends Exchange {
describe() {
return this.deepExtend(super.describe(), {
'id': 'delta',
'name': 'Delta Exchange',
'countries': ['VC'],
'rateLimit': 300,
'version': 'v2',
// new metainfo interface
'has': {
'CORS': undefined,
'spot': true,
'margin': false,
'swap': true,
'future': false,
'option': true,
'addMargin': true,
'cancelAllOrders': true,
'cancelOrder': true,
'closeAllPositions': true,
'closePosition': false,
'createOrder': true,
'createReduceOnlyOrder': true,
'editOrder': true,
'fetchBalance': true,
'fetchClosedOrders': true,
'fetchCurrencies': true,
'fetchDeposit': undefined,
'fetchDepositAddress': true,
'fetchDepositAddresses': false,
'fetchDepositAddressesByNetwork': false,
'fetchDeposits': undefined,
'fetchFundingHistory': false,
'fetchFundingRate': true,
'fetchFundingRateHistory': false,
'fetchFundingRates': true,
'fetchGreeks': true,
'fetchIndexOHLCV': true,
'fetchLedger': true,
'fetchLeverage': true,
'fetchLeverageTiers': false,
'fetchMarginMode': true,
'fetchMarginModes': false,
'fetchMarketLeverageTiers': false,
'fetchMarkets': true,
'fetchMarkOHLCV': true,
'fetchMySettlementHistory': false,
'fetchMyTrades': true,
'fetchOHLCV': true,
'fetchOpenInterest': true,
'fetchOpenOrders': true,
'fetchOption': true,
'fetchOptionChain': false,
'fetchOrderBook': true,
'fetchPosition': true,
'fetchPositionMode': false,
'fetchPositions': true,
'fetchPremiumIndexOHLCV': false,
'fetchSettlementHistory': true,
'fetchStatus': true,
'fetchTicker': true,
'fetchTickers': true,
'fetchTime': true,
'fetchTrades': true,
'fetchTransfer': undefined,
'fetchTransfers': undefined,
'fetchUnderlyingAssets': false,
'fetchVolatilityHistory': false,
'fetchWithdrawal': undefined,
'fetchWithdrawals': undefined,
'reduceMargin': true,
'setLeverage': true,
'setMargin': false,
'setMarginMode': false,
'setPositionMode': false,
'transfer': false,
'withdraw': false,
},
'timeframes': {
'1m': '1m',
'3m': '3m',
'5m': '5m',
'15m': '15m',
'30m': '30m',
'1h': '1h',
'2h': '2h',
'4h': '4h',
'6h': '6h',
'1d': '1d',
'7d': '7d',
'1w': '1w',
'2w': '2w',
'1M': '30d',
},
'urls': {
'logo': 'https://user-images.githubusercontent.com/1294454/99450025-3be60a00-2931-11eb-9302-f4fd8d8589aa.jpg',
'test': {
'public': 'https://testnet-api.delta.exchange',
'private': 'https://testnet-api.delta.exchange',
},
'api': {
'public': 'https://api.delta.exchange',
'private': 'https://api.delta.exchange',
},
'www': 'https://www.delta.exchange',
'doc': [
'https://docs.delta.exchange',
],
'fees': 'https://www.delta.exchange/fees',
'referral': 'https://www.delta.exchange/app/signup/?code=IULYNB',
},
'api': {
'public': {
'get': [
'assets',
'indices',
'products',
'products/{symbol}',
'tickers',
'tickers/{symbol}',
'l2orderbook/{symbol}',
'trades/{symbol}',
'stats',
'history/candles',
'history/sparklines',
'settings',
],
},
'private': {
'get': [
'orders',
'products/{product_id}/orders/leverage',
'positions/margined',
'positions',
'orders/history',
'fills',
'fills/history/download/csv',
'wallet/balances',
'wallet/transactions',
'wallet/transactions/download',
'wallets/sub_accounts_transfer_history',
'users/trading_preferences',
'sub_accounts',
'profile',
'deposits/address',
'orders/leverage',
],
'post': [
'orders',
'orders/bracket',
'orders/batch',
'products/{product_id}/orders/leverage',
'positions/change_margin',
'positions/close_all',
'wallets/sub_account_balance_transfer',
'orders/cancel_after',
'orders/leverage',
],
'put': [
'orders',
'orders/bracket',
'orders/batch',
'positions/auto_topup',
'users/update_mmp',
'users/reset_mmp',
],
'delete': [
'orders',
'orders/all',
'orders/batch',
],
},
},
'fees': {
'trading': {
'tierBased': true,
'percentage': true,
'taker': this.parseNumber('0.0015'),
'maker': this.parseNumber('0.0010'),
'tiers': {
'taker': [
[this.parseNumber('0'), this.parseNumber('0.0015')],
[this.parseNumber('100'), this.parseNumber('0.0013')],
[this.parseNumber('250'), this.parseNumber('0.0013')],
[this.parseNumber('1000'), this.parseNumber('0.001')],
[this.parseNumber('5000'), this.parseNumber('0.0009')],
[this.parseNumber('10000'), this.parseNumber('0.00075')],
[this.parseNumber('20000'), this.parseNumber('0.00065')],
],
'maker': [
[this.parseNumber('0'), this.parseNumber('0.001')],
[this.parseNumber('100'), this.parseNumber('0.001')],
[this.parseNumber('250'), this.parseNumber('0.0009')],
[this.parseNumber('1000'), this.parseNumber('0.00075')],
[this.parseNumber('5000'), this.parseNumber('0.0006')],
[this.parseNumber('10000'), this.parseNumber('0.0005')],
[this.parseNumber('20000'), this.parseNumber('0.0005')],
],
},
},
},
'options': {
'networks': {
'TRC20': 'TRC20(TRON)',
'BEP20': 'BEP20(BSC)',
},
},
'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': {
'triggerPriceType': undefined,
'price': true,
},
// todo implementation
'timeInForce': {
'IOC': true,
'FOK': true,
'PO': true,
'GTD': false,
},
'hedged': false,
'selfTradePrevention': false,
'trailing': false,
'iceberg': false,
'leverage': false,
'marketBuyByCost': false,
'marketBuyRequiresPrice': false,
},
'createOrders': undefined,
'fetchMyTrades': {
'marginMode': false,
'limit': 100,
'daysBack': 100000,
'untilDays': 100000,
'symbolRequired': false,
},
'fetchOrder': undefined,
'fetchOpenOrders': {
'marginMode': false,
'limit': 100,
'trigger': false,
'trailing': false,
'symbolRequired': false,
},
'fetchOrders': undefined,
'fetchClosedOrders': {
'marginMode': false,
'limit': 500,
'daysBack': 100000,
'daysBackCanceled': 1,
'untilDays': 100000,
'trigger': false,
'trailing': false,
'symbolRequired': false,
},
'fetchOHLCV': {
'limit': 2000, // todo: recheck
},
},
'spot': {
'extends': 'default',
},
'swap': {
'linear': {
'extends': 'default',
},
'inverse': {
'extends': 'default',
},
},
'future': {
'linear': {
'extends': 'default',
},
'inverse': {
'extends': 'default',
},
},
},
'precisionMode': TICK_SIZE,
'requiredCredentials': {
'apiKey': true,
'secret': true,
},
'exceptions': {
'exact': {
// Margin required to place order with selected leverage and quantity is insufficient.
'insufficient_margin': InsufficientFunds,
'order_size_exceed_available': InvalidOrder,
'risk_limits_breached': BadRequest,
'invalid_contract': BadSymbol,
'immediate_liquidation': InvalidOrder,
'out_of_bankruptcy': InvalidOrder,
'self_matching_disrupted_post_only': InvalidOrder,
'immediate_execution_post_only': InvalidOrder,
'bad_schema': BadRequest,
'invalid_api_key': AuthenticationError,
'invalid_signature': AuthenticationError,
'open_order_not_found': OrderNotFound,
'unavailable': ExchangeNotAvailable, // {"error":{"code":"unavailable"},"success":false}
},
'broad': {},
},
});
}
createExpiredOptionMarket(symbol) {
// support expired option contracts
const quote = 'USDT';
const optionParts = symbol.split('-');
const symbolBase = symbol.split('/');
let base = undefined;
let expiry = undefined;
let optionType = undefined;
if (symbol.indexOf('/') > -1) {
base = this.safeString(symbolBase, 0);
expiry = this.safeString(optionParts, 1);
optionType = this.safeString(optionParts, 3);
}
else {
base = this.safeString(optionParts, 1);
expiry = this.safeString(optionParts, 3);
optionType = this.safeString(optionParts, 0);
}
if (expiry !== undefined) {
expiry = expiry.slice(4) + expiry.slice(2, 4) + expiry.slice(0, 2);
}
const settle = quote;
const strike = this.safeString(optionParts, 2);
const datetime = this.convertExpireDate(expiry);
const timestamp = this.parse8601(datetime);
return {
'id': optionType + '-' + base + '-' + strike + '-' + expiry,
'symbol': base + '/' + 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': this.parseNumber('1'),
'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')) || (marketId.startsWith('C-')) || (marketId.startsWith('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 delta#fetchTime
* @description fetches the current integer timestamp in milliseconds from the exchange server
* @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.publicGetSettings(params);
// full response sample under `fetchStatus`
const result = this.safeDict(response, 'result', {});
return this.safeIntegerProduct(result, 'server_time', 0.001);
}
/**
* @method
* @name delta#fetchStatus
* @description the latest known information on the availability of the exchange API
* @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.publicGetSettings(params);
//
// {
// "result": {
// "deto_liquidity_mining_daily_reward": "40775",
// "deto_msp": "1.0",
// "deto_staking_daily_reward": "23764.08",
// "enabled_wallets": [
// "BTC",
// ...
// ],
// "portfolio_margin_params": {
// "enabled_portfolios": {
// ".DEAVAXUSDT": {
// "asset_id": 5,
// "futures_contingency_margin_percent": "1",
// "interest_rate": "0",
// "maintenance_margin_multiplier": "0.8",
// "max_price_shock": "20",
// "max_short_notional_limit": "2000",
// "options_contingency_margin_percent": "1",
// "options_discount_range": "10",
// "options_liq_band_range_percentage": "25",
// "settling_asset": "USDT",
// "sort_priority": 5,
// "underlying_asset": "AVAX",
// "volatility_down_shock": "30",
// "volatility_up_shock": "45"
// },
// ...
// },
// "portfolio_enabled_contracts": [
// "futures",
// "perpetual_futures",
// "call_options",
// "put_options"
// ]
// },
// "server_time": 1650640673500273,
// "trade_farming_daily_reward": "100000",
// "circulating_supply": "140000000",
// "circulating_supply_update_time": "1636752800",
// "deto_referral_mining_daily_reward": "0",
// "deto_total_reward_pool": "100000000",
// "deto_trade_mining_daily_reward": "0",
// "kyc_deposit_limit": "20",
// "kyc_withdrawal_limit": "10000",
// "maintenance_start_time": "1650387600000000",
// "msp_deto_commission_percent": "25",
// "under_maintenance": "false"
// },
// "success": true
// }
//
const result = this.safeDict(response, 'result', {});
const underMaintenance = this.safeString(result, 'under_maintenance');
const status = (underMaintenance === 'true') ? 'maintenance' : 'ok';
const updated = this.safeIntegerProduct(result, 'server_time', 0.001, this.milliseconds());
return {
'status': status,
'updated': updated,
'eta': undefined,
'url': undefined,
'info': response,
};
}
/**
* @method
* @name delta#fetchCurrencies
* @description fetches all available currencies on an exchange
* @see https://docs.delta.exchange/#get-list-of-all-assets
* @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.publicGetAssets(params);
//
// {
// "result": [
// {
// "base_withdrawal_fee": "0.005000000000000000",
// "id": "1",
// "interest_credit": false,
// "interest_slabs": null,
// "kyc_deposit_limit": "0.000000000000000000",
// "kyc_withdrawal_limit": "0.000000000000000000",
// "min_withdrawal_amount": "0.010000000000000000",
// "minimum_precision": "4",
// "name": "Ethereum",
// "networks": [
// {
// "allowed_deposit_groups": null,
// "base_withdrawal_fee": "0.0025",
// "deposit_status": "enabled",
// "memo_required": false,
// "min_deposit_amount": "0.000050000000000000",
// "min_withdrawal_amount": "0.010000000000000000",
// "minimum_deposit_confirmations": "12",
// "network": "ERC20",
// "variable_withdrawal_fee": "0",
// "withdrawal_status": "enabled"
// },
// {
// "allowed_deposit_groups": null,
// "base_withdrawal_fee": "0.0001",
// "deposit_status": "enabled",
// "memo_required": false,
// "min_deposit_amount": "0.000050000000000000",
// "min_withdrawal_amount": "0.000300000000000000",
// "minimum_deposit_confirmations": "15",
// "network": "BEP20(BSC)",
// "variable_withdrawal_fee": "0",
// "withdrawal_status": "enabled"
// }
// ],
// "precision": "18",
// "sort_priority": "3",
// "symbol": "ETH",
// "variable_withdrawal_fee": "0.000000000000000000"
// },
// ],
// "success":true
// }
//
const currencies = this.safeList(response, 'result', []);
const result = {};
for (let i = 0; i < currencies.length; i++) {
const currency = currencies[i];
const id = this.safeString(currency, 'symbol');
const numericId = this.safeInteger(currency, 'id');
const code = this.safeCurrencyCode(id);
const chains = this.safeList(currency, 'networks', []);
const networks = {};
for (let j = 0; j < chains.length; j++) {
const chain = chains[j];
const networkId = this.safeString(chain, 'network');
const networkCode = this.networkIdToCode(networkId);
networks[networkCode] = {
'id': networkId,
'network': networkCode,
'name': this.safeString(chain, 'name'),
'info': chain,
'active': this.safeString(chain, 'status') === 'enabled',
'deposit': this.safeString(chain, 'deposit_status') === 'enabled',
'withdraw': this.safeString(chain, 'withdrawal_status') === 'enabled',
'fee': this.safeNumber(chain, 'base_withdrawal_fee'),
'limits': {
'deposit': {
'min': this.safeNumber(chain, 'min_deposit_amount'),
'max': undefined,
},
'withdraw': {
'min': this.safeNumber(chain, 'min_withdrawal_amount'),
'max': undefined,
},
},
};
}
result[code] = this.safeCurrencyStructure({
'id': id,
'numericId': numericId,
'code': code,
'name': this.safeString(currency, 'name'),
'info': currency,
'active': undefined,
'deposit': this.safeString(currency, 'deposit_status') === 'enabled',
'withdraw': this.safeString(currency, 'withdrawal_status') === 'enabled',
'fee': this.safeNumber(currency, 'base_withdrawal_fee'),
'precision': this.parseNumber(this.parsePrecision(this.safeString(currency, 'precision'))),
'limits': {
'amount': { 'min': undefined, 'max': undefined },
'withdraw': {
'min': this.safeNumber(currency, 'min_withdrawal_amount'),
'max': undefined,
},
},
'networks': networks,
'type': 'crypto',
});
}
return result;
}
async loadMarkets(reload = false, params = {}) {
const markets = await super.loadMarkets(reload, params);
const currenciesByNumericId = this.safeDict(this.options, 'currenciesByNumericId');
if ((currenciesByNumericId === undefined) || reload) {
this.options['currenciesByNumericId'] = this.indexByStringifiedNumericId(this.currencies);
}
const marketsByNumericId = this.safeDict(this.options, 'marketsByNumericId');
if ((marketsByNumericId === undefined) || reload) {
this.options['marketsByNumericId'] = this.indexByStringifiedNumericId(this.markets);
}
return markets;
}
indexByStringifiedNumericId(input) {
const result = {};
if (input === undefined) {
return undefined;
}
const keys = Object.keys(input);
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
const item = input[key];
const numericIdString = this.safeString(item, 'numericId');
if (numericIdString === undefined) {
continue;
}
result[numericIdString] = item;
}
return result;
}
/**
* @method
* @name delta#fetchMarkets
* @description retrieves data on all markets for delta
* @see https://docs.delta.exchange/#get-list-of-products
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {object[]} an array of objects representing market data
*/
async fetchMarkets(params = {}) {
const response = await this.publicGetProducts(params);
//
// {
// "meta":{ "after":null, "before":null, "limit":100, "total_count":81 },
// "result":[
// // the below response represents item from perpetual market
// {
// "annualized_funding":"5.475000000000000000",
// "is_quanto":false,
// "ui_config":{
// "default_trading_view_candle":"15",
// "leverage_slider_values":[1,3,5,10,25,50],
// "price_clubbing_values":[0.001,0.005,0.05,0.1,0.5,1,5],
// "show_bracket_orders":false,
// "sort_priority":29,
// "tags":[]
// },
// "basis_factor_max_limit":"0.15",
// "symbol":"P-LINK-D-151120",
// "id":1584,
// "default_leverage":"5.000000000000000000",
// "maker_commission_rate":"0.0005",
// "contract_unit_currency":"LINK",
// "strike_price":"12.507948",
// "settling_asset":{
// // asset structure
// },
// "auction_start_time":null,
// "auction_finish_time":null,
// "settlement_time":"2020-11-15T12:00:00Z",
// "launch_time":"2020-11-14T11:55:05Z",
// "spot_index":{
// // index structure
// },
// "trading_status":"operational",
// "tick_size":"0.001",
// "position_size_limit":100000,
// "notional_type":"vanilla", // vanilla, inverse
// "price_band":"0.4",
// "barrier_price":null,
// "description":"Daily LINK PUT options quoted in USDT and settled in USDT",
// "insurance_fund_margin_contribution":"1",
// "quoting_asset":{
// // asset structure
// },
// "liquidation_penalty_factor":"0.2",
// "product_specs":{"max_volatility":3,"min_volatility":0.3,"spot_price_band":"0.40"},
// "initial_margin_scaling_factor":"0.0001",
// "underlying_asset":{
// // asset structure
// },
// "state":"live",
// "contract_value":"1",
// "initial_margin":"2",
// "impact_size":5000,
// "settlement_price":null,
// "contract_type":"put_options", // put_options, call_options, move_options, perpetual_futures, interest_rate_swaps, futures, spreads
// "taker_commission_rate":"0.0005",
// "maintenance_margin":"1",
// "short_description":"LINK Daily PUT Options",
// "maintenance_margin_scaling_factor":"0.00005",
// "funding_method":"mark_price",
// "max_leverage_notional":"20000"
// },
// // the below response represents item from spot market
// {
// "position_size_limit": 10000000,
// "settlement_price": null,
// "funding_method": "mark_price",
// "settling_asset": null,
// "impact_size": 10,
// "id": 32258,
// "auction_finish_time": null,
// "description": "Solana tether spot market",
// "trading_status": "operational",
// "tick_size": "0.01",
// "liquidation_penalty_factor": "1",
// "spot_index": {
// "config": { "quoting_asset": "USDT", "service_id": 8, "underlying_asset": "SOL" },
// "constituent_exchanges": [
// { "exchange": "binance", "health_interval": 60, "health_priority": 1, "weight": 1 },
// { "exchange": "huobi", "health_interval": 60, "health_priority": 2, "weight": 1 }
// ],
// "constituent_indices": null,
// "description": "Solana index from binance and huobi",
// "health_interval": 300,
// "id": 105,
// "impact_size": "40.000000000000000000",
// "index_type": "spot_pair",
// "is_composite": false,
// "price_method": "ltp",
// "quoting_asset_id": 5,
// "symbol": ".DESOLUSDT",
// "tick_size": "0.000100000000000000",
// "underlying_asset_id": 66
// },
// "contract_type": "spot",
// "launch_time": "2022-02-03T10:18:11Z",
// "symbol": "SOL_USDT",
// "disruption_reason": null,
// "settlement_time": null,
// "insurance_fund_margin_contribution": "1",
// "is_quanto": false,
// "maintenance_margin": "5",
// "taker_commission_rate": "0.0005",
// "auction_start_time": null,
// "max_leverage_notional": "10000000",
// "state": "live",
// "annualized_funding": "0",
// "notional_type": "vanilla",
// "price_band": "100",
// "product_specs": { "kyc_required": false, "max_order_size": 2000, "min_order_size": 0.01, "quoting_precision": 4, "underlying_precision": 2 },
// "default_leverage": "1.000000000000000000",
// "initial_margin": "10",
// "maintenance_margin_scaling_factor": "1",
// "ui_config": {
// "default_trading_view_candle": "1d",
// "leverage_slider_values": [],
// "price_clubbing_values": [ 0.01, 0.05, 0.1, 0.5, 1, 2.5, 5 ],
// "show_bracket_orders": false,
// "sort_priority": 2,
// "tags": []
// },
// "basis_factor_max_limit": "10000",
// "contract_unit_currency": "SOL",
// "strike_price": null,
// "quoting_asset": {
// "base_withdrawal_fee": "10.000000000000000000",
// "deposit_status": "enabled",
// "id": 5,
// "interest_credit": false,
// "interest_slabs": null,
// "kyc_deposit_limit": "100000.000000000000000000",
// "kyc_withdrawal_limit": "10000.000000000000000000",
// "min_withdrawal_amount": "30.000000000000000000",
// "minimum_precision": 2,
// "name": "Tether",
// "networks": [
// { "base_withdrawal_fee": "25", "deposit_status": "enabled", "memo_required": false, "network": "ERC20", "variable_withdrawal_fee": "0", "withdrawal_status": "enabled" },
// { "base_withdrawal_fee": "1", "deposit_status": "enabled", "memo_required": false, "network": "BEP20(BSC)", "variable_withdrawal_fee": "0", "withdrawal_status": "enabled" },
// { "base_withdrawal_fee": "1", "deposit_status": "disabled", "memo_required": false, "network": "TRC20(TRON)", "variable_withdrawal_fee": "0", "withdrawal_status": "disabled" }
// ],
// "precision": 8,
// "sort_priority": 1,
// "symbol": "USDT",
// "variable_withdrawal_fee": "0.000000000000000000",
// "withdrawal_status": "enabled"
// },
// "maker_commission_rate": "0.0005",
// "initial_margin_scaling_factor": "2",
// "underlying_asset": {
// "base_withdrawal_fee": "0.000000000000000000",
// "deposit_status": "enabled",
// "id": 66,
// "interest_credit": false,
// "interest_slabs": null,
// "kyc_deposit_limit": "0.000000000000000000",
// "kyc_withdrawal_limit": "0.000000000000000000",
// "min_withdrawal_amount": "0.020000000000000000",
// "minimum_precision": 4,
// "name": "Solana",
// "networks": [
// { "base_withdrawal_fee": "0.01", "deposit_status": "enabled", "memo_required": false, "network": "SOLANA", "variable_withdrawal_fee": "0", "withdrawal_status": "enabled" },
// { "base_withdrawal_fee": "0.01", "deposit_status": "enabled", "memo_required": false, "network": "BEP20(BSC)", "variable_withdrawal_fee": "0", "withdrawal_status": "enabled" }
// ],
// "precision": 8,
// "sort_priority": 7,
// "symbol": "SOL",
// "variable_withdrawal_fee": "0.000000000000000000",
// "withdrawal_status": "enabled"
// },
// "barrier_price": null,
// "contract_value": "1",
// "short_description": "SOL-USDT spot market"
// },
// ],
// "success":true
// }
//
const markets = this.safeList(response, 'result', []);
const result = [];
for (let i = 0; i < markets.length; i++) {
const market = markets[i];
let type = this.safeString(market, 'contract_type');
if (type === 'options_combos') {
continue;
}
// const settlingAsset = this.safeValue (market, 'settling_asset', {});
const quotingAsset = this.safeDict(market, 'quoting_asset', {});
const underlyingAsset = this.safeDict(market, 'underlying_asset', {});
const settlingAsset = this.safeDict(market, 'settling_asset');
const productSpecs = this.safeDict(market, 'product_specs', {});
const baseId = this.safeString(underlyingAsset, 'symbol');
const quoteId = this.safeString(quotingAsset, 'symbol');
const settleId = this.safeString(settlingAsset, 'symbol');
const id = this.safeString(market, 'symbol');
const numericId = this.safeInteger(market, 'id');
const base = this.safeCurrencyCode(baseId);
const quote = this.safeCurrencyCode(quoteId);
const settle = this.safeCurrencyCode(settleId);
const callOptions = (type === 'call_options');
const putOptions = (type === 'put_options');
const moveOptions = (type === 'move_options');
const spot = (type === 'spot');
const swap = (type === 'perpetual_futures');
const future = (type === 'futures');
const option = (callOptions || putOptions || moveOptions);
const strike = this.safeString(market, 'strike_price');
const expiryDatetime = this.safeString(market, 'settlement_time');
const expiry = this.parse8601(expiryDatetime);
const contractSize = this.safeNumber(market, 'contract_value');
let amountPrecision = undefined;
if (spot) {
amountPrecision = this.parseNumber(this.parsePrecision(this.safeString(productSpecs, 'underlying_precision'))); // seems inverse of 'impact_size'
}
else {
// other markets (swap, futures, move, spread, irs) seem to use the step of '1' contract
amountPrecision = this.parseNumber('1');
}
const linear = (settle === quote);
let optionType = undefined;
let symbol = base + '/' + quote;
if (swap || future || option) {
symbol = symbol + ':' + settle;
if (future || option) {
symbol = symbol + '-' + this.yymmdd(expiry);
if (option) {
type = 'option';
let letter = 'C';
optionType = 'call';
if (putOptions) {
letter = 'P';
optionType = 'put';
}
else if (moveOptions) {
letter = 'M';
optionType = 'move';
}
symbol = symbol + '-' + strike + '-' + letter;
}
else {
type = 'future';
}
}
else {
type = 'swap';
}
}
const state = this.safeString(market, 'state');
result.push({
'id': id,
'numericId': numericId,
'symbol': symbol,
'base': base,
'quote': quote,
'settle': settle,
'baseId': baseId,
'quoteId': quoteId,
'settleId': settleId,
'type': type,
'spot': spot,
'margin': spot ? undefined : false,
'swap': swap,
'future': future,
'option': option,
'active': (state === 'live'),
'contract': !spot,
'linear': spot ? undefined : linear,
'inverse': spot ? undefined : !linear,
'taker': this.safeNumber(market, 'taker_commission_rate'),
'maker': this.safeNumber(market, 'maker_commission_rate'),
'contractSize': spot ? undefined : contractSize,
'expiry': expiry,
'expiryDatetime': this.iso8601(expiry),
'strike': this.parseNumber(strike),
'optionType': optionType,
'precision': {
'amount': amountPrecision,
'price': this.safeNumber(market, 'tick_size'),
},
'limits': {
'leverage': {
'min': undefined,
'max': undefined,
},
'amount': {
'min': this.parseNumber('1'),
'max': this.safeNumber(market, 'position_size_limit'),
},
'price': {
'min': undefined,
'max': undefined,
},
'cost': {
'min': this.safeNumber(market, 'min_size'),
'max': undefined,
},
},
'created': this.parse8601(this.safeString(market, 'launch_time')),
'info': market,
});
}
return result;
}
parseTicker(ticker, market = undefined) {
//
// spot: fetchTicker, fetchTickers
//
// {
// "close": 30634.0,
// "contract_type": "spot",
// "greeks": null,
// "high": 30780.0,
// "low": 30340.5,
// "mark_price": "48000",
// "oi": "0.0000",
// "oi_change_usd_6h": "0.0000",
// "oi_contracts": "0",
// "oi_value": "0.0000",
// "oi_value_symbol": "BTC",
// "oi_value_usd": "0.0000",
// "open": 30464.0,
// "price_band": null,
// "product_id": 8320,
// "quotes": {},
// "size": 2.6816639999999996,
// "spot_price": "30637.91465121",
// "symbol": "BTC_USDT",
// "timestamp": 1689139767621299,
// "turnover": 2.6816639999999996,
// "turnover_symbol": "BTC",
// "turnover_usd": 81896.45613400004,
// "volume": 2.6816639999999996
// }
//
// swap: fetchTicker, fetchTickers
//
// {
// "close": 30600.5,
// "contract_type": "perpetual_futures",
// "funding_rate": "0.00602961",
// "greeks": null,
// "high": 30803.0,
// "low": 30265.5,
// "mark_basis": "-0.45601594",
// "mark_price": "30600.10481568",
// "oi": "469.9190",
// "oi_change_usd_6h": "2226314.9900",
// "oi_contracts": "469919",
// "oi_value": "469.9190",
// "oi_value_symbol": "BTC",
// "oi_value_usd": "14385640.6802",
// "open": 30458.5,
// "price_band": {
// "lower_limit": "29067.08312627",
// "upper_limit": "32126.77608693"
// },
// "product_id": 139,
// "quotes": {
// "ask_iv": null,
// "ask_size": "965",
// "best_ask": "30600.5",
// "best_bid": "30599.5",
// "bid_iv": null,
// "bid_size": "196",
// "impact_mid_price": null,
// "mark_iv": "-0.44931641"
// },
// "size": 1226303,
// "spot_price": "30612.85362773",
// "symbol": "BTCUSDT",
// "timestamp": 1689136597460456,
// "turnover": 37392218.45999999,
// "turnover_symbol": "USDT",
// "turnover_usd": 37392218.45999999,
// "volume": 1226.3029999999485
// }
//
// option: fetchTicker, fetchTickers
//
// {
// "contract_type": "call_options",
// "greeks": {
// "delta": "0.60873994",
// "gamma": "0.00014854",
// "rho": "7.71808010",
// "spot": "30598.49040622",
// "theta": "-30.44743017",
// "vega": "24.83508248"
// },
// "mark_price": "1347.74819696",
// "mark_vol": "0.39966303",
// "oi": "2.7810",
// "oi_change_usd_6h": "0.0000",
// "oi_contracts": "2781",
// "oi_value": "2.7810",
// "oi_value_symbol": "BTC",
// "oi_value_usd": "85127.4337",
// "price_band": {
// "lower_limit": "91.27423497",
// "upper_limit": "7846.19454697"
// },
// "product_id": 107150,
// "quotes": {
// "ask_iv": "0.41023239",
// "ask_size": "2397",
// "best_ask": "1374",
// "best_bid": "1322",
// "bid_iv": "0.38929375",
// "bid_size": "3995",
// "impact_mid_price": null,
// "mark_iv": "0.39965618"
// },
// "spot_price": "30598.43379314",
// "strike_price": "30000",
// "symbol": "C-BTC-30000-280723",
// "timestamp": 1689136932893181,
// "turnover_symbol": "USDT"
// }
//
const timestamp = this.safeIntegerProduct(ticker, 'timestamp', 0.001);
const marketId = this.safeString(ticker, 'symbol');
const symbol = this.safeSymbol(marketId, market);
const last = this.safeString(ticker, 'close');
const quotes = this.safeDict(ticker, 'quotes', {});
return this.safeTicker({
'symbol': symbol,
'timestamp': timestamp,
'datetime': this.iso8601(timestamp),
'high': this.safeNumb