UNPKG

sfccxt

Version:

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

1,064 lines (1,046 loc) 84.6 kB
'use strict'; // --------------------------------------------------------------------------- const Exchange = require ('./base/Exchange'); const { ExchangeError, InsufficientFunds, BadRequest, BadSymbol, InvalidOrder, AuthenticationError, ArgumentsRequired, OrderNotFound, ExchangeNotAvailable } = require ('./base/errors'); const { TICK_SIZE } = require ('./base/functions/number'); // --------------------------------------------------------------------------- module.exports = class delta extends Exchange { describe () { return this.deepExtend (super.describe (), { 'id': 'delta', 'name': 'Delta Exchange', 'countries': [ 'VC' ], // Saint Vincent and the Grenadines 'rateLimit': 300, 'version': 'v2', // new metainfo interface 'has': { 'CORS': undefined, 'spot': true, 'margin': undefined, 'swap': undefined, 'future': undefined, 'option': undefined, 'cancelAllOrders': true, 'cancelOrder': true, 'createOrder': true, 'editOrder': true, 'fetchBalance': true, 'fetchClosedOrders': true, 'fetchCurrencies': true, 'fetchDeposit': undefined, 'fetchDepositAddress': true, 'fetchDeposits': undefined, 'fetchLedger': true, 'fetchLeverageTiers': false, // An infinite number of tiers, see examples/js/delta-maintenance-margin-rate-max-leverage.js 'fetchMarginMode': false, 'fetchMarketLeverageTiers': false, 'fetchMarkets': true, 'fetchMyTrades': true, 'fetchOHLCV': true, 'fetchOpenOrders': true, 'fetchOrderBook': true, 'fetchPosition': true, 'fetchPositionMode': false, 'fetchPositions': true, 'fetchStatus': true, 'fetchTicker': true, 'fetchTickers': true, 'fetchTime': true, 'fetchTrades': true, 'fetchTransfer': undefined, 'fetchTransfers': undefined, 'fetchWithdrawal': undefined, 'fetchWithdrawals': undefined, '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', 'settings', 'indices', 'products', 'tickers', 'tickers/{symbol}', 'l2orderbook/{symbol}', 'trades/{symbol}', 'history/candles', 'history/sparklines', ], }, 'private': { 'get': [ 'orders', 'orders/leverage', 'positions', 'positions/margined', 'orders/history', 'fills', 'fills/history/download/csv', 'wallet/balances', 'wallet/transactions', 'wallet/transactions/download', 'deposits/address', ], 'post': [ 'orders', 'orders/batch', 'orders/leverage', 'positions/change_margin', ], 'put': [ 'orders', 'orders/batch', ], 'delete': [ 'orders', 'orders/all', 'orders/batch', ], }, }, 'fees': { 'trading': { 'tierBased': true, 'percentage': true, 'taker': 0.15 / 100, 'maker': 0.10 / 100, 'tiers': { 'taker': [ [ 0, 0.15 / 100 ], [ 100, 0.13 / 100 ], [ 250, 0.13 / 100 ], [ 1000, 0.1 / 100 ], [ 5000, 0.09 / 100 ], [ 10000, 0.075 / 100 ], [ 20000, 0.065 / 100 ], ], 'maker': [ [ 0, 0.1 / 100 ], [ 100, 0.1 / 100 ], [ 250, 0.09 / 100 ], [ 1000, 0.075 / 100 ], [ 5000, 0.06 / 100 ], [ 10000, 0.05 / 100 ], [ 20000, 0.05 / 100 ], ], }, }, }, 'precisionMode': TICK_SIZE, 'requiredCredentials': { 'apiKey': true, 'secret': false, }, 'exceptions': { 'exact': { // Margin required to place order with selected leverage and quantity is insufficient. 'insufficient_margin': InsufficientFunds, // {"error":{"code":"insufficient_margin","context":{"available_balance":"0.000000000000000000","required_additional_balance":"1.618626000000000000000000000"}},"success":false} 'order_size_exceed_available': InvalidOrder, // The order book doesn't have sufficient liquidity, hence the order couldnt be filled, for example, ioc orders 'risk_limits_breached': BadRequest, // orders couldn't be placed as it will breach allowed risk limits. 'invalid_contract': BadSymbol, // The contract/product is either doesn't exist or has already expired. 'immediate_liquidation': InvalidOrder, // Order will cause immediate liquidation. 'out_of_bankruptcy': InvalidOrder, // Order prices are out of position bankruptcy limits. 'self_matching_disrupted_post_only': InvalidOrder, // Self matching is not allowed during auction. 'immediate_execution_post_only': InvalidOrder, // orders couldn't be placed as it includes post only orders which will be immediately executed 'bad_schema': BadRequest, // {"error":{"code":"bad_schema","context":{"schema_errors":[{"code":"validation_error","message":"id is required","param":""}]}},"success":false} 'invalid_api_key': AuthenticationError, // {"success":false,"error":{"code":"invalid_api_key"}} 'invalid_signature': AuthenticationError, // {"success":false,"error":{"code":"invalid_signature"}} 'open_order_not_found': OrderNotFound, // {"error":{"code":"open_order_not_found"},"success":false} 'unavailable': ExchangeNotAvailable, // {"error":{"code":"unavailable"},"success":false} }, 'broad': { }, }, }); } async fetchTime (params = {}) { /** * @method * @name delta#fetchTime * @description fetches the current integer timestamp in milliseconds from the exchange server * @param {object} params extra parameters specific to the delta api endpoint * @returns {int} the current integer timestamp in milliseconds from the exchange server */ const response = await this.publicGetSettings (params); // full response sample under `fetchStatus` const result = this.safeValue (response, 'result', {}); return this.safeIntegerProduct (result, 'server_time', 0.001); } async fetchStatus (params = {}) { /** * @method * @name delta#fetchStatus * @description the latest known information on the availability of the exchange API * @param {object} params extra parameters specific to the delta api endpoint * @returns {object} a [status structure]{@link https://docs.ccxt.com/en/latest/manual.html#exchange-status-structure} */ 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.safeValue (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, }; } async fetchCurrencies (params = {}) { /** * @method * @name delta#fetchCurrencies * @description fetches all available currencies on an exchange * @param {object} params extra parameters specific to the delta api endpoint * @returns {object} an associative dictionary of currencies */ const response = await this.publicGetAssets (params); // // { // "result":[ // { // "base_withdrawal_fee":"0.0005", // "deposit_status":"enabled", // "id":2, // "interest_credit":true, // "interest_slabs":[ // {"limit":"0.1","rate":"0"}, // {"limit":"1","rate":"0.05"}, // {"limit":"5","rate":"0.075"}, // {"limit":"10","rate":"0.1"}, // {"limit":"9999999999999999","rate":"0"} // ], // "kyc_deposit_limit":"10", // "kyc_withdrawal_limit":"2", // "min_withdrawal_amount":"0.001", // "minimum_precision":4, // "name":"Bitcoin", // "precision":8, // "sort_priority":1, // "symbol":"BTC", // "variable_withdrawal_fee":"0", // "withdrawal_status":"enabled" // }, // ], // "success":true // } // const currencies = this.safeValue (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 depositStatus = this.safeString (currency, 'deposit_status'); const withdrawalStatus = this.safeString (currency, 'withdrawal_status'); const depositsEnabled = (depositStatus === 'enabled'); const withdrawalsEnabled = (withdrawalStatus === 'enabled'); const active = depositsEnabled && withdrawalsEnabled; result[code] = { 'id': id, 'numericId': numericId, 'code': code, 'name': this.safeString (currency, 'name'), 'info': currency, // the original payload 'active': active, 'deposit': depositsEnabled, 'withdraw': withdrawalsEnabled, '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, }, }, }; } return result; } async loadMarkets (reload = false, params = {}) { const markets = await super.loadMarkets (reload, params); const currenciesByNumericId = this.safeValue (this.options, 'currenciesByNumericId'); if ((currenciesByNumericId === undefined) || reload) { this.options['currenciesByNumericId'] = this.indexBy (this.currencies, 'numericId'); } const marketsByNumericId = this.safeValue (this.options, 'marketsByNumericId'); if ((marketsByNumericId === undefined) || reload) { this.options['marketsByNumericId'] = this.indexBy (this.markets, 'numericId'); } return markets; } async fetchMarkets (params = {}) { /** * @method * @name delta#fetchMarkets * @description retrieves data on all markets for delta * @param {object} params extra parameters specific to the exchange api endpoint * @returns {[object]} an array of objects representing market data */ 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.safeValue (response, 'result', []); const result = []; for (let i = 0; i < markets.length; i++) { const market = markets[i]; let type = this.safeString (market, 'contract_type'); // const settlingAsset = this.safeValue (market, 'settling_asset', {}); const quotingAsset = this.safeValue (market, 'quoting_asset', {}); const underlyingAsset = this.safeValue (market, 'underlying_asset', {}); const settlingAsset = this.safeValue (market, 'settling_asset'); const productSpecs = this.safeValue (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 === base); 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'; } } else { symbol = id; } 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': contractSize, 'expiry': expiry, 'expiryDatetime': expiryDatetime, '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, }, }, 'info': market, }); } return result; } parseTicker (ticker, market = undefined) { // // fetchTicker, fetchTickers // // { // "close":15837.5, // "high":16354, // "low":15751.5, // "mark_price":"15820.100867", // "open":16140.5, // "product_id":139, // "size":640552, // "spot_price":"15827.050000000001", // "symbol":"BTCUSDT", // "timestamp":1605373550208262, // "turnover":10298630.3735, // "turnover_symbol":"USDT", // "turnover_usd":10298630.3735, // "volume":640.5520000000001 // } // 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 open = this.safeString (ticker, 'open'); const baseVolume = this.safeString (ticker, 'volume'); const quoteVolume = this.safeString (ticker, 'turnover'); return this.safeTicker ({ 'symbol': symbol, 'timestamp': timestamp, 'datetime': this.iso8601 (timestamp), 'high': this.safeString (ticker, 'high'), 'low': this.safeString (ticker, 'low'), 'bid': undefined, 'bidVolume': undefined, 'ask': undefined, 'askVolume': undefined, 'vwap': undefined, 'open': open, 'close': last, 'last': last, 'previousClose': undefined, 'change': undefined, 'percentage': undefined, 'average': undefined, 'baseVolume': baseVolume, 'quoteVolume': quoteVolume, 'info': ticker, }, market); } async fetchTicker (symbol, params = {}) { /** * @method * @name delta#fetchTicker * @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market * @param {string} symbol unified symbol of the market to fetch the ticker for * @param {object} params extra parameters specific to the delta api endpoint * @returns {object} a [ticker structure]{@link https://docs.ccxt.com/en/latest/manual.html#ticker-structure} */ await this.loadMarkets (); const market = this.market (symbol); const request = { 'symbol': market['id'], }; const response = await this.publicGetTickersSymbol (this.extend (request, params)); // // { // "result":{ // "close":15837.5, // "high":16354, // "low":15751.5, // "mark_price":"15820.100867", // "open":16140.5, // "product_id":139, // "size":640552, // "spot_price":"15827.050000000001", // "symbol":"BTCUSDT", // "timestamp":1605373550208262, // "turnover":10298630.3735, // "turnover_symbol":"USDT", // "turnover_usd":10298630.3735, // "volume":640.5520000000001 // }, // "success":true // } // const result = this.safeValue (response, 'result', {}); return this.parseTicker (result, market); } async fetchTickers (symbols = undefined, params = {}) { /** * @method * @name delta#fetchTickers * @description fetches price tickers for multiple markets, statistical calculations with the information calculated over the past 24 hours each market * @param {[string]|undefined} symbols unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned * @param {object} params extra parameters specific to the delta api endpoint * @returns {object} an array of [ticker structures]{@link https://docs.ccxt.com/en/latest/manual.html#ticker-structure} */ await this.loadMarkets (); symbols = this.marketSymbols (symbols); const response = await this.publicGetTickers (params); // // { // "result":[ // { // "close":0.003966, // "high":0.004032, // "low":0.003606, // "mark_price":"0.00396328", // "open":0.003996, // "product_id":1327, // "size":6242, // "spot_price":"0.0039555", // "symbol":"AAVEBTC", // "timestamp":1605374143864107, // "turnover":23.997904999999996, // "turnover_symbol":"BTC", // "turnover_usd":387957.4544782897, // "volume":6242 // }, // ], // "success":true // } // const tickers = this.safeValue (response, 'result', []); const result = {}; for (let i = 0; i < tickers.length; i++) { const ticker = this.parseTicker (tickers[i]); const symbol = ticker['symbol']; result[symbol] = ticker; } return this.filterByArray (result, 'symbol', symbols); } async fetchOrderBook (symbol, limit = undefined, params = {}) { /** * @method * @name delta#fetchOrderBook * @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data * @param {string} symbol unified symbol of the market to fetch the order book for * @param {int|undefined} limit the maximum amount of order book entries to return * @param {object} params extra parameters specific to the delta api endpoint * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/en/latest/manual.html#order-book-structure} indexed by market symbols */ await this.loadMarkets (); const market = this.market (symbol); const request = { 'symbol': market['id'], }; if (limit !== undefined) { request['depth'] = limit; } const response = await this.publicGetL2orderbookSymbol (this.extend (request, params)); // // { // "result":{ // "buy":[ // {"price":"15814.0","size":912}, // {"price":"15813.5","size":1279}, // {"price":"15813.0","size":1634}, // ], // "sell":[ // {"price":"15814.5","size":625}, // {"price":"15815.0","size":982}, // {"price":"15815.5","size":1328}, // ], // "symbol":"BTCUSDT" // }, // "success":true // } // const result = this.safeValue (response, 'result', {}); return this.parseOrderBook (result, market['symbol'], undefined, 'buy', 'sell', 'price', 'size'); } parseTrade (trade, market = undefined) { // // public fetchTrades // // { // "buyer_role":"maker", // "price":"15896.5", // "seller_role":"taker", // "size":241, // "symbol":"BTCUSDT", // "timestamp":1605376684714595 // } // // private fetchMyTrades // // { // "commission":"0.008335000000000000", // "created_at":"2020-11-16T19:07:19Z", // "fill_type":"normal", // "id":"e7ff05c233a74245b72381f8dd91d1ce", // "meta_data":{ // "effective_commission_rate":"0.0005", // "order_price":"16249", // "order_size":1, // "order_type":"market_order", // "order_unfilled_size":0, // "trading_fee_credits_used":"0" // }, // "order_id":"152999629", // "price":"16669", // "product":{ // "contract_type":"perpetual_futures", // "contract_unit_currency":"BTC", // "contract_value":"0.001", // "id":139, // "notional_type":"vanilla", // "quoting_asset":{"minimum_precision":2,"precision":6,"symbol":"USDT"}, // "settling_asset":{"minimum_precision":2,"precision":6,"symbol":"USDT"}, // "symbol":"BTCUSDT", // "tick_size":"0.5", // "underlying_asset":{"minimum_precision":4,"precision":8,"symbol":"BTC"} // }, // "product_id":139, // "role":"taker", // "side":"sell", // "size":1 // } // const id = this.safeString (trade, 'id'); const orderId = this.safeString (trade, 'order_id'); let timestamp = this.parse8601 (this.safeString (trade, 'created_at')); timestamp = this.safeIntegerProduct (trade, 'timestamp', 0.001, timestamp); const priceString = this.safeString (trade, 'price'); const amountString = this.safeString (trade, 'size'); const product = this.safeValue (trade, 'product', {}); const marketId = this.safeString (product, 'symbol'); const symbol = this.safeSymbol (marketId, market); const sellerRole = this.safeString (trade, 'seller_role'); let side = this.safeString (trade, 'side'); if (side === undefined) { if (sellerRole === 'taker') { side = 'sell'; } else if (sellerRole === 'maker') { side = 'buy'; } } const takerOrMaker = this.safeString (trade, 'role'); const metaData = this.safeValue (trade, 'meta_data', {}); let type = this.safeString (metaData, 'order_type'); if (type !== undefined) { type = type.replace ('_order', ''); } const feeCostString = this.safeString (trade, 'commission'); let fee = undefined; if (feeCostString !== undefined) { const settlingAsset = this.safeValue (product, 'settling_asset', {}); const feeCurrencyId = this.safeString (settlingAsset, 'symbol'); const feeCurrencyCode = this.safeCurrencyCode (feeCurrencyId); fee = { 'cost': feeCostString, 'currency': feeCurrencyCode, }; } return this.safeTrade ({ 'id': id, 'order': orderId, 'timestamp': timestamp, 'datetime': this.iso8601 (timestamp), 'symbol': symbol, 'type': type, 'side': side, 'price': priceString, 'amount': amountString, 'cost': undefined, 'takerOrMaker': takerOrMaker, 'fee': fee, 'info': trade, }, market); } async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) { /** * @method * @name delta#fetchTrades * @description get the list of most recent trades for a particular symbol * @param {string} symbol unified symbol of the market to fetch trades for * @param {int|undefined} since timestamp in ms of the earliest trade to fetch * @param {int|undefined} limit the maximum amount of trades to fetch * @param {object} params extra parameters specific to the delta api endpoint * @returns {[object]} a list of [trade structures]{@link https://docs.ccxt.com/en/latest/manual.html?#public-trades} */ await this.loadMarkets (); const market = this.market (symbol); const request = { 'symbol': market['id'], }; const response = await this.publicGetTradesSymbol (this.extend (request, params)); // // { // "result":[ // { // "buyer_role":"maker", // "price":"15896.5", // "seller_role":"taker", // "size":241, // "symbol":"BTCUSDT", // "timestamp":1605376684714595 // } // ], // "success":true // } // const result = this.safeValue (response, 'result', []); return this.parseTrades (result, market, since, limit); } parseOHLCV (ohlcv, market = undefined) { // // { // "time":1605393120, // "open":15989, // "high":15989, // "low":15987.5, // "close":15987.5, // "volume":565 // } // return [ this.safeTimestamp (ohlcv, 'time'), this.safeNumber (ohlcv, 'open'), this.safeNumber (ohlcv, 'high'), this.safeNumber (ohlcv, 'low'), this.safeNumber (ohlcv, 'close'), this.safeNumber (ohlcv, 'volume'), ]; } async fetchOHLCV (symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) { /** * @method * @name delta#fetchOHLCV * @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market * @param {string} symbol unified symbol of the market to fetch OHLCV data for * @param {string} timeframe the length of time each candle represents * @param {int|undefined} since timestamp in ms of the earliest candle to fetch * @param {int|undefined} limit the maximum amount of candles to fetch * @param {object} params extra parameters specific to the delta api endpoint * @returns {[[int]]} A list of candles ordered as timestamp, open, high, low, close, volume */ await this.loadMarkets (); const market = this.market (symbol); const request = { 'symbol': market['id'], 'resolution': this.timeframes[timeframe], }; const duration = this.parseTimeframe (timeframe); limit = limit ? limit : 2000; // max 2000 if (since === undefined) { const end = this.seconds (); request['end'] = end; request['start'] = end - limit * duration; } else { const start = parseInt (since / 1000); request['start'] = start; request['end'] = this.sum (start, limit * duration); } const response = await this.publicGetHistoryCandles (this.extend (request, params)); // // { // "success":true, // "result":[ // {"time":1605393120,"open":15989,"high":15989,"low":15987.5,"close":15987.5,"volume":565}, // {"time":1605393180,"open":15966,"high":15966,"low":15959,"close":15959,"volume":24}, // {"time":1605393300,"open":15973,"high":15973,"low":15973,"close":15973,"volume":1288}, // ] // } // const result = this.safeValue (response, 'result', []); return this.parseOHLCVs (result, market, timeframe, since, limit); } parseBalance (response) { const balances = this.safeValue (response, 'result', []); const result = { 'info': response }; const currenciesByNumericId = this.safeValue (this.options, 'currenciesByNumericId', {}); for (let i = 0; i < balances.length; i++) { const balance = balances[i]; const cu