Skip to content

Commit

Permalink
feat(rpc): add limit to ListOrders call (#820)
Browse files Browse the repository at this point in the history
This adds a parameter to the `ListOrders` rpc call to limit the number
of orders returned from each side of the order book. It also sorts all
orders before they are sent to the caller.

Closes #748.
  • Loading branch information
ImmanuelSegol authored and sangaman committed Apr 20, 2019
1 parent 082d059 commit 1b78331
Show file tree
Hide file tree
Showing 10 changed files with 94 additions and 33 deletions.
1 change: 1 addition & 0 deletions docs/api.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 16 additions & 15 deletions lib/cli/commands/listorders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ const addSide = (orderSide: Order.AsObject[]): string[] => {
export const formatOrders = (orders: ListOrdersResponse.AsObject) => {
const formattedOrders: FormattedTradingPairOrders[] = [];
orders.ordersMap.forEach((tradingPair) => {
const buy = sortOrders(tradingPair[1].buyOrdersList, true);
const sell = sortOrders(tradingPair[1].sellOrdersList, false);
const buy = tradingPair[1].buyOrdersList;
const sell = tradingPair[1].sellOrdersList;
const totalRows = buy.length < sell.length
? sell.length : buy.length;
const tradingPairOrders = Array.from(Array(totalRows))
Expand All @@ -67,17 +67,6 @@ const createTable = () => {
return table;
};

const sortOrders = (orderSide: Order.AsObject[], isBuy: boolean) => {
return orderSide.sort((a, b) => {
if (a.price === b.price) {
return a.createdAt - b.createdAt;
}
return isBuy
? a.price - b.price
: b.price - a.price;
});
};

const displayOrdersTable = (tradingPair: FormattedTradingPairOrders) => {
const table = createTable();
tradingPair.orders.forEach(order => table.push(order));
Expand All @@ -89,20 +78,32 @@ const displayTables = (orders: ListOrdersResponse.AsObject) => {
formatOrders(orders).forEach(displayOrdersTable);
};

export const command = 'listorders [pair_id]';
export const command = 'listorders [pair_id] [include_own_orders] [limit]';

export const describe = 'list orders from the order book';

export const builder = {
pair_id: {
describe: 'trading pair for which to retrieve orders',
type: 'string',
},
include_own_orders: {
describe: 'whether to include own orders',
type: 'boolean',
default: true,
},
limit: {
describe: 'max number of orders to return',
type: 'number',
default: 0,
},
};

export const handler = (argv: Arguments) => {
const request = new ListOrdersRequest();
const pairId = argv.pair_id ? argv.pair_id.toUpperCase() : undefined;
request.setPairId(pairId);
request.setIncludeOwnOrders(true);
request.setIncludeOwnOrders(argv.include_own_orders);
request.setLimit(argv.limit);
loadXudClient(argv).listOrders(request, callback(argv, displayTables));
};
8 changes: 8 additions & 0 deletions lib/proto/xudrpc.swagger.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions lib/proto/xudrpc_pb.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 28 additions & 1 deletion lib/proto/xudrpc_pb.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 21 additions & 4 deletions lib/service/Service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { EventEmitter } from 'events';
import errors from './errors';
import { SwapClient, OrderSide, SwapRole } from '../constants/enums';
import { parseUri, toUri, UriParts } from '../utils/uriUtils';
import { sortOrders } from '../utils/utils';
import * as lndrpc from '../proto/lndrpc_pb';
import { Pair, Order, OrderPortion, PlaceOrderEvent } from '../orderbook/types';
import Swaps from '../swaps/Swaps';
Expand Down Expand Up @@ -263,20 +264,36 @@ class Service extends EventEmitter {
/**
* Get a map between pair ids and its orders from the order book.
*/
public listOrders = (args: { pairId: string, includeOwnOrders: boolean }): Map<string, OrderSidesArrays<any>> => {
const { pairId, includeOwnOrders } = args;
public listOrders = (args: { pairId: string, includeOwnOrders: boolean, limit: number }): Map<string, OrderSidesArrays<any>> => {
const { pairId, includeOwnOrders, limit } = args;

const result = new Map<string, OrderSidesArrays<any>>();

const listOrderTypes = (pairId: string) => {
const orders = this.orderBook.getPeersOrders(pairId);
const orders: OrderSidesArrays<any> = {
buy: [],
sell: [],
};

const peerOrders = this.orderBook.getPeersOrders(pairId);
orders.buy = peerOrders.buy;
orders.sell = peerOrders.sell;

if (includeOwnOrders) {
const ownOrders: OrderSidesArrays<any> = this.orderBook.getOwnOrders(pairId);
const ownOrders = this.orderBook.getOwnOrders(pairId);

orders.buy = [...orders.buy, ...ownOrders.buy];
orders.sell = [...orders.sell, ...ownOrders.sell];
}

// sort all orders
orders.buy = sortOrders(orders.buy, true);
orders.sell = sortOrders(orders.sell, false);

if (limit > 0) {
orders.buy = orders.buy.slice(0, limit);
orders.sell = orders.buy.slice(0, limit);
}
return orders;
};

Expand Down
13 changes: 12 additions & 1 deletion lib/utils/utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import http from 'http';
import p2pErrors from '../p2p/errors';
import { Pair } from '../orderbook/types';
import { Pair, Order } from '../orderbook/types';
import crypto from 'crypto';
import { promisify } from 'util';
import moment from 'moment';
Expand Down Expand Up @@ -177,3 +177,14 @@ export const convertKvpArrayToKvps = <T>(kvpArray: [string, T][]): { [key: strin

return kvps;
};

export const sortOrders = (orders: Order[], isBuy: boolean): Order[] => {
return orders.sort((a: Order, b: Order) => {
if (a.price === b.price) {
return a.createdAt - b.createdAt;
}
return isBuy
? a.price - b.price
: b.price - a.price;
});
};
2 changes: 2 additions & 0 deletions proto/xudrpc.proto
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,8 @@ message ListOrdersRequest {
string pair_id = 1 [json_name = "pair_id"];
// Whether own orders should be included in result or not.
bool include_own_orders = 2 [json_name = "include_own_orders"];
// The maximum number of orders to return from each side of the order book.
int32 limit = 3 [json_name = "limit"];
}
message ListOrdersResponse {
// A map between pair ids and their buy and sell orders.
Expand Down
1 change: 1 addition & 0 deletions test/integration/Service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ describe('API Service', () => {
const args = {
pairId,
includeOwnOrders: true,
limit: 0,
};
const orders = service.listOrders(args);

Expand Down
13 changes: 1 addition & 12 deletions test/unit/Command.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { formatOrders } from '../../lib/cli/commands/listorders';
import { ListOrdersResponse } from '../../lib/proto/xudrpc_pb';

describe('Command.listorders.formatOrders', () => {
it('should flatten, format and sort orders', () => {
it('should flatten and format orders', () => {
const jsonOrders: ListOrdersResponse.AsObject = {
ordersMap: [
[
Expand Down Expand Up @@ -104,17 +104,6 @@ describe('Command.listorders.formatOrders', () => {
const output = formatOrders(jsonOrders);
expect(output.length).to.equal(1);
expect(output[0].pairId).to.equal('LTC/BTC');
const expectedFirstRow = [
'\u001b[36m0.00000001\u001b[39m',
'\u001b[36m0.004321\u001b[39m',
'\u001b[36mX\u001b[39m',
'0.00000001',
'0.00458',
'',
];
const expectedLastRow = ['', '', '', '0.00000001', '0.00859', ''];
expect(output[0].orders.length).to.equal(5);
expect(output[0].orders[0]).to.deep.equal(expectedFirstRow);
expect(output[0].orders[4]).to.deep.equal(expectedLastRow);
});
});

0 comments on commit 1b78331

Please sign in to comment.