Trade database (trade.db)#
The log of trades (the blotter’s source) and the end-of-day P&L computed from
it. Models: src/trade_engine/models/trade.py; data access:
repositories/trade.py; booking: services/trades.py.
The blotter is not a table. It is a reporting query over trades, joined
with reference data at the application layer (see
Reporting).
trades: one row per booked trade#
Column |
Type |
Reason |
|---|---|---|
|
integer PK |
Stable trade identifier; also the final tie-breaker when replaying trades in order. |
|
string(32), indexed |
Business key to reference and market data. |
|
date, indexed |
Determines which EOD runs include the trade ( |
|
date, nullable |
Settlement date; validated to be on or after |
|
string(8) |
|
|
float |
Positive values; |
|
string(8), default |
Currency of |
|
string(64), default |
Business key validated against reference data at booking. |
|
string(128), default |
Business key validated against reference data at booking. |
|
string(16), default |
|
|
datetime, database default |
When it was booked (as opposed to when it traded); part of the replay ordering. |
|
string(512), nullable |
Free text; also used to tag seeded sample trades. |
Replay order for P&L is (symbol, book, trade_date, entry_timestamp, trade_id),
which is deterministic even when several trades share a date.
Booking rules#
NewTrade (domain/trade.py) rejects, before any database access: blank
symbol, book or trader; non-finite or non-positive quantity or price;
value_date earlier than trade_date; notes over 512 characters.
TradeService.book_trade then checks the instrument is known and active, the book
and trader exist, and ccy matches the instrument’s quote currency. New trades
are always ACTIVE; the API does not accept a status.
pnl_eod: persisted per-position P&L for a calculation date#
Column |
Type |
Reason |
|---|---|---|
|
integer PK |
Surrogate key. |
|
date, string, string; all indexed |
The grain: one row per |
|
string(8), not null |
Currency of every amount in the row (the instrument’s |
|
float |
Signed position at |
|
float |
Weighted-average cost of the open position (0 when flat). |
|
float |
The close used, stored so the figure is explainable without re-querying market data, which may later be corrected. |
|
float |
Stored separately so reports can show each without recomputation; |
|
datetime, database default |
When this result was produced. |
realized_pnl and total_pnl are cumulative since the first trade, not the
day’s change. See P&L and the EOD batch.
Reruns replace all rows for the calc_date (delete then insert in one
transaction). A unique key on (calc_date, symbol, book) is on the
roadmap to make that guarantee a database fact.
Planned changes#
Append-only trade events (amendments and cancels as new linked rows with who,
when and why), fees, cash flows and an eod_runs ledger. See the
roadmap and Multi-asset design.