ccxt
Version:
1,226 lines (1,224 loc) • 89.2 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/defx.js';
import { Precise } from './base/Precise.js';
import { TICK_SIZE } from './base/functions/number.js';
import { sha256 } from './static_dependencies/noble-hashes/sha256.js';
import { NotSupported, ArgumentsRequired, BadRequest, AuthenticationError, InvalidOrder, ExchangeError } from './base/errors.js';
// ---------------------------------------------------------------------------
/**
* @class defx
* @augments Exchange
*/
export default class defx extends Exchange {
describe() {
return this.deepExtend(super.describe(), {
'id': 'defx',
'name': 'Defx X',
// 'countries': [ '' ],
'rateLimit': 100,
'version': 'v1',
'certified': false,
'pro': false,
'hostname': 'defx.com',
'dex': true,
'has': {
'CORS': undefined,
'spot': false,
'margin': false,
'swap': true,
'future': false,
'option': false,
'addMargin': true,
'cancelAllOrders': true,
'cancelAllOrdersAfter': false,
'cancelOrder': true,
'cancelWithdraw': false,
'closeAllPositions': true,
'closePosition': true,
'createConvertTrade': false,
'createDepositAddress': false,
'createMarketBuyOrderWithCost': false,
'createMarketOrder': false,
'createMarketOrderWithCost': false,
'createMarketSellOrderWithCost': false,
'createOrder': true,
'createOrderWithTakeProfitAndStopLoss': true,
'createReduceOnlyOrder': true,
'createStopLimitOrder': false,
'createStopLossOrder': false,
'createStopMarketOrder': false,
'createStopOrder': false,
'createTakeProfitOrder': true,
'createTrailingAmountOrder': false,
'createTrailingPercentOrder': false,
'createTriggerOrder': true,
'fetchAccounts': false,
'fetchBalance': true,
'fetchCanceledOrders': true,
'fetchClosedOrder': false,
'fetchClosedOrders': true,
'fetchConvertCurrencies': false,
'fetchConvertQuote': false,
'fetchConvertTrade': false,
'fetchConvertTradeHistory': false,
'fetchCurrencies': false,
'fetchDepositAddress': false,
'fetchDepositAddresses': false,
'fetchDepositAddressesByNetwork': false,
'fetchDeposits': false,
'fetchDepositsWithdrawals': false,
'fetchFundingHistory': false,
'fetchFundingInterval': false,
'fetchFundingIntervals': false,
'fetchFundingRate': true,
'fetchFundingRateHistory': false,
'fetchFundingRates': false,
'fetchIndexOHLCV': false,
'fetchLedger': true,
'fetchLeverage': false,
'fetchMarginAdjustmentHistory': false,
'fetchMarginMode': false,
'fetchMarkets': true,
'fetchMarkOHLCV': false,
'fetchMarkPrice': false,
'fetchMarkPrices': false,
'fetchMyTrades': true,
'fetchOHLCV': true,
'fetchOpenInterestHistory': false,
'fetchOpenOrder': false,
'fetchOpenOrders': true,
'fetchOrder': true,
'fetchOrderBook': true,
'fetchOrders': true,
'fetchOrderTrades': false,
'fetchPosition': true,
'fetchPositionHistory': false,
'fetchPositionMode': false,
'fetchPositions': true,
'fetchPositionsHistory': false,
'fetchPremiumIndexOHLCV': false,
'fetchStatus': true,
'fetchTicker': true,
'fetchTickers': true,
'fetchTime': true,
'fetchTrades': true,
'fetchTradingFee': false,
'fetchTradingFees': false,
'fetchTransactions': false,
'fetchTransfers': false,
'fetchWithdrawals': false,
'reduceMargin': false,
'sandbox': true,
'setLeverage': true,
'setMargin': false,
'setPositionMode': false,
'transfer': false,
'withdraw': true,
},
'timeframes': {
'1m': '1m',
'3m': '3m',
'5m': '5m',
'15m': '15m',
'30m': '30m',
'1h': '1h',
'2h': '2h',
'4h': '4h',
'12h': '12h',
'1d': '1d',
'1w': '1w',
'1M': '1M',
},
'urls': {
'logo': 'https://github.com/user-attachments/assets/4e92bace-d7a9-45ea-92be-122168dc87e4',
'api': {
'public': 'https://api.{hostname}',
'private': 'https://api.{hostname}',
},
'test': {
'public': 'https://api.testnet.{hostname}',
'private': 'https://api.testnet.{hostname}',
},
'www': 'https://defx.com/home',
'doc': [
'https://docs.defx.com/docs',
'https://api-docs.defx.com/',
],
'fees': [
'',
],
'referral': {
'url': 'https://app.defx.com/join/6I2CZ7',
},
},
'api': {
'v1': {
'public': {
'get': {
'healthcheck/ping': 1,
'symbols/{symbol}/ohlc': 1,
'symbols/{symbol}/trades': 1,
'symbols/{symbol}/prices': 1,
'symbols/{symbol}/ticker/24hr': 1,
'symbols/{symbol}/depth/{level}/{slab}': 1,
'ticker/24HrAgg': 1,
'c/markets': 1,
'c/markets/metadata': 1,
'analytics/market/stats/newUsers': 1,
'analytics/market/stats/tvl': 1,
'analytics/market/stats/volumeByInstrument': 1,
'analytics/market/stats/liquidation': 1,
'analytics/market/stats/totalVolume': 1,
'analytics/market/stats/openInterest': 1,
'analytics/market/stats/totalTrades': 1,
'analytics/market/stats/basis': 1,
'analytics/market/stats/insuranceFund': 1,
'analytics/market/stats/longAndShortRatio': 1,
'analytics/market/stats/fundingRate': 1,
'analytics/market/overview': 1,
'explorer/search': 1,
'explorer/transactions': 1,
'explorer/blocks': 1,
},
},
'private': {
'get': {
'api/order/{orderId}': 1,
'api/orders': 1,
'api/orders/oco/{parentOrderId}': 1,
'api/trades': 1,
'api/position/active': 1,
'api/users/metadata/leverage': 1,
'api/users/metadata/feeMultiplier': 1,
'api/users/metadata/slippage': 1,
'api/users/referral': 1,
'api/users/apikeys': 1,
'connection-signature-message/evm': 1,
'api/users/profile/wallets': 1,
'api/notifications': 1,
'api/wallet/balance': 1,
'api/wallet/transactions': 1,
'api/analytics/user/overview': 1,
'api/analytics/user/pnl': 1,
'api/analytics/points/overview': 1,
'api/analytics/points/history': 1,
},
'post': {
'api/order': 1,
'api/position/oco': 1,
'api/users/socket/listenKeys': 1,
'api/users/metadata/leverage': 1,
'api/users/metadata/feeMultiplier': 1,
'api/users/metadata/slippage': 1,
'api/users/referral/recordReferralSignup': 1,
'api/users/apikeys': 1,
'api/users/profile/wallets': 1,
'api/transfers/withdrawal': 1,
'api/transfers/bridge/withdrawal': 1,
},
'put': {
'api/position/updatePositionMargin': 1,
'api/users/socket/listenKeys/{listenKey}': 1,
'api/users/apikeys/{accessKey}/status': 1,
'api/users/referral': 1,
},
'patch': {
'api/users/apikeys/{accessKey}': 1,
},
'delete': {
'api/orders/allOpen': 1,
'api/order/{orderId}': 1,
'api/position/{positionId}': 1,
'api/position/all': 1,
'api/users/socket/listenKeys/{listenKey}': 1,
'api/users/apikeys/{accessKey}': 1,
},
},
},
},
'fees': {
'trading': {
'tierBased': true,
'percentage': true,
'maker': this.parseNumber('0.0002'),
'taker': this.parseNumber('0.0005'),
},
},
'options': {
'sandboxMode': false,
},
'features': {
'spot': undefined,
'forDerivatives': {
'sandbox': true,
'createOrder': {
'marginMode': false,
'triggerPrice': true,
// todo implement
'triggerPriceType': {
'last': true,
'mark': true,
'index': false,
},
'triggerDirection': false,
'stopLossPrice': false,
'takeProfitPrice': false,
'attachedStopLossTakeProfit': undefined,
'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': 1000,
'daysBack': undefined,
'untilDays': undefined,
'symbolRequired': false,
},
'fetchOrder': {
'marginMode': false,
'trigger': false,
'trailing': false,
'symbolRequired': false,
},
'fetchOpenOrders': {
'marginMode': true,
'limit': 100,
'trigger': false,
'trailing': false,
'symbolRequired': false,
},
'fetchOrders': {
'marginMode': false,
'limit': 500,
'daysBack': 100000,
'untilDays': 100000,
'trigger': false,
'trailing': false,
'symbolRequired': false,
},
'fetchClosedOrders': {
'marginMode': false,
'limit': 500,
'daysBack': 100000,
'daysBackCanceled': 1,
'untilDays': 100000,
'trigger': false,
'trailing': false,
'symbolRequired': false,
},
'fetchOHLCV': {
'limit': 1000,
},
},
'swap': {
'linear': {
'extends': 'forDerivatives',
},
'inverse': undefined,
},
'future': {
'linear': undefined,
'inverse': undefined,
},
},
'commonCurrencies': {},
'exceptions': {
'exact': {
'404': BadRequest,
'missing_auth_signature': AuthenticationError,
'order_rejected': InvalidOrder,
'invalid_order_id': InvalidOrder,
'filter_lotsize_maxqty': InvalidOrder,
'filter_notional_min': InvalidOrder,
'failed_index_price_up_multiplier_filter': InvalidOrder,
'no_open_orders': InvalidOrder,
'active_position_not_found': InvalidOrder,
'position_inactive': InvalidOrder,
'invalid_position_id': InvalidOrder,
'Internal server error': ExchangeError, // {"msg":"Internal server error","code":"internal_server_error"}
},
'broad': {
'Bad Request': BadRequest, // {"errorMessage":"Bad Request","data":[{"param":"symbol","message":"\"symbol\" must be one of [ETH_USDC, BTC_USDC, BNB_USDC, SOL_USDC, DOGE_USDC, TON_USDC, AVAX_USDC, WIF_USDC, KPEPE_USDC, KSHIB_USDC, KBONK_USDC, MOODENG_USDC, POPCAT_USDC, MOTHER_USDC]"}]}
},
},
'precisionMode': TICK_SIZE,
});
}
/**
* @method
* @name defx#fetchStatus
* @description the latest known information on the availability of the exchange API
* @see https://api-docs.defx.com/#4b03bb3b-a0fa-4dfb-b96c-237bde0ce9e6
* @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.v1PublicGetHealthcheckPing(params);
//
// {
// "success": true,
// "t": 1709705048323,
// "v": "0.0.7",
// "msg": "A programmer’s wife tells him, “While you’re at the grocery store, buy some eggs.” He never comes back."
// }
//
let status = undefined;
const success = this.safeBool(response, 'success');
if (success) {
status = 'ok';
}
else {
status = 'error';
}
return {
'status': status,
'updated': undefined,
'eta': undefined,
'url': undefined,
'info': response,
};
}
/**
* @method
* @name defx#fetchTime
* @description fetches the current integer timestamp in milliseconds from the exchange server
* @see https://api-docs.defx.com/#4b03bb3b-a0fa-4dfb-b96c-237bde0ce9e6
* @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.v1PublicGetHealthcheckPing(params);
//
// {
// "success": true,
// "t": 1709705048323,
// "v": "0.0.7",
// "msg": "A programmer’s wife tells him, “While you’re at the grocery store, buy some eggs.” He never comes back."
// }
//
return this.safeInteger(response, 't');
}
/**
* @method
* @name defx#fetchMarkets
* @description retrieves data on all markets for defx
* @see https://api-docs.defx.com/#73cce0c8-f842-4891-9145-01bb6d61324d
* @see https://api-docs.defx.com/#24fd4e5b-840e-451e-99e0-7fea47c7f371
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {object[]} an array of objects representing market data
*/
async fetchMarkets(params = {}) {
const request = {
'type': 'perps',
};
const promises = [
this.v1PublicGetCMarkets(this.extend(request, params)),
this.v1PublicGetCMarketsMetadata(this.extend(request, params)),
];
const responses = await Promise.all(promises);
//
// {
// "data": [
// {
// "market": "DOGE_USDC",
// "candleWindows": [
// "1m",
// "3m",
// "5m",
// "15m",
// "30m",
// "1h",
// "2h",
// "4h",
// "12h",
// "1d",
// "1w",
// "1M"
// ],
// "depthSlabs": [
// "0.00001",
// "0.00005",
// "0.0001",
// "0.001",
// "0.01"
// ],
// "filters": [
// {
// "filterType": "LOT_SIZE",
// "minQty": "1.00000",
// "maxQty": "1500000.00000",
// "stepSize": "1.00000"
// },
// {
// "filterType": "MARKET_LOT_SIZE",
// "minQty": "1.00000",
// "maxQty": "750000.00000",
// "stepSize": "1.00000"
// },
// {
// "filterType": "PRICE_FILTER",
// "minPrice": "0.00244000",
// "maxPrice": "30.00000000",
// "tickSize": "0.00001"
// },
// {
// "filterType": "NOTIONAL",
// "minNotional": "100.00000000"
// },
// {
// "filterType": "PERCENT_PRICE_BY_SIDE",
// "bidMultiplierUp": "1.5",
// "bidMultiplierDown": "0.5",
// "askMultiplierUp": "1.5",
// "askMultiplierDown": "0.5"
// },
// {
// "filterType": "INDEX_PRICE_FILTER",
// "multiplierUp": "1.3",
// "multiplierDown": "0.7"
// }
// ],
// "cappedLeverage": "25",
// "maintenanceMarginTiers": [
// {
// "tier": "1",
// "minMaintenanceMargin": "0",
// "maxMaintenanceMargin": "2500",
// "leverage": "25"
// },
// {
// "tier": "2",
// "minMaintenanceMargin": "2500",
// "maxMaintenanceMargin": "12500",
// "leverage": "20"
// },
// {
// "tier": "3",
// "minMaintenanceMargin": "12500",
// "maxMaintenanceMargin": "25000",
// "leverage": "15"
// },
// {
// "tier": "4",
// "minMaintenanceMargin": "25000",
// "maxMaintenanceMargin": "50000",
// "leverage": "10"
// },
// {
// "tier": "5",
// "minMaintenanceMargin": "50000",
// "maxMaintenanceMargin": "75000",
// "leverage": "8"
// },
// {
// "tier": "6",
// "minMaintenanceMargin": "75000",
// "maxMaintenanceMargin": "125000",
// "leverage": "7"
// },
// {
// "tier": "7",
// "minMaintenanceMargin": "125000",
// "maxMaintenanceMargin": "187500",
// "leverage": "5"
// },
// {
// "tier": "8",
// "minMaintenanceMargin": "187500",
// "maxMaintenanceMargin": "250000",
// "leverage": "3"
// },
// {
// "tier": "9",
// "minMaintenanceMargin": "250000",
// "maxMaintenanceMargin": "375000",
// "leverage": "2"
// },
// {
// "tier": "10",
// "minMaintenanceMargin": "375000",
// "maxMaintenanceMargin": "500000",
// "leverage": "1"
// }
// ],
// "fees": {
// "maker": "0.08",
// "taker": "0.1"
// }
// },
// ]
// }
//
const activeMarkets = this.safeList(responses[0], 'data');
const activeMarketsByType = this.indexBy(activeMarkets, 'market');
const marketMetadatas = this.safeList(responses[1], 'data');
for (let i = 0; i < marketMetadatas.length; i++) {
const marketId = marketMetadatas[i]['market'];
let status = undefined;
if (marketId in activeMarketsByType) {
status = activeMarketsByType[marketId]['status'];
}
marketMetadatas[i]['status'] = status;
}
return this.parseMarkets(marketMetadatas);
}
parseMarket(market) {
const marketId = this.safeString(market, 'market');
const parts = marketId.split('_');
const baseId = this.safeString(parts, 0);
const quoteId = this.safeString(parts, 1);
const base = this.safeCurrencyCode(baseId);
const quote = this.safeCurrencyCode(quoteId);
const symbol = base + '/' + quote + ':' + quote;
const filters = this.safeList(market, 'filters', []);
const fees = this.safeDict(market, 'fees', {});
const filtersByType = this.indexBy(filters, 'filterType');
const priceFilter = this.safeDict(filtersByType, 'PRICE_FILTER', {});
const lotFilter = this.safeDict(filtersByType, 'LOT_SIZE', {});
const marketLotFilter = this.safeDict(filtersByType, 'MARKET_LOT_SIZE', {});
const notionalFilter = this.safeDict(filtersByType, 'NOTIONAL', {});
return {
'id': marketId,
'symbol': symbol,
'base': base,
'quote': quote,
'settle': quote,
'baseId': baseId,
'quoteId': quoteId,
'settleId': quoteId,
'type': 'swap',
'spot': false,
'margin': false,
'swap': true,
'future': false,
'option': false,
'active': this.safeString(market, 'status', '') === 'active',
'contract': true,
'linear': true,
'inverse': false,
'taker': this.safeNumber(fees, 'taker'),
'maker': this.safeNumber(fees, 'maker'),
'contractSize': this.parseNumber('1'),
'expiry': undefined,
'expiryDatetime': undefined,
'strike': undefined,
'optionType': undefined,
'precision': {
'amount': this.safeNumber(lotFilter, 'stepSize'),
'price': this.safeNumber(priceFilter, 'tickSize'),
},
'limits': {
'leverage': {
'min': undefined,
'max': this.safeNumber(market, 'cappedLeverage'),
},
'amount': {
'min': this.safeNumber(lotFilter, 'minQty'),
'max': this.safeNumber(lotFilter, 'maxQty'),
},
'price': {
'min': this.safeNumber(priceFilter, 'minPrice'),
'max': this.safeNumber(priceFilter, 'maxPrice'),
},
'cost': {
'min': this.safeNumber(notionalFilter, 'minNotional'),
'max': undefined,
},
'market': {
'min': this.safeNumber(marketLotFilter, 'minQty'),
'max': this.safeNumber(marketLotFilter, 'maxQty'),
},
},
'created': undefined,
'info': market,
};
}
/**
* @method
* @name defx#fetchTicker
* @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
* @see https://api-docs.defx.com/#fe6f81d0-2f3a-4eee-976f-c8fc8f4c5d56
* @param {string} symbol unified symbol of the market to fetch the ticker for
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
*/
async fetchTicker(symbol, params = {}) {
await this.loadMarkets();
const market = this.market(symbol);
const request = {
'symbol': market['id'],
};
const response = await this.v1PublicGetSymbolsSymbolTicker24hr(this.extend(request, params));
//
// {
// "symbol": "BTC_USDC",
// "priceChange": "0",
// "priceChangePercent": "0",
// "weightedAvgPrice": "0",
// "lastPrice": "2.00",
// "lastQty": "10.000",
// "bestBidPrice": "1646.00",
// "bestBidQty": "10.000",
// "bestAskPrice": "1646.00",
// "bestAskQty": "10.000",
// "openPrice": "0.00",
// "highPrice": "0.00",
// "lowPrice": "0.00",
// "volume": "0.000",
// "quoteVolume": "0.00",
// "openTime": 1700142658697,
// "closeTime": 1700142658697,
// "openInterestBase": "1.000",
// "openInterestQuote": "0.43112300"
// }
//
return this.parseTicker(response, market);
}
/**
* @method
* @name defx#fetchTickers
* @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
* @see https://api-docs.defx.com/#8c61cfbd-40d9-410e-b014-f5b36eba51d1
* @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 exchange API endpoint
* @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
*/
async fetchTickers(symbols = undefined, params = {}) {
await this.loadMarkets();
let market = undefined;
if (symbols !== undefined) {
symbols = this.marketSymbols(symbols);
const firstSymbol = this.safeString(symbols, 0);
if (firstSymbol !== undefined) {
market = this.market(firstSymbol);
}
}
let type = undefined;
[type, params] = this.handleMarketTypeAndParams('fetchTickers', market, params);
if (type === 'spot') {
throw new NotSupported(this.id + ' fetchTickers() is not supported for ' + type + ' markets');
}
const response = await this.v1PublicGetTicker24HrAgg(params);
//
// {
// "ETH_USDC": {
// "priceChange": "0",
// "priceChangePercent": "0",
// "openPrice": "1646.15",
// "highPrice": "1646.15",
// "lowPrice": "1646.15",
// "lastPrice": "1646.15",
// "quoteVolume": "13.17",
// "volume": "0.008",
// "markPrice": "1645.15"
// }
// }
//
return this.parseTickers(response, symbols);
}
parseTicker(ticker, market = undefined) {
//
// fetchTicker
//
// {
// "symbol": "BTC_USDC",
// "priceChange": "0",
// "priceChangePercent": "0",
// "weightedAvgPrice": "0",
// "lastPrice": "2.00",
// "lastQty": "10.000",
// "bestBidPrice": "1646.00",
// "bestBidQty": "10.000",
// "bestAskPrice": "1646.00",
// "bestAskQty": "10.000",
// "openPrice": "0.00",
// "highPrice": "0.00",
// "lowPrice": "0.00",
// "volume": "0.000",
// "quoteVolume": "0.00",
// "openTime": 1700142658697,
// "closeTime": 1700142658697,
// "openInterestBase": "1.000",
// "openInterestQuote": "0.43112300"
// }
//
// fetchTickers
//
// "ETH_USDC": {
// "priceChange": "0",
// "priceChangePercent": "0",
// "openPrice": "1646.15",
// "highPrice": "1646.15",
// "lowPrice": "1646.15",
// "lastPrice": "1646.15",
// "quoteVolume": "13.17",
// "volume": "0.008",
// "markPrice": "1645.15"
// }
//
// fetchMarkPrice
//
// {
// "markPrice": "100.00",
// "indexPrice": "100.00",
// "ltp": "101.34",
// "movingFundingRate": "0.08",
// "payoutFundingRate": "-0.03",
// "nextFundingPayout": 1711555532146
// }
//
const marketId = this.safeString(ticker, 'symbol');
if (marketId !== undefined) {
market = this.market(marketId);
}
const symbol = market['symbol'];
const open = this.safeString(ticker, 'openPrice');
const high = this.safeString(ticker, 'highPrice');
const low = this.safeString(ticker, 'lowPrice');
const close = this.safeString(ticker, 'lastPrice');
const quoteVolume = this.safeString(ticker, 'quoteVolume');
const baseVolume = this.safeString(ticker, 'volume');
const percentage = this.safeString(ticker, 'priceChangePercent');
const change = this.safeString(ticker, 'priceChange');
let ts = this.safeInteger(ticker, 'closeTime');
if (ts === 0) {
ts = undefined;
}
const datetime = this.iso8601(ts);
const bid = this.safeString(ticker, 'bestBidPrice');
const bidVolume = this.safeString(ticker, 'bestBidQty');
const ask = this.safeString(ticker, 'bestAskPrice');
const askVolume = this.safeString(ticker, 'bestAskQty');
return this.safeTicker({
'symbol': symbol,
'timestamp': ts,
'datetime': datetime,
'high': high,
'low': low,
'bid': bid,
'bidVolume': bidVolume,
'ask': ask,
'askVolume': askVolume,
'vwap': undefined,
'open': open,
'close': close,
'last': undefined,
'previousClose': undefined,
'change': change,
'percentage': percentage,
'average': undefined,
'baseVolume': baseVolume,
'quoteVolume': quoteVolume,
'markPrice': this.safeString(ticker, 'markPrice'),
'indexPrice': this.safeString(ticker, 'indexPrice'),
'info': ticker,
}, market);
}
/**
* @method
* @name defx#fetchOHLCV
* @see https://api-docs.defx.com/#54b71951-1472-4670-b5af-4c2dc41e73d0
* @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} [since] timestamp in ms of the earliest candle to fetch
* @param {int} [limit] max=1000, max=100 when since is defined and is less than (now - (999 * (timeframe in ms)))
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @param {int} [params.until] the latest time in ms to fetch orders for
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
*/
async fetchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
await this.loadMarkets();
const market = this.market(symbol);
const maxLimit = 1000;
if (limit === undefined) {
limit = maxLimit;
}
limit = Math.min(maxLimit, limit);
const request = {
'symbol': market['id'],
'interval': this.safeString(this.timeframes, timeframe, timeframe),
'limit': limit,
};
const until = this.safeInteger2(params, 'until', 'till');
params = this.omit(params, ['until', 'till']);
request['endTime'] = (until === undefined) ? this.milliseconds() : until;
if (since === undefined) {
request['startTime'] = 0;
}
else {
request['startTime'] = since;
if (until === undefined) {
const timeframeInSeconds = this.parseTimeframe(timeframe);
const timeframeInMilliseconds = timeframeInSeconds * 1000;
const totalTimeframeInMilliseconds = limit * timeframeInMilliseconds;
request['endTime'] = this.sum(since, totalTimeframeInMilliseconds);
}
}
const response = await this.v1PublicGetSymbolsSymbolOhlc(this.extend(request, params));
//
// [
// {
// "symbol": "BTC_USDC",
// "open": "0.00",
// "high": "0.00",
// "low": "0.00",
// "close": "0.00",
// "volume": "0.000",
// "quoteAssetVolume": "0.00",
// "takerBuyAssetVolume": "0.000",
// "takerBuyQuoteAssetVolume": "0.00",
// "numberOfTrades": 0,
// "start": 1702453663894,
// "end": 1702453663894,
// "isClosed": true
// }
// ]
//
return this.parseOHLCVs(response, market, timeframe, since, limit);
}
parseOHLCV(ohlcv, market = undefined) {
// example response in fetchOHLCV
return [
this.safeInteger(ohlcv, 'start'),
this.safeNumber(ohlcv, 'open'),
this.safeNumber(ohlcv, 'high'),
this.safeNumber(ohlcv, 'low'),
this.safeNumber(ohlcv, 'close'),
this.safeNumber(ohlcv, 'volume'),
];
}
/**
* @method
* @name defx#fetchTrades
* @description get the list of most recent trades for a particular symbol
* @see https://api-docs.defx.com/#5865452f-ea32-4f13-bfbc-03af5f5574fd
* @param {string} symbol unified symbol of the market to fetch trades for
* @param {int} [since] timestamp in ms of the earliest trade to fetch
* @param {int} [limit] the maximum amount of trades to fetch
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
*/
async fetchTrades(symbol, since = undefined, limit = undefined, params = {}) {
await this.loadMarkets();
const market = this.market(symbol);
const maxLimit = 50;
if (limit === undefined) {
limit = maxLimit;
}
limit = Math.min(maxLimit, limit);
const request = {
'symbol': market['id'],
'limit': limit,
};
const response = await this.v1PublicGetSymbolsSymbolTrades(this.extend(request, params));
//
// [
// {
// "buyerMaker": "false",
// "price": "2.0000",
// "qty": "10.0000",
// "symbol": "BTC_USDC",
// "timestamp": "1702453663894"
// }
// ]
//
return this.parseTrades(response, market, since, limit);
}
/**
* @method
* @name defx#fetchMyTrades
* @description fetch all trades made by the user
* @see https://api-docs.defx.com/#06b5b33c-2fc6-48de-896c-fc316f5871a7
* @param {string} symbol unified symbol of the market to fetch trades for
* @param {int} [since] timestamp in ms of the earliest trade to fetch
* @param {int} [limit] the maximum amount of trades to fetch
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
*/
async fetchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
await this.loadMarkets();
const request = {};
if (symbol !== undefined) {
const market = this.market(symbol);
request['symbols'] = market['id'];
}
if (limit !== undefined) {
const maxLimit = 100;
limit = Math.min(maxLimit, limit);
request['pageSize'] = limit;
}
const response = await this.v1PrivateGetApiTrades(this.extend(request, params));
//
// {
// "data": [
// {
// "id": "0192f665-c05b-7ba0-a080-8b6c99083489",
// "orderId": "757730811259651728",
// "time": "2024-11-04T08:58:36.474Z",
// "symbol": "SOL_USDC",
// "side": "SELL",
// "price": "160.43600000",
// "qty": "1.00",
// "fee": "0.08823980",
// "role": "TAKER",
// "pnl": "0.00000000"
// }
// ]
// }
//
const data = this.safeList(response, 'data', []);
return this.parseTrades(data, undefined, since, limit);
}
parseTrade(trade, market = undefined) {
//
// fetchTrades
// {
// "buyerMaker": "false",
// "price": "2.0000",
// "qty": "10.0000",
// "symbol": "BTC_USDC",
// "timestamp": "1702453663894"
// }
//
// fetchMyTrades
// {
// "id": "0192f665-c05b-7ba0-a080-8b6c99083489",
// "orderId": "757730811259651728",
// "time": "2024-11-04T08:58:36.474Z",
// "symbol": "SOL_USDC",
// "side": "SELL",
// "price": "160.43600000",
// "qty": "1.00",
// "fee": "0.08823980",
// "role": "TAKER",
// "pnl": "0.00000000"
// }
//
const time = this.safeString(trade, 'time');
const timestamp = this.safeInteger(trade, 'timestamp', this.parse8601(time));
const marketId = this.safeString(trade, 'symbol');
market = this.safeMarket(marketId, market);
const symbol = market['symbol'];
const price = this.safeString(trade, 'price');
const amount = this.safeString(trade, 'qty');
const id = this.safeString(trade, 'id');
const oid = this.safeString(trade, 'orderId');
const takerOrMaker = this.safeStringLower(trade, 'role');
const buyerMaker = this.safeBool(trade, 'buyerMaker');
let side = this.safeStringLower(trade, 'side');
if (buyerMaker !== undefined) {
if (buyerMaker) {
side = 'sell';
}
else {
side = 'buy';
}
}
return this.safeTrade({
'id': id,
'timestamp': timestamp,
'datetime': this.iso8601(timestamp),
'symbol': symbol,
'side': side,
'price': price,
'amount': amount,
'cost': undefined,
'order': oid,
'takerOrMaker': takerOrMaker,
'type': undefined,
'fee': {
'cost': this.safeString(trade, 'fee'),
'currency': 'USDC',
},
'info': trade,
}, market);
}
/**
* @method
* @name defx#fetchOrderBook
* @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
* @see https://api-docs.defx.com/#6c1a2971-8325-4e7d-9962-e0bfcaacf9c4
* @param {string} symbol unified symbol of the market to fetch the order book for
* @param {int} [limit] the maximum amount of order book entries to return
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @param {string} [params.slab] slab from market.info.depthSlabs
* @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
*/
async fetchOrderBook(symbol, limit = undefined, params = {}) {
await this.loadMarkets();
const market = this.market(symbol);
if (limit === undefined) {
limit = 10; // limit must be one of [5, 10, 20]
}
const marketInfo = this.safeDict(market, 'info', {});
const slab = this.safeList(marketInfo, 'depthSlabs', []);
const request = {
'symbol': market['id'],
'level': limit,
'slab': this.safeString(slab, 0),
};
const response = await this.v1PublicGetSymbolsSymbolDepthLevelSlab(this.extend(request, params));
//
// {
// "symbol": "ETH_USDC",
// "level": "5",
// "slab": "1",
// "lastTradeTimestamp": "1708313446812",
// "timestamp": "1708313446812",
// "bids": [
// {
// "price": "1646.16",
// "qty": "0.001"
// }
// ],
// "asks": [
// {
// "price": "1646.16",
// "qty": "0.001"
// }
// ]
// }
//
const timestamp = this.safeInteger(response, 'timestamp');
return this.parseOrderBook(response, symbol, timestamp, 'bids', 'asks', 'price', 'qty');
}
/**
* @method
* @name defx#fetchMarkPrice
* @description fetches mark price for the market
* @see https://api-docs.defx.com/#12168192-4e7b-4458-a001-e8b80961f0b7
* @param {string} symbol unified symbol of the market to fetch the ticker for
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @param {string} [params.subType] "linear" or "inverse"
* @returns {object} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
*/
async fetchMarkPrice(symbol, params = {}) {
await this.loadMarkets();
const market = this.market(symbol);
const request = {
'symbol': market['id'],
};
const response = await this.v1PublicGetSymbolsSymbolPrices(this.extend(request, params));
//
// {
// "markPrice": "100.00",
// "indexPrice": "100.00",
// "ltp": "101.34",
// "movingFundingRate": "0.08",
// "payoutFundingRate": "-0.03",
// "nextFundingPayout": 1711555532146
// }
//
return this.parseTicker(response, market);
}
/**
* @method
* @name defx#fetchFundingRate
* @description fetch the current funding rate
* @see https://api-docs.defx.com/#12168192-4e7b-4458-a001-e8b80961f0b7
* @param {string} symbol unified market symbol
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {object} a [funding rate structure]{@link https://docs.ccxt.com/#/?id=funding-rate-structure}
*/
async fetchFundingRate(symbol, params = {}) {
await this.loadMarkets();
const market = this.market(symbol);
const request = {
'symbol': market['id'],
};
const response = await this.v1PublicGetSymbolsSymbolPrices(this.extend(request, params));
//
// {
// "markPrice": "100.00",
// "indexPrice": "100.00",
// "ltp": "101.34",
// "movingFundingRate": "0.08",
// "payoutFundingRate": "-0.03",
// "nextFundingPayout": 1711555532146
// }
//
return this.parseFundingRate(response, market);
}
parseFundingRate(contract, market = undefined) {
//
// {
// "markPrice": "100.00",
// "indexPrice": "100.00",
// "ltp": "101.34",
// "movingFundingRate": "0.08",
// "payoutFundingRate": "-0.03",
// "nextFundingPayout": 1711555532146
// }
//
const markPrice = this.safeNumber(contract, 'markPrice');
const indexPrice = this.safeNumber(contract, 'indexPrice');
const fundingRate = this.safeNumber(contract, 'payoutFundingRate');
const fundingTime = this.safeInteger(contract, 'nextFundingPayout');
return {
'info': contract,
'symbol': market['symbol'],
'markPrice': markPrice,
'indexPrice': indexPrice,
'interestRate': undefined,
'estimatedSettlePrice': undefined,
'timestamp': undefined,
'datetime': undefined,
'fundingRate': fundingRate,
'fundingTimestamp': fundingTime,
'fundingDatetime': this.iso8601(fundingTime),
'nextFundingRate': undefined,
'nextFundingTimestamp': undefined,
'nextFundingDatetime': undefined,
'previousFundingRate': undefined,
'previousFundingTimestamp': undefined,
'previousFundingDatetime': undefined,
'interval': undefined,
};
}
/**
* @method
* @name defx#fetchBalance
* @description query for balance and get the amount of funds available for trading or funds locked in orders
* @see https://api-docs.defx.com/#26414338-14f7-40a1-b246-f8ea8571493f
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
*/
async fetchBalance(params = {}) {
await this.loadMarkets();
const response = await this.v1PrivateGetApiWalletBalance(params);
//
// {
// "assets": [
// {
// "asset": "USDC",
// "balance": "0.000"
// }
// ]
// }
//
const data = this.safeList(response, 'assets');
return this.parseBalance(data);
}
parseBalance(balances) {
const result = {
'info': balances,
};
for (let i = 0; i < balances.length; i++) {
const balance = balances[