Quant Trading for Programmers 16: Start With A Clear Paper-Trading Ledger
Quant Trading for Programmers 16: Start With A Clear Paper-Trading Ledger
Article 15 completed the strategy promotion gate. Passing the gate does not mean a strategy can trade real money. It only means the candidate is qualified to enter slower, more conservative paper-trading observation.
Article 16 does not build a complex matching engine or connect to a broker. It does one thing first: make the paper-trading account ledger clear.

Why Start With The Ledger
The first layer of trust in paper trading comes from the ledger.
If cash is not deducted correctly after a buy, positions are not reduced correctly after a sell, or fees are not included in cost, then later equity curves, risk controls, and rebalance alerts will all be built on wrong state.
Here are several common terms used in this chapter:
| Term | Meaning In Paper Trading |
|---|---|
| Ledger | Account state that records cash, positions, trades, and PnL |
| Execution | Account change produced after an order is accepted |
| Average cost | Diluted per-share cost of the current position, including buy-side fees |
| Realized PnL | Profit or loss that actually lands in the account after selling |
| Unrealized PnL | Floating profit or loss estimated from current prices |
Account State
Chapter 16 adds app/paper_ledger.py. The core object is small:
@dataclass(frozen=True)
class PaperAccountState:
cash: float
positions: dict[str, PaperPositionState] = field(default_factory=dict)
Positions keep only the fields needed for now: symbol, shares, average cost, and realized PnL. There is no database or background task here. It is a pure-function ledger, which makes it easy to test and reuse.
Execute Buys And Sells
The order entry point is apply_paper_order().
It reuses the A-share trading rules from article 4: shares are rounded by board lot of 100, buys check cash, sells check available positions, and the same fee-estimation function is used.
execution = apply_paper_order(
account,
trade_date=date(2026, 1, 8),
symbol="000001.SZ",
side="buy",
price=10.0,
shares=1234,
)
This order is normalized to 1200 shares. The ledger returns PaperExecution, which contains both the current execution and the new account state after the execution.
Market Value And Equity
The ledger also provides two small functions:
account_market_value(account, last_prices)
account_total_equity(account, last_prices)
For now, they estimate position market value from latest prices. Article 17 will organize these values into a fuller account snapshot.
Current Mainline Integrated Run
The current mainline repository provides one paper-trading example from article 16 to article 20:
git clone https://github.com/ax2/zi-quant-platform.git
cd zi-quant-platform
uv sync --extra dev
uv run python -m scripts.chapter_examples paper-flow
Article 16 corresponds to the ledger execution section:

This example starts with 100000 in cash, buys 6400 shares of 000001.SZ, uses a trade value of 79744.00, charges 24.72 in fees, and leaves 20231.28 cash after execution. This screenshot is more useful than a standalone test result because it shows how the buy order really changes account state.
Chapter Update And Repository
This chapter adds:
app/paper_ledger.py.- Paper-trading account, position, execution result, and buy/sell update logic.
- Reuse of A-share trading rules and fee estimation.
tests/test_paper_ledger.py, covering buys, insufficient cash, sells, selling without positions, and equity calculation.- A current-mainline
scripts.chapter_examples paper-flowexample that can really run the paper-trading chain for articles 16-20. - Common terms such as ledger, execution, average cost, realized PnL, and unrealized PnL.
Repository:
https://github.com/ax2/zi-quant-platform
Code for this chapter:
git clone https://github.com/ax2/zi-quant-platform.git
cd zi-quant-platform
git checkout chapter-16
uv sync --extra dev
uv run pytest tests/test_paper_ledger.py
Chapter 16 is commit 936cb5c, tagged as chapter-16.
Summary
Paper trading should not start with a UI or alerts.
Article 16 turns account cash, positions, executions, and equity calculation into testable ledger functions. The next article builds account snapshots on top of the ledger so paper-trading state can be displayed, checked, and reviewed.
Follow ZiCode on WeChat
If this post was useful, you can follow later updates on WeChat as well.
X / Twitter
Follow @ax2_zicode
Faster technical notes, short thoughts, and new-post alerts are posted on X.
More in this column
- Quant Trading for Programmers 20: Generate Paper-Trading Daily Reports And Alert Summaries
- Quant Trading for Programmers 19: Generate Rebalance Plans From Target Weights
- Quant Trading for Programmers 18: Paper Trading Needs Risk Checks Too
- Quant Trading for Programmers 17: Generate Paper-Trading Account Snapshots
- Quant Trading for Programmers 15: Strategy Promotion Needs A Gate
- Quant Trading for Programmers 14: Save Strategy Candidates As Experiment Records
- Quant Trading for Programmers 13: Add A First Grid Search For Strategy Parameters
- Quant Trading for Programmers 12: Final Return Is Not Enough