UNPKG

@kraken-crypto/ccxt

Version:

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

1,163 lines (1,159 loc) 102 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var backpack$1 = require('./abstract/backpack.js'); var errors = require('./base/errors.js'); var number = require('./base/functions/number.js'); var Precise = require('./base/Precise.js'); var ed25519 = require('./static_dependencies/noble-curves/ed25519.js'); var crypto = require('./base/functions/crypto.js'); // --------------------------------------------------------------------------- // --------------------------------------------------------------------------- /** * @class backpack * @augments Exchange */ class backpack extends backpack$1["default"] { describe() { return this.deepExtend(super.describe(), { 'id': 'backpack', 'name': 'Backpack', 'countries': ['JP'], 'rateLimit': 50, 'version': 'v1', 'certified': false, 'pro': true, 'has': { 'CORS': undefined, 'spot': true, 'margin': true, 'swap': true, 'future': false, 'option': false, 'addMargin': false, 'cancelAllOrders': true, 'cancelAllOrdersAfter': false, 'cancelOrder': true, 'cancelOrders': false, 'cancelWithdraw': false, 'closePosition': false, 'createConvertTrade': false, 'createDepositAddress': false, 'createLimitBuyOrder': true, 'createLimitOrder': true, 'createLimitSellOrder': true, 'createMarketBuyOrder': true, 'createMarketBuyOrderWithCost': true, 'createMarketOrder': true, 'createMarketOrderWithCost': true, 'createMarketSellOrder': true, 'createMarketSellOrderWithCost': true, 'createOrder': true, 'createOrders': true, 'createOrderWithTakeProfitAndStopLoss': true, 'createPostOnlyOrder': true, 'createReduceOnlyOrder': true, 'createStopLossOrder': false, 'createTakeProfitOrder': false, 'createTrailingAmountOrder': false, 'createTrailingPercentOrder': false, 'createTriggerOrder': true, 'fetchAccounts': false, 'fetchAllGreeks': false, 'fetchBalance': true, 'fetchCanceledAndClosedOrders': false, 'fetchCanceledOrders': false, 'fetchClosedOrder': false, 'fetchClosedOrders': false, 'fetchConvertCurrencies': false, 'fetchConvertQuote': false, 'fetchConvertTrade': false, 'fetchConvertTradeHistory': false, 'fetchCurrencies': true, 'fetchDepositAddress': true, 'fetchDeposits': true, 'fetchDepositsWithdrawals': false, 'fetchDepositWithdrawFees': false, 'fetchFundingHistory': true, 'fetchFundingRate': true, 'fetchFundingRateHistory': true, 'fetchFundingRates': false, 'fetchGreeks': false, 'fetchIndexOHLCV': true, 'fetchLedger': false, 'fetchLeverage': false, 'fetchLeverageTiers': false, 'fetchMarginAdjustmentHistory': false, 'fetchMarginMode': false, 'fetchMarkets': true, 'fetchMarkOHLCV': true, 'fetchMyTrades': true, 'fetchOHLCV': true, 'fetchOpenInterest': true, 'fetchOpenInterestHistory': true, 'fetchOpenOrder': true, 'fetchOpenOrders': true, 'fetchOption': false, 'fetchOptionChain': false, 'fetchOrder': false, 'fetchOrderBook': true, 'fetchOrders': true, 'fetchOrderTrades': false, 'fetchPosition': false, 'fetchPositionHistory': false, 'fetchPositionMode': false, 'fetchPositions': true, 'fetchPositionsForSymbol': false, 'fetchPositionsHistory': false, 'fetchPremiumIndexOHLCV': false, 'fetchStatus': true, 'fetchTicker': true, 'fetchTickers': true, 'fetchTime': true, 'fetchTrades': true, 'fetchTradingFee': false, 'fetchTradingFees': false, 'fetchTransactions': false, 'fetchTransfers': false, 'fetchVolatilityHistory': false, 'fetchWithdrawals': true, 'reduceMargin': false, 'sandbox': false, 'setLeverage': false, 'setMargin': false, 'setMarginMode': false, 'setPositionMode': false, 'transfer': false, 'withdraw': true, }, 'timeframes': { '1m': '1m', '3m': '3m', '5m': '5m', '15': '15m', '30': '30m', '1h': '1h', '2h': '2h', '4h': '4h', '6h': '6h', '8h': '8h', '12h': '12h', '1d': '1d', '3d': '3d', '1w': '1w', '1M': '1month', }, 'urls': { 'logo': 'https://github.com/user-attachments/assets/cc04c278-679f-4554-9f72-930dd632b80f', 'api': { 'public': 'https://api.backpack.exchange', 'private': 'https://api.backpack.exchange', }, 'www': 'https://backpack.exchange/', 'doc': 'https://docs.backpack.exchange/', 'referral': 'https://backpack.exchange/join/ccxt', }, 'api': { 'public': { 'get': { 'api/v1/assets': 1, 'api/v1/collateral': 1, 'api/v1/borrowLend/markets': 1, 'api/v1/borrowLend/markets/history': 1, 'api/v1/markets': 1, 'api/v1/market': 1, 'api/v1/ticker': 1, 'api/v1/tickers': 1, 'api/v1/depth': 1, 'api/v1/klines': 1, 'api/v1/markPrices': 1, 'api/v1/openInterest': 1, 'api/v1/fundingRates': 1, 'api/v1/status': 1, 'api/v1/ping': 1, 'api/v1/time': 1, 'api/v1/wallets': 1, 'api/v1/trades': 1, 'api/v1/trades/history': 1, // done }, }, 'private': { 'get': { 'api/v1/account': 1, 'api/v1/account/limits/borrow': 1, 'api/v1/account/limits/order': 1, 'api/v1/account/limits/withdrawal': 1, 'api/v1/borrowLend/positions': 1, 'api/v1/capital': 1, 'api/v1/capital/collateral': 1, 'wapi/v1/capital/deposits': 1, 'wapi/v1/capital/deposit/address': 1, 'wapi/v1/capital/withdrawals': 1, 'api/v1/position': 1, 'wapi/v1/history/borrowLend': 1, 'wapi/v1/history/interest': 1, 'wapi/v1/history/borrowLend/positions': 1, 'wapi/v1/history/dust': 1, 'wapi/v1/history/fills': 1, 'wapi/v1/history/funding': 1, 'wapi/v1/history/orders': 1, 'wapi/v1/history/rfq': 1, 'wapi/v1/history/quote': 1, 'wapi/v1/history/settlement': 1, 'wapi/v1/history/strategies': 1, 'api/v1/order': 1, 'api/v1/orders': 1, // done }, 'post': { 'api/v1/account/convertDust': 1, 'api/v1/borrowLend': 1, 'wapi/v1/capital/withdrawals': 1, 'api/v1/order': 1, 'api/v1/orders': 1, 'api/v1/rfq': 1, 'api/v1/rfq/accept': 1, 'api/v1/rfq/refresh': 1, 'api/v1/rfq/cancel': 1, 'api/v1/rfq/quote': 1, }, 'delete': { 'api/v1/order': 1, 'api/v1/orders': 1, // done }, 'patch': { 'api/v1/account': 1, }, }, }, 'features': { 'default': { 'sandbox': false, 'createOrder': { 'marginMode': false, 'triggerPrice': true, 'triggerPriceType': undefined, 'triggerDirection': false, 'stopLossPrice': true, 'takeProfitPrice': true, 'attachedStopLossTakeProfit': undefined, 'timeInForce': { 'GTC': true, 'IOC': true, 'FOK': true, 'PO': true, 'GTD': false, }, 'hedged': false, 'trailing': false, 'leverage': false, 'marketBuyByCost': true, 'marketBuyRequiresPrice': true, 'selfTradePrevention': { 'EXPIRE_MAKER': true, 'EXPIRE_TAKER': true, 'EXPIRE_BOTH': true, 'NONE': false, }, 'iceberg': false, }, 'createOrders': { 'max': 20, }, 'fetchMyTrades': { 'marginMode': false, 'limit': 1000, 'daysBack': undefined, 'untilDays': undefined, 'symbolRequired': false, }, 'fetchOrder': undefined, 'fetchOpenOrders': { 'marginMode': false, 'limit': 1000, 'trigger': true, 'trailing': false, 'symbolRequired': false, }, 'fetchOrders': { 'marginMode': false, 'limit': 1000, 'daysBack': undefined, 'untilDays': undefined, 'trigger': true, 'trailing': false, 'symbolRequired': true, }, 'fetchClosedOrders': undefined, 'fetchOHLCV': { 'paginate': false, 'limit': 1000, }, }, 'spot': { 'extends': 'default', }, 'swap': { 'linear': undefined, 'inverse': undefined, }, 'future': { 'linear': undefined, 'inverse': undefined, }, }, 'requiredCredentials': { 'apiKey': true, 'secret': true, }, 'precisionMode': number.TICK_SIZE, 'options': { 'instructions': { 'api/v1/account': { 'GET': 'accountQuery', 'PATCH': 'accountUpdate', }, 'api/v1/capital': { 'GET': 'balanceQuery', }, 'api/v1/account/limits/borrow': { 'GET': 'maxBorrowQuantity', }, 'api/v1/account/limits/order': { 'GET': 'maxOrderQuantity', }, 'api/v1/account/limits/withdrawal': { 'GET': 'maxWithdrawalQuantity', }, 'api/v1/borrowLend/positions': { 'GET': 'borrowLendPositionQuery', }, 'api/v1/borrowLend': { 'POST': 'borrowLendExecute', }, 'wapi/v1/history/borrowLend/positions': { 'GET': 'borrowPositionHistoryQueryAll', }, 'wapi/v1/history/borrowLend': { 'GET': 'borrowHistoryQueryAll', }, 'wapi/v1/history/dust': { 'GET': 'dustHistoryQueryAll', }, 'api/v1/capital/collateral': { 'GET': 'collateralQuery', }, 'wapi/v1/capital/deposit/address': { 'GET': 'depositAddressQuery', }, 'wapi/v1/capital/deposits': { 'GET': 'depositQueryAll', }, 'wapi/v1/history/fills': { 'GET': 'fillHistoryQueryAll', }, 'wapi/v1/history/funding': { 'GET': 'fundingHistoryQueryAll', }, 'wapi/v1/history/interest': { 'GET': 'interestHistoryQueryAll', }, 'api/v1/order': { 'GET': 'orderQuery', 'POST': 'orderExecute', 'DELETE': 'orderCancel', }, 'api/v1/orders': { 'GET': 'orderQueryAll', 'POST': 'orderExecute', 'DELETE': 'orderCancelAll', }, 'wapi/v1/history/orders': { 'GET': 'orderHistoryQueryAll', }, 'wapi/v1/history/pnl': { 'GET': 'pnlHistoryQueryAll', }, 'wapi/v1/history/rfq': { 'GET': 'rfqHistoryQueryAll', }, 'wapi/v1/history/quote': { 'GET': 'quoteHistoryQueryAll', }, 'wapi/v1/history/settlement': { 'GET': 'settlementHistoryQueryAll', }, 'api/v1/position': { 'GET': 'positionQuery', }, 'api/v1/rfq/quote': { 'POST': 'quoteSubmit', }, 'wapi/v1/history/strategies': { 'GET': 'strategyHistoryQueryAll', }, 'wapi/v1/capital/withdrawals': { 'GET': 'withdrawalQueryAll', 'POST': 'withdraw', }, }, 'recvWindow': 5000, 'brokerId': '', 'currencyIdsListForParseMarket': undefined, 'broker': '', 'timeDifference': 0, 'adjustForTimeDifference': false, 'networks': { 'APT': 'Aptos', 'ARB': 'Arbitrum', 'AVAX': 'Avalanche', 'BASE': 'Base', 'BERA': 'Berachain', 'BTC': 'Bitcoin', 'BCH': 'BitcoinCash', 'BSC': 'Bsc', 'ADA': 'Cardano', 'DOGE': 'Dogecoin', 'ECLIPSE': 'Eclipse', 'EQUALSMONEY': 'EqualsMoney', 'ERC20': 'Ethereum', 'HYP': 'Hyperliquid', 'LTC': 'Litecoin', 'OPTIMISM': 'Optimism', 'MATIC': 'Polygon', 'SEI': 'Sei', 'SUI': 'Sui', 'SOL': 'Solana', 'STORY': 'Story', 'TRC20': 'Tron', 'XRP': 'XRP', }, 'networksById': { 'aptos': 'APT', 'arbitrum': 'ARB', 'avalanche': 'AVAX', 'base': 'BASE', 'berachain': 'BERA', 'bitcoin': 'BTC', 'bitcoincash': 'BCH', 'bsc': 'BSC', 'cardano': 'ADA', 'dogecoin': 'DOGE', 'eclipse': 'ECLIPSE', 'equalsmoney': 'EQUALSMONEY', 'ethereum': 'ERC20', 'hyperliquid': 'HYP', 'litecoin': 'LTC', 'optimism': 'OPTIMISM', 'polygon': 'MATIC', 'sei': 'SEI', 'sui': 'SUI', 'solana': 'SOL', 'story': 'STORY', 'tron': 'TRC20', 'xrp': 'XRP', }, }, 'commonCurrencies': {}, 'exceptions': { 'exact': { 'INVALID_CLIENT_REQUEST': errors.BadRequest, 'INVALID_ORDER': errors.InvalidOrder, 'ACCOUNT_LIQUIDATING': errors.BadRequest, 'BORROW_LIMIT': errors.BadRequest, 'BORROW_REQUIRES_LEND_REDEEM': errors.BadRequest, 'FORBIDDEN': errors.OperationRejected, 'INSUFFICIENT_FUNDS': errors.InsufficientFunds, 'INSUFFICIENT_MARGIN': errors.InsufficientFunds, 'INSUFFICIENT_SUPPLY': errors.InsufficientFunds, 'INVALID_ASSET': errors.BadRequest, 'INVALID_MARKET': errors.BadSymbol, 'INVALID_PRICE': errors.BadRequest, 'INVALID_POSITION_ID': errors.BadRequest, 'INVALID_QUANTITY': errors.BadRequest, 'INVALID_RANGE': errors.BadRequest, 'INVALID_SIGNATURE': errors.AuthenticationError, 'INVALID_SOURCE': errors.BadRequest, 'INVALID_SYMBOL': errors.BadSymbol, 'INVALID_TWO_FACTOR_CODE': errors.BadRequest, 'LEND_LIMIT': errors.BadRequest, 'LEND_REQUIRES_BORROW_REPAY': errors.BadRequest, 'MAINTENANCE': errors.ExchangeError, 'MAX_LEVERAGE_REACHED': errors.InsufficientFunds, 'NOT_IMPLEMENTED': errors.OperationFailed, 'ORDER_LIMIT': errors.OperationRejected, 'POSITION_LIMIT': errors.OperationRejected, 'PRECONDITION_FAILED': errors.OperationFailed, 'RESOURCE_NOT_FOUND': errors.ExchangeNotAvailable, 'SERVER_ERROR': errors.NetworkError, 'TIMEOUT': errors.RequestTimeout, 'TOO_MANY_REQUESTS': errors.RateLimitExceeded, 'TRADING_PAUSED': errors.ExchangeNotAvailable, 'UNAUTHORIZED': errors.AuthenticationError, }, // Bad Request parse request payload error: failed to parse "MarketSymbol": Invalid market symbol (occurred while parsing "OrderExecutePayload") // failed to parse parameter `interval`: failed to parse "KlineInterval": Expect a valid enumeration value. 'broad': {}, }, }); } /** * @method * @name backpack#fetchCurrencies * @description fetches all available currencies on an exchange * @see https://docs.backpack.exchange/#tag/Assets * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} an associative dictionary of currencies */ async fetchCurrencies(params = {}) { const response = await this.publicGetApiV1Assets(params); // // [ // { // "coingeckoId": "jito-governance-token", // "displayName": "Jito", // "symbol": "JTO", // "tokens": [ // { // "blockchain": "Solana", // "contractAddress": "jtojtomepa8beP8AuQc6eXt5FriJwfFMwQx2v2f9mCL", // "depositEnabled": true, // "displayName": "Jito", // "maximumWithdrawal": null, // "minimumDeposit": "0.29", // "minimumWithdrawal": "0.58", // "withdrawEnabled": true, // "withdrawalFee": "0.29" // } // ] // } // ... // ] // const result = {}; for (let i = 0; i < response.length; i++) { const currecy = response[i]; const currencyId = this.safeString(currecy, 'symbol'); const code = this.safeCurrencyCode(currencyId); const networks = this.safeList(currecy, 'tokens', []); const parsedNetworks = {}; for (let j = 0; j < networks.length; j++) { const network = networks[j]; const networkId = this.safeString(network, 'blockchain'); const networkIdLowerCase = this.safeStringLower(network, 'blockchain'); const networkCode = this.networkIdToCode(networkIdLowerCase); parsedNetworks[networkCode] = { 'id': networkId, 'network': networkCode, 'limits': { 'withdraw': { 'min': this.safeNumber(network, 'minimumWithdrawal'), 'max': this.parseNumber(this.omitZero(this.safeString(network, 'maximumWithdrawal'))), }, 'deposit': { 'min': this.safeNumber(network, 'minimumDeposit'), 'max': undefined, }, }, 'active': undefined, 'deposit': this.safeBool(network, 'depositEnabled'), 'withdraw': this.safeBool(network, 'withdrawEnabled'), 'fee': this.safeNumber(network, 'withdrawalFee'), 'precision': undefined, 'info': network, }; } let active = undefined; let deposit = undefined; let withdraw = undefined; if (this.isEmpty(parsedNetworks)) { // if networks are not provided active = false; deposit = false; withdraw = false; } result[code] = this.safeCurrencyStructure({ 'id': currencyId, 'code': code, 'precision': undefined, 'type': 'crypto', 'name': this.safeString(currecy, 'displayName'), 'active': active, 'deposit': deposit, 'withdraw': withdraw, 'fee': undefined, 'limits': { 'deposit': { 'min': undefined, 'max': undefined, }, 'withdraw': { 'min': undefined, 'max': undefined, }, }, 'networks': parsedNetworks, 'info': currecy, }); } return result; } /** * @method * @name backpack#fetchMarkets * @description retrieves data on all markets for bitbank * @see https://docs.backpack.exchange/#tag/Markets/operation/get_markets * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} an array of objects representing market data */ async fetchMarkets(params = {}) { if (this.options['adjustForTimeDifference']) { await this.loadTimeDifference(); } const response = await this.publicGetApiV1Markets(params); return this.parseMarkets(response); } parseMarket(market) { // // [ // { // "baseSymbol": "SOL", // "createdAt": "2025-01-21T06:34:54.691858", // "filters": { // "price": { // "borrowmarketFeeMaxMultiplier": null, // "borrowmarketFeeMinMultiplier": null, // "maxImpactMultiplier": "1.03", // "maxMultiplier": "1.25", // "maxPrice": null, // "meanMarkPriceBand": { // "maxMultiplier": "1.15", // "minMultiplier": "0.9" // }, // "meanPremiumBand": null, // "minImpactMultiplier": "0.97", // "minMultiplier": "0.75", // "minPrice": "0.01", // "tickSize": "0.01" // }, // "quantity": { // "maxQuantity": null, // "minQuantity": "0.01", // "stepSize": "0.01" // } // }, // "fundingInterval": 28800000, // "fundingRateLowerBound": null, // "fundingRateUpperBound": null, // "imfFunction": null, // "marketType": "SPOT", // "mmfFunction": null, // "openInterestLimit": "0", // "orderBookState": "Open", // "quoteSymbol": "USDC", // "symbol": "SOL_USDC" // }, // { // "baseSymbol": "SOL", // "createdAt": "2025-01-21T06:34:54.691858", // "filters": { // "price": { // "borrowEntryFeeMaxMultiplier": null, // "borrowEntryFeeMinMultiplier": null, // "maxImpactMultiplier": "1.03", // "maxMultiplier": "1.25", // "maxPrice": "1000", // "meanMarkPriceBand": { // "maxMultiplier": "1.1", // "minMultiplier": "0.9" // }, // "meanPremiumBand": { // "tolerancePct": "0.05" // }, // "minImpactMultiplier": "0.97", // "minMultiplier": "0.75", // "minPrice": "0.01", // "tickSize": "0.01" // }, // "quantity": { // "maxQuantity": null, // "minQuantity": "0.01", // "stepSize": "0.01" // } // }, // "fundingInterval": "28800000", // "fundingRateLowerBound": "-100", // "fundingRateUpperBound": "100", // "imfFunction": { // "base": "0.02", // "factor": "0.0001275", // "type": "sqrt" // }, // "marketType": "PERP", // "mmfFunction": { // "base": "0.0125", // "factor": "0.0000765", // "type": "sqrt" // }, // "openInterestLimit": "4000000", // "orderBookState": "Open", // "quoteSymbol": "USDC", // "symbol": "SOL_USDC_PERP" // } // ] // const id = this.safeString(market, 'symbol'); const baseId = this.safeString(market, 'baseSymbol'); const quoteId = this.safeString(market, 'quoteSymbol'); const base = this.safeCurrencyCode(baseId); const quote = this.safeCurrencyCode(quoteId); let symbol = base + '/' + quote; const filters = this.safeDict(market, 'filters', {}); const priceFilter = this.safeDict(filters, 'price', {}); const maxPrice = this.safeNumber(priceFilter, 'maxPrice'); const minPrice = this.safeNumber(priceFilter, 'minPrice'); const pricePrecision = this.safeNumber(priceFilter, 'tickSize'); const quantityFilter = this.safeDict(filters, 'quantity', {}); const maxQuantity = this.safeNumber(quantityFilter, 'maxQuantity'); const minQuantity = this.safeNumber(quantityFilter, 'minQuantity'); const amountPrecision = this.safeNumber(quantityFilter, 'stepSize'); let type; const typeOfMarket = this.parseMarketType(this.safeString(market, 'marketType')); let linear = undefined; let inverse = undefined; let settle = undefined; let settleId = undefined; let contractSize = undefined; if (typeOfMarket === 'spot') { type = 'spot'; } else if (typeOfMarket === 'swap') { type = 'swap'; linear = true; inverse = false; settleId = this.safeString(market, 'quoteSymbol'); settle = this.safeCurrencyCode(settleId); symbol += ':' + settle; contractSize = 1; } const orderBookState = this.safeString(market, 'orderBookState'); return this.safeMarketStructure({ 'id': id, 'symbol': symbol, 'base': base, 'quote': quote, 'settle': settle, 'baseId': baseId, 'quoteId': quoteId, 'settleId': settleId, 'type': type, 'spot': type === 'spot', 'margin': type === 'spot', 'swap': type === 'swap', 'future': false, 'option': false, 'active': orderBookState === 'Open', 'contract': type !== 'spot', 'linear': linear, 'inverse': inverse, 'taker': undefined, 'maker': undefined, 'contractSize': contractSize, 'expiry': undefined, 'expiryDatetime': undefined, 'strike': undefined, 'optionType': undefined, 'precision': { 'amount': amountPrecision, 'price': pricePrecision, }, 'limits': { 'leverage': { 'min': undefined, 'max': undefined, }, 'amount': { 'min': minQuantity, 'max': maxQuantity, }, 'price': { 'min': minPrice, 'max': maxPrice, }, 'cost': { 'min': undefined, 'max': undefined, }, }, 'created': this.parse8601(this.safeString(market, 'createdAt')), 'info': market, }); } parseMarketType(type) { const types = { 'SPOT': 'spot', 'PERP': 'swap', // current types are described in the docs, but the exchange returns only 'SPOT' and 'PERP' // 'IPERP': 'swap', // 'DATED': 'swap', // 'PREDICTION': 'swap', // 'RFQ': 'swap', }; return this.safeString(types, type, type); } /** * @method * @name backpack#fetchTickers * @see https://docs.backpack.exchange/#tag/Markets/operation/get_tickers * @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 request = {}; const response = await this.publicGetApiV1Tickers(this.extend(request, params)); const tickers = this.parseTickers(response); return this.filterByArrayTickers(tickers, 'symbol', symbols); } /** * @method * @name backpack#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.backpack.exchange/#tag/Markets/operation/get_ticker * @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.publicGetApiV1Ticker(this.extend(request, params)); return this.parseTicker(response, market); } parseTicker(ticker, market = undefined) { // // fetchTicker/fetchTickers // // { // "firstPrice": "327.38", // "high": "337.99", // "lastPrice": "317.14", // "low": "300.01", // "priceChange": "-10.24", // "priceChangePercent": "-0.031279", // "quoteVolume": "21584.32278", // "symbol": "AAVE_USDC", // "trades": "245", // "volume": "65.823" // }, ... // const marketId = this.safeString(ticker, 'symbol'); market = this.safeMarket(marketId, market); const symbol = this.safeSymbol(marketId, market); const open = this.safeString(ticker, 'firstPrice'); const last = this.safeString(ticker, 'lastPrice'); const high = this.safeString(ticker, 'high'); const low = this.safeString(ticker, 'low'); const baseVolume = this.safeString(ticker, 'volume'); const quoteVolume = this.safeString(ticker, 'quoteVolume'); const percentage = this.safeString(ticker, 'priceChangePercent'); const change = this.safeString(ticker, 'priceChange'); return this.safeTicker({ 'symbol': symbol, 'timestamp': undefined, 'datetime': undefined, 'high': high, 'low': low, 'bid': undefined, 'bidVolume': undefined, 'ask': undefined, 'askVolume': undefined, 'vwap': undefined, 'open': open, 'close': last, 'last': last, 'previousClose': undefined, 'change': change, 'percentage': percentage, 'average': undefined, 'baseVolume': baseVolume, 'quoteVolume': quoteVolume, 'markPrice': undefined, 'indexPrice': undefined, 'info': ticker, }, market); } /** * @method * @name backpack#fetchOrderBook * @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data * @see https://docs.backpack.exchange/#tag/Markets/operation/get_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 100, max 200) * @param {object} [params] extra parameters specific to the bitteam api endpoint * @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'], }; const response = await this.publicGetApiV1Depth(this.extend(request, params)); // // { // "asks": [ // ["118318.3","0.00633"], // ["118567.2","0.08450"] // ], // "bids": [ // ["1.0","0.38647"], // ["12.9","1.00000"] // ], // "lastUpdateId":"1504999670", // "timestamp":1753102447307501 // } // const microseconds = this.safeInteger(response, 'timestamp'); const timestamp = this.parseToInt(microseconds / 1000); const orderbook = this.parseOrderBook(response, symbol, timestamp); orderbook['nonce'] = this.safeInteger(response, 'lastUpdateId'); return orderbook; } /** * @method * @name backpack#fetchOHLCV * @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market * @see https://docs.backpack.exchange/#tag/Markets/operation/get_klines * @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 seconds of the earliest candle to fetch * @param {int} [limit] the maximum amount of candles to fetch (default 100) * @param {object} [params] extra parameters specific to the bitteam api endpoint * @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 interval = this.safeString(this.timeframes, timeframe, timeframe); const request = { 'symbol': market['id'], 'interval': interval, }; let until = undefined; [until, params] = this.handleOptionAndParams(params, 'fetchOHLCV', 'until'); if (until !== undefined) { request['endTime'] = this.parseToInt(until / 1000); // convert milliseconds to seconds } const defaultLimit = 100; if (since === undefined) { if (limit === undefined) { limit = defaultLimit; } const duration = this.parseTimeframe(timeframe); const endTime = until ? this.parseToInt(until / 1000) : this.seconds(); const startTime = endTime - (limit * duration); request['startTime'] = startTime; } else { request['startTime'] = this.parseToInt(since / 1000); // convert milliseconds to seconds } const price = this.safeString(params, 'price'); if (price !== undefined) { request['priceType'] = this.capitalize(price); params = this.omit(params, 'price'); } const response = await this.publicGetApiV1Klines(this.extend(request, params)); return this.parseOHLCVs(response, market, timeframe, since, limit); } parseOHLCV(ohlcv, market = undefined) { // // [ // { // "close": "118294.6", // "end": "2025-07-19 13:12:00", // "high": "118297.6", // "low": "118237.5", // "open": "118238", // "quoteVolume": "4106.558156", // "start": "2025-07-19 13:09:00", // "trades": "12", // "volume": "0.03473" // }, // ... // ] // return [ this.parse8601(this.safeString(ohlcv, 'start')), this.safeNumber(ohlcv, 'open'), this.safeNumber(ohlcv, 'high'), this.safeNumber(ohlcv, 'low'), this.safeNumber(ohlcv, 'close'), this.safeNumber(ohlcv, 'volume'), ]; } /** * @method * @name backpack#fetchFundingRate * @description fetch the current funding rate * @see https://docs.backpack.exchange/#tag/Markets/operation/get_mark_prices * @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); if (market['spot']) { throw new errors.BadRequest(this.id + ' fetchFundingRate() symbol does not support market ' + symbol); } const request = { 'symbol': market['id'], }; const response = await this.publicGetApiV1MarkPrices(this.extend(request, params)); const data = this.safeDict(response, 0, {}); return this.parseFundingRate(data, market); } parseFundingRate(contract, market = undefined) { // // { // "fundingRate": "0.0001", // "indexPrice": "118333.18643195", // "markPrice": "118343.51853741", // "nextFundingTimestamp": 1753113600000, // "symbol": "BTC_USDC_PERP" // } // const marketId = this.safeString(contract, 'symbol'); market = this.safeMarket(marketId, market); const symbol = this.safeSymbol(marketId, market); const nextFundingTimestamp = this.safeInteger(contract, 'nextFundingTimestamp'); return { 'info': contract, 'symbol': symbol, 'markPrice': this.safeNumber(contract, 'markPrice'), 'indexPrice': this.safeNumber(contract, 'indexPrice'), 'interestRate': undefined, 'estimatedSettlePrice': undefined, 'timestamp': undefined, 'datetime': undefined, 'fundingRate': this.safeNumber(contract, 'fundingRate'), 'fundingTimestamp': undefined, 'fundingDatetime': undefined, 'nextFundingRate': undefined, 'nextFundingTimestamp': nextFundingTimestamp, 'nextFundingDatetime': this.iso8601(nextFundingTimestamp), 'previousFundingRate': undefined, 'previousFundingTimestamp': undefined, 'previousFundingDatetime': undefined, 'interval': '1h', }; } /** * @method * @name backpack#fetchOpenInterest * @description Retrieves the open interest of a derivative trading pair * @see https://docs.backpack.exchange/#tag/Markets/operation/get_open_interest * @param {string} symbol Unified CCXT market symbol * @param {object} [params] exchange specific parameters * @returns {object} an open interest structure{@link https://docs.ccxt.com/#/?id=interest-history-structure} */ async fetchOpenInterest(symbol, params = {}) { await this.loadMarkets(); const market = this.market(symbol); if (market['spot']) { throw new errors.BadRequest(this.id + ' fetchOpenInterest() symbol does not support market ' + symbol); } const request = { 'symbol': market['id'], }; const response = await this.publicGetApiV1OpenInterest(this.extend(request, params)); const interest = this.safeDict(response, 0, {}); return this.parseOpenInterest(interest, market); } parseOpenInterest(interest, market = undefined) { // // [ // { // "openInterest": "1273.85214", // "symbol": "BTC_USDC_PERP", // "timestamp":1753105735301 // } // ] // const timestamp = this.safeInteger(interest, 'timestamp'); const openInterest = this.safeNumber(interest, 'openInterest'); return this.safeOpenInterest({ 'symbol': market['symbol'], 'openInterestAmount': undefined, 'openInterestValue': openInterest, 'timestamp': timestamp, 'datetime': this.iso8601(timestamp), 'info': interest, }, market); } /** * @method * @name backpack#fetchFundingRateHistory * @description fetches historical funding rate prices * @see https://docs.backpack.exchange/#tag/Markets/operation/get_funding_interval_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 * @param {object} [params] extra parameters specific to the exchange API endpoint * @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 errors.ArgumentsRequired(this.id + ' fetchFundingRateHistory() requires a symbol argument'); } await this.loadMarkets(); const market = this.market(symbol); const request = { 'symbol': market['id'], }; if (limit !== undefined) { request['limit'] = Math.min(limit, 1000); // api maximum 1000 } const response = await this.publicGetApiV1FundingRates(this.extend(request, params)); // // [ // { // "fundingRate": "0.0001", // "intervalEndTimestamp": "2025-07-22T00:00:00", // "symbol": "BTC_USDC_PERP" // } // ] // const rates = []; for (let i = 0; i < response.length; i++) { const rate = response[i]; const datetime = this.safeString(rate, 'intervalEndTimestamp'); const timestamp = this.parse8601(datetime); rates.push({ 'info': rate, 'symbol': market['symbol'], 'fundingRate': this.safeNumber(rate, 'fundingRate'), 'timestamp': timestamp, 'datetime': datetime, }); } const sorted = this.sortBy(rates, 'timestamp'); return this.filterBySymbolSinceLimit(sorted, market['symbol'], since, limit); } /** * @method * @name backpack#fetchTrades * @description get the list of most recent trades for a particular symbol * @see https://docs.backpack.exchange/#tag/Trades/operation/get_recent_trades * @see https://docs.backpack.exchange/#tag/Trades/operation/get_historical_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 * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {int} [params.offset] the number of trades to skip, default is 0 * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades} */ async fetchTrades(symbol, since = undefined, limit = undefined, params = {}) {