Skip to content

Commit

Permalink
fix(orderbook): show aggregated quantity
Browse files Browse the repository at this point in the history
  • Loading branch information
Karl Ranna committed Jul 10, 2019
1 parent df694c1 commit 55538ce
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 37 deletions.
61 changes: 34 additions & 27 deletions lib/cli/commands/orderbook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ type FormattedOrderbook = {
rows: string[][],
};

type BucketDepth = {
type Bucket = {
price: number,
depth: number;
quantity: number;
};

type OrderbookJson = {
pairId: string,
sell: BucketDepth[],
buy: BucketDepth[],
sell: Bucket[],
buy: Bucket[],
};

const COLUMNS = [19, 19, 19, 19];
Expand All @@ -28,19 +28,26 @@ const HEADER = [
{ content: colors.red('Sell'), colSpan: 2 },
];
const SECONDARY_HEADER = [
colors.green('Quantity'),
colors.green('Price'),
colors.green('Depth'),
colors.red('Price'),
colors.red('Depth'),
colors.red('Quantity'),
];

const addSide = (buckets: BucketDepth[]): string[] => {
const addSide = (buckets: Bucket[], isBuy = false): string[] => {
const bucket = buckets.pop();
if (bucket) {
return [
bucket.price.toString(),
satsToCoinsStr(bucket.depth),
];
if (isBuy) {
return [
satsToCoinsStr(bucket.quantity),
bucket.price.toString(),
];
} else {
return [
bucket.price.toString(),
satsToCoinsStr(bucket.quantity),
];
}
} else {
return Array.from(Array(COLUMNS_IN_ORDER_SIDE)).map(() => '');
}
Expand All @@ -55,7 +62,7 @@ export const createOrderbook = (orders: ListOrdersResponse.AsObject, precision:
? sell.length : buy.length;
const orderbookRows = Array.from(Array(totalRows))
.map(() => {
return addSide(buy).concat(addSide(sell));
return addSide(buy, true).concat(addSide(sell));
});
formattedOrderbooks.push({
pairId: tradingPair[0],
Expand Down Expand Up @@ -94,11 +101,11 @@ const getPriceBuckets = (orders: Order.AsObject[], count = 8): number[] => {
return uniquePrices.splice(0, count);
};

const getDepthForBuckets = (
const getQuantityForBuckets = (
orders: Order.AsObject[],
priceBuckets: number[],
filledBuckets: BucketDepth[] = [],
): BucketDepth[] => {
filledBuckets: Bucket[] = [],
): Bucket[] => {
// go through all the available price buckets
const price = priceBuckets.shift();
if (!price) {
Expand All @@ -111,15 +118,15 @@ const getDepthForBuckets = (
filteredOrders = orders
.filter(order => order.price === price);
}
// calculate depth of the bucket
const depth = filteredOrders
// calculate quantity of the bucket
const quantity = filteredOrders
.reduce((total, order) => {
return total + order.price * order.quantity;
return total + order.quantity;
}, 0);
filledBuckets.push({ price, depth });
filledBuckets.push({ price, quantity });
// filter orders for the next cycle
const restOfOrders = orders.filter(order => order.price !== price);
return getDepthForBuckets(restOfOrders, priceBuckets, filledBuckets);
return getQuantityForBuckets(restOfOrders, priceBuckets, filledBuckets);
};

export const createOrderbookSide = (orders: Order.AsObject[], precision = 5) => {
Expand All @@ -130,12 +137,12 @@ export const createOrderbookSide = (orders: Order.AsObject[], precision = 5) =>
// get price buckets in which to divide orders to
const priceBuckets = getPriceBuckets(orders);
// divide prices into buckets
return getDepthForBuckets(orders, priceBuckets);
return getQuantityForBuckets(orders, priceBuckets);
};

export const command = 'orderbook [pair_id] [precision]';

export const describe = 'list the order book';
export const describe = 'display the order book, with orders aggregated per price point';

export const builder = {
pair_id: {
Expand All @@ -151,16 +158,16 @@ export const builder = {

const displayJson = (orders: ListOrdersResponse.AsObject, argv: Arguments) => {
const jsonOrderbooks: OrderbookJson[] = [];
const depthInSatoshisPerCoin = (bucket: BucketDepth) => {
bucket.depth = parseFloat(
satsToCoinsStr(bucket.depth),
const quantityInSatoshisPerCoin = (bucket: Bucket) => {
bucket.quantity = parseFloat(
satsToCoinsStr(bucket.quantity),
);
};
orders.ordersMap.forEach((tradingPair) => {
const buy = createOrderbookSide(tradingPair[1].buyOrdersList, argv.precision);
buy.forEach(depthInSatoshisPerCoin);
buy.forEach(quantityInSatoshisPerCoin);
const sell = createOrderbookSide(tradingPair[1].sellOrdersList, argv.precision);
sell.forEach(depthInSatoshisPerCoin);
sell.forEach(quantityInSatoshisPerCoin);
jsonOrderbooks.push({
sell,
buy,
Expand Down
20 changes: 10 additions & 10 deletions test/unit/Command.orderbook.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,14 @@ describe('Command.orderbook.createOrderbookSide', () => {
.concat(createOrders(80, 0.011131, 100000))
.concat(createOrders(100, 0.011111, 100000));
expect(createOrderbookSide(orders)).to.deep.equal([
{ price: 0.01216, depth: 121600 },
{ price: 0.01119, depth: 123090 },
{ price: 0.01118, depth: 33540 },
{ price: 0.01117, depth: 44680 },
{ price: 0.01116, depth: 55800 },
{ price: 0.01115, depth: 66900 },
{ price: 0.01114, depth: 77980 },
{ price: 0.01113, depth: 200140 },
{ price: 0.01216, quantity: 10000000 },
{ price: 0.01119, quantity: 11000000 },
{ price: 0.01118, quantity: 3000000 },
{ price: 0.01117, quantity: 4000000 },
{ price: 0.01116, quantity: 5000000 },
{ price: 0.01115, quantity: 6000000 },
{ price: 0.01114, quantity: 7000000 },
{ price: 0.01113, quantity: 18000000 },
]);
});

Expand All @@ -73,8 +73,8 @@ describe('Command.orderbook.createOrderbookSide', () => {
.concat(createOrders(30, 0.011181, 100000))
.concat(createOrders(40, 0.011171, 100000));
expect(createOrderbookSide(orders, 3)).to.deep.equal([
{ price: 0.012, depth: 120000 },
{ price: 0.011, depth: 198000 },
{ price: 0.012, quantity: 10000000 },
{ price: 0.011, quantity: 18000000 },
]);
});
});

0 comments on commit 55538ce

Please sign in to comment.