Stock Rush

Anuj AcharjeeAnuj Acharjee
6 min read

OBJECTIVES

  • To simulate the core functionalities of a stock broker platform using a custom-built stock exchange engine.

  • To allow users to place MARKET and LIMIT orders, replicating real trading mechanisms.

  • To dynamically update stock prices based on in-game trades and events instead of relying on real exchange APIs.

  • To provide users with a fixed amount of virtual funds at the start, encouraging strategic thinking to grow their in-game portfolio.

  • To offer an educational and engaging experience for learning trading concepts in a risk-free environment.

TECHNOLOGIES USED

Frontend:

  • React.js – Component-based UI for a dynamic user experience.

  • Tailwind CSS – Utility-first CSS framework for fast and responsive design.

  • React-chart.js – Data visualization for stock price trends.

  • Redux – State management to handle real-time stock updates.

  • Axios – Handles API requests efficiently.

Backend:

  • Node.js & Express.js – Handles API requests and application logic.

  • Node.js Addon (N-API) – Acts as a bridge between the Node.js backend and the native C++ engine, enabling high-performance execution logic within the JavaScript runtime.

  • C++ (Stock Execution & Exchange Engine) – High-performance execution of trades, order book management, and matching.

  • Socket.IO – Enables real-time communication for fast trade execution and updates.

Database & Caching:

  • MongoDB – NoSQL database to store users, orders, stocks, and transaction data.

  • Redis – In-memory caching for fast access to frequently queried data.

  • Kafka - Distributed event streaming platform used for real-time processing of order events, trade execution, stock price updates, and scalable communication between services.


SYSTEM DESIGN


USER AUTHENTICATION

  • The system implements JWT-based authentication using both Access and Refresh Tokens.
  • Upon successful sign-in, the user receives an Access Token and a Refresh Token.
  • The Access Token is included in each API request to authenticate the user.
  • When the Access Token expires, the system verifies the Refresh Token (stored securely in the database) and, if valid, generates and returns a new Access Token to the user.

ORDER EXECUTION FLOW

This section outlines the complete flow of an order, from user initiation in Node.js to final execution in the C++ engine via N-API.

  1. Order Validator (Node.js)

    When a user places an order, the system first validates it:

    • Buy Orders: The system checks if the user has sufficient funds to complete the transaction.

    • Sell Orders: The system verifies that the user holds enough quantity of the stock intended to be sold.

If the validation fails, the order is immediately rejected.
If successful, the order is forwarded to the native execution engine via Node.js Addon (N-API).

  1. Order Object Creation (C++ via N-API)

    The N-API bridge converts the validated order into a native C++ Order object.
    This object is then added to the Order Manager’s internal queues for further processing.

  2. Order Manager (C++)

    OrderManager is a singleton class responsible for managing all incoming orders.

    • Maintains two FIFO queues:

      • BuyExecutionQueue

      • SellExecutionQueue

These queues ensure fair, time-prioritized execution of orders.
Whenever a new order is enqueued, the OrderManager signals the Order Executioner to begin processing.

  1. Order Executioner (C++)

    The OrderExecutioner is responsible for actually processing the orders:

    • It contains two dedicated threads:

      • One for processing Buy Orders

      • One for processing Sell Orders

Execution Flow:

  1. These threads continuously listen for new orders in their respective queues.

  2. Upon dequeuing an order, they push it into the executeOrder function which uses a Thread Pool, enabling concurrent and non-blocking execution.

  1. Order Execution (executeOrder) (C++)

    The executeOrder function is the core component responsible for matching and executing trades.

    Match Found

    When an order is processed:

    • The function checks the Order Book of the relevant stock for a suitable counter-order.

    • If a match is found, the system proceeds with trade execution:

      • The matched order(s) are executed immediately.

      • A message is sent back to the Node.js layer via N-API to:

        • Update the database (e.g., user balances, stock quantities).

        • Notify users of the trade execution.

      • The in-memory Order Book is updated to reflect the removal or modification of the matched orders.

Limit Order – No Match Found

If no match is found and the order is a LIMIT order:

  • The order is not discarded.

  • It is placed into the Order Book at the specified price level for that stock.

  • The order stays active in memory, waiting for a future matching order.

This design supports price control and maintains fairness based on price-time priority—ensuring older and better-priced orders get executed first.

Market Order – No Match Found

If no match is found and the order is a MARKET order:

  • The order is rejected.

  • Market orders are intended for immediate execution at the best available price.

  • Since they do not specify a price, they cannot be stored in the Order Book or held for future matching.

Rejecting unmatched market orders ensures their real-time nature is preserved and avoids undefined behavior in illiquid markets.

  1. Order Book Structure (C++)

    • Each stock maintains its own independent Order Book.
  • The Order Book uses two std::map structures:

    • Buy Orders: map<float, vector<OrderPtr>, greater<float>> (sorted in descending price)

    • Sell Orders: map<float, vector<OrderPtr>> (sorted in ascending price)

  • This price-level sorting ensures that best price orders are prioritized during matching.

  1. Stock Locking Mechanism (C++)

    To ensure thread safety during concurrent order execution, a stock-level locking system is employed.

    • Each stock is associated with a lock to prevent simultaneous reads/writes to its Order Book.

    • This avoids race conditions and ensures data consistency when multiple orders are being processed for the same stock.

  1. Post-Execution Handling (Node.js + Kafka + MongoDB)

    Once an order is successfully executed in the C++ engine:

    • The execution details are sent back to the Node.js layer via N-API.

    • Node.js then publishes the executed order to a Kafka topic.

    • Kafka acts as a buffered event stream, enabling high-throughput, fault-tolerant handling of execution data.

On the other side:

  • A Kafka consumer service listens to this topic.

  • It accumulates executed orders in batches and performs bulk updates in MongoDB.

This architecture ensures:

  • High performance and low latency in order execution.

  • Scalable and efficient writes to the database.

  • Loose coupling between execution and persistence layers.

  1. In-Memory Caching Layer (Redis)

    Redis is used as a high-performance, in-memory cache to reduce latency and database load.

    It stores frequently accessed and fast-changing data such as:

    • User Funds & Portfolio: Quick access to user balance and holdings during order validation.

    • Order Books: Real-time in-memory storage of buy/sell orders for each stock to enable fast matching and updates.

By caching this data in Redis, the system ensures:

  • Sub-millisecond read/write times

  • Reduced dependency on MongoDB for real-time operations

  • Improved throughput for high-frequency trading scenarios


CONCLUSION

This architecture combines the performance of a C++ execution engine with the scalability of Node.js, Kafka, Redis, and MongoDB.
Each component is designed for high concurrency, low latency, and fault tolerance, making the system well-suited for real-time stock trading at scale.
By separating concerns across validation, execution, queuing, and storage, the platform ensures accuracy, fairness, and system resilience in every trade.

2
Subscribe to my newsletter

Read articles from Anuj Acharjee directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Anuj Acharjee
Anuj Acharjee

𝚂𝚘𝚏𝚝𝚠𝚊𝚛𝚎 𝙳𝚎𝚟𝚎𝚕𝚘𝚙𝚎𝚛 | 𝙲𝚂𝙴 '27