@kraken-crypto/ccxt
Version:
A cryptocurrency trading API with more than 100 exchanges in JavaScript / TypeScript / Python / C# / PHP / Go
1,153 lines (1,150 loc) • 107 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var arkham$1 = require('./abstract/arkham.js');
var Precise = require('./base/Precise.js');
var errors = require('./base/errors.js');
var number = require('./base/functions/number.js');
var sha256 = require('./static_dependencies/noble-hashes/sha256.js');
// ---------------------------------------------------------------------------
/**
* @class arkham
* @augments Exchange
*/
class arkham extends arkham$1["default"] {
describe() {
return this.deepExtend(super.describe(), {
'id': 'arkham',
'name': 'ARKHAM',
'countries': ['US'],
'version': 'v1',
'rateLimit': 20 / 3,
'certified': false,
'pro': true,
'has': {
'CORS': false,
'spot': true,
'margin': false,
'swap': true,
'future': false,
'option': false,
'borrowCrossMargin': false,
'borrowIsolatedMargin': false,
'borrowMargin': false,
'cancelAllOrders': true,
'cancelOrder': true,
'createDepositAddress': true,
'createOrder': true,
'fetchAccounts': true,
'fetchAllGreeks': false,
'fetchBalance': true,
'fetchBorrowInterest': false,
'fetchBorrowRate': false,
'fetchBorrowRateHistories': false,
'fetchBorrowRateHistory': false,
'fetchBorrowRates': false,
'fetchBorrowRatesPerSymbol': false,
'fetchClosedOrders': true,
'fetchCrossBorrowRate': false,
'fetchCrossBorrowRates': false,
'fetchCurrencies': true,
'fetchDepositAddress': false,
'fetchDepositAddressesByNetwork': true,
'fetchDeposits': true,
'fetchFundingHistory': true,
'fetchGreeks': false,
'fetchIsolatedBorrowRate': false,
'fetchIsolatedBorrowRates': false,
'fetchLeverage': true,
'fetchLeverageTiers': true,
'fetchMyTrades': true,
'fetchOHLCV': true,
'fetchOpenOrders': true,
'fetchOption': false,
'fetchOptionChain': false,
'fetchOrder': true,
'fetchOrderBook': true,
'fetchPositions': true,
'fetchTicker': true,
'fetchTickers': true,
'fetchTime': true,
'fetchTrades': true,
'fetchTradingFees': true,
'fetchVolatilityHistory': false,
'fetchWithdrawals': true,
'repayCrossMargin': false,
'repayIsolatedMargin': false,
'sandbox': false,
'setLeverage': true,
'withdraw': true,
},
'timeframes': {
// enums are wrong in DOCS, these string values need to be in request
'1m': '1m',
'5m': '5m',
'15m': '15m',
'30m': '30m',
'1h': '1h',
'6h': '6h',
'1d': '24h',
},
'urls': {
'logo': 'https://github.com/user-attachments/assets/5cefdcfb-2c10-445b-835c-fa21317bf5ac',
'api': {
'v1': 'https://arkm.com/api',
},
'www': 'https://arkm.com/',
'referral': {
'url': 'https://arkm.com/register?ref=ccxt',
'discount': 0,
},
'doc': [
'https://arkm.com/limits-api',
'https://info.arkm.com/api-platform',
],
'fees': 'https://arkm.com/fees',
},
'api': {
'v1': {
'public': {
'get': {
'alerts': 1,
'announcements': 1,
'assets': 1,
'book': 1,
'candles': 1,
'chains': 1,
'contracts': 1,
'index-price': 1,
'index-prices': 1,
'margin-schedules': 1,
'marketcapchart': 1,
'marketcaps': 1,
'pair': 1,
'pairs': 1,
'server-time': 1,
'ticker': 1,
'tickers': 1,
'trades': 1,
},
},
'private': {
// for orders: spot 20/s, todo: perp 40/s
'get': {
'user': 7.5,
'orders': 7.5,
'orders/by-client-order-id': 7.5,
'orders/history': 7.5,
'orders/history/by-client-order-id': 7.5,
'orders/history_offset': 7.5,
'orders/{id}': 7.5,
'trades': 7.5,
'trades/history': 7.5,
'trades/time': 7.5,
'trigger-orders': 7.5,
'account/airdrops': 7.5,
'account/balance-updates': 7.5,
'account/balances': 7.5,
'account/balances/ll': 7.5,
'account/balances/history': 7.5,
'account/balances/commissions': 7.5,
'account/deposit/addresses': 7.5,
'account/deposits': 7.5,
'account/fees': 7.5,
'account/funding-rate-payments': 7.5,
'account/leverage': 7.5,
'account/lsp-assignments': 7.5,
'account/margin': 7.5,
'account/margin/all': 7.5,
'account/notifications': 7.5,
'account/position-updates': 7.5,
'account/positions': 7.5,
'account/realized-pnl': 7.5,
'account/rebates': 7.5,
'account/referral-links': 7.5,
'account/sessions': 7.5,
'account/settings': 7.5,
'account/settings/price-alert': 7.5,
'account/transfers': 7.5,
'account/unsubscribe': 7.5,
'account/watchlist': 7.5,
'account/withdrawal/addresses': 7.5,
'account/withdrawal/addresses/{id}': 7.5,
'account/withdrawals': 7.5,
'subaccounts': 7.5,
'airdrop': 7.5,
'airdrop/claim': 7.5,
'affiliate-dashboard/commission-earned': 7.5,
'affiliate-dashboard/min-arkm-last-30d': 7.5,
'affiliate-dashboard/points': 7.5,
'affiliate-dashboard/points-season-1': 7.5,
'affiliate-dashboard/points-season-2': 7.5,
'affiliate-dashboard/realized-pnl': 7.5,
'affiliate-dashboard/rebate-balance': 7.5,
'affiliate-dashboard/referral-count': 7.5,
'affiliate-dashboard/referrals-season-1': 7.5,
'affiliate-dashboard/referrals-season-2': 7.5,
'affiliate-dashboard/trading-volume-stats': 7.5,
'affiliate-dashboard/volume-season-1': 7.5,
'affiliate-dashboard/volume-season-2': 7.5,
'affiliate-dashboard/api-key': 7.5,
'competitions/opt-in-status': 7.5,
'rewards/info': 7.5,
'rewards/vouchers': 7.5,
},
'post': {
'orders/new': 7.5,
'trigger-orders/new': 7.5,
'orders/cancel': 7.5,
'trigger-orders/cancel': 7.5,
'orders/cancel/all': 7.5,
'trigger-orders/cancel/all': 7.5,
'orders/new/simple': 7.5,
'account/deposit/addresses/new': 7.5,
'account/leverage': 7.5,
'account/notifications/read': 7.5,
'account/referral-links': 7.5,
'account/sessions/delete': 7.5,
'account/sessions/terminate-all': 7.5,
'account/settings/update': 7.5,
'account/watchlist/add': 7.5,
'account/watchlist/remove': 7.5,
'account/withdraw': 7.5,
'account/withdrawal/addresses/confirm': 7.5,
'subaccounts': 7.5,
'subaccounts/transfer': 7.5,
'subaccounts/perp-transfer': 7.5,
'subaccounts/update-settings': 7.5,
'airdrop': 7.5,
'api-key/create': 7.5,
'authenticate': 7.5,
'competitions/opt-in': 7.5,
'rewards/vouchers/claim': 7.5,
},
'put': {
'account/referral-links/{id}/slug': 7.5,
'account/settings/price-alert': 7.5,
'account/withdrawal/addresses/{id}': 7.5,
'subaccounts': 7.5,
'api-key/update/{id}': 7.5,
},
'delete': {
'account/settings/price-alert': 7.5,
'account/withdrawal/addresses/{id}': 7.5,
'subaccounts/{subaccountId}': 7.5,
'api-key/{id}': 7.5,
},
},
},
},
'options': {
'networks': {
'ETH': 'ETH',
'ERC20': 'ETH',
'BTC': 'BTC',
'SOL': 'SOL',
'TON': 'TON',
'DOGE': 'DOGE',
'SUI': 'SUI',
'XRP': 'XRP',
'OP': 'OP',
'AVAXC': 'AVAX',
'ARBONE': 'ARB',
},
'networksById': {
'ETH': 'ERC20',
'ERC20': 'ERC20',
},
'requestExpiration': 5000,
'timeframeDurations': {
'1m': 60000000,
'5m': 300000000,
'15m': 900000000,
'30m': 1800000000,
'1h': 3600000000,
'6h': 21600000000,
'1d': 86400000000,
},
},
'features': {
'default': {
'sandbox': false,
'createOrder': {
'marginMode': false,
'triggerPrice': true,
'triggerPriceType': {
'mark': true,
'index': true,
'last': true,
},
'triggerDirection': true,
'stopLossPrice': true,
'takeProfitPrice': true,
'attachedStopLossTakeProfit': undefined,
'timeInForce': {
'IOC': true,
'FOK': true,
'PO': true,
'GTD': false,
},
'hedged': false,
'selfTradePrevention': false,
'trailing': false,
'iceberg': false,
'leverage': false,
'marketBuyByCost': false,
'marketBuyRequiresPrice': false,
},
'createOrders': undefined,
'fetchMyTrades': {
'marginMode': false,
'limit': 100,
'daysBack': undefined,
'untilDays': 1,
'symbolRequired': false,
},
'fetchOrder': {
'marginMode': false,
'trigger': false,
'trailing': false,
'symbolRequired': false,
},
'fetchOpenOrders': {
'marginMode': true,
'limit': undefined,
'trigger': false,
'trailing': false,
'symbolRequired': false,
},
'fetchOrders': undefined,
'fetchClosedOrders': {
'marginMode': false,
'limit': 100,
'daysBack': undefined,
'daysBackCanceled': undefined,
'untilDays': undefined,
'trigger': false,
'trailing': false,
'symbolRequired': false,
},
'fetchOHLCV': {
'limit': 365,
},
},
'spot': {
'extends': 'default',
},
'swap': {
'linear': {
'extends': 'default',
},
'inverse': undefined,
},
'future': {
'linear': {
'extends': 'default',
},
'inverse': undefined,
},
},
'precisionMode': number.TICK_SIZE,
'exceptions': {
'exact': {
// 1XXXX General Errors
// These errors can occur for a variety of reasons and may be returned by the API or Websocket on any endpoint.
'10000': errors.OperationFailed,
'10001': errors.BadRequest,
'10002': errors.AuthenticationError,
'10003': errors.BadSymbol,
'10004': errors.ArgumentsRequired,
'10005': errors.RateLimitExceeded,
'10006': errors.PermissionDenied,
'10007': errors.PermissionDenied,
'10008': errors.RateLimitExceeded,
'10009': errors.PermissionDenied,
'10010': errors.PermissionDenied,
'10011': errors.AuthenticationError,
'10012': errors.PermissionDenied,
'10013': errors.PermissionDenied,
'10014': errors.AuthenticationError,
'10015': errors.PermissionDenied,
'10016': errors.PermissionDenied,
'10017': errors.PermissionDenied,
'10018': errors.AuthenticationError,
'10019': errors.AuthenticationError,
'10020': errors.PermissionDenied,
'10021': errors.PermissionDenied,
'10022': errors.ExchangeError,
'10023': errors.BadRequest,
'10024': errors.ExchangeError,
'10025': errors.BadRequest,
// #2XXXX General Websocket Errors
'20001': errors.BadRequest,
'20002': errors.ArgumentsRequired,
'20003': errors.BadRequest,
'20004': errors.ArgumentsRequired,
'20005': errors.BadRequest,
// #3XXXX Trading Errors
'30001': errors.InvalidOrder,
'30002': errors.InvalidOrder,
'30003': errors.InvalidOrder,
'30004': errors.InvalidOrder,
'30005': errors.InvalidOrder,
'30006': errors.InvalidOrder,
'30007': errors.BadSymbol,
'30008': errors.OperationRejected,
'30009': errors.OperationRejected,
'30010': errors.InsufficientFunds,
'30011': errors.BadSymbol,
'30012': errors.OperationRejected,
'30013': errors.OperationRejected,
'30014': errors.InvalidOrder,
'30015': errors.OrderNotFound,
'30016': errors.InvalidOrder,
'30017': errors.InvalidOrder,
'30018': errors.InvalidOrder,
'30019': errors.OperationRejected,
'30020': errors.InvalidOrder,
'30021': errors.InvalidOrder,
'30022': errors.InvalidOrder,
'30023': errors.InvalidOrder,
'30024': errors.InvalidOrder,
'30025': errors.BadRequest,
'30026': errors.PermissionDenied,
'30027': errors.PermissionDenied,
'30028': errors.OrderNotFound,
// #4XXXX Funding Errors
'40001': errors.OperationRejected,
'40002': errors.BadRequest,
'40003': errors.InvalidAddress,
'40004': errors.OperationRejected,
'40005': errors.BadRequest,
'40006': errors.PermissionDenied,
'40007': errors.OperationRejected,
'40008': errors.OperationRejected,
'40009': errors.OperationRejected,
'40010': errors.BadRequest,
'40011': errors.OperationRejected,
'40012': errors.BadRequest,
'40013': errors.BadRequest,
// #9XXXX Other Errors
'90001': errors.BadRequest,
'90002': errors.BadRequest,
'90003': errors.OperationRejected,
'90004': errors.BadRequest,
'90005': errors.BadRequest,
'90006': errors.RateLimitExceeded,
'90007': errors.AuthenticationError,
'90008': errors.RateLimitExceeded,
'90009': errors.PermissionDenied,
'90010': errors.BadRequest,
'90011': errors.RateLimitExceeded,
},
'broad': {
'less than min withdrawal ': errors.OperationRejected, // {"message":"amount 1 less than min withdrawal 5"}
},
},
});
}
/**
* @method
* @name arkham#fetchCurrencies
* @description fetches all available currencies on an exchange
* @see https://arkm.com/docs#get/public/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.v1PublicGetAssets(params);
//
// [
// {
// "symbol": "USDT",
// "name": "Tether",
// "imageUrl": "https://static.arkhamintelligence.com/tokens/tether.png",
// "stablecoin": true,
// "featuredPair": "BTC_USDT",
// "chains": [
// {
// "symbol": "ETH",
// "assetSymbol": "ETH",
// "name": "Ethereum",
// "type": "1",
// "confirmations": "6",
// "blockTime": "12000000"
// }
// ],
// "status": "listed",
// "minDeposit": "5",
// "minWithdrawal": "5",
// "withdrawalFee": "2"
// },
// ...
//
const result = {};
for (let i = 0; i < response.length; i++) {
const currency = response[i];
const id = this.safeString(currency, 'symbol');
const code = this.safeCurrencyCode(id);
const networks = {};
const chains = this.safeList(currency, 'chains', []);
for (let j = 0; j < chains.length; j++) {
const chain = chains[j];
const networkId = this.safeString(chain, 'symbol');
const network = this.networkIdToCode(networkId);
networks[network] = {
'info': chain,
'id': networkId,
'network': network,
'title': this.safeString(chain, 'name'),
'active': undefined,
'deposit': undefined,
'withdraw': undefined,
'fee': undefined,
'precision': undefined,
'limits': {
'withdraw': {
'min': undefined,
'max': undefined,
},
},
};
}
result[code] = this.safeCurrencyStructure({
'info': currency,
'id': id,
'code': code,
'name': this.safeString(currency, 'name'),
'active': this.safeString(currency, 'status') === 'listed',
'deposit': undefined,
'withdraw': undefined,
'fee': this.safeNumber(currency, 'withdrawalFee'),
'precision': undefined,
'limits': {
'amount': {
'min': undefined,
'max': undefined,
},
'withdraw': {
'min': this.safeNumber(currency, 'minWithdrawal'),
'max': undefined,
},
'deposit': {
'min': this.safeNumber(currency, 'minDeposit'),
'max': undefined,
},
},
'type': 'crypto',
'networks': networks,
});
}
return result;
}
/**
* @method
* @name arkham#fetchMarkets
* @see https://arkm.com/docs#get/public/pairs
* @description retrieves data on all markets for arkm
* @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.v1PublicGetPairs(params);
//
// [
// {
// "symbol": "BTC_USDT",
// "baseSymbol": "BTC",
// "baseImageUrl": "https://static.arkhamintelligence.com/tokens/bitcoin.png",
// "baseIsStablecoin": false,
// "baseName": "Bitcoin",
// "quoteSymbol": "USDT",
// "quoteImageUrl": "https://static.arkhamintelligence.com/tokens/tether.png",
// "quoteIsStablecoin": true,
// "quoteName": "Tether",
// "minTickPrice": "0.01",
// "minLotSize": "0.00001",
// "minSize": "0.00001",
// "maxSize": "9000",
// "minPrice": "0.01",
// "maxPrice": "1000000",
// "minNotional": "5",
// "maxPriceScalarUp": "1.8",
// "maxPriceScalarDown": "0.2",
// "pairType": "spot", // atm, always 'spot' value
// "maxLeverage": "0",
// "status": "listed"
// },
// {
// "symbol": "BTC_USDT_PERP",
// "baseSymbol": "BTC.P",
// "baseImageUrl": "https://static.arkhamintelligence.com/tokens/bitcoin.png",
// "baseIsStablecoin": false,
// "baseName": "Bitcoin Perpetual",
// "quoteSymbol": "USDT",
// "quoteImageUrl": "https://static.arkhamintelligence.com/tokens/tether.png",
// "quoteIsStablecoin": true,
// "quoteName": "Tether",
// "minTickPrice": "0.01",
// "minLotSize": "0.00001",
// "minSize": "0.00001",
// "maxSize": "9000",
// "minPrice": "0.01",
// "maxPrice": "1000000",
// "minNotional": "5",
// "maxPriceScalarUp": "1.5",
// "maxPriceScalarDown": "0.5",
// "pairType": "perpetual",
// "marginSchedule": "C",
// "maxLeverage": "25",
// "status": "listed"
// },
// ...
//
const result = [];
for (let i = 0; i < response.length; i++) {
const market = response[i];
const id = this.safeString(market, 'symbol');
const baseId = this.safeString(market, 'baseSymbol');
const quoteId = this.safeString(market, 'quoteSymbol');
let base = this.safeCurrencyCode(baseId);
const quote = this.safeCurrencyCode(quoteId);
let marketType = undefined;
let symbol = undefined;
const pairType = this.safeString(market, 'pairType');
const isSpot = pairType === 'spot';
const isPerpetual = pairType === 'perpetual';
let settle = undefined;
let settleId = undefined;
if (isSpot) {
marketType = 'spot';
symbol = base + '/' + quote;
}
else if (isPerpetual) {
marketType = 'swap';
base = base.replace('.P', '');
settle = quote;
settleId = quoteId;
symbol = base + '/' + quote + ':' + settle;
}
result.push({
'id': id,
'symbol': symbol,
'base': base,
'quote': quote,
'settle': settle,
'baseId': baseId,
'quoteId': quoteId,
'settleId': settleId,
'type': marketType,
'spot': isSpot,
'margin': undefined,
'swap': isPerpetual,
'future': false,
'option': false,
'active': this.safeString(market, 'status') === 'listed',
'contract': isPerpetual,
'linear': isPerpetual ? true : undefined,
'inverse': isPerpetual ? false : undefined,
'contractSize': isSpot ? undefined : 1,
'expiry': undefined,
'expiryDatetime': undefined,
'strike': undefined,
'optionType': undefined,
'precision': {
'price': this.safeNumber(market, 'minTickPrice'),
'amount': this.safeNumber(market, 'minLotSize'),
},
'limits': {
'leverage': {
'min': undefined,
'max': undefined,
},
'amount': {
'min': this.safeNumber(market, 'minSize'),
'max': this.safeNumber(market, 'maxSize'),
},
'price': {
'min': this.safeNumber(market, 'minPrice'),
'max': this.safeNumber(market, 'maxPrice'),
},
'cost': {
'min': this.safeNumber(market, 'minNotional'),
'max': undefined,
},
},
'created': undefined,
'info': market,
});
}
return result;
}
/**
* @method
* @name arkham#fetchTime
* @description fetches the current integer timestamp in milliseconds from the exchange server
* @see https://arkm.com/docs#get/public/server-time
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {int} the current integer timestamp in milliseconds from the exchange server
*/
async fetchTime(params = {}) {
const response = await this.v1PublicGetServerTime(params);
//
// {
// "serverTime": "1753465832770820"
// }
//
return this.safeIntegerProduct(response, 'serverTime', 0.001);
}
/**
* @method
* @name arkham#fetchOrderBook
* @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
* @see https://arkm.com/docs#get/public/book
* @param {string} symbol unified symbol of the market to fetch the order book for
* @param {int} [limit] the number of order book entries to return, max 50
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
*/
async fetchOrderBook(symbol, limit = undefined, params = {}) {
await this.loadMarkets();
const market = this.market(symbol);
const request = {
'symbol': market['id'],
};
if (limit !== undefined) {
request['limit'] = limit;
}
const response = await this.v1PublicGetBook(this.extend(request, params));
//
// {
// "symbol": "BTC_USDT",
// "group": "0.01",
// "asks": [
// {
// "price": "122900.43",
// "size": "0.0243"
// },
// {
// "price": "121885.53",
// "size": "0.00116"
// },
// ...
// ],
// "bids": [
// {
// "price": "20400",
// "size": "0.00316"
// },
// {
// "price": "30000",
// "size": "0.00116"
// },
// ...
// ],
// "lastTime": "1753419275604353"
// }
//
const timestamp = this.safeIntegerProduct(response, 'lastTime', 0.001);
const marketId = this.safeString(response, 'symbol');
return this.parseOrderBook(response, this.safeSymbol(marketId, market), timestamp, 'bids', 'asks', 'price', 'size');
}
/**
* @method
* @name arkham#fetchOHLCV
* @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
* @see https://arkm.com/docs#get/public/candles
* @param {string} symbol unified symbol of the market to fetch OHLCV data for
* @param {string} timeframe the length of time each candle represents
* @param {int} [since] timestamp in ms of the earliest candle to fetch
* @param {int} [limit] the maximum amount of candles to fetch
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @param {int} [params.until] timestamp in ms for the ending date filter, default is the current time
* @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
*/
async fetchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
const maxLimit = 365;
await this.loadMarkets();
let paginate = false;
[paginate, params] = this.handleOptionAndParams(params, 'fetchOHLCV', 'paginate', false);
if (paginate) {
return await this.fetchPaginatedCallDeterministic('fetchOHLCV', symbol, since, limit, timeframe, params, maxLimit);
}
const market = this.market(symbol);
const request = {
'symbol': market['id'],
'duration': this.safeString(this.timeframes, timeframe, timeframe),
};
const durationMs = this.parseTimeframe(timeframe) * 1000;
const until = this.safeInteger(params, 'until');
params = this.omit(params, ['until']);
const selectedLimit = (limit !== undefined) ? Math.min(limit, maxLimit) : maxLimit;
if (since !== undefined) {
request['start'] = since;
request['end'] = this.sum(since, selectedLimit * durationMs);
}
else {
const now = this.milliseconds();
request['end'] = (until !== undefined) ? until : now;
request['start'] = request['end'] - selectedLimit * durationMs;
}
// exchange needs microseconds
request['start'] = request['start'] * 1000;
request['end'] = request['end'] * 1000;
const response = await this.v1PublicGetCandles(this.extend(request, params));
//
// [
// {
// "symbol": "BTC_USDT_PERP",
// "time": "1753464720000000",
// "duration": "60000000",
// "open": "116051.35",
// "high": "116060.27",
// "low": "116051.35",
// "close": "116060.27",
// "volume": "0.0257",
// "quoteVolume": "2982.6724054"
// },
// ...
// ]
//
return this.parseOHLCVs(response, market, timeframe, since, limit);
}
parseOHLCV(ohlcv, market = undefined) {
//
// {
// "symbol": "BTC_USDT_PERP",
// "time": "1753464720000000",
// "duration": "60000000",
// "open": "116051.35",
// "high": "116060.27",
// "low": "116051.35",
// "close": "116060.27",
// "volume": "0.0257",
// "quoteVolume": "2982.6724054"
// }
//
return [
this.safeIntegerProduct(ohlcv, 'time', 0.001),
this.safeNumber(ohlcv, 'open'),
this.safeNumber(ohlcv, 'high'),
this.safeNumber(ohlcv, 'low'),
this.safeNumber(ohlcv, 'close'),
this.safeNumber(ohlcv, 'volume'),
];
}
async fetchTickers(symbols = undefined, params = {}) {
const response = await this.v1PublicGetTickers(params);
//
// [
// {
// "symbol": "BTC_USDT_PERP",
// "baseSymbol": "BTC.P",
// "quoteSymbol": "USDT",
// "indexCurrency": "USDT",
// "price": "118806.89",
// "price24hAgo": "118212.29",
// "high24h": "119468.05",
// "low24h": "117104.44",
// "volume24h": "180.99438",
// "quoteVolume24h": "21430157.5928827",
// "markPrice": "118814.71",
// "indexPrice": "118804.222610343",
// "fundingRate": "0.000007",
// "nextFundingRate": "0.000006",
// "nextFundingTime": "1753390800000000",
// "productType": "perpetual",
// "openInterest": "2.55847",
// "usdVolume24h": "21430157.5928827",
// "openInterestUSD": "303963.8638583"
// },
// ...
//
return this.parseTickers(response, symbols);
}
/**
* @method
* @name arkham#fetchTicker
* @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
* @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.v1PublicGetTicker(this.extend(request, params));
//
// {
// "symbol": "BTC_USDT_PERP",
// "baseSymbol": "BTC.P",
// "quoteSymbol": "USDT",
// "indexCurrency": "USDT",
// "price": "118806.89",
// "price24hAgo": "118212.29",
// "high24h": "119468.05",
// "low24h": "117104.44",
// "volume24h": "180.99438",
// "quoteVolume24h": "21430157.5928827",
// "markPrice": "118814.71",
// "indexPrice": "118804.222610343",
// "fundingRate": "0.000007",
// "nextFundingRate": "0.000006",
// "nextFundingTime": "1753390800000000",
// "productType": "perpetual",
// "openInterest": "2.55847",
// "usdVolume24h": "21430157.5928827",
// "openInterestUSD": "303963.8638583"
// }
//
return this.parseTicker(response, market);
}
parseTicker(ticker, market = undefined) {
const marketId = this.safeString(ticker, 'symbol');
market = this.safeMarket(marketId, market);
return this.safeTicker({
'info': ticker,
'symbol': this.safeSymbol(marketId, market),
'high': this.safeNumber(ticker, 'high24h'),
'low': this.safeNumber(ticker, 'low24h'),
'bid': this.safeNumber(ticker, 'bid'),
'last': this.safeNumber(ticker, 'price'),
'open': this.safeNumber(ticker, 'price24hAgo'),
'change': this.safeNumber(ticker, 'priceChange'),
'percentage': this.safeNumber(ticker, 'priceChangePercent'),
'baseVolume': this.safeNumber(ticker, 'volume24h'),
'quoteVolume': this.safeNumber(ticker, 'usdVolume24h'),
'markPrice': this.safeNumber(ticker, 'markPrice'),
'indexPrice': this.safeNumber(ticker, 'indexPrice'),
'vwap': undefined,
'average': undefined,
'previousClose': undefined,
'askVolume': undefined,
'bidVolume': undefined,
});
}
/**
* @method
* @name arkham#fetchTrades
* @description get the list of most recent trades for a particular symbol
* @see https://arkm.com/docs#get/public/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 {string} [params.loc] crypto location, default: us
* @param {string} [params.method] method, default: marketPublicGetV1beta3CryptoLocTrades
* @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 marketId = market['id'];
const request = {
'symbol': marketId,
};
if (limit !== undefined) {
request['limit'] = limit;
}
const response = await this.v1PublicGetTrades(this.extend(request, params));
//
// [
// {
// "symbol": "BTC_USDT_PERP",
// "revisionId": "1130514101",
// "size": "0.01668",
// "price": "116309.57",
// "takerSide": "sell",
// "time": "1753439710374047"
// },
// ...
// ]
//
return this.parseTrades(response, market, since, limit);
}
parseTrade(trade, market = undefined) {
//
// fetchTrades
//
// {
// "symbol": "BTC_USDT_PERP",
// "revisionId": "1130514101",
// "size": "0.01668",
// "price": "116309.57",
// "takerSide": "sell",
// "time": "1753439710374047"
// }
//
// fetchMyTrades
//
// {
// "symbol": "SOL_USDT",
// "revisionId": "891839406",
// "size": "0.042",
// "price": "185.06",
// "takerSide": "sell",
// "time": "1753773952039342",
// "orderId": "3717304929194",
// "userSide": "sell",
// "quoteFee": "0.00777252",
// "arkmFee": "0",
// "clientOrderId": ""
// }
//
const marketId = this.safeString(trade, 'symbol');
market = this.safeMarket(marketId, market);
const timestamp = this.safeIntegerProduct(trade, 'time', 0.001);
const quoteFee = this.safeNumber(trade, 'quoteFee');
const arkmFee = this.safeNumber(trade, 'arkmFee');
let fee = undefined;
if (quoteFee !== undefined) {
fee = {
'cost': quoteFee,
'currency': market['quote'],
};
}
else if (arkmFee !== undefined) {
fee = {
'cost': arkmFee,
'currency': 'ARKM',
};
}
return this.safeTrade({
'info': trade,
'id': this.safeString(trade, 'revisionId'),
'timestamp': timestamp,
'datetime': this.iso8601(timestamp),
'symbol': market['symbol'],
'type': undefined,
'side': this.safeString2(trade, 'userSide', 'takerSide'),
'takerOrMaker': undefined,
'price': this.safeString(trade, 'price'),
'amount': this.safeString(trade, 'size'),
'cost': undefined,
'fee': fee,
'order': this.safeString(trade, 'orderId'),
}, market);
}
/**
* @method
* @name arkmm#fetchOrder
* @description fetches information on an order made by the user
* @see https://arkm.com/docs#get/orders/by-client-order-id
* @param {string} id the order id
* @param {string} symbol unified symbol of the market the order was made in
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @param {string} [params.clientOrderId] a unique id for the order
* @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
*/
async fetchOrder(id, symbol = undefined, params = {}) {
const request = {
'id': parseInt(id),
};
const response = await this.v1PrivateGetOrdersId(this.extend(request, params));
//
// {
// "orderId": "3690478767430",
// "userId": "2959123",
// "subaccountId": "0",
// "symbol": "SOL_USDT",
// "time": "1753696843913970",
// "side": "sell",
// "type": "limitGtc",
// "size": "0.066",
// "price": "293.2",
// "postOnly": false,
// "reduceOnly": false,
// "executedSize": "0",
// "status": "booked",
// "avgPrice": "0",
// "executedNotional": "0",
// "creditFeePaid": "0",
// "marginBonusFeePaid": "0",
// "quoteFeePaid": "0",
// "arkmFeePaid": "0",
// "revisionId": "887956326",
// "lastTime": "1753696843914830",
// "clientOrderId": "",
// "lastSize": "0",
// "lastPrice": "0",
// "lastCreditFee": "0",
// "lastMarginBonusFee": "0",
// "lastQuoteFee": "0",
// "lastArkmFee": "0"
// }
//
return this.parseOrder(response);
}
/**
* @method
* @name arkham#fetchClosedOrders
* @description fetches information on multiple closed orders made by the user
* @see https://arkm.com/docs#get/orders/history
* @param {string} symbol unified market symbol of the market orders were made in
* @param {int} [since] the earliest time in ms to fetch orders for
* @param {int} [limit] the maximum number of order 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 orders for
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
*/
async fetchClosedOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
await this.loadMarkets();
const request = {};
let market = undefined;
if (symbol !== undefined) {
market = this.market(symbol);
request['symbol'] = market['id'];
}
if (limit !== undefined) {
request['limit'] = limit; // note, API does not work for this param
}
const response = await this.v1PrivateGetOrdersHistory(this.extend(request, params));
//
// [
// {
// "orderId": "3690478767430",
// "userId": "2959123",
// "subaccountId": "0",
// "symbol": "SOL_USDT",
// "time": "1753696843913970",
// "side": "sell",
// "type": "limitGtc",
// "size": "0.066",
// "price": "293.2",
// "postOnly": false,
// "reduceOnly": false,
// "executedSize": "0",
// "status": "closed",
// "avgPrice": "0",
// "executedNotional": "0",
// "creditFeePaid": "0",
// "marginBonusFeePaid": "0",
// "quoteFeePaid": "0",
// "arkmFeePaid": "0",
// "revisionId": "888084076",
// "lastTime": "1753701350088305",
// "clientOrderId": "",
// "lastSize": "0",
// "lastPrice": "0",
// "lastCreditFee": "0",
// "lastMarginBonusFee": "0",
// "lastQuoteFee": "0",
// "lastArkmFee": "0"
// }
// ]
//
return this.parseOrders(response, market, since, limit);
}
/**
* @method
* @name arkham#fetchOpenOrders
* @description fetch all unfilled currently open orders
* @see https://arkm.com/docs#get/orders
* @param {string} symbol unified market symbol of the market orders were made in
* @param {int} [since] the earliest time in ms to fetch orders for
* @param {int} [limit] the maximum number of order structures to retrieve
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @param {int} [params.until] the latest time in