Runnable Capstone Lab
The companion project under ../code/ is a deliberately small
single-symbol event-driven trading simulation plus a post-trade ledger/outbox lab.
It is not a realistic exchange or accounting system. Its purpose is to make
interview concepts executable:
- frozen/slot-based domain events;
- protocols and injected policies;
- stable event ordering and deterministic replay;
- rolling signal generation without repeated full-window sums;
- pre-trade position/order limits;
- explicit fills, positions, cash, and decisions;
- bounded
asynciopipeline with observable backpressure; - standard-library unit tests;
- transactional SQLite journal and Kafka outbox boundary.
Run it
From the GitBook directory:
cd code
PYTHONPATH=src python3 -m unittest discover -s tests -v
PYTHONPATH=src python3 -m hedgeprep.demo
PYTHONPATH=src python3 -m hedgeprep.async_pipeline
Python 3.12 or newer is recommended.
Read in this order
events.py: immutable domain vocabulary.risk.py: narrow policy with explicit rejection reasons.strategy.py: O(1) rolling state and decision rule.engine.py: deterministic orchestration and accounting.async_pipeline.py: queue bounds, producer/consumer ownership, sentinel end.tests/: executable invariants.ledger.py: balanced entries, idempotency, and transactional outbox.
Day 3 extension choices
Pick one, time-boxed to 90 minutes:
A. Add costs
Add per-share fee and half-spread slippage. Keep prices/cash consistent, add a hand-calculated test, and explain whether floats remain acceptable.
B. Add delayed fills
Schedule fills at the next market event rather than immediately. Define order of market, decision, order, and fill at equal timestamps. Test no same-tick look-ahead.
C. Add kill switch
Stop new orders after cumulative loss or stale data, while continuing to process fills. Test the difference between halting decisions and halting state updates.
D. Add replay manifest
Hash the input events and write a JSON manifest containing code/config version, seed, event count, and result checksum. Explain what is still missing for six-month reproducibility.
E. Extend the post-trade ledger
Add a reconciliation_break table and a consumer checkpoint. Process a duplicate
cash-settlement event safely, reject a conflicting duplicate, publish through the
outbox, and add an aged-break query/index. Explain the remaining acknowledgement
race between Kafka and mark_published.
Interview walkthrough (five minutes)
- State scope: teaching simulator, not production exchange fidelity.
- Point to immutable events and the explicit total order.
- Explain strategy/risk separation and deterministic injected inputs.
- Name two deliberate limitations and how production would address them.
- Show one invariant test and one extension trade-off.
Review questions
- Why does the event order include a sequence after timestamp?
- What fails if duplicate fills arrive?
- Why does risk use projected position?
- Where would a broker adapter fit without changing the domain?
- Which async queue events could be coalesced and which must not be?
- How would you profile this before optimizing it?