Initially ported from Go orderbook, this order book has been enhanced with new features
⭐ Star me on GitHub — it motivates me a lot!
Ultra-fast matching engine written in TypeScript
- Standard price-time priority
- Supports both market and limit orders
- Supports time in force GTC, FOK and IOC
- Supports order cancelling
- Supports order price and/or size updating
- High performance (above 300k trades per second)
Machine: ASUS ExpertBook, 11th Gen Intel(R) Core(TM) i7-1165G7, 2.80Ghz, 16GB RAM, Node.js v18.4.0.
Install with npm:
npm install hft-limit-order-book --save
Install with yarn:
yarn add hft-limit-order-book
To start using order book you need to import OrderBook
and create new instance:
import { OrderBook } from 'hft-limit-order-book';
const lob = new OrderBook();
Then you'll be able to use next primary functions:
lob.createOrder(type: 'limit' | 'market', side: 'buy' | 'sell', size: number, price: number, orderID: string)
lob.limit(side: 'buy' | 'sell', orderID: string, size: number, price: number);
lob.market(side: 'buy' | 'sell', size: number);
lob.modify(orderID: string, { side: 'buy' | 'sell', size: number, price: number });
lob.cancel(orderID: string);
To add an order to the order book you can call the general createOrder()
function or calling the underlying limit()
or market()
functions
// Create a limit order
createOrder('limit', side: 'buy' | 'sell', size: number, price: number, orderID: string, timeInForce?: 'GTC' | 'FOK' | 'IOC');
// Create a market order
createOrder('market', side: 'buy' | 'sell', size: number);
/**
* Create a limit order
*
* @param side - `sell` or `buy`
* @param orderID - Unique order ID
* @param size - How much of currency you want to trade in units of base currency
* @param price - The price at which the order is to be fullfilled, in units of the quote currency
* @param timeInForce - Time-in-force type supported are: GTC, FOK, IOC
* @returns An object with the result of the processed order or an error
*/
limit(side: 'buy' | 'sell', orderID: string, size: number, price: number, timeInForce?: 'GTC' | 'FOK' | 'IOC');
For example:
limit("sell", "uniqueID", 55, 100);
asks: 110 -> 5 110 -> 5
100 -> 1 100 -> 56
-------------- -> --------------
bids: 90 -> 5 90 -> 5
80 -> 1 80 -> 1
done - null
partial - null
limit("buy", "uniqueID", 7, 120);
asks: 110 -> 5
100 -> 1
-------------- -> --------------
bids: 90 -> 5 120 -> 1
80 -> 1 90 -> 5
80 -> 1
done - 2 (or more orders)
partial - uniqueID order
limit("buy", "uniqueID", 3, 120);
asks: 110 -> 5
100 -> 1 110 -> 3
-------------- -> --------------
bids: 90 -> 5 90 -> 5
80 -> 1 80 -> 1
done - 1 order with 100 price, (may be also few orders with 110 price) + uniqueID order
partial - 1 order with price 110
/**
* Create a market order
*
* @param side - `sell` or `buy`
* @param size - How much of currency you want to trade in units of base currency
* @returns An object with the result of the processed order or an error
*/
market(side: 'buy' | 'sell', size: number);
For example:
market('sell', 6);
asks: 110 -> 5 110 -> 5
100 -> 1 100 -> 1
-------------- -> --------------
bids: 90 -> 5 80 -> 1
80 -> 2
done - 2 (or more orders)
partial - 1 order with price 80
quantityLeft - 0
market('buy', 10);
asks: 110 -> 5
100 -> 1
-------------- -> --------------
bids: 90 -> 5 90 -> 5
80 -> 1 80 -> 1
done - 2 (or more orders)
partial - null
quantityLeft - 4
/**
* Modify an existing order with given ID. When an order is modified by price or quantity,
* it will be deemed as a new entry. Under the price-time-priority algorithm, orders are
* prioritized according to their order price and order time. Hence, the latest orders
* will be placed at the back of the matching order queue.
*
* @param orderID - The ID of the order to be modified
* @param orderUpdate - An object with the modified size and/or price of an order. The shape of the object is `{size, price}`.
* @returns An object with the result of the processed order or an error
*/
modify(orderID: string, { size: number, price: number });
For example:
limit("sell", "uniqueID", 55, 100);
asks: 110 -> 5 110 -> 5
100 -> 1 100 -> 56
-------------- -> --------------
bids: 90 -> 5 90 -> 5
80 -> 1 80 -> 1
// Modify the size from 55 to 65
modify("uniqueID", { size: 65 })
asks: 110 -> 5 110 -> 5
100 -> 56 100 -> 66
-------------- -> --------------
bids: 90 -> 5 90 -> 5
80 -> 1 80 -> 1
// Modify the price from 100 to 110
modify("uniqueID", { price: 110 })
asks: 110 -> 5 110 -> 70
100 -> 66 100 -> 1
-------------- -> --------------
bids: 90 -> 5 90 -> 5
80 -> 1 80 -> 1
/**
* Remove an existing order with given ID from the order book
*
* @param orderID - The ID of the order to be removed
* @returns The removed order if exists or `undefined`
*/
cancel(orderID: string);
For example:
cancel("myUniqueID-Sell-1-with-100")
asks: 110 -> 5
100 -> 1 110 -> 5
-------------- -> --------------
bids: 90 -> 5 90 -> 5
80 -> 1 80 -> 1
Build production (distribution) files in your dist folder:
npm run build
To run all the unit-test
npm run test
Run testing coverage
npm run test:cov
Before running benchmark, make sure to have built the source code with npm run build
first
npm run bench
I would greatly appreciate any contributions to make this project better. Please make sure to follow the below guidelines before getting your hands dirty.
- Fork the repository
- Create your branch (git checkout -b my-branch)
- Commit any changes to your branch
- Push your changes to your remote branch
- Open a pull request
If this project help you reduce time to develop, you can give me a cup of coffee 🍵 :)
- USDT (TRC20):
TXArNxsq2Ee8Jvsk45PudVio52Joiq1yEe
- BTC:
1GYDVSAQNgG7MFhV5bk15XJy3qoE4NFenp
- BTC (BEP20):
0xf673ee099be8129ec05e2f549d96ebea24ac5d97
- ETH (ERC20):
0xf673ee099be8129ec05e2f549d96ebea24ac5d97
- BNB (BEP20):
0xf673ee099be8129ec05e2f549d96ebea24ac5d97
Copyright Andrea Fassina, Licensed under MIT.