@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
JavaScript
'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 = {}) {