{"id":19408799,"url":"https://github.com/daern91/order-book","last_synced_at":"2025-02-25T02:17:52.752Z","repository":{"id":208311638,"uuid":"721319510","full_name":"daern91/order-book","owner":"daern91","description":"order book written in rust capable of over 10mm trades per second","archived":false,"fork":false,"pushed_at":"2023-11-20T20:41:54.000Z","size":70,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-07T14:24:30.375Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/daern91.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2023-11-20T20:14:17.000Z","updated_at":"2023-11-20T20:44:54.000Z","dependencies_parsed_at":"2023-11-20T21:45:05.432Z","dependency_job_id":null,"html_url":"https://github.com/daern91/order-book","commit_stats":null,"previous_names":["daern91/order-book"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daern91%2Forder-book","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daern91%2Forder-book/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daern91%2Forder-book/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/daern91%2Forder-book/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/daern91","download_url":"https://codeload.github.com/daern91/order-book/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240587480,"owners_count":19825005,"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":[],"created_at":"2024-11-10T12:07:54.696Z","updated_at":"2025-02-25T02:17:52.681Z","avatar_url":"https://github.com/daern91.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"### Order Book Programming Exercise\n\nWIP yet functional order book with support for adding, cancelling, and matching limit and market orders.\n\nAs per exercise requirements, one can pipe the \"input.csv\" file into stdin.\nPlease note that matching is enabled by a boolean. The `main` file enables it after the first scenarios in the CSV have run to pass tests. The first scenarios gets rejected when they cross and later they match/trade.\n\n#### Setup\n\n##### Docker\n\n```\n$ docker build -t orderbook .\n$ cat input_file.csv | docker run -i orderbook\n// using vimdiff to check test results (for zsh)\n$ vimdiff =(cat input_file.csv |  docker run -i orderbook) output_cleaned.csv\n// should be no difference\n```\n\nIf you have a broken CSV the program will panic unless you pass in the flag `--ignore-errors`\n\n```\n$ cat input_file.csv | docker run -i orderbook --ignore-errors\n$ cat input_file.csv | cargo run -- --ignore-errors\n```\n\n#### Tests\n\nThere is a simple integration test inside the `tests/` folder. You can run it to check the same plus a few additional scenario outputs in a hard-coded way. Please note that it uses nightly features.\n\n```\n// run only tests/ folder with watch\n$ cargo +nightly watch -x \"test --test '*'\"\n// run all incl. unit tests and nightly integration tests\ncargo +nightly watch -x test\n```\n\n##### Benches\n\n```\n// benchmarking\n$ cargo bench\n// html report gets written to\n// target/criterion/report/index.html\n```\n\nWe use `criterion` for benchmarking which also gives us great html reports.\nOn my local machine, we see the below speeds (mb pro M1 max 64 GB memory)\n)\n\n\u003c!-- ![10mm limit order adds](\u003c./CleanShot 2023-11-15 at 05.11.57@2x.png\u003e){: width=\"50%\"} --\u003e\n\n\u003cimg src=\"https://raw.githubusercontent.com/daern91/order-book/main/CleanShot%202023-11-15%20at%2005.11.57%402x.png\" width=40% height=40%\u003e\n\n#### Structure\n\nThe idea is that we create one order book for each symbol/ticker with the following (minimized) structure.:\n\n```\nOrderBook -\u003e\n    symbol: String\n    orders: BTreeMap\u003corder_id, Order\u003e,\n        Order -\u003e (id, user_id, ...etc)\n    bids: OrderSide,\n    asks: OrderSide,\n        OrderSide -\u003e\n            prices: BTreeMap\u003cprice, OrderQueue\u003e,\n            ...stats\n                OrderQueue -\u003e\n                    orders: Vec\u003cOrder\u003e,\n                    ...stats\n```\n\nWe store the orders both directly in the `OrderBook.orders` tree and also inside the Vector where they get pushed to the execution queue. We simply use the order_id as `key` here.\nFor the first draft, I went with a simple `BTreeMap`. However, I'm expecting we can gain performance by using an AVL or Red Black Tree instead for rotation.\nIn addition, we could store the queue index inside the map for quicker lookup in the queue too.\n\nOn the bids/asks side, we have another tree where we use `price` as the key and the queue of orders. So we can easily check the quantity/volume of each price point.\n\nEach orderbook uses its own \"producer\" thread which pushes log outputs to the single consumer thread.\n\n#### Improvements and Features\n\nGiven the limited time for this assignment and the fact that I did it as a hackathon exercise, I believe the code would be good to be refactored and tailored differently. I didn’t want to follow this during the exercise as the time was limited and I prioritized the goals first. Error handling is another area of interest that requires more sophistication.\n\n- [ ] Refactor main code\n- [ ] Add error handling\n- [ ] Update logging\n- [ ] Benchmark, order and price lookups, iterate and document the progress. Move towards O(1) and look into memory usage\n- [ ] Add proper user_id handling, for lookup, deletes, edits\n- [ ] Implement missing TimeInForce logic (IOC and FOK)\n- [ ] Implement edit_order functionality\n- [ ] Add more order types, e.g. Iceberg or Scale Order from Insilico https://insilicoterminal.com/\n- [ ] Add more test scenarios\n- [ ] Documentation tests\n- [ ] Set up cicd pipeline\n- [ ] Set up simple FE for live visualizations\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdaern91%2Forder-book","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdaern91%2Forder-book","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdaern91%2Forder-book/lists"}