{"id":19053305,"url":"https://github.com/sbmueller/orderbook","last_synced_at":"2026-06-29T10:31:46.894Z","repository":{"id":37908605,"uuid":"506351887","full_name":"sbmueller/orderbook","owner":"sbmueller","description":"Interview coding task performed June 2022","archived":false,"fork":false,"pushed_at":"2023-02-16T15:30:35.000Z","size":12,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-06-21T21:28:11.795Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/sbmueller.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,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-06-22T17:53:22.000Z","updated_at":"2026-04-07T05:01:07.000Z","dependencies_parsed_at":"2024-11-08T23:40:22.583Z","dependency_job_id":null,"html_url":"https://github.com/sbmueller/orderbook","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/sbmueller/orderbook","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sbmueller%2Forderbook","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sbmueller%2Forderbook/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sbmueller%2Forderbook/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sbmueller%2Forderbook/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sbmueller","download_url":"https://codeload.github.com/sbmueller/orderbook/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sbmueller%2Forderbook/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34923763,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-29T02:00:05.398Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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-08T23:30:02.605Z","updated_at":"2026-06-29T10:31:46.875Z","avatar_url":"https://github.com/sbmueller.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Orderbook\n\nCoding task performed June 2022 in context of an interview process. There was a\n48h time limit to complete the task.\n\nCopyright (C) 2022 Sebastian Müller\n\n## Task\n\nThe task was to implement an order book that maintains orders at a asset\nexchange. The input of the application is a CSV file with either new orders,\norder cancellations or book flushes in the format\n\n```\n# New order\nN, user_id, symbol, price, quantity, side, order_id\n# Cancellation\nC, user_id, order_id\n# Flush\nF\n```\n\nThis input file is read in a separate thread while processing of the orders\ntakes place in the main thread. Orders that cross the book are rejected by\ndefault, but can be matched and traded with the `--trade` flag. The application\noutputs a log on a separate thread with acknowledgements, top-of-book changes,\nrejection of orders or trades of orders in the format\n\n```\n# Acknowledgement\nA, user_id, order_id\n# Top-of-book change\nB, side, price, quantity\n# Reject\nR, user_id, order_id\n# Trade\nT, user_id_buyer, order_id_buyer, user_id_seller, order_id_seller, price, quantity\n```\n\n## Usage\n\nThe project compiles to a command line tool. Use\n```\ncargo build --release\n```\nto compile the program. The default output directory is `target/release`. In\nthere, call the executable with the `--help` flag to get usage information\n```\n./target/release/orderbook --help\n```\n\n## Assumptions Taken\n\n- Input files are always in the correct format\n- Orders are sane (e.g. cancellation can only be done for existing orders)\n- The application only works for inputs that address the same trading symbol.\n  For different symbols, the inputs need to be separated and the application\n  can be executed in multiple instances for each symbol.\n- Trades are only performed as-whole. There are no partial trades.\n\n## Design Decisions\n\nThe heart of the application is the order book, which is implemented by two\n`BTreeMap`s for the asks and the bids, using price as key and a vector of\norders as value. This is inspired by [bigfatwhale](https://github.com/bigfatwhale/orderbook/tree/master/rust).\nSince this data structure is ordered and implements `DoubleEndedIterator` it is\neasy and fast to identify the highest bid and the lowest ask. These values need\nto be determined frequently to match trades in a real application. The vectors\nin the values of the `BTreeMap` contain orders sorted by time, so the 2nd\npriority besides price can be considered as well.\n\nThere is one thread for reading the input file. The thread uses a MPSC channel\nto send interpreted orders to the main thread. A second thread is responsible\nfor the logging, where the same design is applied. The main thread sends\nmessages to be published to the logging thread.\n\n## Time and Space Complexities\n\nUsing a `BTreeMap`, the time complexity of adding orders is always O(log n).\nFinding the lowest bid and highest ask takes O(1). Cancelling an order will\ntake O(n) time since a linear search is applied to find the desired order.\nMatching a new order takes O(k) time. n is the number of total orders in the\norder book while k are the number of orders on the highest bid or lowest ask.\n\nThe space complexity for a BTree is defined as O(n) however I'm not sure if\nthat also applies for a `BTreeMap`.\n\n## Outlook (if more time was available)\n\n### Improve error handling\n- Handle malfomed input files\n- Handle insane orders (e.g. cancel of non-existing order)\n\n### Unit Tests\n\nNo tests have been written for this solution due to the time limit. However the\ncode is designed to be easily testable. The `OrderBook` takes a `mpsc::Sender`\nas argument in its factory function and using dependency insertion, a test case\ncould insert the sender for a test purpose channel and monitor the output of\nthe `OrderBook`. Then, the inputs from the provided example CSV can be\nconverted to `Order`s in the test cases and passed into the `OrderBook`. The\n`mpsc::Receiver` can then check if the correct output is produced for each\ninput.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsbmueller%2Forderbook","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsbmueller%2Forderbook","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsbmueller%2Forderbook/lists"}