{"id":18488080,"url":"https://github.com/fasenderos/nodejs-order-book","last_synced_at":"2025-05-16T09:03:02.704Z","repository":{"id":49787394,"uuid":"517968287","full_name":"fasenderos/nodejs-order-book","owner":"fasenderos","description":"Ultra-fast Limit Order Book for Node.js written in TypeScript for high-frequency trading (HFT) :rocket::rocket:","archived":false,"fork":false,"pushed_at":"2025-05-06T18:30:06.000Z","size":3202,"stargazers_count":166,"open_issues_count":5,"forks_count":40,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-05-08T18:02:12.738Z","etag":null,"topics":["exchange","hft","hft-trading","limit-order-book","low-latency","matching-algorithm","matching-engine","nodejs","nodejs-order-book","order-book","orderbook","performance","trading","trading-algorithms","typescript"],"latest_commit_sha":null,"homepage":"https://github.com/fasenderos/nodejs-order-book","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fasenderos.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":["fasenderos"]}},"created_at":"2022-07-26T08:02:48.000Z","updated_at":"2025-05-07T10:41:56.000Z","dependencies_parsed_at":"2024-02-19T20:26:36.245Z","dependency_job_id":"d1180a82-8ebf-4530-a623-2e872f931616","html_url":"https://github.com/fasenderos/nodejs-order-book","commit_stats":{"total_commits":203,"total_committers":3,"mean_commits":67.66666666666667,"dds":0.2660098522167488,"last_synced_commit":"b7b43ef08378559f445e190c5f73735cc575f1e5"},"previous_names":["fasenderos/nodejs-order-book","fasenderos/hft-limit-order-book","fasenderos/order-book"],"tags_count":36,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fasenderos%2Fnodejs-order-book","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fasenderos%2Fnodejs-order-book/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fasenderos%2Fnodejs-order-book/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fasenderos%2Fnodejs-order-book/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fasenderos","download_url":"https://codeload.github.com/fasenderos/nodejs-order-book/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254501555,"owners_count":22081528,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["exchange","hft","hft-trading","limit-order-book","low-latency","matching-algorithm","matching-engine","nodejs","nodejs-order-book","order-book","orderbook","performance","trading","trading-algorithms","typescript"],"created_at":"2024-11-06T12:51:12.770Z","updated_at":"2025-05-16T09:03:02.680Z","avatar_url":"https://github.com/fasenderos.png","language":"TypeScript","readme":"\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://www.npmjs.com/package/nodejs-order-book\" target=\"_blank\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/nodejs-order-book?color=blue\" alt=\"NPM Version\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/fasenderos/nodejs-order-book/blob/main/LICENSE\" target=\"_blank\"\u003e\u003cimg src=\"https://img.shields.io/npm/l/nodejs-order-book\" alt=\"Package License\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://www.npmjs.com/package/nodejs-order-book\" target=\"_blank\"\u003e\u003cimg src=\"https://img.shields.io/npm/dm/nodejs-order-book\" alt=\"NPM Downloads\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://circleci.com/gh/fasenderos/nodejs-order-book\" target=\"_blank\"\u003e\u003cimg src=\"https://img.shields.io/circleci/build/github/fasenderos/nodejs-order-book/main\" alt=\"CircleCI\" \u003e\u003c/a\u003e\n    \u003ca href=\"https://codecov.io/github/fasenderos/nodejs-order-book\" target=\"_blank\"\u003e\u003cimg src=\"https://img.shields.io/codecov/c/github/fasenderos/nodejs-order-book\" alt=\"Codecov\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/fasenderos/nodejs-order-book\"\u003e\u003cimg src=\"https://badgen.net/badge/icon/typescript?icon=typescript\u0026label\" alt=\"Built with TypeScript\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n# Node.js Order Book\n\n\u003cp align=\"center\"\u003e\nUltra-fast Node.js Order Book written in TypeScript \u003c/br\u003e for high-frequency trading (HFT) :rocket::rocket: \u003c/br\u003e\u003c/br\u003e\n:star: Star me on GitHub — it motivates me a lot!\n\u003c/p\u003e\n\n## Table of Contents\n\n- [Features](#features)\n- [Installation](#installation)\n- [Usage](#usage)\n- [Experimental Conditional Orders](#conditional-orders-)\n- [About Primary Functions](#about-primary-functions)\n  - [Create order `createOrder()`](#create-order)\n  - [Create Limit order `limit()`](#create-limit-order)\n  - [Create Market order `market()`](#create-market-order)\n  - [Create Stop Limit order `stopLimit()`](#create-stop-limit-order)\n  - [Create Stop Market order `stopMarket()`](#create-stop-market-order)\n  - [Create OCO (One-Cancels-the-Other) order `oco()`](#create-oco-one-cancels-the-other-order)\n  - [Modify an existing order `modifiy()`](#modify-an-existing-order)\n  - [Cancel order `cancel()`](#cancel-order)\n- [Order Book Options](#order-book-options)\n  - [Snapshot](#snapshot)\n  - [Journal Logs](#journal-logs)\n  - [Enable Journaling](#enable-journaling)\n- [Development](#development)\n  - [Build](#build)\n  - [Testing](#testing)\n  - [Coverage](#coverage)\n  - [Benchmarking](#benchmarking)\n- [Contributing](#contributing)\n- [Donation](#donation)\n- [License](#license)\n\n## Features\n\u003e Initially ported from [Go orderbook](https://github.com/i25959341/orderbook), this order book has been enhanced with new features\n\n- Standard price-time priority\n- Supports both market and limit orders\n- Supports `post-only` limit order \u003cimg src=\"https://img.shields.io/badge/New-green\" alt=\"New\"\u003e\n- Supports conditional orders [**Stop Limit, Stop Market and OCO**](#conditional-orders-) \u003cimg src=\"https://img.shields.io/badge/New-green\" alt=\"New\"\u003e \u003cimg src=\"https://img.shields.io/badge/Experimental-blue\" alt=\"Experimental\"\u003e\n- Supports time in force GTC, FOK and IOC \u003cimg src=\"https://img.shields.io/badge/New-green\" alt=\"New\"\u003e\n- Supports order cancelling\n- Supports order price and/or size updating \u003cimg src=\"https://img.shields.io/badge/New-green\" alt=\"New\"\u003e\n- Snapshot and journaling functionalities for restoring the order book during server startup \u003cimg src=\"https://img.shields.io/badge/New-green\" alt=\"New\"\u003e\n- **High performance (above 300k trades per second)**\n\n**Machine:** ASUS ExpertBook, 11th Gen Intel(R) Core(TM) i7-1165G7, 2.80Ghz, 16GB RAM, Node.js v18.4.0.\n\n\u003cimg src=\"https://user-images.githubusercontent.com/1219087/181792292-8619ee25-bf75-4871-a06c-bd6c82157f33.png\" alt=\"nodejs-order-book-benchmark\" title=\"nodejs-order-book benchmark\" /\u003e\n\n## Installation\n\nInstall with npm:\n\n```sh\nnpm install nodejs-order-book\n```\n\nInstall with yarn:\n\n```sh\nyarn add nodejs-order-book\n```\n\nInstall with pnpm:\n\n```sh\npnpm add nodejs-order-book\n```\n\n## Usage\n\nTo start using order book you need to import `OrderBook` and create new instance:\n\n```js\nimport { OrderBook } from 'nodejs-order-book'\n\nconst ob = new OrderBook()\n```\n\nThen you'll be able to use next primary functions:\n\n```js\nob.createOrder({ type: 'limit' | 'market', side: 'buy' | 'sell', size: number, price?: number, id?: string, postOnly?: boolean, timeInForce?: 'GTC' | 'FOK' | 'IOC' })\n\nob.limit({ id: string, side: 'buy' | 'sell', size: number, price: number, postOnly?: boolean, timeInForce?: 'GTC' | 'FOK' | 'IOC' })\n\nob.market({ side: 'buy' | 'sell', size: number })\n\nob.modify(orderID: string, { side: 'buy' | 'sell', size: number, price: number })\n\nob.cancel(orderID: string)\n```\n### Conditional Orders ![Experimental](https://img.shields.io/badge/Experimental-blue)\nThe version `v6.1.0` introduced support for Conditional Orders `Stop Market`, `Stop Limit` and `OCO`. Even though the test coverage for these new features is at 100%, they are not yet considered stable because they have not been tested with real-world scenarios. For this reason, if you want to use conditional orders, you need to instantiate the order book with the `experimentalConditionalOrders` option set to `true`.\n```js\nimport { OrderBook } from 'nodejs-order-book'\n\nconst ob = new OrderBook({ experimentalConditionalOrders: true })\n\nob.createOrder({ type: 'stop_limit' | 'stop_market' | 'oco', side: 'buy' | 'sell', size: number, price?: number, id?: string, stopPrice?: number, timeInForce?: 'GTC' | 'FOK' | 'IOC', stopLimitTimeInForce?: 'GTC' | 'FOK' | 'IOC' })\n\nob.stopLimit({ id: string, side: 'buy' | 'sell', size: number, price: number, stopPrice: number, timeInForce?: 'GTC' | 'FOK' | 'IOC' })\n\nob.stopMarket({ side: 'buy' | 'sell', size: number, stopPrice: number })\n\nob.oco({ id: string, side: 'buy' | 'sell', size: number, price: number, stopPrice: number, stopLimitPrice: number, timeInForce?: 'GTC' | 'FOK' | 'IOC', stopLimitTimeInForce?: 'GTC' | 'FOK' | 'IOC' })\n```\n\n## About primary functions\n\nTo add an order to the order book you can call the general `createOrder()` function or calling the underlying `limit()`, `market()`, `stopLimit()`, `stopMarket()` or `oco()` functions\n\n### Create Order\n\n```js\n// Create limit order\nob.createOrder({ type: 'limit', side: 'buy' | 'sell', size: number, price: number, id: string, postOnly?: boolean, timeInForce?: 'GTC' | 'FOK' | 'IOC' })\n\n// Create market order\nob.createOrder({ type: 'market', side: 'buy' | 'sell', size: number })\n\n// Create stop limit order\nob.createOrder({ type: 'stop_limit', side: 'buy' | 'sell', size: number, price: number, id: string, stopPrice: number, timeInForce?: 'GTC' | 'FOK' | 'IOC' })\n\n// Create stop market order\nob.createOrder({ type: 'stop_market', side: 'buy' | 'sell', size: number, stopPrice: number })\n\n// Create OCO order\nob.createOrder({ type: 'oco', side: 'buy' | 'sell', size: number, stopPrice: number, stopLimitPrice: number, timeInForce?: 'GTC' | 'FOK' | 'IOC', stopLimitTimeInForce?: 'GTC' | 'FOK' | 'IOC' })\n```\n\n### Create Limit Order\n\n```js\n/**\n * Create a limit order. See {@link LimitOrderOptions} for details.\n *\n * @param options\n * @param options.side - `sell` or `buy`\n * @param options.id - Unique order ID\n * @param options.size - How much of currency you want to trade in units of base currency\n * @param options.price - The price at which the order is to be fullfilled, in units of the quote currency\n * @param options.postOnly - When `true` the order will be rejected if immediately matches and trades as a taker. Default is `false`\n * @param options.timeInForce - Time-in-force type supported are: GTC, FOK, IOC. Default is GTC\n * @returns An object with the result of the processed order or an error. See {@link IProcessOrder} for the returned data structure\n */\nob.limit({ side: 'buy' | 'sell', id: string, size: number, price: number, postOnly?: boolean, timeInForce?: 'GTC' | 'FOK' | 'IOC' })\n```\n\nFor example:\n\n```\nob.limit({ side: \"sell\", id: \"uniqueID\", size: 55, price: 100 })\n\nasks: 110 -\u003e 5      110 -\u003e 5\n      100 -\u003e 1      100 -\u003e 56\n--------------  -\u003e  --------------\nbids: 90  -\u003e 5      90  -\u003e 5\n      80  -\u003e 1      80  -\u003e 1\n\ndone    - null\npartial - null\n```\n\n```\nob.limit({ side: \"buy\", id: \"uniqueID\", size: 7, price: 120 })\n\nasks: 110 -\u003e 5\n      100 -\u003e 1\n--------------  -\u003e  --------------\nbids: 90  -\u003e 5      120 -\u003e 1\n      80  -\u003e 1      90  -\u003e 5\n                    80  -\u003e 1\n\ndone    - 2 (or more orders)\npartial - uniqueID order\n```\n\n```\nob.limit({ side: \"buy\", id: \"uniqueID\", size: 3, price: 120 })\n\nasks: 110 -\u003e 5\n      100 -\u003e 1      110 -\u003e 3\n--------------  -\u003e  --------------\nbids: 90  -\u003e 5      90  -\u003e 5\n      80  -\u003e 1      80  -\u003e 1\n\ndone    - 1 order with 100 price, (may be also few orders with 110 price) + uniqueID order\npartial - 1 order with price 110\n```\n\n### Create Market Order\n\n```js\n/**\n * Create a market order. See {@link MarketOrderOptions} for details.\n *\n * @param options\n * @param options.side - `sell` or `buy`\n * @param options.size - How much of currency you want to trade in units of base currency\n * @returns An object with the result of the processed order or an error. See {@link IProcessOrder} for the returned data structure\n */\nob.market({ side: 'buy' | 'sell', size: number })\n```\n\nFor example:\n\n```\nob.market({ side: 'sell', size: 6 })\n\nasks: 110 -\u003e 5      110 -\u003e 5\n      100 -\u003e 1      100 -\u003e 1\n--------------  -\u003e  --------------\nbids: 90  -\u003e 5      80 -\u003e 1\n      80  -\u003e 2\n\ndone         - 2 (or more orders)\npartial      - 1 order with price 80\nquantityLeft - 0\n```\n\n```\nob.market({ side: 'buy', size: 10 })\n\nasks: 110 -\u003e 5\n      100 -\u003e 1\n--------------  -\u003e  --------------\nbids: 90  -\u003e 5      90  -\u003e 5\n      80  -\u003e 1      80  -\u003e 1\n\ndone         - 2 (or more orders)\npartial      - null\nquantityLeft - 4\n```\n\n### Create Stop Limit Order\n\n```js\n/**\n * Create a stop limit order. See {@link StopLimitOrderOptions} for details.\n *\n * @param options\n * @param options.side - `sell` or `buy`\n * @param options.id - Unique order ID\n * @param options.size - How much of currency you want to trade in units of base currency\n * @param options.price - The price at which the order is to be fullfilled, in units of the quote currency\n * @param options.stopPrice - The price at which the order will be triggered.\n * @param options.timeInForce - Time-in-force type supported are: GTC, FOK, IOC. Default is GTC\n * @returns An object with the result of the processed order or an error. See {@link IProcessOrder} for the returned data structure\n */\nob.stopLimit({ side: 'buy' | 'sell', id: string, size: number, price: number, stopPrice: number, timeInForce?: 'GTC' | 'FOK' | 'IOC' })\n```\n\n### Create Stop Market Order\n\n```js\n/**\n * Create a stop market order. See {@link StopMarketOrderOptions} for details.\n *\n * @param options\n * @param options.side - `sell` or `buy`\n * @param options.size - How much of currency you want to trade in units of base currency\n * @param options.stopPrice - The price at which the order will be triggered.\n * @returns An object with the result of the processed order or an error. See {@link IProcessOrder} for the returned data structure\n */\nob.stopMarket({ side: 'buy' | 'sell', size: number, stopPrice: number })\n```\n\n### Create OCO (One-Cancels-the-Other) Order\n\n```js\n/**\n * Create an OCO (One-Cancels-the-Other) order.\n * OCO order combines a `stop_limit` order and a `limit` order, where if stop price\n * is triggered or limit order is fully or partially fulfilled, the other is canceled.\n * Both orders have the same `side` and `size`. If you cancel one of the orders, the\n * entire OCO order pair will be canceled.\n *\n * For BUY orders the `stopPrice` must be above the current price and the `price` below the current price\n * For SELL orders the `stopPrice` must be below the current price and the `price` above the current price\n *\n * See {@link OCOOrderOptions} for details.\n *\n * @param options\n * @param options.side - `sell` or `buy`\n * @param options.id - Unique order ID\n * @param options.size - How much of currency you want to trade in units of base currency\n * @param options.price - The price of the `limit` order at which the order is to be fullfilled, in units of the quote currency\n * @param options.stopPrice - The price at which the `stop_limit` order will be triggered.\n * @param options.stopLimitPrice - The price of the `stop_limit` order at which the order is to be fullfilled, in units of the quote currency.\n * @param options.timeInForce - Time-in-force of the `limit` order. Type supported are: GTC, FOK, IOC. Default is GTC\n * @param options.stopLimitTimeInForce - Time-in-force of the `stop_limit` order. Type supported are: GTC, FOK, IOC. Default is GTC\n * @returns An object with the result of the processed order or an error. See {@link IProcessOrder} for the returned data structure\n */\nob.oco({ side: 'buy' | 'sell', id: string, size: number, price: number, stopPrice: number, stopLimitPrice: number, timeInForce?: 'GTC' | 'FOK' | 'IOC', stopLimitTimeInForce?: 'GTC' | 'FOK' | 'IOC' })\n```\n\n### Modify an existing order\n\n```js\n/**\n * Modify an existing order with given ID. When an order is modified by price or quantity,\n * it will be deemed as a new entry. Under the price-time-priority algorithm, orders are\n * prioritized according to their order price and order time. Hence, the latest orders\n * will be placed at the back of the matching order queue.\n *\n * @param orderID - The ID of the order to be modified\n * @param orderUpdate - An object with the modified size and/or price of an order. The shape of the object is `{size, price}`.\n * @returns An object with the result of the processed order or an error\n */\nob.modify(orderID: string, { size: number, price: number })\n```\n\nFor example:\n\n```\nob.limit({ side: \"sell\", id: \"uniqueID\", size: 55, price: 100 })\n\nasks: 110 -\u003e 5      110 -\u003e 5\n      100 -\u003e 1      100 -\u003e 56\n--------------  -\u003e  --------------\nbids: 90  -\u003e 5      90  -\u003e 5\n      80  -\u003e 1      80  -\u003e 1\n\n// Modify the size from 55 to 65\nob.modify(\"uniqueID\", { size: 65 })\n\nasks: 110 -\u003e 5      110 -\u003e 5\n      100 -\u003e 56     100 -\u003e 66\n--------------  -\u003e  --------------\nbids: 90  -\u003e 5      90  -\u003e 5\n      80  -\u003e 1      80  -\u003e 1\n\n\n// Modify the price from 100 to 110\nob.modify(\"uniqueID\", { price: 110 })\n\nasks: 110 -\u003e 5      110 -\u003e 70\n      100 -\u003e 66     100 -\u003e 1\n--------------  -\u003e  --------------\nbids: 90  -\u003e 5      90  -\u003e 5\n      80  -\u003e 1      80  -\u003e 1\n```\n\n### Cancel Order\n\n```js\n/**\n * Remove an existing order with given ID from the order book\n *\n * @param orderID - The ID of the order to be removed\n * @returns The removed order if exists or `undefined`\n */\nob.cancel(orderID: string)\n```\n\nFor example:\n\n```\nob.cancel(\"myUniqueID-Sell-1-with-100\")\n\nasks: 110 -\u003e 5\n      100 -\u003e 1      110 -\u003e 5\n--------------  -\u003e  --------------\nbids: 90  -\u003e 5      90  -\u003e 5\n      80  -\u003e 1      80  -\u003e 1\n```\n\n## Order Book Options\n\nThe orderbook can be initialized with the following options by passing them to the constructor:\n\n### Snapshot\nA `snapshot` represents the state of the order book at a specific point in time. It includes the following properties:\n\n - `asks`: List of ask orders, each with a `price` and a list of associated `orders`.\n - `bids`: List of bid orders, each with a `price` and a list of associated `orders`.\n - `stopBook`: an object with `bids` and `asks` properties related to every `StopOrder` in the orderbook.\n - `ts`: A timestamp indicating when the snapshot was taken, in Unix timestamp format.\n - `lastOp`: The id of the last operation included in the snapshot\n\nSnapshots are crucial for restoring the order book to a previous state. The orderbook can restore from a snapshot before processing any journal logs, ensuring consistency and accuracy.\nAfter taking the snapshot, you can safely remove all logs preceding the `lastOp` id.\n\n**Note**: The snapshot of the order book returns an object containing an `array` of `bids` and `asks`, which in turn are arrays of order objects. If the snapshot is saved to the database as a `string`, make sure to pass the snapshot in its original format when initializing the order book. For example, you can achieve this by using `JSON.parse` to convert the string back into its original object form.\n\n```js\nconst ob = new OrderBook({ enableJournaling: true})\n\n// after every order save the log to the database\nconst order = ob.limit({ side: \"sell\", id: \"uniqueID\", size: 55, price: 100 })\nawait saveLog(order.log)\n\n// ... after some time take a snapshot of the order book and save it on the database\n\nconst snapshot = ob.snapshot()\nawait saveSnapshot(JSON.stringify(snapshot))\n\n// If you want you can safely remove all logs preceding the `lastOp` id of the snapshot, and continue to save each subsequent log to the database\nawait removePreviousLogs(snapshot.lastOp)\n\n// On server restart get the snapshot and logs from the database and initialize the order book\nconst logs = await getLogs()\nconst snapshot = await getSnapshot()\n\nconst ob = new OrderBook({ snapshot: JSON.parse(snapshot), journal: log, enableJournaling: true })\n```\n\n### Journal Logs\nThe `journal` option expects an array of journal logs that you can get by setting `enableJournaling` to true. When the journal is provided, the order book will replay all the operations, bringing the order book to the same state as the last log.\n```js\n// Assuming 'logs' is an array of log entries retrieved from the database\n\nconst logs = await getLogs()\nconst ob = new OrderBook({ journal: logs, enableJournalLog: true })\n```\nBy combining snapshots with journaling, you can effectively restore and audit the state of the order book.\n\n### Enable Journaling\n`enabledJournaling` is a configuration setting that determines whether journaling is enabled or disabled. When enabled, the property `log` will be added to the body of the response for each operation. The logs must be saved to the database and can then be used when a new instance of the order book is instantiated.\n```js\nconst ob = new OrderBook({ enableJournaling: true }) // false by default\n\n// after every order save the log to the database\nconst order = ob.limit({ side: \"sell\", id: \"uniqueID\", size: 55, price: 100 })\nawait saveLog(order.log)\n```\n\n## Development\n\n### Build\n\nBuild production (distribution) files in your dist folder:\n\n```sh\nnpm run build\n```\n\n### Testing\n\nTo run all the unit-test\n\n```sh\nnpm run test\n```\n\n### Coverage\n\nRun testing coverage\n\n```sh\nnpm run test:cov\n```\n\n### Benchmarking\n\nBefore running benchmark, make sure to have built the source code with `npm run build` first\n\n```sh\nnpm run bench\n```\n\n## Contributing\n\nI would greatly appreciate any contributions to make this project better. Please make sure to follow the below guidelines before getting your hands dirty.\n\n1. Fork the repository\n2. Create your branch (git checkout -b my-branch)\n3. Commit any changes to your branch\n4. Push your changes to your remote branch\n5. Open a pull request\n\n## Donation\n\nIf this project help you reduce time to develop, you can give me a cup of coffee 🍵 :)\n\n- USDT (TRC20): `TXArNxsq2Ee8Jvsk45PudVio52Joiq1yEe`\n- BTC: `1GYDVSAQNgG7MFhV5bk15XJy3qoE4NFenp`\n- BTC (BEP20): `0xf673ee099be8129ec05e2f549d96ebea24ac5d97`\n- ETH (ERC20): `0xf673ee099be8129ec05e2f549d96ebea24ac5d97`\n- BNB (BEP20): `0xf673ee099be8129ec05e2f549d96ebea24ac5d97`\n\n## License\n\nCopyright [Andrea Fassina](https://github.com/fasenderos), Licensed under [MIT](LICENSE).\n","funding_links":["https://github.com/sponsors/fasenderos"],"categories":["TypeScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffasenderos%2Fnodejs-order-book","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffasenderos%2Fnodejs-order-book","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffasenderos%2Fnodejs-order-book/lists"}