ccxt
Version:
1,204 lines (1,202 loc) • 159 kB
JavaScript
// ----------------------------------------------------------------------------
// PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
// https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
// EDIT THE CORRESPONDENT .ts FILE INSTEAD
// ---------------------------------------------------------------------------
import Exchange from './abstract/poloniex.js';
import { ArgumentsRequired, ExchangeError, ExchangeNotAvailable, NotSupported, RequestTimeout, AuthenticationError, PermissionDenied, InsufficientFunds, OrderNotFound, InvalidOrder, AccountSuspended, OnMaintenance, BadSymbol, BadRequest } from './base/errors.js';
import { Precise } from './base/Precise.js';
import { TICK_SIZE } from './base/functions/number.js';
import { sha256 } from './static_dependencies/noble-hashes/sha256.js';
// ---------------------------------------------------------------------------
/**
* @class poloniex
* @augments Exchange
*/
export default class poloniex extends Exchange {
describe() {
return this.deepExtend(super.describe(), {
'id': 'poloniex',
'name': 'Poloniex',
'countries': ['US'],
// 200 requests per second for some unauthenticated market endpoints => 1000ms / 200 = 5ms between requests
'rateLimit': 5,
'certified': false,
'pro': true,
'has': {
'CORS': undefined,
'spot': true,
'margin': undefined,
'swap': true,
'future': true,
'option': false,
'addMargin': true,
'cancelAllOrders': true,
'cancelOrder': true,
'cancelOrders': undefined,
'createDepositAddress': true,
'createMarketBuyOrderWithCost': true,
'createMarketOrderWithCost': false,
'createMarketSellOrderWithCost': false,
'createOrder': true,
'createOrders': undefined,
'createStopOrder': true,
'createTriggerOrder': true,
'editOrder': true,
'fetchBalance': true,
'fetchClosedOrder': false,
'fetchClosedOrders': true,
'fetchCurrencies': true,
'fetchDepositAddress': true,
'fetchDepositAddresses': false,
'fetchDepositAddressesByNetwork': false,
'fetchDeposits': true,
'fetchDepositsWithdrawals': true,
'fetchDepositWithdrawFee': 'emulated',
'fetchDepositWithdrawFees': true,
'fetchFundingHistory': false,
'fetchFundingInterval': false,
'fetchFundingIntervals': false,
'fetchFundingRate': false,
'fetchFundingRateHistory': false,
'fetchFundingRates': undefined,
'fetchLedger': undefined,
'fetchLeverage': true,
'fetchLiquidations': undefined,
'fetchMarginMode': false,
'fetchMarkets': true,
'fetchMyTrades': true,
'fetchOHLCV': true,
'fetchOpenInterestHistory': false,
'fetchOpenOrder': false,
'fetchOpenOrders': true,
'fetchOrder': true,
'fetchOrderBook': true,
'fetchOrderBooks': false,
'fetchOrderTrades': true,
'fetchPosition': false,
'fetchPositionMode': true,
'fetchPositions': true,
'fetchTicker': true,
'fetchTickers': true,
'fetchTime': true,
'fetchTrades': true,
'fetchTradingFee': false,
'fetchTradingFees': true,
'fetchTransactions': 'emulated',
'fetchTransfer': false,
'fetchTransfers': false,
'fetchWithdrawals': true,
'reduceMargin': true,
'sandbox': true,
'setLeverage': true,
'setPositionMode': true,
'transfer': true,
'withdraw': true,
},
'timeframes': {
'1m': 'MINUTE_1',
'5m': 'MINUTE_5',
'10m': 'MINUTE_10',
'15m': 'MINUTE_15',
'30m': 'MINUTE_30',
'1h': 'HOUR_1',
'2h': 'HOUR_2',
'4h': 'HOUR_4',
'6h': 'HOUR_6',
'12h': 'HOUR_12',
'1d': 'DAY_1',
'3d': 'DAY_3',
'1w': 'WEEK_1',
'1M': 'MONTH_1', // not in swap
},
'urls': {
'logo': 'https://user-images.githubusercontent.com/1294454/27766817-e9456312-5ee6-11e7-9b3c-b628ca5626a5.jpg',
'api': {
'spot': 'https://api.poloniex.com',
'swap': 'https://api.poloniex.com',
},
'test': {
'spot': 'https://sand-spot-api-gateway.poloniex.com',
},
'www': 'https://www.poloniex.com',
'doc': 'https://api-docs.poloniex.com/spot/',
'fees': 'https://poloniex.com/fees',
'referral': 'https://poloniex.com/signup?c=UBFZJRPJ',
},
'api': {
'public': {
'get': {
'markets': 20,
'markets/{symbol}': 1,
'currencies': 20,
'currencies/{currency}': 20,
'v2/currencies': 20,
'v2/currencies/{currency}': 20,
'timestamp': 1,
'markets/price': 1,
'markets/{symbol}/price': 1,
'markets/markPrice': 1,
'markets/{symbol}/markPrice': 1,
'markets/{symbol}/markPriceComponents': 1,
'markets/{symbol}/orderBook': 1,
'markets/{symbol}/candles': 1,
'markets/{symbol}/trades': 20,
'markets/ticker24h': 20,
'markets/{symbol}/ticker24h': 20,
'markets/collateralInfo': 1,
'markets/{currency}/collateralInfo': 1,
'markets/borrowRatesInfo': 1,
},
},
'private': {
'get': {
'accounts': 4,
'accounts/balances': 4,
'accounts/{id}/balances': 4,
'accounts/activity': 20,
'accounts/transfer': 20,
'accounts/transfer/{id}': 4,
'feeinfo': 20,
'accounts/interest/history': 1,
'subaccounts': 4,
'subaccounts/balances': 20,
'subaccounts/{id}/balances': 4,
'subaccounts/transfer': 20,
'subaccounts/transfer/{id}': 4,
'wallets/addresses': 20,
'wallets/addresses/{currency}': 20,
'wallets/activity': 20,
'margin/accountMargin': 4,
'margin/borrowStatus': 4,
'margin/maxSize': 4,
'orders': 20,
'orders/{id}': 4,
'orders/killSwitchStatus': 4,
'smartorders': 20,
'smartorders/{id}': 4,
'orders/history': 20,
'smartorders/history': 20,
'trades': 20,
'orders/{id}/trades': 4,
},
'post': {
'accounts/transfer': 4,
'subaccounts/transfer': 20,
'wallets/address': 20,
'wallets/withdraw': 20,
'v2/wallets/withdraw': 20,
'orders': 4,
'orders/batch': 20,
'orders/killSwitch': 4,
'smartorders': 4,
},
'delete': {
'orders/{id}': 4,
'orders/cancelByIds': 20,
'orders': 20,
'smartorders/{id}': 4,
'smartorders/cancelByIds': 20,
'smartorders': 20,
},
'put': {
'orders/{id}': 20,
'smartorders/{id}': 20,
},
},
'swapPublic': {
'get': {
// 300 calls / second
'v3/market/allInstruments': 2 / 3,
'v3/market/instruments': 2 / 3,
'v3/market/orderBook': 2 / 3,
'v3/market/candles': 10,
'v3/market/indexPriceCandlesticks': 10,
'v3/market/premiumIndexCandlesticks': 10,
'v3/market/markPriceCandlesticks': 10,
'v3/market/trades': 2 / 3,
'v3/market/liquidationOrder': 2 / 3,
'v3/market/tickers': 2 / 3,
'v3/market/markPrice': 2 / 3,
'v3/market/indexPrice': 2 / 3,
'v3/market/indexPriceComponents': 2 / 3,
'v3/market/fundingRate': 2 / 3,
'v3/market/openInterest': 2 / 3,
'v3/market/insurance': 2 / 3,
'v3/market/riskLimit': 2 / 3,
},
},
'swapPrivate': {
'get': {
'v3/account/balance': 4,
'v3/account/bills': 20,
'v3/trade/order/opens': 20,
'v3/trade/order/trades': 20,
'v3/trade/order/history': 20,
'v3/trade/position/opens': 20,
'v3/trade/position/history': 20,
'v3/position/leverages': 20,
'v3/position/mode': 20,
},
'post': {
'v3/trade/order': 4,
'v3/trade/orders': 40,
'v3/trade/position': 20,
'v3/trade/positionAll': 100,
'v3/position/leverage': 20,
'v3/position/mode': 20,
'v3/trade/position/margin': 20,
},
'delete': {
'v3/trade/order': 2,
'v3/trade/batchOrders': 20,
'v3/trade/allOrders': 20,
},
},
},
'fees': {
'trading': {
'feeSide': 'get',
// starting from Jan 8 2020
'maker': this.parseNumber('0.0009'),
'taker': this.parseNumber('0.0009'),
},
'funding': {},
},
'commonCurrencies': {
'AIR': 'AirCoin',
'APH': 'AphroditeCoin',
'BCC': 'BTCtalkcoin',
'BCHABC': 'BCHABC',
'BDG': 'Badgercoin',
'BTM': 'Bitmark',
'CON': 'Coino',
'ETHTRON': 'ETH',
'GOLD': 'GoldEagles',
'GPUC': 'GPU',
'HOT': 'Hotcoin',
'ITC': 'Information Coin',
'KEY': 'KEYCoin',
'MASK': 'NFTX Hashmasks Index',
'MEME': 'Degenerator Meme',
'PLX': 'ParallaxCoin',
'REPV2': 'REP',
'STR': 'XLM',
'SOC': 'SOCC',
'TRADE': 'Unitrade',
'TRXETH': 'TRX',
'XAP': 'API Coin',
// this is not documented in the API docs for Poloniex
// https://github.com/ccxt/ccxt/issues/7084
// when the user calls withdraw ('USDT', amount, address, tag, params)
// with params = { 'currencyToWithdrawAs': 'USDTTRON' }
// or params = { 'currencyToWithdrawAs': 'USDTETH' }
// fetchWithdrawals ('USDT') returns the corresponding withdrawals
// with a USDTTRON or a USDTETH currency id, respectfully
// therefore we have map them back to the original code USDT
// otherwise the returned withdrawals are filtered out
'USDTBSC': 'USDT',
'USDTTRON': 'USDT',
'USDTETH': 'USDT',
'UST': 'USTC',
},
'options': {
'defaultType': 'spot',
'createMarketBuyOrderRequiresPrice': true,
'networks': {
'BEP20': 'BSC',
'ERC20': 'ETH',
'TRC20': 'TRON',
'TRX': 'TRON',
},
'networksById': {
'TRX': 'TRC20',
'TRON': 'TRC20',
},
'limits': {
'cost': {
'min': {
'BTC': 0.0001,
'ETH': 0.0001,
'USDT': 1.0,
'TRX': 100,
'BNB': 0.06,
'USDC': 1.0,
'USDJ': 1.0,
'TUSD': 0.0001,
'DAI': 1.0,
'PAX': 1.0,
'BUSD': 1.0,
},
},
},
'accountsByType': {
'spot': 'spot',
'future': 'futures',
},
'accountsById': {
'exchange': 'spot',
'futures': 'future',
},
},
'features': {
'default': {
'sandbox': true,
'createOrder': {
'marginMode': true,
'triggerPrice': true,
'triggerPriceType': undefined,
'triggerDirection': false,
'stopLossPrice': false,
'takeProfitPrice': false,
'attachedStopLossTakeProfit': undefined,
'timeInForce': {
'IOC': true,
'FOK': true,
'PO': true,
'GTD': false,
},
'hedged': false,
'leverage': false,
'marketBuyByCost': true,
'marketBuyRequiresPrice': false,
'selfTradePrevention': true,
'trailing': false,
'iceberg': false,
},
'createOrders': {
'max': 20,
},
'fetchMyTrades': {
'marginMode': false,
'limit': 1000,
'daysBack': 100000,
'untilDays': 100000,
'symbolRequired': false,
},
'fetchOrder': {
'marginMode': false,
'trigger': false,
'trailing': false,
'symbolRequired': false,
},
'fetchOpenOrders': {
'marginMode': false,
'limit': 2000,
'trigger': false,
'trailing': false,
'symbolRequired': false,
},
'fetchOrders': undefined,
'fetchClosedOrders': undefined,
'fetchOHLCV': {
'limit': 500,
},
},
'spot': {
'extends': 'default',
},
'forContracts': {
'extends': 'default',
'createOrder': {
'marginMode': true,
'triggerPrice': false,
'hedged': true,
'stpMode': true,
'marketBuyByCost': false,
},
'createOrders': {
'max': 10,
},
'fetchOpenOrders': {
'limit': 100,
},
'fetchClosedOrders': {
'marginMode': false,
'limit': 100,
'daysBack': undefined,
'daysBackCanceled': 1 / 6,
'untilDays': undefined,
'trigger': false,
'trailing': false,
'symbolRequired': false,
},
'fetchMyTrades': {
'limit': 100,
'untilDays': 90,
},
},
'swap': {
'linear': {
'extends': 'forContracts',
},
'inverse': {
'extends': 'forContracts',
},
},
'future': {
'linear': {
'extends': 'forContracts',
},
'inverse': {
'extends': 'forContracts',
},
},
},
'precisionMode': TICK_SIZE,
'exceptions': {
'exact': {
// General
'500': ExchangeNotAvailable,
'603': RequestTimeout,
'601': BadRequest,
'415': ExchangeError,
'602': ArgumentsRequired,
// Accounts
'21604': BadRequest,
'21600': AuthenticationError,
'21605': AuthenticationError,
'21102': ExchangeError,
'21100': AuthenticationError,
'21704': AuthenticationError,
'21700': BadRequest,
'21705': BadRequest,
'21707': ExchangeError,
'21708': BadRequest,
'21601': AccountSuspended,
'21711': ExchangeError,
'21709': InsufficientFunds,
'250000': ExchangeError,
'250001': BadRequest,
'250002': BadRequest,
'250003': BadRequest,
'250004': BadRequest,
'250005': InsufficientFunds,
'250008': BadRequest,
'250012': ExchangeError,
// Trading
'21110': BadRequest,
'10040': BadSymbol,
'10060': ExchangeError,
'10020': BadSymbol,
'10041': BadSymbol,
'21340': OnMaintenance,
'21341': InvalidOrder,
'21342': InvalidOrder,
'21343': InvalidOrder,
'21351': AccountSuspended,
'21352': BadSymbol,
'21353': PermissionDenied,
'21354': PermissionDenied,
'21359': OrderNotFound,
'21360': InvalidOrder,
'24106': BadRequest,
'24201': ExchangeNotAvailable,
// Orders
'21301': OrderNotFound,
'21302': ExchangeError,
'21304': ExchangeError,
'21305': OrderNotFound,
'21307': ExchangeError,
'21309': InvalidOrder,
'21310': InvalidOrder,
'21311': InvalidOrder,
'21312': InvalidOrder,
'21314': InvalidOrder,
'21315': InvalidOrder,
'21317': InvalidOrder,
'21319': InvalidOrder,
'21320': InvalidOrder,
'21321': InvalidOrder,
'21322': InvalidOrder,
'21324': BadRequest,
'21327': InvalidOrder,
'21328': InvalidOrder,
'21330': InvalidOrder,
'21335': InvalidOrder,
'21336': InvalidOrder,
'21337': InvalidOrder,
'21344': InvalidOrder,
'21345': InvalidOrder,
'21346': InvalidOrder,
'21348': InvalidOrder,
'21347': InvalidOrder,
'21349': InvalidOrder,
'21350': InvalidOrder,
'21355': ExchangeError,
'21356': BadRequest,
'21721': InsufficientFunds,
'24101': BadSymbol,
'24102': InvalidOrder,
'24103': InvalidOrder,
'24104': InvalidOrder,
'24105': InvalidOrder,
'25020': InvalidOrder,
// Smartorders
'25000': InvalidOrder,
'25001': InvalidOrder,
'25002': InvalidOrder,
'25003': ExchangeError,
'25004': InvalidOrder,
'25005': ExchangeError,
'25006': InvalidOrder,
'25007': InvalidOrder,
'25008': InvalidOrder,
'25009': ExchangeError,
'25010': PermissionDenied,
'25011': InvalidOrder,
'25012': ExchangeError,
'25013': OrderNotFound,
'25014': OrderNotFound,
'25015': OrderNotFound,
'25016': ExchangeError,
'25017': ExchangeError,
'25018': BadRequest,
'25019': BadSymbol, // Invalid symbol
},
'broad': {},
},
});
}
parseOHLCV(ohlcv, market = undefined) {
//
// spot:
//
// [
// [
// "22814.01",
// "22937.42",
// "22832.57",
// "22937.42",
// "3916.58764051",
// "0.171199",
// "2982.64647063",
// "0.130295",
// 33,
// 0,
// "22877.449915304470460711",
// "MINUTE_5",
// 1659664800000,
// 1659665099999
// ]
// ]
//
// contract:
//
// [
// "84207.02",
// "84320.85",
// "84207.02",
// "84253.83",
// "3707.5395",
// "44",
// "14",
// "1740770040000",
// "1740770099999",
// ],
//
const ohlcvLength = ohlcv.length;
const isContract = ohlcvLength === 9;
if (isContract) {
return [
this.safeInteger(ohlcv, 7),
this.safeNumber(ohlcv, 2),
this.safeNumber(ohlcv, 1),
this.safeNumber(ohlcv, 0),
this.safeNumber(ohlcv, 3),
this.safeNumber(ohlcv, 5),
];
}
return [
this.safeInteger(ohlcv, 12),
this.safeNumber(ohlcv, 2),
this.safeNumber(ohlcv, 1),
this.safeNumber(ohlcv, 0),
this.safeNumber(ohlcv, 3),
this.safeNumber(ohlcv, 5),
];
}
/**
* @method
* @name poloniex#fetchOHLCV
* @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
* @see https://api-docs.poloniex.com/spot/api/public/market-data#candles
* @see https://api-docs.poloniex.com/v3/futures/api/market/get-kline-data
* @param {string} symbol unified symbol of the market to fetch OHLCV data for
* @param {string} timeframe the length of time each candle represents
* @param {int} [since] timestamp in ms of the earliest candle to fetch
* @param {int} [limit] the maximum amount of candles to fetch
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @param {int} [params.until] timestamp in ms
* @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 = {}) {
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, 500);
}
const market = this.market(symbol);
let request = {
'symbol': market['id'],
'interval': this.safeString(this.timeframes, timeframe, timeframe),
};
const keyStart = market['spot'] ? 'startTime' : 'sTime';
const keyEnd = market['spot'] ? 'endTime' : 'eTime';
if (since !== undefined) {
request[keyStart] = since;
}
if (limit !== undefined) {
// limit should in between 100 and 500
request['limit'] = limit;
}
[request, params] = this.handleUntilOption(keyEnd, request, params);
if (market['contract']) {
if (this.inArray(timeframe, ['10m', '1M'])) {
throw new NotSupported(this.id + ' ' + timeframe + ' ' + market['type'] + ' fetchOHLCV is not supported');
}
const responseRaw = await this.swapPublicGetV3MarketCandles(this.extend(request, params));
//
// {
// code: "200",
// msg: "Success",
// data: [
// [
// "84207.02",
// "84320.85",
// "84207.02",
// "84253.83",
// "3707.5395",
// "44",
// "14",
// "1740770040000",
// "1740770099999",
// ],
//
const data = this.safeList(responseRaw, 'data');
return this.parseOHLCVs(data, market, timeframe, since, limit);
}
const response = await this.publicGetMarketsSymbolCandles(this.extend(request, params));
//
// [
// [
// "22814.01",
// "22937.42",
// "22832.57",
// "22937.42",
// "3916.58764051",
// "0.171199",
// "2982.64647063",
// "0.130295",
// 33,
// 0,
// "22877.449915304470460711",
// "MINUTE_5",
// 1659664800000,
// 1659665099999
// ]
// ]
//
return this.parseOHLCVs(response, market, timeframe, since, limit);
}
async loadMarkets(reload = false, params = {}) {
const markets = await super.loadMarkets(reload, params);
const currenciesByNumericId = this.safeValue(this.options, 'currenciesByNumericId');
if ((currenciesByNumericId === undefined) || reload) {
this.options['currenciesByNumericId'] = this.indexBy(this.currencies, 'numericId');
}
return markets;
}
/**
* @method
* @name poloniex#fetchMarkets
* @description retrieves data on all markets for poloniex
* @see https://api-docs.poloniex.com/spot/api/public/reference-data#symbol-information
* @see https://api-docs.poloniex.com/v3/futures/api/market/get-all-product-info
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {object[]} an array of objects representing market data
*/
async fetchMarkets(params = {}) {
const promises = [this.fetchSpotMarkets(params), this.fetchSwapMarkets(params)];
const results = await Promise.all(promises);
return this.arrayConcat(results[0], results[1]);
}
async fetchSpotMarkets(params = {}) {
const markets = await this.publicGetMarkets(params);
//
// [
// {
// "symbol" : "BTS_BTC",
// "baseCurrencyName" : "BTS",
// "quoteCurrencyName" : "BTC",
// "displayName" : "BTS/BTC",
// "state" : "NORMAL",
// "visibleStartTime" : 1659018816626,
// "tradableStartTime" : 1659018816626,
// "symbolTradeLimit" : {
// "symbol" : "BTS_BTC",
// "priceScale" : 10,
// "quantityScale" : 0,
// "amountScale" : 8,
// "minQuantity" : "100",
// "minAmount" : "0.00001",
// "highestBid" : "0",
// "lowestAsk" : "0"
// }
// }
// ]
//
return this.parseMarkets(markets);
}
async fetchSwapMarkets(params = {}) {
// do similar as spot per https://api-docs.poloniex.com/v3/futures/api/market/get-product-info
const response = await this.swapPublicGetV3MarketAllInstruments(params);
//
// {
// "code": "200",
// "msg": "Success",
// "data": [
// {
// "symbol": "BNB_USDT_PERP",
// "bAsset": ".PBNBUSDT",
// "bCcy": "BNB",
// "qCcy": "USDT",
// "visibleStartTime": "1620390600000",
// "tradableStartTime": "1620390600000",
// "sCcy": "USDT",
// "tSz": "0.001",
// "pxScale": "0.001,0.01,0.1,1,10",
// "lotSz": "1",
// "minSz": "1",
// "ctVal": "0.1",
// "status": "OPEN",
// "oDate": "1620287590000",
// "maxPx": "1000000",
// "minPx": "0.001",
// "maxQty": "1000000",
// "minQty": "1",
// "maxLever": "50",
// "lever": "10",
// "ctType": "LINEAR",
// "alias": "",
// "iM": "0.02",
// "mM": "0.0115",
// "mR": "2000",
// "buyLmt": "",
// "sellLmt": "",
// "ordPxRange": "0.05",
// "marketMaxQty": "2800",
// "limitMaxQty": "1000000"
// },
//
const markets = this.safeList(response, 'data');
return this.parseMarkets(markets);
}
parseMarket(market) {
if ('ctType' in market) {
return this.parseSwapMarket(market);
}
else {
return this.parseSpotMarket(market);
}
}
parseSpotMarket(market) {
const id = this.safeString(market, 'symbol');
const baseId = this.safeString(market, 'baseCurrencyName');
const quoteId = this.safeString(market, 'quoteCurrencyName');
const base = this.safeCurrencyCode(baseId);
const quote = this.safeCurrencyCode(quoteId);
const state = this.safeString(market, 'state');
const active = state === 'NORMAL';
const symbolTradeLimit = this.safeValue(market, 'symbolTradeLimit');
// these are known defaults
return {
'id': id,
'symbol': base + '/' + quote,
'base': base,
'quote': quote,
'settle': undefined,
'baseId': baseId,
'quoteId': quoteId,
'settleId': undefined,
'type': 'spot',
'spot': true,
'margin': false,
'swap': false,
'future': false,
'option': false,
'active': active,
'contract': false,
'linear': undefined,
'inverse': undefined,
'contractSize': undefined,
'expiry': undefined,
'expiryDatetime': undefined,
'strike': undefined,
'optionType': undefined,
'precision': {
'amount': this.parseNumber(this.parsePrecision(this.safeString(symbolTradeLimit, 'quantityScale'))),
'price': this.parseNumber(this.parsePrecision(this.safeString(symbolTradeLimit, 'priceScale'))),
},
'limits': {
'amount': {
'min': this.safeNumber(symbolTradeLimit, 'minQuantity'),
'max': undefined,
},
'price': {
'min': undefined,
'max': undefined,
},
'cost': {
'min': this.safeNumber(symbolTradeLimit, 'minAmount'),
'max': undefined,
},
},
'created': this.safeInteger(market, 'tradableStartTime'),
'info': market,
};
}
parseSwapMarket(market) {
//
// {
// "symbol": "BNB_USDT_PERP",
// "bAsset": ".PBNBUSDT",
// "bCcy": "BNB",
// "qCcy": "USDT",
// "visibleStartTime": "1620390600000",
// "tradableStartTime": "1620390600000",
// "sCcy": "USDT",
// "tSz": "0.001",
// "pxScale": "0.001,0.01,0.1,1,10",
// "lotSz": "1",
// "minSz": "1",
// "ctVal": "0.1",
// "status": "OPEN",
// "oDate": "1620287590000",
// "maxPx": "1000000",
// "minPx": "0.001",
// "maxQty": "1000000",
// "minQty": "1",
// "maxLever": "50",
// "lever": "10",
// "ctType": "LINEAR",
// "alias": "",
// "iM": "0.02",
// "mM": "0.0115",
// "mR": "2000",
// "buyLmt": "",
// "sellLmt": "",
// "ordPxRange": "0.05",
// "marketMaxQty": "2800",
// "limitMaxQty": "1000000"
// },
//
const id = this.safeString(market, 'symbol');
const baseId = this.safeString(market, 'bCcy');
const quoteId = this.safeString(market, 'qCcy');
const settleId = this.safeString(market, 'sCcy');
const base = this.safeCurrencyCode(baseId);
const quote = this.safeCurrencyCode(quoteId);
const settle = this.safeCurrencyCode(settleId);
const status = this.safeString(market, 'status');
const active = status === 'OPEN';
const linear = market['ctType'] === 'LINEAR';
let symbol = base + '/' + quote;
if (linear) {
symbol += ':' + settle;
}
else {
// actually, exchange does not have any inverse future now
symbol += ':' + base;
}
const alias = this.safeString(market, 'alias');
let type = 'swap';
if (alias !== undefined) {
type = 'future';
}
return {
'id': id,
'symbol': symbol,
'base': base,
'quote': quote,
'settle': settle,
'baseId': baseId,
'quoteId': quoteId,
'settleId': settleId,
'type': (type === 'future') ? 'future' : 'swap',
'spot': false,
'margin': false,
'swap': type === 'swap',
'future': type === 'future',
'option': false,
'active': active,
'contract': true,
'linear': linear,
'inverse': !linear,
'contractSize': this.safeNumber(market, 'ctVal'),
'expiry': undefined,
'expiryDatetime': undefined,
'strike': undefined,
'optionType': undefined,
'taker': this.safeNumber(market, 'tFee'),
'maker': this.safeNumber(market, 'mFee'),
'precision': {
'amount': this.safeNumber(market, 'lotSz'),
'price': this.safeNumber(market, 'tSz'),
},
'limits': {
'amount': {
'min': this.safeNumber(market, 'minSz'),
'max': this.safeNumber(market, 'limitMaxQty'),
},
'price': {
'min': this.safeNumber(market, 'minPx'),
'max': this.safeNumber(market, 'maxPx'),
},
'cost': {
'min': undefined,
'max': undefined,
},
'leverage': {
'max': this.safeNumber(market, 'maxLever'),
'min': undefined,
},
},
'created': this.safeInteger(market, 'oDate'),
'info': market,
};
}
/**
* @method
* @name poloniex#fetchTime
* @description fetches the current integer timestamp in milliseconds from the exchange server
* @see https://api-docs.poloniex.com/spot/api/public/reference-data#system-timestamp
* @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.publicGetTimestamp(params);
return this.safeInteger(response, 'serverTime');
}
parseTicker(ticker, market = undefined) {
//
// spot:
//
// {
// "symbol" : "BTC_USDT",
// "open" : "26053.33",
// "low" : "26053.33",
// "high" : "26798.02",
// "close" : "26447.58",
// "quantity" : "6116.210188",
// "amount" : "161082122.88450926",
// "tradeCount" : "134709",
// "startTime" : "1692784440000",
// "closeTime" : "1692870839630",
// "displayName" : "BTC/USDT",
// "dailyChange" : "0.0151",
// "bid" : "26447.57",
// "bidQuantity" : "0.016313",
// "ask" : "26447.58",
// "askQuantity" : "0.068307",
// "ts" : "1692870845446",
// "markPrice" : "26444.11"
// }
//
// swap:
//
// {
// "s": "XRP_USDT_PERP",
// "o": "2.0503",
// "l": "2.0066",
// "h": "2.216",
// "c": "2.1798",
// "qty": "21090",
// "amt": "451339.65",
// "tC": "3267",
// "sT": "1740736380000",
// "cT": "1740822777559",
// "dN": "XRP/USDT/PERP",
// "dC": "0.0632",
// "bPx": "2.175",
// "bSz": "3",
// "aPx": "2.1831",
// "aSz": "111",
// "mPx": "2.1798",
// "iPx": "2.1834"
// },
//
const timestamp = this.safeInteger2(ticker, 'ts', 'cT');
const marketId = this.safeString2(ticker, 'symbol', 's');
market = this.safeMarket(marketId);
const relativeChange = this.safeString2(ticker, 'dailyChange', 'dc');
const percentage = Precise.stringMul(relativeChange, '100');
return this.safeTicker({
'id': marketId,
'symbol': market['symbol'],
'timestamp': timestamp,
'datetime': this.iso8601(timestamp),
'high': this.safeString2(ticker, 'high', 'h'),
'low': this.safeString2(ticker, 'low', 'l'),
'bid': this.safeString2(ticker, 'bid', 'bPx'),
'bidVolume': this.safeString2(ticker, 'bidQuantity', 'bSz'),
'ask': this.safeString2(ticker, 'ask', 'aPx'),
'askVolume': this.safeString2(ticker, 'askQuantity', 'aSz'),
'vwap': undefined,
'open': this.safeString2(ticker, 'open', 'o'),
'close': this.safeString2(ticker, 'close', 'c'),
'previousClose': undefined,
'change': undefined,
'percentage': percentage,
'average': undefined,
'baseVolume': this.safeString2(ticker, 'quantity', 'qty'),
'quoteVolume': this.safeString2(ticker, 'amount', 'amt'),
'markPrice': this.safeString2(ticker, 'markPrice', 'mPx'),
'indexPrice': this.safeString(ticker, 'iPx'),
'info': ticker,
}, market);
}
/**
* @method
* @name poloniex#fetchTickers
* @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
* @see https://api-docs.poloniex.com/spot/api/public/market-data#ticker
* @see https://api-docs.poloniex.com/v3/futures/api/market/get-market-info
* @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();
let market = undefined;
const request = {};
if (symbols !== undefined) {
symbols = this.marketSymbols(symbols, undefined, true, true, false);
const symbolsLength = symbols.length;
if (symbolsLength > 0) {
market = this.market(symbols[0]);
if (symbolsLength === 1) {
request['symbol'] = market['id'];
}
}
}
let marketType = undefined;
[marketType, params] = this.handleMarketTypeAndParams('fetchTickers', market, params);
if (marketType === 'swap') {
const responseRaw = await this.swapPublicGetV3MarketTickers(this.extend(request, params));
//
// {
// "code": "200",
// "msg": "Success",
// "data": [
// {
// "s": "XRP_USDT_PERP",
// "o": "2.0503",
// "l": "2.0066",
// "h": "2.216",
// "c": "2.1798",
// "qty": "21090",
// "amt": "451339.65",
// "tC": "3267",
// "sT": "1740736380000",
// "cT": "1740822777559",
// "dN": "XRP/USDT/PERP",
// "dC": "0.0632",
// "bPx": "2.175",
// "bSz": "3",
// "aPx": "2.1831",
// "aSz": "111",
// "mPx": "2.1798",
// "iPx": "2.1834"
// },
//
const data = this.safeList(responseRaw, 'data');
return this.parseTickers(data, symbols);
}
const response = await this.publicGetMarketsTicker24h(params);
//
// [
// {
// "symbol" : "BTC_USDT",
// "open" : "26053.33",
// "low" : "26053.33",
// "high" : "26798.02",
// "close" : "26447.58",
// "quantity" : "6116.210188",
// "amount" : "161082122.88450926",
// "tradeCount" : "134709",
// "startTime" : "1692784440000",
// "closeTime" : "1692870839630",
// "displayName" : "BTC/USDT",
// "dailyChange" : "0.0151",
// "bid" : "26447.57",
// "bidQuantity" : "0.016313",
// "ask" : "26447.58",
// "askQuantity" : "0.068307",
// "ts" : "1692870845446",
// "markPrice" : "26444.11"
// }
// ]
//
return this.parseTickers(response, symbols);
}
/**
* @method
* @name poloniex#fetchCurrencies
* @description fetches all available currencies on an exchange
* @see https://api-docs.poloniex.com/spot/api/public/reference-data#currency-information
* @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.publicGetCurrencies(this.extend(params, { 'includeMultiChainCurrencies': true }));
//
// [
// {
// "USDT": {
// "id": 214,
// "name": "Tether USD",
// "description": "Sweep to Main Account",
// "type": "address",
// "withdrawalFee": "0.00000000",
// "minConf": 2,
// "depositAddress": null,
// "blockchain": "OMNI",
// "delisted": false,
// "tradingState": "NORMAL",
// "walletState": "DISABLED",
// "walletDepositState": "DISABLED",
// "walletWithdrawalState": "DISABLED",
// "supportCollateral": true,
// "supportBorrow": true,
// "parentChain": null,
// "isMultiChain": true,
// "isChildChain": false,
// "childChains": [
// "USDTBSC",
// "USDTETH",
// "USDTSOL",
// "USDTTRON"
// ]
// }
// },
// ...
// {
// "USDTBSC": {
// "id": 582,
// "name": "Binance-Peg BSC-USD",
// "description": "Sweep to Main Account",
// "type": "address",
// "withdrawalFee": "0.00000000",
// "minConf": 15,
// "depositAddress": null,
// "blockchain": "BSC",
// "delisted": false,
// "tradingState": "OFFLINE",
// "walletState": "ENABLED",
// "walletDepositState": "ENABLED",
// "walletWithdrawalState": "DISABLED",
// "supportCollateral": false,
//