{"id":19069220,"url":"https://github.com/edyatl/exengine","last_synced_at":"2025-02-22T03:41:03.044Z","repository":{"id":168794309,"uuid":"350507890","full_name":"edyatl/exengine","owner":"edyatl","description":"A quite primitive trading backend single-product trading. Simple and fast.","archived":false,"fork":false,"pushed_at":"2021-03-23T22:13:48.000Z","size":14,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-02T15:34:51.119Z","etag":null,"topics":["backend","buy","c","deals","engine","exchange","gcc","non-bloated","order","performance","sell","stack","stdin","stdout","tokens","trade"],"latest_commit_sha":null,"homepage":"","language":"C","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/edyatl.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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":"2021-03-22T22:28:38.000Z","updated_at":"2021-03-23T22:13:50.000Z","dependencies_parsed_at":null,"dependency_job_id":"c172d35c-c2b4-4cbf-939a-c76cda8684e4","html_url":"https://github.com/edyatl/exengine","commit_stats":null,"previous_names":["edyatl/exengine"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edyatl%2Fexengine","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edyatl%2Fexengine/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edyatl%2Fexengine/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/edyatl%2Fexengine/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/edyatl","download_url":"https://codeload.github.com/edyatl/exengine/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240122575,"owners_count":19751142,"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":["backend","buy","c","deals","engine","exchange","gcc","non-bloated","order","performance","sell","stack","stdin","stdout","tokens","trade"],"created_at":"2024-11-09T01:13:44.080Z","updated_at":"2025-02-22T03:41:03.019Z","avatar_url":"https://github.com/edyatl.png","language":"C","readme":"# exengine - Exchange engine for one good\n\n\n\u003e Exengine is a quite primitive trading backend single-product trading.\n\n\n## Usage \n\nBuild the source and start the program. It reads standard input stream and produces standard output.\n\nExengine will waiting for two types of commands:\n\n1. Place new order - comma separated tokens (for example: O,1,S,35,199.99).\n2. Cancel order - comma separated tokens (for example: C,1)\n\nThe meaning of **place new order** command is:\n\n* (O)rder,id,(S)ell,quantity,price\n* (O)rder,id,(B)uy,quantity,price\n\nField \"id\" must be a global counter of unique increasing numbers for both types of order placement (sell order 1, buy order 2, sell order 3, ... and so on).\n\nThe meaning of **cancel order** command is:\n\n* (C)ancel,id\n\nWhen there are sell and buy orders with relevant price, program will make the deal and print the trade record to standard output.\n\n\n### Example:\n\nImagine that you are trading a new cryptocurrency - Super Crypto Coin (SCC). Only coins of the same type are available and cannot be split into less than one coin.\nThe market price of the SCC coin ranges from $250 to $300.\n\nLet's trade.\n\n**StdIn:**\n\n\n    O,1,S,23,275.77\n    O,2,S,93,275.10\n    O,3,S,8,293.61\n    O,4,S,31,292.84\n    O,5,S,16,275.12\n    O,6,S,17,296.69\n    O,7,B,10,290.84\n    O,8,S,55,264.63\n    O,9,B,57,265.27\n\n*7 orders for sell and 2 orders for buy on the exchange.*\n\n**StdOut:**\n\n\n    T,1,S,2,7,10,275.1\n    T,2,S,8,9,55,264.63\n\n*2 trade deals were made. Order #2 sold 10 coins to order #7 at $275.1 per coin. And order #7 has been fully cleared from the exchange. After that, order #8 sold 55 coins to order #9  at price $264.63 per coin and clearly closed.*\n\nIf the program receives a cancel order command, then the order with this id removes from the stack and prints a cancel record.\n\n\n**StdIn:**\n\n\n    C,3\n\n\n**StdOut:**\n\n\n    X,3\n\n*Order #3 removed from the exchange.*\n\n## Purpose\n\nA simple, non-bloated, error-free solution of exchange engine with maximum performance.\n\n## Achieved\n\n- Runs ~120x faster then its [prototype](https://github.com/edyatl/exengine_py) in Python.\n\n## Algorithm and approach\n\n\n1. Read input and split tokens into an array.  \n \n2. Two different stacks are created for buy_orders and sel_orders. The stack structure is used to store orders as the simplest and most efficient structure.\n\n3. One item of the stack consists of three fields: id, quantity, price. The total size of one stack item is 12 bytes. For each stack, an array of 1024 items is reserved by default. (You can change this capacity by changing the CAPACITY constant at the head of c file.) \n\n4. Dynamic memory allocation is not used because static memory is much faster and gives us less room for memory errors. \n\n5. There is no particular field for the trading side (buy or sell), but the side is determined by the stack. \n\n6. The price is stored as a float, obviously, this is not a good type for money field, but in this task price is static and is only used  for comparison operations. Therefore, I think that in this case it is permissible to use the float type for simplicity.\n\n7. Each time a new order is added, the trade function performs trades between buy and sell orders in recursion. If a buy order stack and a sell order stack exist, it determines the max and min orders by price, and then check if  their prices are suitable for the trade deal. If so order with less quantity removes and the quantity of the remaining order is reduced by the transaction amount. If both orders have the same quantity, then the second order is also deleted.\n\n8. The order is removed from the trade stack by assigning the values of the next element to the removed item of the stack, and so on along the chain to the top of the stack. And then the top of the stack is shifted down one item.\n\n9. Orders are traded and removed according to FIFO method (First In First Out).\n\n10. Also don't be confused by one alien crutch - `pyprint_float()` function, which is just for printing floats in Python style. It adds `.0` if the number has no digits after the decimal separator. The first output file for the tests was the result of a Python program, that's why this function was appeared. \n\n## To do\n\n- Make protection from going into infinite recursion.\n- Solve the issue with compilation with optimization.\n- Try to make a port in Cython  to compare performance.\n\n## Known issues\n\nWith gcc 4.8.4 and gcc 5.4.0 when use optimization (-O flag) result binary produces incorrect output of trading records. \n\nAnd gcc 10.2.0 with -O2 works like a charm.\n\n\n## Contributing\n\nAny ideas, patches, bug reports and so on are always welcome.\n\n\n## Authors\n\nYevgeny Dyatlov ([@edyatl](https://github.com/edyatl))\n\n\n## License\n\nThis project is licensed under the MIT License.\n\nCopyright (c) 2021 Yevgeny Dyatlov ([@edyatl](https://github.com/edyatl))\n\nPlease see the [LICENSE](https://github.com/edyatl/exengine/blob/master/LICENSE) file for details.","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fedyatl%2Fexengine","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fedyatl%2Fexengine","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fedyatl%2Fexengine/lists"}