UNPKG

ccxt

Version:

A cryptocurrency trading API with more than 100 exchanges in JavaScript / TypeScript / Python / C# / PHP / Go

1,146 lines (1,144 loc) • 134 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/bydfi.js'; import { ArgumentsRequired, AuthenticationError, BadRequest, ExchangeError, InsufficientFunds, NotSupported, PermissionDenied, RateLimitExceeded } from '../ccxt.js'; import { Precise } from './base/Precise.js'; import { sha256 } from './static_dependencies/noble-hashes/sha256.js'; import { TICK_SIZE } from './base/functions/number.js'; // --------------------------------------------------------------------------- /** * @class bydfi * @augments Exchange */ export default class bydfi extends Exchange { describe() { return this.deepExtend(super.describe(), { 'id': 'bydfi', 'name': 'BYDFi', 'countries': ['SG'], 'rateLimit': 50, 'version': 'v1', 'certified': false, 'pro': true, 'has': { 'CORS': undefined, 'spot': false, 'margin': false, 'swap': true, 'future': false, 'option': false, 'addMargin': false, 'borrowCrossMargin': false, 'borrowIsolatedMargin': false, 'borrowMargin': false, 'cancelAllOrders': true, 'cancelOrder': false, 'cancelOrders': false, 'cancelOrdersWithClientOrderId': false, 'cancelOrderWithClientOrderId': false, 'closeAllPositions': false, 'closePosition': false, 'createDepositAddress': false, 'createLimitBuyOrder': false, 'createLimitOrder': true, 'createLimitSellOrder': false, 'createMarketBuyOrder': false, 'createMarketBuyOrderWithCost': false, 'createMarketOrder': true, 'createMarketOrderWithCost': false, 'createMarketSellOrder': false, 'createMarketSellOrderWithCost': false, 'createOrder': true, 'createOrders': true, 'createOrderWithTakeProfitAndStopLoss': false, 'createPostOnlyOrder': true, 'createReduceOnlyOrder': true, 'createStopLimitOrder': true, 'createStopLossOrder': true, 'createStopMarketOrder': false, 'createStopOrder': false, 'createTakeProfitOrder': true, 'createTrailingAmountOrder': false, 'createTrailingPercentOrder': true, 'createTriggerOrder': false, 'deposit': false, 'editOrder': true, 'editOrders': true, 'editOrderWithClientOrderId': true, 'fetchAccounts': false, 'fetchBalance': true, 'fetchBidsAsks': false, 'fetchBorrowInterest': false, 'fetchBorrowRate': false, 'fetchBorrowRateHistories': false, 'fetchBorrowRateHistory': false, 'fetchBorrowRates': false, 'fetchBorrowRatesPerSymbol': false, 'fetchCanceledAndClosedOrders': true, 'fetchCanceledOrders': false, 'fetchClosedOrder': false, 'fetchClosedOrders': false, 'fetchConvertCurrencies': false, 'fetchConvertQuote': false, 'fetchConvertTrade': false, 'fetchConvertTradeHistory': false, 'fetchCrossBorrowRate': false, 'fetchCrossBorrowRates': false, 'fetchCurrencies': false, 'fetchDeposit': false, 'fetchDepositAddress': false, 'fetchDepositAddresses': false, 'fetchDepositAddressesByNetwork': false, 'fetchDeposits': true, 'fetchDepositsWithdrawals': false, 'fetchDepositWithdrawFee': false, 'fetchDepositWithdrawFees': false, 'fetchFundingHistory': false, 'fetchFundingInterval': false, 'fetchFundingIntervals': false, 'fetchFundingRate': true, 'fetchFundingRateHistory': true, 'fetchFundingRates': false, 'fetchGreeks': false, 'fetchIndexOHLCV': false, 'fetchIsolatedBorrowRate': false, 'fetchIsolatedBorrowRates': false, 'fetchIsolatedPositions': false, 'fetchL2OrderBook': true, 'fetchL3OrderBook': false, 'fetchLastPrices': false, 'fetchLedger': false, 'fetchLedgerEntry': false, 'fetchLeverage': true, 'fetchLeverages': false, 'fetchLeverageTiers': false, 'fetchLiquidations': false, 'fetchLongShortRatio': false, 'fetchLongShortRatioHistory': false, 'fetchMarginAdjustmentHistory': false, 'fetchMarginMode': true, 'fetchMarginModes': false, 'fetchMarketLeverageTiers': false, 'fetchMarkets': true, 'fetchMarkOHLCV': false, 'fetchMarkPrices': false, 'fetchMyLiquidations': false, 'fetchMySettlementHistory': false, 'fetchMyTrades': true, 'fetchOHLCV': true, 'fetchOpenInterest': false, 'fetchOpenInterestHistory': false, 'fetchOpenInterests': false, 'fetchOpenOrder': false, 'fetchOpenOrders': true, 'fetchOption': false, 'fetchOptionChain': false, 'fetchOrder': false, 'fetchOrderBook': true, 'fetchOrderBooks': false, 'fetchOrders': false, 'fetchOrdersByStatus': false, 'fetchOrderTrades': false, 'fetchOrderWithClientOrderId': false, 'fetchPosition': false, 'fetchPositionHistory': true, 'fetchPositionMode': true, 'fetchPositions': true, 'fetchPositionsForSymbol': true, 'fetchPositionsHistory': true, 'fetchPositionsRisk': false, 'fetchPremiumIndexOHLCV': false, 'fetchSettlementHistory': false, 'fetchStatus': false, 'fetchTicker': true, 'fetchTickers': true, 'fetchTime': false, 'fetchTrades': true, 'fetchTradingFee': false, 'fetchTradingFees': false, 'fetchTradingLimits': false, 'fetchTransactionFee': false, 'fetchTransactionFees': false, 'fetchTransactions': false, 'fetchTransfer': false, 'fetchTransfers': true, 'fetchUnderlyingAssets': false, 'fetchVolatilityHistory': false, 'fetchWithdrawAddresses': false, 'fetchWithdrawal': false, 'fetchWithdrawals': true, 'fetchWithdrawalWhitelist': false, 'reduceMargin': false, 'repayCrossMargin': false, 'repayIsolatedMargin': false, 'setLeverage': true, 'setMargin': false, 'setMarginMode': true, 'setPositionMode': true, 'signIn': false, 'transfer': true, 'watchMyLiquidationsForSymbols': false, 'withdraw': false, 'ws': true, }, 'urls': { 'logo': 'https://github.com/user-attachments/assets/bfffb73d-29bd-465d-b75b-98e210491769', 'api': { 'public': 'https://api.bydfi.com/api', 'private': 'https://api.bydfi.com/api', }, 'www': 'https://bydfi.com/', 'doc': 'https://developers.bydfi.com/en/', 'referral': 'https://partner.bydfi.com/j/DilWutCI', }, 'fees': {}, 'api': { 'public': { 'get': { 'v1/public/api_limits': 1, 'v1/swap/market/exchange_info': 1, 'v1/swap/market/depth': 1, 'v1/swap/market/trades': 1, 'v1/swap/market/klines': 1, 'v1/swap/market/ticker/24hr': 1, 'v1/swap/market/ticker/price': 1, 'v1/swap/market/mark_price': 1, 'v1/swap/market/funding_rate': 1, 'v1/swap/market/funding_rate_history': 1, 'v1/swap/market/risk_limit': 1, // https://developers.bydfi.com/en/swap/market#risk-limit }, }, 'private': { 'get': { 'v1/account/assets': 1, 'v1/account/transfer_records': 1, 'v1/spot/deposit_records': 1, 'v1/spot/withdraw_records': 1, 'v1/swap/trade/open_order': 1, 'v1/swap/trade/plan_order': 1, 'v1/swap/trade/leverage': 1, 'v1/swap/trade/history_order': 1, 'v1/swap/trade/history_trade': 1, 'v1/swap/trade/position_history': 1, 'v1/swap/trade/positions': 1, 'v1/swap/account/balance': 1, 'v1/swap/user_data/assets_margin': 1, 'v1/swap/user_data/position_side/dual': 1, 'v1/agent/teams': 1, 'v1/agent/agent_links': 1, 'v1/agent/regular_overview': 1, 'v1/agent/agent_sub_overview': 1, 'v1/agent/partener_user_deposit': 1, 'v1/agent/partener_users_data': 1, 'v1/agent/affiliate_uids': 1, 'v1/agent/affiliate_commission': 1, 'v1/agent/internal_withdrawal_status': 1, // https://developers.bydfi.com/en/agent/#get-internal-withdrawal-status }, 'post': { 'v1/account/transfer': 1, 'v1/swap/trade/place_order': 1, 'v1/swap/trade/batch_place_order': 1, 'v1/swap/trade/edit_order': 1, 'v1/swap/trade/batch_edit_order': 1, 'v1/swap/trade/cancel_all_order': 1, 'v1/swap/trade/leverage': 1, 'v1/swap/trade/batch_leverage_margin': 1, 'v1/swap/user_data/margin_type': 1, 'v1/swap/user_data/position_side/dual': 1, 'v1/agent/internal_withdrawal': 1, // https://developers.bydfi.com/en/agent/#internal-withdrawal }, }, }, 'features': { 'spot': undefined, 'swap': { 'linear': { 'sandbox': false, 'createOrder': { 'marginMode': false, 'triggerPrice': false, 'triggerPriceType': { 'mark': true, 'last': true, 'index': false, }, 'stopLossPrice': true, 'takeProfitPrice': true, 'attachedStopLossTakeProfit': undefined, 'timeInForce': { 'IOC': true, 'FOK': true, 'PO': true, 'GTD': false, }, 'hedged': true, 'selfTradePrevention': false, 'trailing': true, 'iceberg': false, 'leverage': false, 'marketBuyRequiresPrice': false, 'marketBuyByCost': false, }, 'createOrders': { 'max': 5, }, 'fetchMyTrades': { 'marginMode': false, 'daysBack': 182, 'limit': 500, 'untilDays': 7, 'symbolRequired': false, }, 'fetchOrder': undefined, 'fetchOpenOrder': { 'marginMode': false, 'trigger': true, 'trailing': false, 'symbolRequired': true, }, 'fetchOpenOrders': { 'marginMode': false, 'limit': 500, 'trigger': true, 'trailing': false, 'symbolRequired': true, }, 'fetchOrders': undefined, 'fetchCanceledAndClosedOrders': { 'marginMode': false, 'limit': 500, 'daysBack': 182, 'untilDays': 7, 'trigger': false, 'trailing': false, 'symbolRequired': false, }, 'fetchClosedOrders': undefined, 'fetchOHLCV': { 'limit': 500, }, }, 'inverse': undefined, }, 'future': { 'linear': undefined, 'inverse': undefined, }, }, 'timeframes': { '1m': '1m', '3m': '3m', '5m': '5m', '15m': '15m', '30m': '30m', '1h': '1h', '2h': '2h', '4h': '4h', '6h': '6h', '12h': '12h', '1d': '1d', }, 'precisionMode': TICK_SIZE, 'exceptions': { 'exact': { '101001': AuthenticationError, '101103': AuthenticationError, '102001': BadRequest, '102002': PermissionDenied, '401': AuthenticationError, '500': ExchangeError, '501': ExchangeError, '506': ExchangeError, '510': RateLimitExceeded, '511': AuthenticationError, '513': BadRequest, '514': BadRequest, '600': BadRequest, 'Position does not exist': BadRequest, 'Requires transaction permissions': PermissionDenied, 'Service error': ExchangeError, 'transfer failed': InsufficientFunds, // {"code":500,"message":"transfer failed","success":false} }, 'broad': { 'is missing': ArgumentsRequired, // {"code":600,"message":"The parameter 'startTime' is missing"} }, }, 'commonCurrencies': {}, 'options': { 'networks': { 'ERC20': 'ETH', // todo add more networks }, 'timeInForce': { 'GTC': 'GTC', 'FOK': 'FOK', 'IOC': 'IOC', 'PO': 'POST_ONLY', // Post Only }, 'accountsByType': { 'spot': 'SPOT', 'swap': 'SWAP', 'funding': 'FUND', }, 'accountsById': { 'SPOT': 'spot', 'SWAP': 'swap', 'FUND': 'funding', }, }, }); } /** * @method * @name bydfi#fetchMarkets * @description retrieves data on all markets for bydfi * @see https://developers.bydfi.com/en/swap/market#fetching-trading-rules-and-pairs * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} an array of objects representing market data */ async fetchMarkets(params = {}) { const response = await this.publicGetV1SwapMarketExchangeInfo(params); // // { // "code": "200", // "message": "success", // "data": [ // { // "symbol": "CLANKER-USDT", // "baseAsset": "CLANKER", // "marginAsset": "USDT", // "quoteAsset": "USDT", // "contractFactor": "0.01", // "limitMaxQty": "50000", // "limitMinQty": "1", // "marketMaxQty": "10000", // "marketMinQty": "1", // "pricePrecision": "8", // "basePrecision": "8", // "feeRateTaker": "0.0006", // "feeRateMaker": "0.0002", // "liqFeeRate": "0.0006", // "openBuyLimitRateMax": "0.05", // "openSellLimitRateMax": "100", // "openBuyLimitRateMin": "0.98", // "openSellLimitRateMin": "0.05", // "priceOrderPrecision": "2", // "baseShowPrecision": "2", // "maxLeverageLevel": "20", // "volumePrecision": "2", // "maxLimitOrderNum": "200", // "maxPlanOrderNum": "10", // "reverse": false, // "onboardTime": "1763373600000", // "status": "NORMAL" // }, // ... // ], // "success": true // } const data = this.safeList(response, 'data', []); return this.parseMarkets(data); } parseMarket(market) { // // { // "symbol": "CLANKER-USDT", // "baseAsset": "CLANKER", // "marginAsset": "USDT", // "quoteAsset": "USDT", // "contractFactor": "0.01", // "limitMaxQty": "50000", // "limitMinQty": "1", // "marketMaxQty": "10000", // "marketMinQty": "1", // "pricePrecision": "8", // "basePrecision": "8", // "feeRateTaker": "0.0006", // "feeRateMaker": "0.0002", // "liqFeeRate": "0.0006", // "openBuyLimitRateMax": "0.05", // "openSellLimitRateMax": "100", // "openBuyLimitRateMin": "0.98", // "openSellLimitRateMin": "0.05", // "priceOrderPrecision": "2", // "baseShowPrecision": "2", // "maxLeverageLevel": "20", // "volumePrecision": "2", // "maxLimitOrderNum": "200", // "maxPlanOrderNum": "10", // "reverse": false, // "onboardTime": "1763373600000", // "status": "NORMAL" // } // const id = this.safeString(market, 'symbol'); const baseId = this.safeString(market, 'baseAsset'); const quoteId = this.safeString(market, 'quoteAsset'); const settleId = this.safeString(market, 'marginAsset'); const base = this.safeCurrencyCode(baseId); const quote = this.safeCurrencyCode(quoteId); const settle = this.safeCurrencyCode(settleId); const symbol = base + '/' + quote + ':' + settle; const inverse = this.safeBool(market, 'reverse'); const limitMaxQty = this.safeString(market, 'limitMaxQty'); const marketMaxQty = this.safeString(market, 'marketMaxQty'); const maxAmountString = Precise.stringMax(limitMaxQty, marketMaxQty); const marketMinQty = this.safeString(market, 'marketMinQty'); const limitMinQty = this.safeString(market, 'limitMinQty'); const minAmountString = Precise.stringMin(marketMinQty, limitMinQty); const contractSize = this.safeString(market, 'contractFactor'); const pricePrecision = this.parsePrecision(this.safeString(market, 'priceOrderPrecision')); const rawAmountPrecision = this.parsePrecision(this.safeString(market, 'volumePrecision')); const amountPrecision = Precise.stringDiv(rawAmountPrecision, contractSize); const basePrecision = this.parsePrecision(this.safeString(market, 'basePrecision')); const taker = this.safeNumber(market, 'feeRateTaker'); const maker = this.safeNumber(market, 'feeRateMaker'); const maxLeverage = this.safeNumber(market, 'maxLeverageLevel'); const status = this.safeString(market, 'status'); return this.safeMarketStructure({ 'id': id, 'symbol': symbol, 'base': base, 'quote': quote, 'settle': settle, 'baseId': baseId, 'quoteId': quoteId, 'settleId': settleId, 'type': 'swap', 'spot': false, 'margin': undefined, 'swap': true, 'future': false, 'option': false, 'active': status === 'NORMAL', 'contract': true, 'linear': !inverse, 'inverse': inverse, 'taker': taker, 'maker': maker, 'contractSize': this.parseNumber(contractSize), 'expiry': undefined, 'expiryDatetime': undefined, 'strike': undefined, 'optionType': undefined, 'precision': { 'amount': this.parseNumber(amountPrecision), 'price': this.parseNumber(pricePrecision), 'base': this.parseNumber(basePrecision), }, 'limits': { 'leverage': { 'min': undefined, 'max': maxLeverage, }, 'amount': { 'min': this.parseNumber(minAmountString), 'max': this.parseNumber(maxAmountString), }, 'price': { 'min': undefined, 'max': undefined, }, 'cost': { 'min': undefined, 'max': undefined, }, }, 'created': this.parse8601(this.safeString(market, 'createdAt')), 'info': market, }); } /** * @method * @name bydfi#fetchOrderBook * @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data * @see https://developers.bydfi.com/en/swap/market#depth-information * @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, could be 5, 10, 20, 50, 100, 500 or 1000 (default 500) * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.loc] crypto location, default: us * @returns {object} A dictionary of [order book structures]{@link https://github.com/ccxt/ccxt/wiki/Manual#order-book-structure} indexed by market symbols */ async fetchOrderBook(symbol, limit = undefined, params = {}) { await this.loadMarkets(); const market = this.market(symbol); const request = { 'symbol': market['id'], }; if (limit !== undefined) { request['limit'] = this.getClosestLimit(limit); } const response = await this.publicGetV1SwapMarketDepth(this.extend(request, params)); // // { // "code": 200, // "message": "success", // "data": { // "lastUpdateId": "221780076", // "symbol": "ETH-USDT", // "asks": [ // { // "price": "2958.21", // "amount": "39478" // }, // ... // ], // "bids": [ // { // "price": "2958.19", // "amount": "174498" // }, // ... // ], // "e": "221780076" // }, // "success": true // } // const data = this.safeDict(response, 'data', {}); const timestamp = this.milliseconds(); const orderBook = this.parseOrderBook(data, market['symbol'], timestamp, 'bids', 'asks', 'price', 'amount'); orderBook['nonce'] = this.safeInteger(data, 'lastUpdateId'); return orderBook; } getClosestLimit(limit) { const limits = [5, 10, 20, 50, 100, 500, 1000]; let result = 1000; for (let i = 0; i < limits.length; i++) { if (limit <= limits[i]) { result = limits[i]; break; } } return result; } /** * @method * @name bydfi#fetchTrades * @description get the list of most recent trades for a particular symbol * @see https://developers.bydfi.com/en/swap/market#recent-trades * @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 (default 500, max 1000) * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {int} [params.fromId] retrieve from which trade ID to start. Default to retrieve the most recent trade records * @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 request = { 'symbol': market['id'], }; if (limit !== undefined) { request['limit'] = limit; } const response = await this.publicGetV1SwapMarketTrades(this.extend(request, params)); // // { // "code": 200, // "message": "success", // "data": [ // { // "id": "7407825178362667008", // "symbol": "ETH-USDT", // "price": "2970.49", // "quantity": "63", // "side": "SELL", // "time": 1766163153218 // } // ], // "success": true // } // const data = this.safeList(response, 'data', []); return this.parseTrades(data, market, since, limit); } /** * @method * @name bydfi#fetchMyTrades * @description fetch all trades made by the user * @see https://developers.bydfi.com/en/swap/trade#historical-trades-query * @param {string} symbol unified market symbol * @param {int} [since] the earliest time in ms to fetch trades for * @param {int} [limit] the maximum number of trades structures to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {int} [params.until] the latest time in ms to fetch trades for * @param {string} [params.contractType] FUTURE or DELIVERY, default is FUTURE * @param {string} [params.wallet] The unique code of a sub-wallet * @param {string} [params.orderType] order type ('LIMIT', 'MARKET', 'LIQ', 'LIMIT_CLOSE', 'MARKET_CLOSE', 'STOP', 'TAKE_PROFIT', 'STOP_MARKET', 'TAKE_PROFIT_MARKET' or 'TRAILING_STOP_MARKET') * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/?id=trade-structure} */ async fetchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) { await this.loadMarkets(); const paginate = this.safeBool(params, 'paginate', false); if (paginate) { const maxLimit = 500; params = this.omit(params, 'paginate'); params = this.extend(params, { 'paginationDirection': 'backward' }); const paginatedResponse = await this.fetchPaginatedCallDynamic('fetchMyTrades', symbol, since, limit, params, maxLimit, true); return this.sortBy(paginatedResponse, 'timestamp'); } let contractType = 'FUTURE'; [contractType, params] = this.handleOptionAndParams(params, 'fetchMyTrades', 'contractType', contractType); const request = { 'contractType': contractType, }; let market = undefined; if (symbol !== undefined) { market = this.market(symbol); request['symbol'] = market['id']; } params = this.handleSinceAndUntil('fetchMyTrades', since, params); if (limit !== undefined) { request['limit'] = limit; } const response = await this.privateGetV1SwapTradeHistoryTrade(this.extend(request, params)); // // { // "code": 200, // "message": "success", // "data": [ // { // "orderId": "7408919189505597440", // "wallet": "W001", // "symbol": "ETH-USDC", // "time": "1766423985842", // "dealPrice": "3032.45", // "dealVolume": "1", // "fee": "0", // "side": "BUY", // "type": "2", // "liqPrice": null, // "basePrecision": "8", // "baseShowPrecision": "2", // "tradePnl": "0", // "marginType": "CROSS", // "leverageLevel": 1 // } // ], // "success": true // } // const data = this.safeList(response, 'data', []); return this.parseTrades(data, market, since, limit); } parseTrade(trade, market = undefined) { // // fetchTrades // { // "id": "7407825178362667008", // "symbol": "ETH-USDT", // "price": "2970.49", // "quantity": "63", // "side": "SELL", // "time": 1766163153218 // } // // fetchMyTrades // { // "orderId": "7408919189505597440", // "wallet": "W001", // "symbol": "ETH-USDC", // "time": "1766423985842", // "dealPrice": "3032.45", // "dealVolume": "1", // "fee": "0", // "side": "BUY", // "type": "2", // "liqPrice": null, // "basePrecision": "8", // "baseShowPrecision": "2", // "tradePnl": "0", // "marginType": "CROSS", // "leverageLevel": 1 // } // const marketId = this.safeString(trade, 'symbol'); market = this.safeMarket(marketId, market); const timestamp = this.safeInteger(trade, 'time'); let fee = undefined; const rawType = this.safeString(trade, 'type'); const feeCost = this.safeString(trade, 'fee'); if (feeCost !== undefined) { fee = { 'cost': feeCost, 'currency': market['settle'], }; } const orderId = this.safeString(trade, 'orderId'); let side = undefined; // fetchMyTrades always returns side BUY if (orderId === undefined) { // from fetchTrades side = this.safeStringLower(trade, 'side'); } return this.safeTrade({ 'info': trade, 'timestamp': timestamp, 'datetime': this.iso8601(timestamp), 'symbol': market['symbol'], 'id': this.safeString(trade, 'id'), 'order': orderId, 'type': this.parseTradeType(rawType), 'side': side, 'takerOrMaker': undefined, 'price': this.safeString2(trade, 'price', 'dealPrice'), 'amount': this.safeString2(trade, 'quantity', 'dealVolume'), 'cost': undefined, 'fee': fee, }, market); } parseTradeType(type) { const types = { '1': 'limit', '2': 'market', '3': 'liquidation', }; return this.safeString(types, type, type); } /** * @method * @name bydfi#fetchOHLCV * @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market * @see https://developers.bydfi.com/en/swap/market#candlestick-data * @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] the maximum amount of candles to fetch (max 500) * @param {object} [params] extra parameters specific to the bitteam api endpoint * @param {int} [params.until] timestamp in ms of the latest candle to fetch * @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 maxLimit = 500; // docs says max 1500, but in practice only 500 works let paginate = false; [paginate, params] = this.handleOptionAndParams(params, 'fetchOHLCV', 'paginate'); if (paginate) { return this.fetchPaginatedCallDeterministic('fetchOHLCV', symbol, since, limit, timeframe, params, maxLimit); } const market = this.market(symbol); const interval = this.safeString(this.timeframes, timeframe, timeframe); const request = { 'symbol': market['id'], 'interval': interval, }; let startTime = since; const numberOfCandles = limit ? limit : maxLimit; let until = undefined; [until, params] = this.handleOptionAndParams(params, 'fetchOHLCV', 'until'); const now = this.milliseconds(); const duration = this.parseTimeframe(timeframe) * 1000; const timeDelta = duration * numberOfCandles; if (startTime === undefined && until === undefined) { startTime = now - timeDelta; until = now; } else if (until === undefined) { until = startTime + timeDelta; if (until > now) { until = now; } } else if (startTime === undefined) { startTime = until - timeDelta; } request['startTime'] = startTime; request['endTime'] = until; if (limit !== undefined) { request['limit'] = limit; } const response = await this.publicGetV1SwapMarketKlines(this.extend(request, params)); // // { // "code": 200, // "message": "success", // "data": [ // { // "s": "ETH-USDT", // "t": "1766166000000", // "c": "2964.990000000000000000", // "o": "2967.830000000000000000", // "h": "2967.830000000000000000", // "l": "2964.130000000000000000", // "v": "20358.000000000000000000" // } // ], // "success": true // } // const data = this.safeList(response, 'data', []); const result = this.parseOHLCVs(data, market, timeframe, since, limit); return result; } parseOHLCV(ohlcv, market = undefined) { // // { // "s": "ETH-USDT", // "t": "1766166000000", // "c": "2964.990000000000000000", // "o": "2967.830000000000000000", // "h": "2967.830000000000000000", // "l": "2964.130000000000000000", // "v": "20358.000000000000000000" // } // return [ this.safeInteger(ohlcv, 't'), this.safeNumber(ohlcv, 'o'), this.safeNumber(ohlcv, 'h'), this.safeNumber(ohlcv, 'l'), this.safeNumber(ohlcv, 'c'), this.safeNumber(ohlcv, 'v'), ]; } /** * @method * @name bydfi#fetchTickers * @see https://developers.bydfi.com/en/swap/market#24hr-price-change-statistics * @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market * @param {string[]|undefined} symbols unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned * @param {object} [params] extra parameters specific to the 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(); const response = await this.publicGetV1SwapMarketTicker24hr(params); // // { // "code": 200, // "message": "success", // "data": [ // { // "symbol": "BTC-USDT", // "open": "86452.9", // "high": "89371.2", // "low": "84418.5", // "last": "87050.3", // "vol": "12938783", // "time": 1766169423872 // } // ], // "success": true // } // const data = this.safeList(response, 'data', []); return this.parseTickers(data, symbols); } /** * @method * @name bydfi#fetchTicker * @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market * @see https://developers.bydfi.com/en/swap/market#24hr-price-change-statistics * @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.publicGetV1SwapMarketTicker24hr(this.extend(request, params)); const data = this.safeList(response, 'data', []); const ticker = this.safeDict(data, 0, {}); return this.parseTicker(ticker, market); } parseTicker(ticker, market = undefined) { // // fetchTicker/fetchTickers // { // "symbol": "BTC-USDT", // "open": "86452.9", // "high": "89371.2", // "low": "84418.5", // "last": "87050.3", // "vol": "12938783", // "time": 1766169423872 // } // const marketId = this.safeString2(ticker, 'symbol', 's'); market = this.safeMarket(marketId, market); const timestamp = this.safeInteger2(ticker, 'time', 'E'); const last = this.safeString2(ticker, 'last', 'c'); return this.safeTicker({ 'symbol': this.safeSymbol(marketId, market), 'timestamp': timestamp, 'datetime': this.iso8601(timestamp), 'high': this.safeString2(ticker, 'high', 'h'), 'low': this.safeString2(ticker, 'low', 'l'), 'bid': undefined, 'bidVolume': undefined, 'ask': undefined, 'askVolume': undefined, 'vwap': undefined, 'open': this.safeString2(ticker, 'open', 'o'), 'close': last, 'last': last, 'previousClose': undefined, 'change': undefined, 'percentage': undefined, 'average': undefined, 'baseVolume': this.safeString2(ticker, 'vol', 'v'), 'quoteVolume': undefined, 'markPrice': undefined, 'indexPrice': undefined, 'info': ticker, }, market); } /** * @method * @name bydfi#fetchFundingRate * @description fetch the current funding rate * @see https://developers.bydfi.com/en/swap/market#recent-funding-rate * @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.publicGetV1SwapMarketFundingRate(this.extend(request, params)); // // { // "code": 200, // "message": "success", // "data": { // "symbol": "BTC-USDT", // "lastFundingRate": "0.0001", // "nextFundingTime": "1766188800000", // "time": "1766170665007" // }, // "success": true // } // const data = this.safeDict(response, 'data'); return this.parseFundingRate(data, market); } parseFundingRate(contract, market = undefined) { // // { // "symbol": "BTC-USDT", // "lastFundingRate": "0.0001", // "nextFundingTime": "1766188800000", // "time": "1766170665007" // } // const marketId = this.safeString(contract, 'symbol'); const symbol = this.safeSymbol(marketId, market); const timestamp = this.safeInteger(contract, 'time'); const nextFundingTimestamp = this.safeInteger(contract, 'nextFundingTime'); return { 'info': contract, 'symbol': symbol, 'markPrice': undefined, 'indexPrice': undefined, 'interestRate': undefined, 'estimatedSettlePrice': undefined, 'timestamp': timestamp, 'datetime': this.iso8601(timestamp), 'fundingRate': this.safeNumber(contract, 'lastFundingRate'), 'fundingTimestamp': undefined, 'fundingDatetime': undefined, 'nextFundingRate': undefined, 'nextFundingTimestamp': nextFundingTimestamp, 'nextFundingDatetime': this.iso8601(nextFundingTimestamp), 'previousFundingRate': undefined, 'previousFundingTimestamp': undefined, 'previousFundingDatetime': undefined, 'interval': undefined, }; } /** * @method * @name bydfi#fetchFundingRateHistory * @description fetches historical funding rate prices * @see https://developers.bydfi.com/en/swap/market#historical-funding-rates * @param {string} symbol unified symbol of the market to fetch the funding rate history for * @param {int} [since] timestamp in ms of the earliest funding rate to fetch * @param {int} [limit] the maximum amount of [funding rate structures]{@link https://docs.ccxt.com/?id=funding-rate-history-structure} to fetch * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {int} [params.until] timestamp in ms of the latest funding rate to fetch * @returns {object[]} a list of [funding rate structures]{@link https://docs.ccxt.com/?id=funding-rate-history-structure} */ async fetchFundingRateHistory(symbol = undefined, since = undefined, limit = undefined, params = {}) { if (symbol === undefined) { throw new ArgumentsRequired(this.id + ' fetchFundingRateHistory() requires a symbol argument'); } await this.loadMarkets(); const market = this.market(symbol); const request = { 'symbol': market['id'], }; if (since !== undefined) { request['startTime'] = since; } if (limit !== undefined) { request['limit'] = limit; } let until = undefined; [until, params] = this.handleOptionAndParams(params, 'fetchFundingRateHistory', 'until'); if (until !== undefined) { request['endTime'] = until; } const response = await this.publicGetV1SwapMarketFundingRateHistory(this.extend(request, params)); // // { // "code": 200, // "message": "success", // "data": [ // { // "symbol": "ETH-USDT", // "fundingRate": "0.00000025", // "fundingTime": "1765584000000", // "markPrice": "3083.2" // } // ], // "success": true // } // const data = this.safeList(response, 'data', []); return this.parseFundingRateHistories(data, market, since, limit); } parseFundingRateHistory(contract, market = undefined) { // // { // "symbol": "ETH-USDT", // "fundingRate": "0.00000025", // "fundingTime": "1765584000000", // "markPrice": "3083.2" // } // const marketId = this.safeString(contract, 'symbol'); const timestamp = this.safeInteger(contract, 'fundingTime'); return { 'info': contract, 'symbol': this.safeSymbol(marketId, market), 'fundingRate': this.safeNumber(contract, 'fundingRate'), 'timestamp': timestamp, 'datetime': this.iso8601(timestamp), }; } /** * @method * @name bydfi#createOrder * @description create a trade order * @see https://developers.bydfi.com/en/swap/trade#placing-an-order * @param {string} symbol unified symbol of the market to create an order in * @param {string} type 'market' or 'limit' * @param {string} side 'buy' or 'sell' * @param {float} amount how much of currency you want to trade in units of base currency * @param {float} [price] the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {string} [params.wallet] The unique code of a sub-wallet. W001 is the default wallet and the main wallet code of the contract * @param {bool} [params.hedged] true for hedged mode, false for one way mode, default is false * @param {string} [params.clientOrderId] Custom order ID, must be unique for open orders * @param {string} [params.timeInForce] 'GTC' (Good Till Cancelled), 'FOK' (Fill Or Kill), 'IOC' (Immediate Or Cancel), 'PO' (Post Only) * @param {bool} [params.postOnly] true or false, whether the order is post-only * @param {bool} [params.reduceOnly] true or false, true or fal