@proton/ccxt
Version:
A JavaScript / TypeScript / Python / C# / PHP cryptocurrency trading library with support for 130+ exchanges
777 lines (774 loc) • 32.1 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 wazirxRest from '../wazirx.js';
import { NotSupported, ExchangeError } from '../base/errors.js';
import { ArrayCacheBySymbolById, ArrayCacheByTimestamp, ArrayCache } from '../base/ws/Cache.js';
// ---------------------------------------------------------------------------
export default class wazirx extends wazirxRest {
describe() {
return this.deepExtend(super.describe(), {
'has': {
'ws': true,
'watchBalance': true,
'watchTicker': true,
'watchTickers': true,
'watchTrades': true,
'watchMyTrades': true,
'watchOrders': true,
'watchOrderBook': true,
'watchOHLCV': true,
},
'urls': {
'api': {
'ws': 'wss://stream.wazirx.com/stream',
},
},
'options': {},
'streaming': {},
'exceptions': {},
'api': {
'private': {
'post': {
'create_auth_token': 1,
},
},
},
});
}
async watchBalance(params = {}) {
/**
* @method
* @name wazirx#watchBalance
* @description query for balance and get the amount of funds available for trading or funds locked in orders
* @see https://docs.wazirx.com/#account-update
* @param {object} params extra parameters specific to the wazirx api endpoint
* @returns {object} a [balance structure]{@link https://docs.ccxt.com/en/latest/manual.html?#balance-structure}
*/
await this.loadMarkets();
const token = await this.authenticate(params);
const messageHash = 'balance';
const url = this.urls['api']['ws'];
const subscribe = {
'event': 'subscribe',
'streams': ['outboundAccountPosition'],
'auth_key': token,
};
const request = this.deepExtend(subscribe, params);
return await this.watch(url, messageHash, request, messageHash);
}
handleBalance(client, message) {
//
// {
// "data":
// {
// "B": [
// {
// "a":"wrx",
// "b":"2043856.426455209",
// "l":"3001318.98"
// }
// ],
// "E":1631683058909
// },
// "stream":"outboundAccountPosition"
// }
//
const data = this.safeValue(message, 'data', {});
const balances = this.safeValue(data, 'B', []);
const timestamp = this.safeInteger(data, 'E');
this.balance['info'] = balances;
this.balance['timestamp'] = timestamp;
this.balance['datetime'] = this.iso8601(timestamp);
for (let i = 0; i < balances.length; i++) {
const balance = balances[i];
const currencyId = this.safeString(balance, 'a');
const code = this.safeCurrencyCode(currencyId);
const available = this.safeNumber(balance, 'b');
const locked = this.safeNumber(balance, 'l');
const account = this.account();
account['free'] = available;
account['used'] = locked;
this.balance[code] = account;
}
this.balance = this.safeBalance(this.balance);
const messageHash = 'balance';
client.resolve(this.balance, messageHash);
}
parseWsTrade(trade, market = undefined) {
//
// trade
// {
// "E": 1631681323000, Event time
// "S": "buy", Side
// "a": 26946138, Buyer order ID
// "b": 26946169, Seller order ID
// "m": true, Is buyer maker?
// "p": "7.0", Price
// "q": "15.0", Quantity
// "s": "btcinr", Symbol
// "t": 17376030 Trade ID
// }
// ownTrade
// {
// "E": 1631683058000,
// "S": "ask",
// "U": "inr",
// "a": 114144050,
// "b": 114144121,
// "f": "0.2",
// "m": true,
// "o": 26946170,
// "p": "5.0",
// "q": "20.0",
// "s": "btcinr",
// "t": 17376032,
// "w": "100.0"
// }
//
const timestamp = this.safeInteger(trade, 'E');
const marketId = this.safeString(trade, 's');
market = this.safeMarket(marketId, market);
const feeCost = this.safeString(trade, 'f');
const feeCurrencyId = this.safeString(trade, 'U');
const isMaker = this.safeValue(trade, 'm') === true;
let fee = undefined;
if (feeCost !== undefined) {
fee = {
'cost': feeCost,
'currency': this.safeCurrencyCode(feeCurrencyId),
'rate': undefined,
};
}
return this.safeTrade({
'id': this.safeString(trade, 't'),
'info': trade,
'timestamp': timestamp,
'datetime': this.iso8601(timestamp),
'symbol': market['symbol'],
'order': this.safeStringN(trade, ['o']),
'type': undefined,
'side': this.safeString(trade, 'S'),
'takerOrMaker': isMaker ? 'maker' : 'taker',
'price': this.safeString(trade, 'p'),
'amount': this.safeString(trade, 'q'),
'cost': undefined,
'fee': fee,
}, market);
}
async watchTicker(symbol, params = {}) {
/**
* @method
* @name wazirx#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.wazirx.com/#all-market-tickers-stream
* @param {string} symbol unified symbol of the market to fetch the ticker for
* @param {object} params extra parameters specific to the wazirx api endpoint
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
*/
await this.loadMarkets();
const market = this.market(symbol);
const url = this.urls['api']['ws'];
const messageHash = 'ticker:' + market['symbol'];
const subscribeHash = 'tickers';
const stream = '!' + 'ticker@arr';
const subscribe = {
'event': 'subscribe',
'streams': [stream],
};
const request = this.deepExtend(subscribe, params);
return await this.watch(url, messageHash, request, subscribeHash);
}
async watchTickers(symbols = undefined, params = {}) {
/**
* @method
* @name wazirx#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.wazirx.com/#all-market-tickers-stream
* @param {[string]} symbols unified symbol of the market to fetch the ticker for
* @param {object} params extra parameters specific to the wazirx api endpoint
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
*/
await this.loadMarkets();
symbols = this.marketSymbols(symbols);
const url = this.urls['api']['ws'];
const messageHash = 'tickers';
const stream = '!' + 'ticker@arr';
const subscribe = {
'event': 'subscribe',
'streams': [stream],
};
const request = this.deepExtend(subscribe, params);
const tickers = await this.watch(url, messageHash, request, messageHash);
return this.filterByArray(tickers, 'symbol', symbols, false);
}
handleTicker(client, message) {
//
// {
// "data":
// [
// {
// "E":1631625534000, // Event time
// "T":"SPOT", // Type
// "U":"wrx", // Quote unit
// "a":"0.0", // Best sell price
// "b":"0.0", // Best buy price
// "c":"5.0", // Last price
// "h":"5.0", // High price
// "l":"5.0", // Low price
// "o":"5.0", // Open price
// "q":"0.0", // Quantity
// "s":"btcwrx", // Symbol
// "u":"btc" // Base unit
// }
// ],
// "stream":"!ticker@arr"
// }
//
const data = this.safeValue(message, 'data', []);
for (let i = 0; i < data.length; i++) {
const ticker = data[i];
const parsedTicker = this.parseWSTicker(ticker);
const symbol = parsedTicker['symbol'];
this.tickers[symbol] = parsedTicker;
const messageHash = 'ticker:' + symbol;
client.resolve(parsedTicker, messageHash);
}
client.resolve(this.tickers, 'tickers');
}
parseWSTicker(ticker, market = undefined) {
//
// {
// "E":1631625534000, // Event time
// "T":"SPOT", // Type
// "U":"wrx", // Quote unit
// "a":"0.0", // Best sell price
// "b":"0.0", // Best buy price
// "c":"5.0", // Last price
// "h":"5.0", // High price
// "l":"5.0", // Low price
// "o":"5.0", // Open price
// "q":"0.0", // Quantity
// "s":"btcwrx", // Symbol
// "u":"btc" // Base unit
// }
//
const marketId = this.safeString(ticker, 's');
const timestamp = this.safeInteger(ticker, 'E');
return this.safeTicker({
'symbol': this.safeSymbol(marketId, market),
'timestamp': timestamp,
'datetime': this.iso8601(timestamp),
'high': this.safeString(ticker, 'h'),
'low': this.safeString(ticker, 'l'),
'bid': this.safeNumber(ticker, 'b'),
'bidVolume': undefined,
'ask': this.safeNumber(ticker, 'a'),
'askVolume': undefined,
'vwap': undefined,
'open': this.safeString(ticker, 'o'),
'close': undefined,
'last': this.safeString(ticker, 'l'),
'previousClose': undefined,
'change': undefined,
'percentage': undefined,
'average': undefined,
'baseVolume': undefined,
'quoteVolume': this.safeString(ticker, 'q'),
'info': ticker,
}, market);
}
async watchTrades(symbol, since = undefined, limit = undefined, params = {}) {
/**
* @method
* @name wazirx#watchTrades
* @description get the list of most recent trades for a particular symbol
* @param {string} symbol unified symbol of the market to fetch trades for
* @param {int|undefined} since timestamp in ms of the earliest trade to fetch
* @param {int|undefined} limit the maximum amount of trades to fetch
* @param {object} params extra parameters specific to the wazirx api endpoint
* @returns {[object]} a list of [trade structures]{@link https://docs.ccxt.com/en/latest/manual.html?#public-trades}
*/
await this.loadMarkets();
const market = this.market(symbol);
symbol = market['symbol'];
const messageHash = market['id'] + '@trades';
const url = this.urls['api']['ws'];
const message = {
'event': 'subscribe',
'streams': [messageHash],
};
const request = this.extend(message, params);
const trades = await this.watch(url, messageHash, request, messageHash);
if (this.newUpdates) {
limit = trades.getLimit(symbol, limit);
}
return this.filterBySinceLimit(trades, since, limit, 'timestamp', true);
}
handleTrades(client, message) {
//
// {
// "data": {
// "trades": [{
// "E": 1631681323000, Event time
// "S": "buy", Side
// "a": 26946138, Buyer order ID
// "b": 26946169, Seller order ID
// "m": true, Is buyer maker?
// "p": "7.0", Price
// "q": "15.0", Quantity
// "s": "btcinr", Symbol
// "t": 17376030 Trade ID
// }]
// },
// "stream": "btcinr@trades"
// }
//
const data = this.safeValue(message, 'data', {});
const rawTrades = this.safeValue(data, 'trades', []);
const messageHash = this.safeString(message, 'stream');
const split = messageHash.split('@');
const marketId = this.safeString(split, 0);
const market = this.safeMarket(marketId);
const symbol = this.safeSymbol(marketId, market);
let trades = this.safeValue(this.trades, symbol);
if (trades === undefined) {
const limit = this.safeInteger(this.options, 'tradesLimit', 1000);
trades = new ArrayCache(limit);
this.trades[symbol] = trades;
}
for (let i = 0; i < rawTrades.length; i++) {
const parsedTrade = this.parseWsTrade(rawTrades[i], market);
trades.append(parsedTrade);
}
client.resolve(trades, messageHash);
}
async watchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
/**
* @method
* @name wazirx#watchMyTrades
* @description watch trades by user
* @see https://docs.wazirx.com/#trade-update
* @param {string} symbol unified symbol of the market to fetch trades for
* @param {int|undefined} since timestamp in ms of the earliest trade to fetch
* @param {int|undefined} limit the maximum amount of trades to fetch
* @param {object} params extra parameters specific to the wazirx api endpoint
* @returns {[object]} a list of [trade structures]{@link https://docs.ccxt.com/en/latest/manual.html?#public-trades}
*/
await this.loadMarkets();
const token = await this.authenticate(params);
if (symbol !== undefined) {
const market = this.market(symbol);
symbol = market['symbol'];
}
const url = this.urls['api']['ws'];
const messageHash = 'myTrades';
const message = {
'event': 'subscribe',
'streams': ['ownTrade'],
'auth_key': token,
};
const request = this.deepExtend(message, params);
const trades = await this.watch(url, messageHash, request, messageHash);
if (this.newUpdates) {
limit = trades.getLimit(symbol, limit);
}
return this.filterBySymbolSinceLimit(trades, symbol, since, limit, true);
}
async watchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
/**
* @method
* @name wazirx#watchOHLCV
* @description watches historical candlestick data containing the open, high, low, and close price, and the volume of a market
* @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|undefined} since timestamp in ms of the earliest candle to fetch
* @param {int|undefined} limit the maximum amount of candles to fetch
* @param {object} params extra parameters specific to the wazirx api endpoint
* @returns {[[int]]} A list of candles ordered as timestamp, open, high, low, close, volume
*/
await this.loadMarkets();
const market = this.market(symbol);
symbol = market['symbol'];
const url = this.urls['api']['ws'];
const messageHash = 'ohlcv:' + symbol + ':' + timeframe;
const stream = market['id'] + '@kline_' + timeframe;
const message = {
'event': 'subscribe',
'streams': [stream],
};
const request = this.deepExtend(message, params);
const ohlcv = await this.watch(url, messageHash, request, messageHash);
if (this.newUpdates) {
limit = ohlcv.getLimit(symbol, limit);
}
return this.filterBySinceLimit(ohlcv, since, limit, 0, true);
}
handleOHLCV(client, message) {
//
// {
// "data": {
// "E":1631683058904, Event time
// "s": "btcinr", Symbol
// "t": 1638747660000, Kline start time
// "T": 1638747719999, Kline close time
// "i": "1m", Interval
// "o": "0.0010", Open price
// "c": "0.0020", Close price
// "h": "0.0025", High price
// "l": "0.0015", Low price
// "v": "1000", Base asset volume
// },
// "stream": "btcinr@kline_1m"
// }
//
const data = this.safeValue(message, 'data', {});
const marketId = this.safeString(data, 's');
const market = this.safeMarket(marketId);
const symbol = this.safeSymbol(marketId, market);
const timeframe = this.safeString(data, 'i');
this.ohlcvs[symbol] = this.safeValue(this.ohlcvs, symbol, {});
let stored = this.safeValue(this.ohlcvs[symbol], timeframe);
if (stored === undefined) {
const limit = this.safeInteger(this.options, 'OHLCVLimit', 1000);
stored = new ArrayCacheByTimestamp(limit);
this.ohlcvs[symbol][timeframe] = stored;
}
const parsed = this.parseWsOHLCV(data, market);
stored.append(parsed);
const messageHash = 'ohlcv:' + symbol + ':' + timeframe;
client.resolve(stored, messageHash);
}
parseWsOHLCV(ohlcv, market = undefined) {
//
// {
// "E":1631683058904, Event time
// "s": "btcinr", Symbol
// "t": 1638747660000, Kline start time
// "T": 1638747719999, Kline close time
// "i": "1m", Interval
// "o": "0.0010", Open price
// "c": "0.0020", Close price
// "h": "0.0025", High price
// "l": "0.0015", Low price
// "v": "1000", Base asset volume
// }
//
return [
this.safeInteger(ohlcv, 't'),
this.safeNumber(ohlcv, 'o'),
this.safeNumber(ohlcv, 'c'),
this.safeNumber(ohlcv, 'h'),
this.safeNumber(ohlcv, 'l'),
this.safeNumber(ohlcv, 'v'),
];
}
async watchOrderBook(symbol, limit = undefined, params = {}) {
/**
* @method
* @name wazirx#watchOrderBook
* @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
* @see https://docs.wazirx.com/#depth-stream
* @param {string} symbol unified symbol of the market to fetch the order book for
* @param {int|undefined} limit the maximum amount of order book entries to return
* @param {object} params extra parameters specific to the wazirx api endpoint
* @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
*/
await this.loadMarkets();
const market = this.market(symbol);
symbol = market['symbol'];
const url = this.urls['api']['ws'];
const messageHash = 'orderbook:' + symbol;
const stream = market['id'] + '@depth';
const subscribe = {
'event': 'subscribe',
'streams': [stream],
};
const request = this.deepExtend(subscribe, params);
const orderbook = await this.watch(url, messageHash, request, messageHash);
return orderbook.limit();
}
handleDelta(bookside, delta) {
const bidAsk = this.parseBidAsk(delta, 0, 1);
bookside.storeArray(bidAsk);
}
handleDeltas(bookside, deltas) {
for (let i = 0; i < deltas.length; i++) {
this.handleDelta(bookside, deltas[i]);
}
}
handleOrderBook(client, message) {
//
// {
// "data": {
// "E": 1659475095000,
// "a": [
// ["23051.0", "1.30141"],
// ],
// "b": [
// ["22910.0", "1.30944"],
// ],
// "s": "btcusdt"
// },
// "stream": "btcusdt@depth"
// }
//
const data = this.safeValue(message, 'data', {});
const timestamp = this.safeInteger(data, 'E');
const marketId = this.safeString(data, 's');
const market = this.safeMarket(marketId);
const symbol = market['symbol'];
const messageHash = 'orderbook:' + symbol;
const currentOrderBook = this.safeValue(this.orderbooks, symbol);
if (currentOrderBook === undefined) {
const snapshot = this.parseOrderBook(data, symbol, timestamp, 'b', 'a');
const orderBook = this.orderBook(snapshot);
this.orderbooks[symbol] = orderBook;
}
else {
const asks = this.safeValue(data, 'a', []);
const bids = this.safeValue(data, 'b', []);
this.handleDeltas(currentOrderBook['asks'], asks);
this.handleDeltas(currentOrderBook['bids'], bids);
currentOrderBook['nonce'] = timestamp;
currentOrderBook['timestamp'] = timestamp;
currentOrderBook['datetime'] = this.iso8601(timestamp);
this.orderbooks[symbol] = currentOrderBook;
}
client.resolve(this.orderbooks[symbol], messageHash);
}
async watchOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
await this.loadMarkets();
if (symbol !== undefined) {
const market = this.market(symbol);
symbol = market['symbol'];
}
const token = await this.authenticate(params);
const messageHash = 'orders';
const message = {
'event': 'subscribe',
'streams': ['orderUpdate'],
'auth_key': token,
};
const url = this.urls['api']['ws'];
const request = this.deepExtend(message, params);
const orders = await this.watch(url, messageHash, request, messageHash, request);
if (this.newUpdates) {
limit = orders.getLimit(symbol, limit);
}
return this.filterBySymbolSinceLimit(orders, symbol, since, limit);
}
handleOrder(client, message) {
//
// {
// "data": {
// "E": 1631683058904,
// "O": 1631683058000,
// "S": "ask",
// "V": "70.0",
// "X": "wait",
// "i": 26946170,
// "m": true,
// "o": "sell",
// "p": "5.0",
// "q": "70.0",
// "s": "wrxinr",
// "v": "0.0"
// },
// "stream": "orderUpdate"
// }
//
const order = this.safeValue(message, 'data', {});
const parsedOrder = this.parseWsOrder(order);
if (this.orders === undefined) {
const limit = this.safeInteger(this.options, 'ordersLimit', 1000);
this.orders = new ArrayCacheBySymbolById(limit);
}
this.orders.append(parsedOrder);
let messageHash = 'orders';
client.resolve(this.orders, messageHash);
messageHash += ':' + parsedOrder['symbol'];
client.resolve(this.orders, messageHash);
}
parseWsOrder(order, market = undefined) {
//
// {
// "E": 1631683058904,
// "O": 1631683058000,
// "S": "ask",
// "V": "70.0",
// "X": "wait",
// "i": 26946170,
// "m": true,
// "o": "sell",
// "p": "5.0",
// "q": "70.0",
// "s": "wrxinr",
// "v": "0.0"
// }
//
const timestamp = this.safeInteger(order, 'O');
const marketId = this.safeString(order, 's');
const status = this.safeString(order, 'X');
market = this.safeMarket(marketId);
return this.safeOrder({
'info': order,
'id': this.safeString(order, 'i'),
'clientOrderId': this.safeString(order, 'c'),
'datetime': this.iso8601(timestamp),
'timestamp': timestamp,
'lastTradeTimestamp': undefined,
'symbol': market['symbol'],
'type': this.safeValue(order, 'm') ? 'limit' : 'market',
'timeInForce': undefined,
'postOnly': undefined,
'side': this.safeString(order, 'o'),
'price': this.safeString(order, 'p'),
'stopPrice': undefined,
'triggerPrice': undefined,
'amount': this.safeString(order, 'V'),
'filled': undefined,
'remaining': this.safeString(order, 'q'),
'cost': undefined,
'average': this.safeString(order, 'v'),
'status': this.parseOrderStatus(status),
'fee': undefined,
'trades': undefined,
}, market);
}
handleMyTrades(client, message) {
//
// {
// "data": {
// "E": 1631683058000,
// "S": "ask",
// "U": "usdt",
// "a": 114144050,
// "b": 114144121,
// "f": "0.2",
// "ga": '0.0',
// "gc": 'usdt',
// "m": true,
// "o": 26946170,
// "p": "5.0",
// "q": "20.0",
// "s": "btcusdt",
// "t": 17376032,
// "w": "100.0"
// },
// "stream": "ownTrade"
// }
//
const trade = this.safeValue(message, 'data', {});
const messageHash = 'myTrades';
let myTrades = undefined;
if (this.myTrades === undefined) {
const limit = this.safeInteger(this.options, 'tradesLimit', 1000);
myTrades = new ArrayCacheBySymbolById(limit);
this.myTrades = myTrades;
}
else {
myTrades = this.myTrades;
}
const parsedTrade = this.parseWsTrade(trade);
myTrades.append(parsedTrade);
client.resolve(myTrades, messageHash);
}
handleConnected(client, message) {
//
// {
// data: {
// timeout_duration: 1800
// },
// event: 'connected'
// }
//
return message;
}
handleSubscribed(client, message) {
//
// {
// data: {
// streams: ['!ticker@arr']
// },
// event: 'subscribed',
// id: 0
// }
//
return message;
}
handleError(client, message) {
//
// {
// "data": {
// "code": 400,
// "message": "Invalid request: streams must be an array"
// },
// "event": "error",
// "id": 0
// }
//
// {
// message: 'HeartBeat message not received, closing the connection',
// status: 'error'
// }
//
throw new ExchangeError(this.id + ' ' + this.json(message));
}
handleMessage(client, message) {
const status = this.safeString(message, 'status');
if (status === 'error') {
return this.handleError(client, message);
}
const event = this.safeString(message, 'event');
const eventHandlers = {
'error': this.handleError,
'connected': this.handleConnected,
'subscribed': this.handleSubscribed,
};
const eventHandler = this.safeValue(eventHandlers, event);
if (eventHandler !== undefined) {
return eventHandler.call(this, client, message);
}
const stream = this.safeString(message, 'stream', '');
const streamHandlers = {
'ticker@arr': this.handleTicker,
'@depth': this.handleOrderBook,
'@kline': this.handleOHLCV,
'@trades': this.handleTrades,
'outboundAccountPosition': this.handleBalance,
'orderUpdate': this.handleOrder,
'ownTrade': this.handleMyTrades,
};
const streams = Object.keys(streamHandlers);
for (let i = 0; i < streams.length; i++) {
if (this.inArray(streams[i], stream)) {
const handler = streamHandlers[streams[i]];
return handler.call(this, client, message);
}
}
throw new NotSupported(this.id + ' this message type is not supported yet. Message: ' + this.json(message));
}
async authenticate(params = {}) {
const url = this.urls['api']['ws'];
const client = this.client(url);
const messageHash = 'authenticated';
const now = this.milliseconds();
let subscription = this.safeValue(client.subscriptions, messageHash);
const expires = this.safeInteger(subscription, 'expires');
if (subscription === undefined || now > expires) {
subscription = await this.privatePostCreateAuthToken();
subscription['expires'] = now + this.safeInteger(subscription, 'timeout_duration') * 1000;
//
// {
// "auth_key": "Xx***dM",
// "timeout_duration": 900
// }
//
client.subscriptions[messageHash] = subscription;
}
return this.safeString(subscription, 'auth_key');
}
}