ccxt
Version:
371 lines (368 loc) • 15.4 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 paradexRest from '../paradex.js';
import { ArrayCache } from '../base/ws/Cache.js';
// ---------------------------------------------------------------------------
export default class paradex extends paradexRest {
describe() {
return this.deepExtend(super.describe(), {
'has': {
'ws': true,
'watchTicker': true,
'watchTickers': true,
'watchOrderBook': true,
'watchOrders': false,
'watchTrades': true,
'watchTradesForSymbols': false,
'watchBalance': false,
'watchOHLCV': false,
},
'urls': {
'logo': 'https://x.com/tradeparadex/photo',
'api': {
'ws': 'wss://ws.api.prod.paradex.trade/v1',
},
'test': {
'ws': 'wss://ws.api.testnet.paradex.trade/v1',
},
'www': 'https://www.paradex.trade/',
'doc': 'https://docs.api.testnet.paradex.trade/',
'fees': 'https://docs.paradex.trade/getting-started/trading-fees',
'referral': '',
},
'options': {},
'streaming': {},
});
}
/**
* @method
* @name paradex#watchTrades
* @description get the list of most recent trades for a particular symbol
* @see https://docs.api.testnet.paradex.trade/#sub-trades-market_symbol-operation
* @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
* @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
*/
async watchTrades(symbol, since = undefined, limit = undefined, params = {}) {
await this.loadMarkets();
let messageHash = 'trades.';
if (symbol !== undefined) {
const market = this.market(symbol);
messageHash += market['id'];
}
else {
messageHash += 'ALL';
}
const url = this.urls['api']['ws'];
const request = {
'jsonrpc': '2.0',
'method': 'subscribe',
'params': {
'channel': messageHash,
},
};
const trades = await this.watch(url, messageHash, this.deepExtend(request, params), messageHash);
if (this.newUpdates) {
limit = trades.getLimit(symbol, limit);
}
return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
}
handleTrade(client, message) {
//
// {
// "jsonrpc": "2.0",
// "method": "subscription",
// "params": {
// "channel": "trades.ALL",
// "data": {
// "id": "1718179273230201709233240002",
// "market": "kBONK-USD-PERP",
// "side": "BUY",
// "size": "34028",
// "price": "0.028776",
// "created_at": 1718179273230,
// "trade_type": "FILL"
// }
// }
// }
//
const params = this.safeDict(message, 'params', {});
const data = this.safeDict(params, 'data', {});
const parsedTrade = this.parseTrade(data);
const symbol = parsedTrade['symbol'];
const messageHash = this.safeString(params, 'channel');
let stored = this.safeValue(this.trades, symbol);
if (stored === undefined) {
stored = new ArrayCache(this.safeInteger(this.options, 'tradesLimit', 1000));
this.trades[symbol] = stored;
}
stored.append(parsedTrade);
client.resolve(stored, messageHash);
return message;
}
/**
* @method
* @name paradex#watchOrderBook
* @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
* @see https://docs.api.testnet.paradex.trade/#sub-order_book-market_symbol-snapshot-15-refresh_rate-operation
* @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
* @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 watchOrderBook(symbol, limit = undefined, params = {}) {
await this.loadMarkets();
const market = this.market(symbol);
const messageHash = 'order_book.' + market['id'] + '.snapshot@15@100ms';
const url = this.urls['api']['ws'];
const request = {
'jsonrpc': '2.0',
'method': 'subscribe',
'params': {
'channel': messageHash,
},
};
const orderbook = await this.watch(url, messageHash, this.deepExtend(request, params), messageHash);
return orderbook.limit();
}
handleOrderBook(client, message) {
//
// {
// "jsonrpc": "2.0",
// "method": "subscription",
// "params": {
// "channel": "order_book.BTC-USD-PERP.snapshot@15@50ms",
// "data": {
// "seq_no": 14127815,
// "market": "BTC-USD-PERP",
// "last_updated_at": 1718267837265,
// "update_type": "s",
// "inserts": [
// {
// "side": "BUY",
// "price": "67629.7",
// "size": "0.992"
// },
// {
// "side": "SELL",
// "price": "69378.6",
// "size": "3.137"
// }
// ],
// "updates": [],
// "deletes": []
// }
// }
// }
//
const params = this.safeDict(message, 'params', {});
const data = this.safeDict(params, 'data', {});
const marketId = this.safeString(data, 'market');
const market = this.safeMarket(marketId);
const timestamp = this.safeInteger(data, 'last_updated_at');
const symbol = market['symbol'];
if (!(symbol in this.orderbooks)) {
this.orderbooks[symbol] = this.orderBook();
}
const orderbookData = {
'bids': [],
'asks': [],
};
const inserts = this.safeList(data, 'inserts');
for (let i = 0; i < inserts.length; i++) {
const insert = this.safeDict(inserts, i);
const side = this.safeString(insert, 'side');
const price = this.safeString(insert, 'price');
const size = this.safeString(insert, 'size');
if (side === 'BUY') {
orderbookData['bids'].push([price, size]);
}
else {
orderbookData['asks'].push([price, size]);
}
}
const orderbook = this.orderbooks[symbol];
const snapshot = this.parseOrderBook(orderbookData, symbol, timestamp, 'bids', 'asks');
snapshot['nonce'] = this.safeNumber(data, 'seq_no');
orderbook.reset(snapshot);
const messageHash = this.safeString(params, 'channel');
client.resolve(orderbook, messageHash);
}
/**
* @method
* @name paradex#watchTicker
* @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
* @see https://docs.api.testnet.paradex.trade/#sub-markets_summary-operation
* @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 watchTicker(symbol, params = {}) {
await this.loadMarkets();
symbol = this.symbol(symbol);
const channel = 'markets_summary';
const url = this.urls['api']['ws'];
const request = {
'jsonrpc': '2.0',
'method': 'subscribe',
'params': {
'channel': channel,
},
};
const messageHash = channel + '.' + symbol;
return await this.watch(url, messageHash, this.deepExtend(request, params), messageHash);
}
/**
* @method
* @name paradex#watchTickers
* @description watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
* @see https://docs.api.testnet.paradex.trade/#sub-markets_summary-operation
* @param {string[]} symbols 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 watchTickers(symbols = undefined, params = {}) {
await this.loadMarkets();
symbols = this.marketSymbols(symbols);
const channel = 'markets_summary';
const url = this.urls['api']['ws'];
const request = {
'jsonrpc': '2.0',
'method': 'subscribe',
'params': {
'channel': channel,
},
};
const messageHashes = [];
if (Array.isArray(symbols)) {
for (let i = 0; i < symbols.length; i++) {
const messageHash = channel + '.' + symbols[i];
messageHashes.push(messageHash);
}
}
else {
messageHashes.push(channel);
}
const newTickers = await this.watchMultiple(url, messageHashes, this.deepExtend(request, params), messageHashes);
if (this.newUpdates) {
const result = {};
result[newTickers['symbol']] = newTickers;
return result;
}
return this.filterByArray(this.tickers, 'symbol', symbols);
}
handleTicker(client, message) {
//
// {
// "jsonrpc": "2.0",
// "method": "subscription",
// "params": {
// "channel": "markets_summary",
// "data": {
// "symbol": "ORDI-USD-PERP",
// "oracle_price": "49.80885481",
// "mark_price": "49.80885481",
// "last_traded_price": "62.038",
// "bid": "49.822",
// "ask": "58.167",
// "volume_24h": "0",
// "total_volume": "54542628.66054200416",
// "created_at": 1718334307698,
// "underlying_price": "47.93",
// "open_interest": "6999.5",
// "funding_rate": "0.03919997509811",
// "price_change_rate_24h": ""
// }
// }
// }
//
const params = this.safeDict(message, 'params', {});
const data = this.safeDict(params, 'data', {});
const marketId = this.safeString(data, 'symbol');
const market = this.safeMarket(marketId);
const symbol = market['symbol'];
const channel = this.safeString(params, 'channel');
const messageHash = channel + '.' + symbol;
const ticker = this.parseTicker(data, market);
this.tickers[symbol] = ticker;
client.resolve(ticker, channel);
client.resolve(ticker, messageHash);
return message;
}
handleErrorMessage(client, message) {
//
// {
// "jsonrpc": "2.0",
// "id": 0,
// "error": {
// "code": -32600,
// "message": "invalid subscribe request",
// "data": "invalid channel"
// },
// "usIn": 1718179125962419,
// "usDiff": 76,
// "usOut": 1718179125962495
// }
//
const error = this.safeDict(message, 'error');
if (error === undefined) {
return true;
}
else {
const errorCode = this.safeString(error, 'code');
if (errorCode !== undefined) {
const feedback = this.id + ' ' + this.json(error);
this.throwExactlyMatchedException(this.exceptions['exact'], '-32600', feedback);
const messageString = this.safeValue(error, 'message');
if (messageString !== undefined) {
this.throwBroadlyMatchedException(this.exceptions['broad'], messageString, feedback);
}
}
return false;
}
}
handleMessage(client, message) {
if (!this.handleErrorMessage(client, message)) {
return;
}
//
// {
// "jsonrpc": "2.0",
// "method": "subscription",
// "params": {
// "channel": "trades.ALL",
// "data": {
// "id": "1718179273230201709233240002",
// "market": "kBONK-USD-PERP",
// "side": "BUY",
// "size": "34028",
// "price": "0.028776",
// "created_at": 1718179273230,
// "trade_type": "FILL"
// }
// }
// }
//
const data = this.safeDict(message, 'params');
if (data !== undefined) {
const channel = this.safeString(data, 'channel');
const parts = channel.split('.');
const name = this.safeString(parts, 0);
const methods = {
'trades': this.handleTrade,
'order_book': this.handleOrderBook,
'markets_summary': this.handleTicker,
// ...
};
const method = this.safeValue(methods, name);
if (method !== undefined) {
method.call(this, client, message);
}
}
}
}