Reference database (reference.db)#
Slow-changing master data: what can be traded, in which books, by whom. It is
small, critical and rarely written, so it is kept apart from the fast-growing
market and result tables. Models: src/trade_engine/models/reference.py;
data access: repositories/reference.py.
Instruments follow a neutral-core-plus-subtype design; see Multi-asset design for how it extends to other asset classes.
instruments: neutral core#
One row per tradable instrument, whatever its asset class.
Column |
Type |
Reason |
|---|---|---|
|
integer PK |
Surrogate key; target of subtype foreign keys. |
|
string(32), unique, indexed |
Unique internal code used by every other database. Unique so a symbol resolves to exactly one instrument; indexed for the per-trade validation lookup. |
|
string(16), not null, indexed, |
Selects the subtype table and any class-specific behaviour. The database rejects unknown classes; indexed for class-level reporting. |
|
string(8), not null |
Currency (or quote asset) of prices, trades and P&L. A trade’s |
|
float, not null, default 1.0, |
Normalises quoting conventions (e.g. 0.01 for bonds quoted in percent of par). Used by P&L and notional. |
|
string(256), nullable |
Human-readable label shown on the blotter. |
|
boolean, default true |
Soft retirement: history stays valid, new trades are rejected. |
fx_instruments: FX subtype#
One row per instrument whose asset_class is FX.
Column |
Type |
Reason |
|---|---|---|
|
integer PK and FK to |
One-to-one with the core row; same database, so the foreign key is enforceable. |
|
string(8), not null |
The currency being bought or sold; with |
|
float, default 0.0001 |
Quote precision; per-instrument because it differs (e.g. JPY pairs). |
|
float, default 100000 |
Standard trade size. |
pip_size and lot_size should be effective-dated if they can change (see the
roadmap).
books#
Column |
Type |
Reason |
|---|---|---|
|
integer PK |
Surrogate key. |
|
string(64), unique |
Books are the unit of position, P&L and limits, so the name is a stable, unique code. |
|
string(256), nullable |
Free text. |
traders#
Column |
Type |
Reason |
|---|---|---|
|
integer PK |
Surrogate key. |
|
string(128), unique |
Unique so a booked trader can be validated and attributed unambiguously. |
How other code uses it#
Booking:
TradeService.book_tradechecks that the instrument exists and is active, that the book and trader exist, and that the trade’sccymatches the instrument’squote_ccy. This is the application-layer replacement for the foreign keys that cannot cross databases.P&L and risk: both look up
quote_ccyandprice_multiplierper symbol and fail with a clear error if an instrument is unknown.Blotter: joins instrument
descriptionandasset_classonto trades (see Reporting).
Seed data (scripts/init_db.py)#
services/seeding.py creates, idempotently, the EURUSD instrument (class FX,
quote USD, multiplier 1.0) with its fx_instruments row (base EUR, pip
0.0001, lot 100,000), the book MAIN and the trader SYSTEM.
Invariants#
symbol,books.nameandtraders.nameare immutable codes. Retire withactive = false(instruments) rather than renaming or deleting.Every
fx_instrumentsrow has a matchinginstrumentsrow withasset_class = 'FX'. The foreign key guarantees the first half; the second is enforced by the seeding code and is a candidate for a database check.