xud
Version:
Exchange Union Daemon
169 lines • 7 kB
JavaScript
;
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