Project Skeleton: Build Your First HFT Microservice
Quick goal: assemble a tiny, end-to-end microservice that replays market data, runs a simple strategy, submits orders through a minimal gateway, logs decisions, and reports backtest PnL — all locally and reproducibly.
- Target reader: you — an engineer into Algorithmic Trading with beginner familiarity in
C++,Python,Java,C, andJS. This screen gives you a low-friction C++ starting point and clear follow-ups for your other languages.
ASCII architecture (what we'll simulate locally):
[Synthetic Multicast Feed] --> [Feed Handler / Replay] --> [Strategy] --> [Order Gateway] --> [Simulated Exchange] | | `----> [Logger / Backtest Recorder] <-'
Think of it like a small pit crew: the feed handler hands the tire (price) to the mechanic (strategy); the mechanic decides whether to pit (trade) and the pit-box (order gateway) enforces safety checks.
Why C++ here?
- C++ shows hot-path structure (tight loops, low allocation). Beginners: treat this as a clear, opinionated starting point; later you can prototype in
Pythonfor fast experiments or rewrite hotspots back into C++.
What the provided C++ program does (run it as main.cpp):
- Generates a deterministic synthetic feed (
generate_feed) — reproducible like a unit test. - Computes a
simple_smaover aSMA_WINDOWand runs a tiny mean-reversion strategy: when price deviates from the SMA byTHRESH, it places aBUYorSELLorder. - Submits orders to a naive
submit_ordergateway which enforcesMAX_ORDER_SIZEand a simple rate limitMAX_ORDERS_PER_SEC. - Executes orders immediately (simulated exchange), updates
positionandcash, and logs events. - Prints a final backtest summary (final PnL) so you can iterate quickly.
Why this is useful to you (language crosswalks):
- C++: shows how to keep the hot path allocation-light —
dequefor SMA window, plain structs forTick/Order. - Python: port the same logic into
pandasor a tight loop withnumpyfor fast prototyping; keep the same knobs (SMA_WINDOW,THRESH) so results are comparable. - Java/C: similar structure applies — use arrays/pools for low-allocation paths.
- JS: great for visualization and teaching — replay the same tick vector in a browser and draw live PnL charts.
Exercises & challenges (try these after running the C++ program):
- Tweak
SMA_WINDOWandTHRESHto see how trade frequency and PnL change. - Reduce
MAX_ORDERS_PER_SECto simulate an exchange throttling you — watch rejections. - Port the strategy loop to Python (keep random seed same) and compare final PnL — are they identical?
- Replace immediate execution with a simple matching engine: keep an
order_bookvector and match orders at best price. - Add an
auditevent (append-only) that recordstimestamp_ns,decision,reason,trace_id— then export to CSV. - For fun: change the strategy to a momentum rule (buy when price > SMA + x) — which performs better on this synthetic feed?
Mini-challenges tailored to your background:
- If you like Java: implement the
OrderandFeedas small POJOs and run the replay loop in aScheduledExecutorService. - If you like Python: re-implement
generate_feedwithnumpy.random.default_rng(42)and vectorize SMA vianumpy.convolve. - If you like JS: visualize the replay and PnL using
d3or a simple HTML canvas — great for demoing to teammates.
Next steps after this skeleton
- Replace synthetic feed with real multicast capture (lab later covers
PF_RING/DPDK). - Harden the gateway: add pre-trade rules, per-client token buckets, and immutable audit logs.
- Add unit tests and a deterministic CI job that compiles the C++ and runs the backtest with fixed seeds.
Try this now
- Run the C++ program above. Then try one change: halve
SMA_WINDOWand re-run — what happens to order count and PnL?
Happy hacking — this tiny microservice is your playground for moving from prototypes to production-ready HFT components. Feel free to port pieces to Python/Java/JS to learn tradeoffs and iterate fast.
xxxxxxxxxx}using namespace std;using ns = chrono::nanoseconds;using clk = chrono::high_resolution_clock;struct Tick { ns ts; double price;};struct Order { string side; // "BUY" or "SELL" int size; double price; ns ts;};// Simple console logger (hot-path should be lighter in real HFT)void log_event(const string &s) { auto now = chrono::duration_cast<ns>(clk::now().time_since_epoch()).count(); cout << "[" << now << "] " << s << "\n";


