UNPKG

ccxt

Version:

A JavaScript / TypeScript / Python / C# / PHP cryptocurrency trading library with support for 100+ exchanges

1,226 lines (1,224 loc) 89.2 kB
// ---------------------------------------------------------------------------- // 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[