sfccxt
Version:
A JavaScript / Python / PHP cryptocurrency trading library with support for 130+ exchanges
1,064 lines (1,046 loc) • 84.6 kB
JavaScript
'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