UNPKG

xud

Version:
169 lines 7 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.handler = exports.builder = exports.describe = exports.command = exports.createOrderbookSide = exports.createOrderbook = void 0; const cli_table3_1 = __importDefault(require("cli-table3")); const safe_1 = __importDefault(require("colors/safe")); const enums_1 = require("../../constants/enums"); const xudrpc_pb_1 = require("../../proto/xudrpc_pb"); const command_1 = require("../command"); const utils_1 = require("../utils"); const COLUMNS = [19, 19, 19, 19]; const COLUMNS_IN_ORDER_SIDE = COLUMNS.length / 2; const HEADER = [ { content: safe_1.default.green('Buy'), colSpan: 2 }, { content: safe_1.default.red('Sell'), colSpan: 2 }, ]; const SECONDARY_HEADER = [ safe_1.default.green('Quantity'), safe_1.default.green('Price'), safe_1.default.red('Price'), safe_1.default.red('Quantity'), ]; const addSide = (buckets, isBuy = false) => { const bucket = buckets.pop(); if (bucket) { if (isBuy) { return [ utils_1.satsToCoinsStr(bucket.quantity), bucket.price.toString(), ]; } else { return [ bucket.price.toString(), utils_1.satsToCoinsStr(bucket.quantity), ]; } } else { return Array.from(Array(COLUMNS_IN_ORDER_SIDE)).map(() => ''); } }; exports.createOrderbook = (orders, precision) => { const formattedOrderbooks = []; orders.ordersMap.forEach((tradingPair) => { const buy = exports.createOrderbookSide(tradingPair[1].buyOrdersList, precision); const sell = exports.createOrderbookSide(tradingPair[1].sellOrdersList, precision); const totalRows = buy.length < sell.length ? sell.length : buy.length; const orderbookRows = Array.from(Array(totalRows)) .map(() => { return addSide(buy, true).concat(addSide(sell)); }); formattedOrderbooks.push({ pairId: tradingPair[0], rows: orderbookRows, }); }); return formattedOrderbooks; }; const createTable = () => { const table = new cli_table3_1.default({ colWidths: COLUMNS, }); table.push(HEADER); table.push(SECONDARY_HEADER); return table; }; const displayOrderbook = (orderbook) => { const table = createTable(); orderbook.rows.forEach(row => table.push(row)); console.log(safe_1.default.underline(safe_1.default.bold(`\nTrading pair: ${orderbook.pairId}`))); console.log(table.toString()); }; const displayTables = (orders, argv) => { exports.createOrderbook(orders, argv.precision).forEach(displayOrderbook); }; const getPriceBuckets = (orders, count = 8) => { const uniquePrices = [ ...new Set(orders.map(order => order.price)), ]; return uniquePrices.splice(0, count); }; const getQuantityForBuckets = (orders, priceBuckets, filledBuckets = []) => { // go through all the available price buckets const price = priceBuckets.shift(); if (!price) { // stop recursion when we're out of buckets to fill return filledBuckets; } let filteredOrders = orders; // filter to specific bucket when the next one exists if (priceBuckets.length !== 0) { filteredOrders = orders .filter(order => order.price === price); } // calculate quantity of the bucket const quantity = filteredOrders .reduce((total, order) => { return total + order.quantity; }, 0); filledBuckets.push({ price, quantity }); // filter orders for the next cycle const restOfOrders = orders.filter(order => order.price !== price); return getQuantityForBuckets(restOfOrders, priceBuckets, filledBuckets); }; exports.createOrderbookSide = (orders, precision = 5) => { // round prices down to the desired precision orders.forEach((order) => { order.price = parseFloat(order.price.toFixed(precision)); }); // get price buckets in which to divide orders to const priceBuckets = getPriceBuckets(orders); // divide prices into buckets return getQuantityForBuckets(orders, priceBuckets); }; exports.command = 'orderbook [pair_id] [precision]'; exports.describe = 'display the order book, with orders aggregated per price point'; exports.builder = (argv) => argv .option('pair_id', { describe: 'trading pair for which to retrieve the order book', type: 'string', }) .option('precision', { describe: 'the number of digits following the decimal point', type: 'number', default: 8, }) .example('$0 orderbook', 'display the order books for all trading pairs') .example('$0 orderbook LTC/BTC', 'display the LTC/BTC order book') .example('$0 orderbook LTC/BTC 2', 'display the LTC/BTC order book with 2 decimal precision') .example('$0 orderbook --precision 2', 'display the order books for all trading pairs with 2 decimal precision'); const displayJson = (orders, argv) => { const jsonOrderbooks = []; const quantityInSatoshisPerCoin = (bucket) => { bucket.quantity = parseFloat(utils_1.satsToCoinsStr(bucket.quantity)); }; orders.ordersMap.forEach((tradingPair) => { const buy = exports.createOrderbookSide(tradingPair[1].buyOrdersList, argv.precision); buy.forEach(quantityInSatoshisPerCoin); const sell = exports.createOrderbookSide(tradingPair[1].sellOrdersList, argv.precision); sell.forEach(quantityInSatoshisPerCoin); jsonOrderbooks.push({ sell, buy, pairId: tradingPair[0], }); }); console.log(JSON.stringify(jsonOrderbooks, undefined, 2)); }; exports.handler = (argv) => __awaiter(void 0, void 0, void 0, function* () { const request = new xudrpc_pb_1.ListOrdersRequest(); const pairId = argv.pair_id ? argv.pair_id.toUpperCase() : undefined; request.setPairId(pairId); request.setOwner(Number(enums_1.Owner.Both)); (yield command_1.loadXudClient(argv)).listOrders(request, command_1.callback(argv, displayTables, displayJson)); }); //# sourceMappingURL=orderbook.js.map