UNPKG

ccxt

Version:

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

1,175 lines (1,173 loc) • 127 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/oxfun.js'; import { AccountNotEnabled, ArgumentsRequired, AuthenticationError, BadRequest, BadSymbol, ExchangeError, InvalidOrder, InsufficientFunds, OrderNotFound, MarketClosed, NetworkError, NotSupported, OperationFailed, RateLimitExceeded, RequestTimeout } from './base/errors.js'; import { TICK_SIZE } from './base/functions/number.js'; import { sha256 } from './static_dependencies/noble-hashes/sha256.js'; // --------------------------------------------------------------------------- /** * @class oxfun * @augments Exchange */ export default class oxfun extends Exchange { describe() { return this.deepExtend(super.describe(), { 'id': 'oxfun', 'name': 'OXFUN', 'countries': ['PA'], 'version': 'v3', 'rateLimit': 120, 'pro': true, 'has': { 'CORS': undefined, 'spot': true, 'margin': false, 'swap': true, 'future': false, 'option': false, 'addMargin': false, 'cancelAllOrders': true, 'cancelOrder': true, 'cancelOrders': true, 'closeAllPositions': false, 'closePosition': false, 'createDepositAddress': false, 'createMarketBuyOrderWithCost': true, 'createMarketOrderWithCost': false, 'createMarketSellOrderWithCost': false, 'createOrder': true, 'createOrders': true, 'createPostOnlyOrder': true, 'createReduceOnlyOrder': false, 'createStopLimitOrder': true, 'createStopMarketOrder': true, 'createStopOrder': true, 'deposit': false, 'editOrder': false, 'fetchAccounts': true, 'fetchBalance': true, 'fetchBidsAsks': false, 'fetchBorrowInterest': false, 'fetchBorrowRateHistories': false, 'fetchBorrowRateHistory': false, 'fetchCanceledOrders': false, 'fetchClosedOrder': false, 'fetchClosedOrders': false, 'fetchCrossBorrowRate': false, 'fetchCrossBorrowRates': false, 'fetchCurrencies': true, 'fetchDeposit': false, 'fetchDepositAddress': true, 'fetchDepositAddresses': false, 'fetchDepositAddressesByNetwork': false, 'fetchDeposits': true, 'fetchDepositWithdrawFee': false, 'fetchDepositWithdrawFees': false, 'fetchFundingHistory': true, 'fetchFundingRate': true, 'fetchFundingRateHistory': true, 'fetchFundingRates': true, 'fetchIndexOHLCV': false, 'fetchIsolatedBorrowRate': false, 'fetchIsolatedBorrowRates': false, 'fetchL3OrderBook': false, 'fetchLedger': false, 'fetchLeverage': false, 'fetchLeverageTiers': true, 'fetchMarketLeverageTiers': 'emulated', 'fetchMarkets': true, 'fetchMarkOHLCV': false, 'fetchMyTrades': true, 'fetchOHLCV': true, 'fetchOpenInterestHistory': false, 'fetchOpenOrder': false, 'fetchOpenOrders': true, 'fetchOrder': true, 'fetchOrderBook': true, 'fetchOrderBooks': false, 'fetchOrders': false, 'fetchOrderTrades': false, 'fetchPosition': false, 'fetchPositionHistory': false, 'fetchPositionMode': false, 'fetchPositions': true, 'fetchPositionsForSymbol': false, 'fetchPositionsHistory': false, 'fetchPositionsRisk': false, 'fetchPremiumIndexOHLCV': false, 'fetchStatus': false, 'fetchTicker': true, 'fetchTickers': true, 'fetchTime': false, 'fetchTrades': true, 'fetchTradingFee': false, 'fetchTradingFees': false, 'fetchTradingLimits': false, 'fetchTransactionFee': false, 'fetchTransactionFees': false, 'fetchTransactions': false, 'fetchTransfers': true, 'fetchWithdrawal': false, 'fetchWithdrawals': true, 'fetchWithdrawalWhitelist': false, 'reduceMargin': false, 'repayCrossMargin': false, 'repayIsolatedMargin': false, 'sandbox': true, 'setLeverage': false, 'setMargin': false, 'setMarginMode': false, 'setPositionMode': false, 'signIn': false, 'transfer': true, 'withdraw': true, 'ws': true, }, 'timeframes': { '1m': '60s', '5m': '300s', '15m': '900s', '30m': '1800s', '1h': '3600s', '2h': '7200s', '4h': '14400s', '1d': '86400s', }, 'urls': { 'logo': 'https://github.com/ccxt/ccxt/assets/43336371/6a196124-c1ee-4fae-8573-962071b61a85', 'referral': 'https://ox.fun/register?shareAccountId=5ZUD4a7G', 'api': { 'public': 'https://api.ox.fun', 'private': 'https://api.ox.fun', }, 'test': { 'public': 'https://stgapi.ox.fun', 'private': 'https://stgapi.ox.fun', }, 'www': 'https://ox.fun/', 'doc': 'https://docs.ox.fun/', 'fees': 'https://support.ox.fun/en/articles/8819866-trading-fees', }, 'api': { 'public': { 'get': { 'v3/markets': 1, 'v3/assets': 1, 'v3/tickers': 1, 'v3/funding/estimates': 1, 'v3/candles': 1, 'v3/depth': 1, 'v3/markets/operational': 1, 'v3/exchange-trades': 1, 'v3/funding/rates': 1, 'v3/leverage/tiers': 1, }, }, 'private': { 'get': { 'v3/account': 1, 'v3/account/names': 1, 'v3/wallet': 1, 'v3/transfer': 1, 'v3/balances': 1, 'v3/positions': 1, 'v3/funding': 1, 'v3/deposit-addresses': 1, 'v3/deposit': 1, 'v3/withdrawal-addresses': 1, 'v3/withdrawal': 1, 'v3/withdrawal-fees': 1, 'v3/orders/status': 1, 'v3/orders/working': 1, 'v3/trades': 1, }, 'post': { 'v3/transfer': 1, 'v3/withdrawal': 1, 'v3/orders/place': 1, }, 'delete': { 'v3/orders/cancel': 1, 'v3/orders/cancel-all': 1, }, }, }, 'fees': { 'trading': { 'tierBased': true, 'percentage': true, 'maker': this.parseNumber('0.00020'), 'taker': this.parseNumber('0.00070'), 'tiers': { 'maker': [ [this.parseNumber('0'), this.parseNumber('0.00020')], [this.parseNumber('2500000'), this.parseNumber('0.00010')], [this.parseNumber('25000000'), this.parseNumber('0')], ], 'taker': [ [this.parseNumber('0'), this.parseNumber('0.00070')], [this.parseNumber('2500000'), this.parseNumber('0.00050')], [this.parseNumber('25000000'), this.parseNumber('0.00040')], ], }, }, }, 'precisionMode': TICK_SIZE, // exchange-specific options 'options': { 'sandboxMode': false, 'networks': { 'BTC': 'Bitcoin', 'ERC20': 'Ethereum', 'AVAX': 'Avalanche', 'SOL': 'Solana', 'ARB': 'Arbitrum', 'MATIC': 'Polygon', 'FTM': 'Fantom', 'BNB': 'BNBSmartChain', 'OPTIMISM': 'Optimism', }, 'networksById': { 'Bitcoin': 'BTC', 'Ethereum': 'ERC20', 'Avalanche': 'AVAX', 'Solana': 'SOL', 'Arbitrum': 'ARB', 'Polygon': 'MATIC', 'Fantom': 'FTM', 'Base': 'BASE', 'BNBSmartChain': 'BNB', 'Optimism': 'OPTIMISM', }, }, 'features': { 'default': { 'sandbox': true, 'createOrder': { 'marginMode': false, 'triggerPrice': true, 'triggerDirection': false, 'triggerPriceType': undefined, 'stopLossPrice': false, 'takeProfitPrice': false, 'attachedStopLossTakeProfit': undefined, 'timeInForce': { 'IOC': true, 'FOK': true, 'PO': true, 'GTD': false, }, 'hedged': false, 'trailing': false, 'leverage': false, 'marketBuyByCost': true, 'marketBuyRequiresPrice': false, 'selfTradePrevention': true, 'iceberg': true, // todo }, 'createOrders': { 'max': 10, // todo }, 'fetchMyTrades': { 'marginMode': false, 'limit': 500, 'daysBack': 100000, 'untilDays': 7, 'symbolRequired': false, }, 'fetchOrder': { 'marginMode': false, 'trigger': false, 'trailing': false, 'symbolRequired': false, }, 'fetchOpenOrders': { 'marginMode': false, 'limit': undefined, 'trigger': false, 'trailing': false, 'symbolRequired': false, }, 'fetchOrders': undefined, 'fetchClosedOrders': undefined, 'fetchOHLCV': { 'limit': 500, }, }, 'spot': { 'extends': 'default', }, 'swap': { 'linear': { 'extends': 'default', }, 'inverse': undefined, }, 'future': { 'linear': undefined, 'inverse': undefined, }, }, 'exceptions': { 'exact': { '-0010': OperationFailed, '-429': RateLimitExceeded, '-05001': AuthenticationError, '-10001': ExchangeError, '-20000': BadRequest, '-20001': BadRequest, '-20002': BadRequest, '-20003': NotSupported, '-20005': AuthenticationError, '-20006': BadRequest, '-20007': AuthenticationError, '-20008': BadRequest, '-20009': BadRequest, '-20010': ArgumentsRequired, '-20011': ArgumentsRequired, '-20012': ArgumentsRequired, '-20013': ArgumentsRequired, '-20014': BadRequest, '-20015': BadSymbol, '-20016': BadRequest, '-20017': BadRequest, '-20018': BadRequest, '-20019': BadRequest, '-20020': BadRequest, '-20021': BadRequest, '-20022': ArgumentsRequired, '-20023': ArgumentsRequired, '-20024': ExchangeError, '-20025': AuthenticationError, '-20026': BadRequest, '-20027': BadRequest, '-20028': BadRequest, '-20029': BadRequest, '-20030': BadRequest, '-20031': MarketClosed, '-20032': NetworkError, '-20033': BadRequest, '-20034': BadRequest, '-20050': ExchangeError, '-30001': BadRequest, '-35034': AuthenticationError, '-35046': AuthenticationError, '-40001': ExchangeError, '-50001': ExchangeError, '-300001': AccountNotEnabled, '-300011': InvalidOrder, '-300012': InvalidOrder, '-100005': OrderNotFound, '-100006': InvalidOrder, '-100008': BadRequest, '-100015': NetworkError, '-710001': ExchangeError, '-710002': BadRequest, '-710003': BadRequest, '-710004': BadRequest, '-710005': InsufficientFunds, '-710006': InsufficientFunds, '-710007': InsufficientFunds, '-000101': NetworkError, '-000201': NetworkError, // Trade service is busy, try again later }, 'broad': { '-20001': OperationFailed, '-200050': RequestTimeout, // The market is not active }, }, }); } /** * @method * @name oxfun#fetchMarkets * @description retrieves data on all markets for bitmex * @see https://docs.ox.fun/?json#get-v3-markets * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} an array of objects representing market data */ async fetchMarkets(params = {}) { const [responseFromMarkets, responseFromTickers] = await Promise.all([this.publicGetV3Markets(params), this.publicGetV3Tickers(params)]); const marketsFromMarkets = this.safeList(responseFromMarkets, 'data', []); // // { // success: true, // data: [ // { // marketCode: 'OX-USD-SWAP-LIN', // name: 'OX/USD Perp', // referencePair: 'OX/USDT', // base: 'OX', // counter: 'USD', // type: 'FUTURE', // tickSize: '0.00001', // minSize: '1', // listedAt: '1704766320000', // upperPriceBound: '0.02122', // lowerPriceBound: '0.01142', // markPrice: '0.01632', // indexPrice: '0.01564', // lastUpdatedAt: '1714762235569' // }, // { // marketCode: 'BTC-USD-SWAP-LIN', // name: 'BTC/USD Perp', // referencePair: 'BTC/USDT', // base: 'BTC', // counter: 'USD', // type: 'FUTURE', // tickSize: '1', // minSize: '0.0001', // listedAt: '1704686640000', // upperPriceBound: '67983', // lowerPriceBound: '55621', // markPrice: '61802', // indexPrice: '61813', // lastUpdatedAt: '1714762234765' // }, // { // "marketCode": "MILK-OX", // "name": "MILK/OX", // "referencePair": "MILK/OX", // "base": "MILK", // "counter": "OX", // "type": "SPOT", // "tickSize": "0.0001", // "minSize": "1", // "listedAt": "1706608500000", // "upperPriceBound": "1.0000", // "lowerPriceBound": "-1.0000", // "markPrice": "0.0269", // "indexPrice": "0.0269", // "lastUpdatedAt": "1714757402185" // }, // ... // ] // } // const marketsFromTickers = this.safeList(responseFromTickers, 'data', []); // // { // "success": true, // "data": [ // { // "marketCode": "DYM-USD-SWAP-LIN", // "markPrice": "3.321", // "open24h": "3.315", // "high24h": "3.356", // "low24h": "3.255", // "volume24h": "0", // "currencyVolume24h": "0", // "openInterest": "1768.1", // "lastTradedPrice": "3.543", // "lastTradedQuantity": "1.0", // "lastUpdatedAt": "1714853388102" // }, // ... // ] // } // const markets = this.arrayConcat(marketsFromMarkets, marketsFromTickers); return this.parseMarkets(markets); } parseMarkets(markets) { const marketIds = []; const result = []; for (let i = 0; i < markets.length; i++) { const market = markets[i]; const marketId = this.safeString(market, 'marketCode'); if (!(this.inArray(marketId, marketIds))) { marketIds.push(marketId); result.push(this.parseMarket(market)); } } return result; } parseMarket(market) { const id = this.safeString(market, 'marketCode', ''); const parts = id.split('-'); const baseId = this.safeString(parts, 0); const quoteId = this.safeString(parts, 1); const base = this.safeCurrencyCode(baseId); const quote = this.safeCurrencyCode(quoteId); let symbol = base + '/' + quote; let type = this.safeStringLower(market, 'type', 'spot'); // markets from v3/tickers are spot and have no type let settleId = undefined; let settle = undefined; const isFuture = (type === 'future'); // the exchange has only perpetual futures if (isFuture) { type = 'swap'; settleId = 'OX'; settle = this.safeCurrencyCode('OX'); symbol = symbol + ':' + settle; } const isSpot = type === 'spot'; return this.safeMarketStructure({ 'id': id, 'numericId': undefined, 'symbol': symbol, 'base': base, 'quote': quote, 'settle': settle, 'baseId': baseId, 'quoteId': quoteId, 'settleId': settleId, 'type': type, 'spot': isSpot, 'margin': false, 'swap': isFuture, 'future': false, 'option': false, 'active': true, 'contract': isFuture, 'linear': isFuture ? true : undefined, 'inverse': isFuture ? false : undefined, 'taker': this.fees['trading']['taker'], 'maker': this.fees['trading']['maker'], 'contractSize': isFuture ? 1 : undefined, 'expiry': undefined, 'expiryDatetime': undefined, 'strike': undefined, 'optionType': undefined, 'precision': { 'amount': undefined, 'price': this.safeNumber(market, 'tickSize'), }, 'limits': { 'leverage': { 'min': undefined, 'max': undefined, }, 'amount': { 'min': this.safeNumber(market, 'minSize'), 'max': undefined, }, 'price': { 'min': undefined, 'max': undefined, }, 'cost': { 'min': undefined, 'max': undefined, }, }, 'created': this.safeInteger(market, 'listedAt'), 'index': undefined, 'info': market, }); } /** * @method * @name oxfun#fetchCurrencies * @description fetches all available currencies on an exchange * @see https://docs.ox.fun/?json#get-v3-assets * @param {dict} [params] extra parameters specific to the exchange API endpoint * @returns {dict} an associative dictionary of currencies */ async fetchCurrencies(params = {}) { const response = await this.publicGetV3Assets(params); // // { // "success": true, // "data": [ // { // "asset": "OX", // "isCollateral": true, // "loanToValue": "1.000000000", // "loanToValueFactor": "0.000000000", // "networkList": [ // { // "network": "BNBSmartChain", // "tokenId": "0x78a0A62Fba6Fb21A83FE8a3433d44C73a4017A6f", // "transactionPrecision": "18", // "isWithdrawalFeeChargedToUser": true, // "canDeposit": true, // "canWithdraw": false, // "minDeposit": "0.00010", // "minWithdrawal": "0.00010" // }, // { // "network": "Polygon", // "tokenId": "0x78a0A62Fba6Fb21A83FE8a3433d44C73a4017A6f", // "transactionPrecision": "18", // "isWithdrawalFeeChargedToUser": true, // "canDeposit": true, // "canWithdraw": false, // "minDeposit": "0.00010", // "minWithdrawal": "0.00010" // }, // ... // ] // }, // { // "asset": "BTC", // "isCollateral": true, // "loanToValue": "0.950000000", // "loanToValueFactor": "0.000000000", // "networkList": [ // { // "network": "Bitcoin", // "transactionPrecision": "8", // "isWithdrawalFeeChargedToUser": true, // "canDeposit": true, // "canWithdraw": true, // "minDeposit": "0.00010", // "minWithdrawal": "0.00010" // } // ] // }, // { // "asset": "USDT.ARB", // "isCollateral": true, // "loanToValue": "0.950000000", // "loanToValueFactor": "0.000000000", // "networkList": [ // { // "network": "Arbitrum", // "tokenId": "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9", // "transactionPrecision": "18", // "isWithdrawalFeeChargedToUser": true, // "canDeposit": true, // "canWithdraw": true, // "minDeposit": "0.00010", // "minWithdrawal": "0.00010" // } // ] // }, // ... // ] // } // const data = this.safeList(response, 'data', []); const result = {}; for (let i = 0; i < data.length; i++) { const currency = data[i]; const fullId = this.safeString(currency, 'asset', ''); const parts = fullId.split('.'); const id = parts[0]; const code = this.safeCurrencyCode(id); if (!(code in result)) { result[code] = { 'id': id, 'code': code, 'precision': undefined, 'type': undefined, 'name': undefined, 'active': undefined, 'deposit': undefined, 'withdraw': undefined, 'fee': undefined, 'limits': { 'withdraw': { 'min': undefined, 'max': undefined, }, 'deposit': { 'min': undefined, 'max': undefined, }, }, 'networks': {}, 'info': [], }; } const chains = this.safeList(currency, 'networkList', []); for (let j = 0; j < chains.length; j++) { const chain = chains[j]; const networkId = this.safeString(chain, 'network'); const networkCode = this.networkIdToCode(networkId); result[code]['networks'][networkCode] = { 'id': networkId, 'network': networkCode, 'margin': undefined, 'deposit': this.safeBool(chain, 'canDeposit'), 'withdraw': this.safeBool(chain, 'canWithdraw'), 'active': undefined, 'fee': undefined, 'precision': this.parseNumber(this.parsePrecision(this.safeString(chain, 'transactionPrecision'))), 'limits': { 'deposit': { 'min': this.safeNumber(chain, 'minDeposit'), 'max': undefined, }, 'withdraw': { 'min': this.safeNumber(chain, 'minWithdrawal'), 'max': undefined, }, }, 'info': chain, }; } const infos = this.safeList(result[code], 'info', []); infos.push(currency); result[code]['info'] = infos; } // only after all entries are formed in currencies, restructure each entry const allKeys = Object.keys(result); for (let i = 0; i < allKeys.length; i++) { const code = allKeys[i]; result[code] = this.safeCurrencyStructure(result[code]); // this is needed after adding network entry } return result; } /** * @method * @name oxfun#fetchTickers * @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market * @see https://docs.ox.fun/?json#get-v3-tickers * @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(); symbols = this.marketSymbols(symbols); const response = await this.publicGetV3Tickers(params); // // { // "success": true, // "data": [ // { // "marketCode": "NII-USDT", // "markPrice": "0", // "open24h": "0", // "high24h": "0", // "low24h": "0", // "volume24h": "0", // "currencyVolume24h": "0", // "openInterest": "0", // "lastTradedPrice": "0", // "lastTradedQuantity": "0", // "lastUpdatedAt": "1714853388621" // }, // { // "marketCode": "GEC-USDT", // "markPrice": "0", // "open24h": "0", // "high24h": "0", // "low24h": "0", // "volume24h": "0", // "currencyVolume24h": "0", // "openInterest": "0", // "lastTradedPrice": "0", // "lastTradedQuantity": "0", // "lastUpdatedAt": "1714853388621" // }, // { // "marketCode": "DYM-USD-SWAP-LIN", // "markPrice": "3.321", // "open24h": "3.315", // "high24h": "3.356", // "low24h": "3.255", // "volume24h": "0", // "currencyVolume24h": "0", // "openInterest": "1768.1", // "lastTradedPrice": "3.543", // "lastTradedQuantity": "1.0", // "lastUpdatedAt": "1714853388102" // }, // ... // ] // } // const tickers = this.safeList(response, 'data', []); return this.parseTickers(tickers, symbols); } /** * @method * @name oxfun#fetchTicker * @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market * @see https://docs.ox.fun/?json#get-v3-tickers * @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 = { 'marketCode': market['id'], }; const response = await this.publicGetV3Tickers(this.extend(request, params)); // // { // "success": true, // "data": [ // { // "marketCode": "BTC-USD-SWAP-LIN", // "markPrice": "64276", // "open24h": "63674", // "high24h": "64607", // "low24h": "62933", // "volume24h": "306317655.80000", // "currencyVolume24h": "48.06810", // "openInterest": "72.39250", // "lastTradedPrice": "64300.0", // "lastTradedQuantity": "1.0", // "lastUpdatedAt": "1714925196034" // } // ] // } // const data = this.safeList(response, 'data', []); const ticker = this.safeDict(data, 0, {}); return this.parseTicker(ticker, market); } parseTicker(ticker, market = undefined) { // // { // "marketCode": "BTC-USD-SWAP-LIN", // "markPrice": "64276", // "open24h": "63674", // "high24h": "64607", // "low24h": "62933", // "volume24h": "306317655.80000", // "currencyVolume24h": "48.06810", // "openInterest": "72.39250", // "lastTradedPrice": "64300.0", // "lastTradedQuantity": "1.0", // "lastUpdatedAt": "1714925196034" // } // const timestamp = this.safeInteger(ticker, 'lastUpdatedAt'); const marketId = this.safeString(ticker, 'marketCode'); market = this.safeMarket(marketId, market); const symbol = market['symbol']; const last = this.safeString(ticker, 'lastTradedPrice'); return this.safeTicker({ 'symbol': symbol, 'timestamp': timestamp, 'datetime': this.iso8601(timestamp), 'high': this.safeString(ticker, 'high24h'), 'low': this.safeString(ticker, 'low24h'), 'bid': undefined, 'bidVolume': undefined, 'ask': undefined, 'askVolume': undefined, 'vwap': undefined, 'open': this.safeString(ticker, 'open24h'), 'close': last, 'last': last, 'previousClose': undefined, 'change': undefined, 'percentage': undefined, 'average': undefined, 'baseVolume': this.safeString(ticker, 'currencyVolume24h'), 'quoteVolume': undefined, 'markPrice': this.safeString(ticker, 'markPrice'), 'info': ticker, }, market); } /** * @method * @name oxfun#fetchOHLCV * @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market * @see https://docs.ox.fun/?json#get-v3-candles * @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 (default 24 hours ago) * @param {int} [limit] the maximum amount of candles to fetch (default 200, max 500) * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {int} [params.until] timestamp in ms of the latest candle to fetch (default now) * @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); timeframe = this.safeString(this.timeframes, timeframe, timeframe); const request = { 'marketCode': market['id'], 'timeframe': timeframe, }; if (since !== undefined) { request['startTime'] = since; // startTime and endTime must be within 7 days of each other } if (limit !== undefined) { request['limit'] = limit; } const until = this.safeInteger(params, 'until'); if (until !== undefined) { request['endTime'] = until; params = this.omit(params, 'until'); } else if (since !== undefined) { request['endTime'] = this.sum(since, 7 * 24 * 60 * 60 * 1000); // for the exchange not to throw an exception if since is younger than 7 days } const response = await this.publicGetV3Candles(this.extend(request, params)); // // { // "success": true, // "timeframe": "3600s", // "data": [ // { // "open": "0.03240000", // "high": "0.03240000", // "low": "0.03240000", // "close": "0.03240000", // "volume": "0", // "currencyVolume": "0", // "openedAt": "1714906800000" // }, // { // "open": "0.03240000", // "high": "0.03240000", // "low": "0.03240000", // "close": "0.03240000", // "volume": "0", // "currencyVolume": "0", // "openedAt": "1714903200000" // }, // ... // ] // } // const result = this.safeList(response, 'data', []); return this.parseOHLCVs(result, market, timeframe, since, limit); } parseOHLCV(ohlcv, market = undefined) { // // { // "open": "0.03240000", // "high": "0.03240000", // "low": "0.03240000", // "close": "0.03240000", // "volume": "0", // "currencyVolume": "0", // "openedAt": "1714906800000" // } // return [ this.safeInteger(ohlcv, 'openedAt'), this.safeNumber(ohlcv, 'open'), this.safeNumber(ohlcv, 'high'), this.safeNumber(ohlcv, 'low'), this.safeNumber(ohlcv, 'close'), this.safeNumber(ohlcv, 'currencyVolume'), ]; } /** * @method * @name oxfun#fetchOrderBook * @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data * @see https://docs.ox.fun/?json#get-v3-depth * @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 (default 5, max 100) * @param {object} [params] extra parameters specific to the exchange API endpoint * @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); const request = { 'marketCode': market['id'], }; if (limit !== undefined) { request['level'] = limit; } const response = await this.publicGetV3Depth(this.extend(request, params)); // // { // "success": true, // "level": "5", // "data": { // "marketCode": "BTC-USD-SWAP-LIN", // "lastUpdatedAt": "1714933499266", // "asks": [ // [ 64073.0, 8.4622 ], // [ 64092.0, 8.1912 ], // [ 64111.0, 8.0669 ], // [ 64130.0, 11.7195 ], // [ 64151.0, 10.1798 ] // ], // "bids": [ // [ 64022.0, 10.1292 ], // [ 64003.0, 8.1619 ], // [ 64000.0, 1.0 ], // [ 63984.0, 12.7724 ], // [ 63963.0, 11.0073 ] // ] // } // } // const data = this.safeDict(response, 'data', {}); const timestamp = this.safeInteger(data, 'lastUpdatedAt'); return this.parseOrderBook(data, market['symbol'], timestamp); } /** * @method * @name oxfun#fetchFundingRates * @description fetch the current funding rates for multiple markets * @see https://docs.ox.fun/?json#get-v3-funding-estimates * @param {string[]} symbols unified market symbols * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {Order[]} an array of [funding rate structures]{@link https://docs.ccxt.com/#/?id=funding-rate-structure} */ async fetchFundingRates(symbols = undefined, params = {}) { await this.loadMarkets(); symbols = this.marketSymbols(symbols); const response = await this.publicGetV3FundingEstimates(params); // // { // "success": true, // "data": [ // { // "marketCode": "OX-USD-SWAP-LIN", // "fundingAt": "1715515200000", // "estFundingRate": "0.000200000" // }, // { // "marketCode": "BTC-USD-SWAP-LIN", // "fundingAt": "1715515200000", // "estFundingRate": "0.000003" // }, // ... // ] // } // const data = this.safeList(response, 'data', []); return this.parseFundingRates(data, symbols); } /** * @method * @name oxfun#fetchFundingRate * @description fetch the current funding rates for a symbol * @see https://docs.ox.fun/?json#get-v3-funding-estimates * @param {string} symbol unified market symbols * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {Order[]} an array of [funding rate structures]{@link https://docs.ccxt.com/#/?id=funding-rate-structure} */ async fetchFundingRate(symbol, params = {}) { await this.loadMarkets(); const request = { 'marketCode': this.marketId(symbol), }; const response = await this.publicGetV3FundingEstimates(this.extend(request, params)); // const data = this.safeList(response, 'data', []); const first = this.safeDict(data, 0, {}); return this.parseFundingRate(first, this.market(symbol)); } parseFundingRate(fundingRate, market = undefined) { // // { // "marketCode": "OX-USD-SWAP-LIN", // "fundingAt": "1715515200000", // "estFundingRate": "0.000200000" // } // const symbol = this.safeString(fundingRate, 'marketCode'); market = this.market(symbol); const estFundingRateTimestamp = this.safeInteger(fundingRate, 'fundingAt'); return { 'info': fundingRate, 'symbol': market['symbol'], 'markPrice': undefined, 'indexPrice': undefined, 'interestRate': this.parseNumber('0'), 'estimatedSettlePrice': undefined, 'timestamp': estFundingRateTimestamp, 'datetime': this.iso8601(estFundingRateTimestamp), 'fundingRate': this.safeNumber(fundingRate, 'estFundingRate'), 'fundingTimestamp': undefined, 'fundingDatetime': undefined, 'nextFundingRate': undefined, 'nextFundingTimestamp': undefined, 'nextFundingDatetime': undefined, 'previousFundingRate': undefined, 'previousFundingTimestamp': undefined, 'previousFundingDatetime': undefined, 'interval': undefined, }; } /** * @method * @name oxfun#fetchFundingRateHistory * @description Fetches the history of funding rates * @see https://docs.ox.fun/?json#get-v3-funding-rates * @param {string} symbol unified symbol of the market to fetch trades for * @param {int} [since] timestamp in ms of the earliest trade to fetch (default 24 hours ago) * @param {int} [limit] the maximum amount of trades to fetch (default 200, max 500) * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {int} [params.until] timestamp in ms of the latest trade to fetch (default now) * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades} */ async fetchFundingRateHistory(symbol = undefined, since = undefined, limit = undefined, params = {}) { await this.loadMarkets(); const market = this.market(symbol); const request = { 'marketCode': market['id'], }; if (since !== undefined) { request['startTime'] = since; // startTime and endTime must be within 7 days of each other } if (limit !== undefined) { request['limit'] = limit; } const until = this.safeInteger(params, 'until'); if (until !== undefined) { request['endTime'] = until; params = this.omit(params, 'until'); } const response = await this.publicGetV3FundingRates(this.extend(request, params)); // // { // success: true, // data: [ // { // marketCode: 'NEAR-USD-SWAP-LIN', // fundingRate: '-0.000010000', // createdAt: '1715428870755' // }, // { // marketCode: 'ENA-USD-SWAP-LIN', // fundingRate: '0.000150000', // createdAt: '1715428868616' // }, // ... // } // const data = this.safeList(response, 'data', []); return this.parseFundingRateHistories(data, market, since, limit); } parseFundingRateHistory(info, market = undefined) { // // { // success: true, // data: [ // { // marketCode: 'NEAR-USD-SWAP-LIN', // fundingRate: '-0.000010000', // createdAt: '1715428870755' // }, // { // marketCode: 'ENA-USD-SWAP-LIN', // fundingRate: '0.000150000', // createdAt: '1715428868616' // }, // ... // } // const marketId = this.safeString(info, 'marketCode'); market = this.safeMarket(marketId, market); const symbol = market['symbol']; const timestamp = this.safeInteger(info, 'createdAt'); return { 'info': info, 'symbol': symbol, 'fundingRate': this.safeNumber(info, 'fundingRate'), 'timestamp': timestamp, 'datetime': this.iso8601(timestamp), }; } /** * @method * @name oxfun#fetchFundingHistory * @description fetches the history of funding payments * @see https://docs.ox.fun/?json#get-v3-funding * @param {string} symbol unified symbol of the market to fetch trades for * @param {int} [since] timestamp in ms of the earliest trade to fetch (default 24 hours ago) * @param {int} [limit] the maximum amount of trades to fetch (default 200, max 500) * @par