UNPKG

@proton/ccxt

Version:

A JavaScript / TypeScript / Python / C# / PHP cryptocurrency trading library with support for 130+ exchanges

324 lines (321 loc) 13.2 kB
// ---------------------------------------------------------------------------- // 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 lunoRest from '../luno.js'; import { ArrayCache } from '../base/ws/Cache.js'; // --------------------------------------------------------------------------- export default class luno extends lunoRest { describe() { return this.deepExtend(super.describe(), { 'has': { 'ws': true, 'watchTicker': false, 'watchTickers': false, 'watchTrades': true, 'watchMyTrades': false, 'watchOrders': undefined, 'watchOrderBook': true, 'watchOHLCV': false, }, 'urls': { 'api': { 'ws': 'wss://ws.luno.com/api/1', }, }, 'options': { 'sequenceNumbers': {}, }, 'streaming': {}, 'exceptions': {}, }); } async watchTrades(symbol, since = undefined, limit = undefined, params = {}) { /** * @method * @name luno#watchTrades * @description get the list of most recent trades for a particular symbol * @see https://www.luno.com/en/developers/api#tag/Streaming-API * @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 luno api endpoint * @returns {[object]} a list of [trade structures]{@link https://docs.ccxt.com/en/latest/manual.html?#public-trades} */ await this.checkRequiredCredentials(); await this.loadMarkets(); const market = this.market(symbol); symbol = market['symbol']; const subscriptionHash = '/stream/' + market['id']; const subscription = { 'symbol': symbol }; const url = this.urls['api']['ws'] + subscriptionHash; const messageHash = 'trades:' + symbol; const subscribe = { 'api_key_id': this.apiKey, 'api_key_secret': this.secret, }; const request = this.deepExtend(subscribe, params); const trades = await this.watch(url, messageHash, request, subscriptionHash, subscription); if (this.newUpdates) { limit = trades.getLimit(symbol, limit); } return this.filterBySinceLimit(trades, since, limit, 'timestamp', true); } handleTrades(client, message, subscription) { // // { // sequence: '110980825', // trade_updates: [], // create_update: { // order_id: 'BXHSYXAUMH8C2RW', // type: 'ASK', // price: '24081.09000000', // volume: '0.07780000' // }, // delete_update: null, // status_update: null, // timestamp: 1660598775360 // } // const rawTrades = this.safeValue(message, 'trade_updates', []); const length = rawTrades.length; if (length === 0) { return; } const symbol = subscription['symbol']; const market = this.market(symbol); const messageHash = 'trades:' + symbol; let stored = this.safeValue(this.trades, symbol); if (stored === undefined) { const limit = this.safeInteger(this.options, 'tradesLimit', 1000); stored = new ArrayCache(limit); this.trades[symbol] = stored; } for (let i = 0; i < rawTrades.length; i++) { const rawTrade = rawTrades[i]; const trade = this.parseTrade(rawTrade, market); stored.append(trade); } this.trades[symbol] = stored; client.resolve(this.trades[symbol], messageHash); } parseTrade(trade, market = undefined) { // // watchTrades (public) // // { // "base": "69.00000000", // "counter": "113.6499000000000000", // "maker_order_id": "BXEEU4S2BWF5WRB", // "taker_order_id": "BXKNCSF7JDHXY3H", // "order_id": "BXEEU4S2BWF5WRB" // } // return this.safeTrade({ 'info': trade, 'id': undefined, 'timestamp': undefined, 'datetime': undefined, 'symbol': market['symbol'], 'order': undefined, 'type': undefined, 'side': undefined, // takerOrMaker has no meaning for public trades 'takerOrMaker': undefined, 'price': undefined, 'amount': this.safeString(trade, 'base'), 'cost': this.safeString(trade, 'counter'), 'fee': undefined, }, market); } async watchOrderBook(symbol, limit = undefined, params = {}) { /** * @method * @name luno#watchOrderBook * @description watches information on open orders with bid (buy) and ask (sell) prices, volumes and other data * @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 {objectConstructor} params extra parameters specific to the luno api endpoint * @param {string|undefined} params.type accepts l2 or l3 for level 2 or level 3 order book * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols */ await this.checkRequiredCredentials(); await this.loadMarkets(); const market = this.market(symbol); symbol = market['symbol']; const subscriptionHash = '/stream/' + market['id']; const subscription = { 'symbol': symbol }; const url = this.urls['api']['ws'] + subscriptionHash; const messageHash = 'orderbook:' + symbol; const subscribe = { 'api_key_id': this.apiKey, 'api_key_secret': this.secret, }; const request = this.deepExtend(subscribe, params); const orderbook = await this.watch(url, messageHash, request, subscriptionHash, subscription); return orderbook.limit(); } handleOrderBook(client, message, subscription) { // // { // "sequence": "24352", // "asks": [{ // "id": "BXMC2CJ7HNB88U4", // "price": "1234.00", // "volume": "0.93" // }], // "bids": [{ // "id": "BXMC2CJ7HNB88U5", // "price": "1201.00", // "volume": "1.22" // }], // "status": "ACTIVE", // "timestamp": 1528884331021 // } // // update // { // sequence: '110980825', // trade_updates: [], // create_update: { // order_id: 'BXHSYXAUMH8C2RW', // type: 'ASK', // price: '24081.09000000', // volume: '0.07780000' // }, // delete_update: null, // status_update: null, // timestamp: 1660598775360 // } // const symbol = subscription['symbol']; const messageHash = 'orderbook:' + symbol; const timestamp = this.safeString(message, 'timestamp'); let storedOrderBook = this.safeValue(this.orderbooks, symbol); if (storedOrderBook === undefined) { storedOrderBook = this.indexedOrderBook({}); this.orderbooks[symbol] = storedOrderBook; } const asks = this.safeValue(message, 'asks'); if (asks !== undefined) { const snapshot = this.customParseOrderBook(message, symbol, timestamp, 'bids', 'asks', 'price', 'volume', 'id'); storedOrderBook.reset(snapshot); } else { this.handleDelta(storedOrderBook, message); storedOrderBook['timestamp'] = timestamp; storedOrderBook['datetime'] = this.iso8601(timestamp); } const nonce = this.safeInteger(message, 'sequence'); storedOrderBook['nonce'] = nonce; client.resolve(storedOrderBook, messageHash); } customParseOrderBook(orderbook, symbol, timestamp = undefined, bidsKey = 'bids', asksKey = 'asks', priceKey = 'price', amountKey = 'volume', thirdKey = undefined) { const bids = this.parseBidsAsks(this.safeValue(orderbook, bidsKey, []), priceKey, amountKey, thirdKey); const asks = this.parseBidsAsks(this.safeValue(orderbook, asksKey, []), priceKey, amountKey, thirdKey); return { 'symbol': symbol, 'bids': this.sortBy(bids, 0, true), 'asks': this.sortBy(asks, 0), 'timestamp': timestamp, 'datetime': this.iso8601(timestamp), 'nonce': undefined, }; } parseBidsAsks(bidasks, priceKey = 'price', amountKey = 'volume', thirdKey = undefined) { bidasks = this.toArray(bidasks); const result = []; for (let i = 0; i < bidasks.length; i++) { result.push(this.customParseBidAsk(bidasks[i], priceKey, amountKey, thirdKey)); } return result; } customParseBidAsk(bidask, priceKey = 'price', amountKey = 'volume', thirdKey = undefined) { const price = this.safeNumber(bidask, priceKey); const amount = this.safeNumber(bidask, amountKey); const result = [price, amount]; if (thirdKey !== undefined) { const thirdValue = this.safeString(bidask, thirdKey); result.push(thirdValue); } return result; } handleDelta(orderbook, message) { // // create // { // sequence: '110980825', // trade_updates: [], // create_update: { // order_id: 'BXHSYXAUMH8C2RW', // type: 'ASK', // price: '24081.09000000', // volume: '0.07780000' // }, // delete_update: null, // status_update: null, // timestamp: 1660598775360 // } // delete // { // sequence: '110980825', // trade_updates: [], // create_update: null, // delete_update: { // "order_id": "BXMC2CJ7HNB88U4" // }, // status_update: null, // timestamp: 1660598775360 // } // trade // { // sequence: '110980825', // trade_updates: [ // { // "base": "0.1", // "counter": "5232.00", // "maker_order_id": "BXMC2CJ7HNB88U4", // "taker_order_id": "BXMC2CJ7HNB88U5" // } // ], // create_update: null, // delete_update: null, // status_update: null, // timestamp: 1660598775360 // } // const createUpdate = this.safeValue(message, 'create_update'); const asksOrderSide = orderbook['asks']; const bidsOrderSide = orderbook['bids']; if (createUpdate !== undefined) { const array = this.customParseBidAsk(createUpdate, 'price', 'volume', 'order_id'); const type = this.safeString(createUpdate, 'type'); if (type === 'ASK') { asksOrderSide.storeArray(array); } else if (type === 'BID') { bidsOrderSide.storeArray(array); } } const deleteUpdate = this.safeValue(message, 'delete_update'); if (deleteUpdate !== undefined) { const orderId = this.safeString(deleteUpdate, 'order_id'); asksOrderSide.storeArray(0, 0, orderId); bidsOrderSide.storeArray(0, 0, orderId); } return message; } handleMessage(client, message) { if (message === '') { return; } const subscriptions = Object.values(client.subscriptions); const handlers = [this.handleOrderBook, this.handleTrades]; for (let j = 0; j < handlers.length; j++) { const handler = handlers[j]; handler.call(this, client, message, subscriptions[0]); } return message; } }