Timed Trading — Data Dictionary
Practical eng reference for live KV blobs, API ticker fields, D1 tables, sessions, entitlement tiers, and central Discord/digest payloads.
1. KV namespaces
| Binding | Purpose |
|---|---|
KV | Auth + sessions (session:<sid>, user:<id>) |
KV_TIMED | Ticker snapshots + live state (timed:*) |
KV_TIMED_TRAIL | 5m bar trail for Markov (trail:<TICKER>:<bucket_ts>) |
KV_MODEL_CONFIG | Operator model knobs (model_config:gates, model_config:overlays) |
Prod reads need --env production. KV is eventually consistent (~60s).
2. timed:prices (KV_TIMED) — live price aggregate
2.1 Blob envelope
| Name | Type/shape | Meaning | Owner/writer | Readers | Freshness / invariants | Do not confuse with |
|---|---|---|---|---|---|---|
timed:prices | JSON object | Universe live quotes | tt-feed REST cron; PriceStream DO | /timed/prices, /timed/all overlay, health, SL feed, client poll | Writers must never omit per-row q_ts/p_ts; blob-level fields must survive partial DO rewrites | timed:latest:<T>; timed:all / snapshot |
.prices | { [SYM]: row } | Per-symbol short-key rows | Same | All consumers unwrap .prices | Always unwrap: (await get)?.prices || {} | Top-level of the blob |
.updated_at | number (ms) | Blob write time | Feed cron / DO flush | Health, notify hub | Poll freshness only — not value freshness | Per-row t, q_ts, p_ts |
.ticker_count | number | Count of symbols in .prices | Feed cron | Ops / logs | — | Universe size in SECTOR_MAP |
._source | string | Writer path label | Feed cron | Logs | TBD exact enum values | — |
.stale_symbols | string[] (capped ~30) | Samples still stale after sweep | Feed cron | /timed/health, watchdog | Cleared / suppressed when market closed; DO must preserve on rewrite | Per-row missing q_ts |
.stale_symbol_count | number | Full stale count | Feed cron | Health / watchdog | Same session gating as stale_symbols | valueStaleCount (writer-independent) |
.market_open | boolean | RTH open flag at last write | Feed cron | Overlay / UI | DO preserves on rewrite | Client isNyRegularMarketOpen() |
2.2 Per-symbol short keys
| Name | Type | Meaning | Owner/writer | Readers | Freshness / invariants | Do not confuse with |
|---|---|---|---|---|---|---|
p | number | Headline / RTH session price. Outside RTH for equities = today’s RTH close; live EXT print is ahp | REST + stream DO | Overlay, movers, SL | During RTH, live last; outside RTH must not become AH print | ahp; scoring price/close |
pc | number | Previous regular-session close | REST + stream | Day change, overlay prev_close | Session-closed: preserve when TD zeros day fields | p (today close) |
dc | number | null | Day change $ (p - pc) | REST + stream | Overlay → day_change | Prefer TD native change; preserve when market closed if TD zeros | ahdc |
dp | number | null | Day change % | REST + stream | Overlay → day_change_pct, RTH movers | Same preserve rules as dc | ahdp; never raw UI dailyChgPct without getDailyChange |
dh / dl / dv | number | Daily high / low / volume | REST + stream | _live_daily_* | — | Candle OHLC in D1 |
t | number (ms) | Poll / flush timestamp | Every writer tick | Legacy tick freshness only | Must not gate display freshness | q_ts, p_ts |
q_ts | number (ms) | Vendor quote receipt stamp | REST: jittered now; stream: event lastTs; merge never regresses | isPriceValueFresh, client, health | Mandatory; jitter prevents batch lockstep aging | Vendor trade_ts; poll t |
p_ts | number (ms) | Last time p actually moved | Writers on price change; merge never regresses | Freshness gates (with q_ts) | Mandatory | q_ts (receipt ≠ price move) |
ahp | number | Extended-hours last print | REST/stream only when !isNyRegularMarketOpen() | EXT movers | Never write during RTH | p |
ahdc / ahdp | number | EXT change $ / % vs RTH close | Same as ahp | _ah_change* | Same RTH gate; crypto excluded from EXT row UI | dc/dp |
session | string (optional) | Vendor session hint | Some tick paths | Client tick day-change | Bare WS ticks often omit | Blob .market_open |
trade_ts | number (optional) | Vendor last-trade time | REST parse | Forensics | Not used as q_ts after 2026-07-28 TD quantization fix | q_ts |
2.3 Freshness constants
| Name | Value | Meaning |
|---|---|---|
PF_FRESH_MS | 10 min | RTH value-fresh window |
VALUE_STALE_PAGE_GRACE_MS | 10 min | Extra grace before Discord/health page (≥20 min stale) |
PF_VALUE_FRESH_MS_CLOSED | 26 h | Outside-RTH value-fresh window |
PF_STALE_JITTER_MAX_MS | 8 min | REST q_ts jitter window |
| Page threshold | ≥40 symbols value-stale in RTH/preopen | price_value_freshness + /timed/health |
Invariant: Stream DO must own every symbol present in timed:prices or DO rewrite can clobber cron q_ts on orphans.
3. Other critical KV blobs
| Name | Type/shape | Meaning | Owner/writer | Readers | Freshness / invariants | Do not confuse with |
|---|---|---|---|---|---|---|
timed:latest:<TICKER> | Large JSON (~150–200 KB) | Full scoring payload | Scoring / ingest / rescore (tt-engine) | Rails, admin, hydrate | Stale if scoring skip/OOM; not a live price source | Slim index timed:all:snapshot |
timed:all:snapshot | Slim JSON index | Universe index for /timed/all fast path | Scoring tail | /timed/all, options/desk | Must pass max-age at read | Full payload in timed:latest:* |
timed:all | { data, updated_at } | Dashboard universe map (micro-cache) | /timed/all assembly | Pages UI | 5-min fast path must overlayTimedPricesRow | timed:all:snapshot |
timed:investor:scores | Object keyed by ticker | Investor kanban / scores | Investor compute cron | Investor UI | Purge must clear companion keys | /timed/all trader graph |
timed:investor:rank | Ranked list | Investor rank order | Scoring cron (~*/5) | Investor dashboard | Single-ticker rescore does not refresh this | Trader rank on snapshot |
timed:capture:latest:<T> | JSON | Latest ingest capture | POST /timed/ingest-capture | Market internals, local smoke | Best local exercise path | timed:latest: scoring blob |
timed:capture:trail:<T> | JSON array | Short capture history | Ingest | Internals | TBD retention | D1 timed_trail |
timed:cloud-pivot:desk | Desk JSON | Cloud Pivot desk state | Scoring tick only | /timed/plays/today | Gate on scanned; no empty fallback writes | Action rings |
timed:opt-dt-actions | Action ring (cap 500) | Index option day-trade paper actions | Options DT engine | Portfolio DT P&L, coverage | Include TRIM in round accounting | account_ledger |
timed:opt-dt-book:<signalId> | Book JSON | Open DT paper book per signal | DT engine | Mirror / UI | — | timed:opt-dt-carry:<T> |
timed:opt-dt-carry:<T> | Carry JSON | Per-underlying carry / book pointer | DT engine | Re-entry / lean | — | Mirror row |
timed:opt-dt-mirror:<signalId> | Mirror state | Broker mirror flags | options-auto-mirror | Coverage, reconcile | — | timed:opt-dt-mirror-log |
timed:opt-dt-mirror-log | Log ring | DT mirror attempt outcomes | Mirror + coverage | model_broker_coverage | Entry declines with reason are terminal | Per-signal mirror key |
timed:opt-dt:last-close:<T> | stamp | Last DT close for re-entry cooldown (10 min) | DT engine | Entry gate | — | Reduce-unreconciled keys |
timed:opt-dt:reduce-unreconciled | map | Fired reduces not yet reconciled | Mirror Stage 5b | Health | Keys off reconcile state | Partner-close keys |
timed:brief:claim:{date}:{type} | claim | Daily brief generate lease | Brief cron | Brief cron | Prevents double evening email race | daily_briefs D1 row |
bridge:client:recent | ring | Bridge order dispatch ring | Broker bridge client | Coverage, catch-up | Records model qty; accepted_qty separate | D1 mirror_order_attempt |
timed:trades:all | array (legacy/cache) | Paper trade list used by feed SL loop | Trade simulation | Feed SL breach | Prefer D1 trades for authority | D1 trades |
timed:cache:candle-tf-counts | counts JSON | Candle coverage gaps (1h TTL) | Candle ingest helpers | Onboard / gap detection | Bust with ingestion-status | Scanning ticker_candles GROUP BY |
4. API ticker / score fields
Used by /timed/all, /timed/prices consumers, cards, rails. Live + proprietary fields are tier-gated (Section 7).
4.1 Price + day-change aliases
| Name | Type | Meaning | Owner/writer | Readers | Freshness / invariants | Do not confuse with |
|---|---|---|---|---|---|---|
price / close | number | Snapshot / RTH close fields | Scoring + overlay | Headline outside RTH | Outside RTH overlay sets close = pf.p when value-fresh | _live_price; ahp |
_live_price | number | Live feed overlay of p | overlay / client merge | RTH headline when fresh | Gated by q_ts/p_ts | EXT print |
_live_prev_close | number | Overlay of pc | Overlay | getDailyChange source 1 | — | Scoring prev_close |
prev_close / aliases | number | Prior close aliases | Server must emit aliases | getDailyChange chain | Prefer live pc; heal splits | pc short key only in prices blob |
day_change / aliases | number | Day $ change aliases | Overlay / snapshot | Fallback only — UI must recompute via getDailyChange | Do not trust blindly | ahdc |
day_change_pct / aliases | number | Day % aliases | Same | Same | Same | ahdp; raw dailyChgPct |
_ah_price / _ah_change* | number | EXT overlay | Overlay when !marketOpen | EXT movers row | Cleared during RTH; crypto excluded | Headline price |
_rth_session_close | number | Client merge lock of RTH close | Frontend merge | Headline outside RTH | — | prev_close |
_quote_receipt_ts | number | Client alias of q_ts | Overlay | getPriceReceiptAgeMs | Never use poll t | _price_updated_at |
_price_value_ts | number | Client alias of p_ts | Overlay | Freshness | — | _price_updated_at |
_price_updated_at | number | Max of blob/updated + receipt stamps | Overlay | Age labels | Not the sole freshness gate | scored_at |
Rule: getDailyChange(t) in react-app/shared-price-utils.js is the only allowed daily-change computation for UI. Prefer (headlinePrice − prevClose).
4.2 Proprietary / model fields (redacted for Member + anon)
| Name | Type | Meaning | Owner/writer | Readers | Notes |
|---|---|---|---|---|---|
rank / score / dynamicScore / conviction / entry_quality | number | Ranking / conviction | Scoring | Pro+ UI | In PROPRIETARY_SNAPSHOT_FIELDS |
sl / tp / tp1..3 / targets / … | number / obj | Stops & targets | Scoring / plan | Pro+ | Redacted for free/anon |
kanban_stage / trade_plan / regime_forecast | string / obj | Stage + plan | Scoring | Rails | — |
_breakout_watch / breakout | obj | Breakout watch badge | Scoring | UI | Field contract tested vs worker |
_news_summary | obj/string | News stamp from D1 | Scoring cron | Rank context | — |
_journey | obj | Journey phases | Scoring | Journey UI | Redacted Members |
investor_score / breakdown | number / obj | Long-term score | Investor compute | Investor page | Via investor KV more than /timed/all |
tf_tech | multi-TF obj | Multi-TF tech bundle | Scoring | Charts / ST | Large; missing W/M → backfill |
rootStrategy | obj | Mode / confluence | Scoring | Verdict | — |
_redacted | boolean true | Snapshot stripped for tier | redactTickerSnapshot | Clients | Presence means prices+scores removed |
Live price field set stripped together with proprietary set for unentitled tiers — see LIVE_PRICE_SNAPSHOT_FIELDS / PROPRIETARY_SNAPSHOT_FIELDS in worker/api.js.
5. D1 tables (core)
Database: timed-trading-ledger (prod). Schemas are mostly lazy CREATE TABLE IF NOT EXISTS; worker/d1-schema.sql is the documented baseline.
5.1 Trades / paper / ledger
| Name | Type/shape (key columns) | Meaning | Owner/writer | Readers | Freshness / invariants | Do not confuse with |
|---|---|---|---|---|---|---|
trades | trade_id PK; ticker, direction, entry_*/exit_*, status, trimmed_pct, pnl*, setup_*, … | Short-term model / paper trades | Trade simulation / kanban | Portfolio, autopsy, coverage, CIO | Live rows typically run_id null/empty | backtest_run_trades; investor_positions |
trades.shares / notional | REAL | Size fields | Backfill / entry writers | Account summary, Size column | DDL site TBD | Options DT contracts |
trade_events | event_id PK; trade_id, type, price, qty_pct_* | Trade lifecycle events | Simulation | Autopsy / ledger rebuild | Unique (trade_id, type, ts) | Mirror order attempts |
positions | position_id PK; ticker, direction, status, qty, cost_basis, SL/TP | Execution adapter position rows | Simulation / sync | Catch-up, share backfill | position_id often == trade_id | investor_positions; model_position |
account_ledger | ledger_id; mode (trader/investor/day_trade); cash_delta; balance | Cash + realized P&L books | Ledger writers per book | Portfolio equity curves | Day Trader sleeve uses mode=day_trade + $25k start | Option DT actions only in KV ring |
data_audit_log | audit_id; op, scope, caller, rows_affected | Forensic log of destructive ops | Best-effort helpers | Ops forensics | Never throws into caller path | Broker audit rings |
alerts | alert_id; ticker, side, rank, discord_sent, payload_json | Alert ledger / dedupe | Alert pipeline | Discord status / dedupe | Unique ticker+ts | Discord webhook embeds |
5.2 Investor
| Name | Key columns | Meaning | Owner/writer | Readers | Notes |
|---|---|---|---|---|---|
investor_positions | id PK; ticker, status, shares, cost_basis, avg_entry, peak_price, thesis*, … | Long-term book | Investor compute / DCA / rebalance | Investor UI, mirror, peak heal | peak_price must be SELECTed or MFE trim understates |
investor_lots | id; position_id; action; shares; price; value; ts; reason | Lot log (buys/sells) | Same | PnL / monthly; chunked fetch (≤80 ids / IN) | D1 100-bind cap |
5.3 Universe / candles / captures
| Name | Key columns | Meaning | Owner/writer | Readers | Notes |
|---|---|---|---|---|---|
ticker_index | ticker PK; first/last_seen | Universe membership | Onboard / scoring | Registry, dead-weight | Every Selected name needs sector + candles + score |
ticker_latest | ticker PK; ts; kanban_stage; payload_json | D1 fallback cache of latest payload | Scoring tail sync | /timed/all fallback | Fingerprint must not store full payload in isolate memory |
ticker_candles | (ticker, tf, ts) PK; ohlcv; session | Multi-TF OHLCV | Bar cron / live sync / backfill | Charts, scoring, peak heal | Never unbounded GROUP BY |
timed_trail | (ticker, ts) PK; scores + payload_json | Historical ingest trail | Ingest | Replay / time-travel | Keyset-page large scans |
ingest_receipts | receipt_id PK; ticker, ts, payload_hash | Idempotent raw webhook receipts | Ingest | Dedup / forensics | — |
ticker_news | (discovery module) | News facts | news-tracker | Scoring _news_summary | — |
ticker_profiles / sector_profiles | profile rows | Fundamentals / sector | Onboard | Rank context | — |
5.4 Broker mirror / intents
| Name | Key columns | Meaning | Owner/writer | Readers | Freshness / invariants | Do not confuse with |
|---|---|---|---|---|---|---|
model_position | position_id PK; lane; signal_id; qty; status; seq | Entangled-mirror model position | Mirror kernel | Converge / coverage | Sleeve qty derived from fills | Paper KV book |
model_leg | (position_id, seq); event; remaining_after | Model leg events | Kernel | Reconstruct remaining | Unique (position_id, event, remaining_after) | trade_events |
mirror_sleeve | (position_id, account_id); status; divergence_reason | Per-account sleeve | Kernel | Converge | broker_account_id is join key across tenants | Ring row |
mirror_order_attempt | client_order_id PK; filled_qty; status; reason | Every account order attempt before send | Kernel / bridge | Coverage | Never truncate client_order_id entropy | bridge:client:recent |
mirror_dispatch_outbox | (position_id, seq); status pending | Durable reduce dispatch | Kernel | Cron + converge drain | Phase-2 queue precursor | Broker intents |
broker_intents | id PK; trade_id; side; qty; status pending; order_json | Deferred reducer places that did not place | recordBrokerIntent | Drain cron / heal | Terminal outcomes not stored as pending | Mirror attempts (placed path) |
Manifest / sync columns such as broker_remaining_qty, sync_drift_count live on broker-mirror tables — full equity manifest table name TBD (see skills/broker-bridge.md).
5.5 Briefs / CIO / learning
| Name | Meaning | Owner | Notes |
|---|---|---|---|
daily_briefs | Morning/evening brief content + prediction levels | Daily brief cron | Claim KV before OpenAI |
daily_market_snapshots | Per-date macro snapshot | Brief | — |
market_events | Econ calendar incl. FOMC | Brief / FSD | Curated FOMC snap; purge horizon-bound |
ai_cio_decisions | CIO approve/reject + outcomes | CIO service | Filter is_replay=0 for live stats |
learning_proposals | Loop-2 proposals | Learning | See skills/learning-loops.md |
decision_records | Decision audit | Decision records module | — |
Many research/backtest tables exist — omitted here; accuracy over completeness.
6. Session concepts
| Name | Type | Meaning | Owner | Readers | Invariants | Do not confuse with |
|---|---|---|---|---|---|---|
| RTH | session | NY regular hours (~09:30–16:00 ET; half-days 13:00) | isNyRegularMarketOpen() / market-calendar | Feed writers, overlay, UI | Calendar must match worker + frontend | Extended hours |
| EXT / AH | session | Pre/post regular session | Feed when !RTH | EXT movers row | Hidden during RTH; persists when closed | Headline p |
| PRE | session | 04:00–09:30 ET weekday | Client helpers | Tick day-change gating | PRE tick dayChg can be gap vs prev close | RTH day % |
| Crypto 24/7 | symbols | BTCUSD, ETHUSD | Feed + UI | — | No EXT row; excluded from equity value-stale accounting | Equity AH fields |
| Value-stale exclude | set | SPX, VIX, NDX, … + crypto | feed-outputs | Health | Futures/indices use other lanes | Equity universe |
7. Entitlement tiers
| Code tier | User meaning | Live prices | Proprietary scores / SL/TP | UI gate |
|---|---|---|---|---|
admin | Admin / API key locally | Yes | Yes | _ttIsPro true (admin) |
pro | Paying Pro or VIP (VIP collapsed → pro) | Yes | Yes | window._ttIsPro |
free | Member (signed in, never paid) — not a product “free plan” | No | No | _ttIsPro false |
anon | Not signed in | No | No | false |
| Name | Meaning | Owner | Notes |
|---|---|---|---|
canAccessLivePrices(tier) | tier ∈ {admin, pro} | worker/api.js | Gates /timed/prices, ws-ticket, unredacted /timed/all |
redactTickerMapForTier | Strips live + proprietary fields; sets _redacted:true | API assembly | Cache keys include tier bucket |
| Footer attribution | “Market data powered by Twelve Data” | Frontend | Licensing — required |
8. Discord / digest / alert fields
8.1 Transport
| Name | Meaning | Owner | Notes |
|---|---|---|---|
Lane trade | Model trade lifecycle → DISCORD_WEBHOOK_URL | notifyDiscord | Default lane |
Lane general | Briefs / intel → DISCORD_GENERAL_WEBHOOK_URL | Same | Falls back to trade if unset (logged) |
Lane system | Ops / cron failures → DISCORD_SYSTEM_WEBHOOK_URL | Same | Username suffix • Ops |
DISCORD_ENABLE | Must be "true" | Env | Otherwise skipped |
| Embed limits | title <256, field.value <1024, total <6000 | Discord API | 400 on bust — check worker logs |
8.2 D1 alerts row
See Section 5.1 — discord_sent, discord_status, discord_error, payload_json, dedupe_day.
8.3 Representative embed payloads
| Kind | Typical fields | Lane |
|---|---|---|
| Cron failure | title Cron Failure: {op}, error text | system |
| Weekly investor digest | Market Health, Portfolio Summary, Stage Changes, Top Accumulation, Sector Rotation | general |
| Investor zone / thesis | ticker, Long Term Score, Confidence, RS Rank, Zone Type, Signals, optional AI CIO guidance | trade |
| Investor open / add / trim | Shares, Price, Value, Stage, Score | trade |
| Broker coverage clean/fail | title BROKER COVERAGE · … | system |
| Daily brief | Markdown/content from daily_briefs | general |
Exact field lists for every trade embed variant: TBD (see worker/alerts.js + discord helpers).
9. Related health / watch fields
| Name | Location | Meaning |
|---|---|---|
valueStaleCount / valueStaleSymbols | /timed/health | Writer-independent count from timed:prices rows |
price_value_freshness | Cron tombstone / Discord | Pages when ≥40 symbols >20m stale in RTH/preopen |
deployedSha / workerRole | /timed/health, /timed/version | Deploy verification |
10. Biggest gaps still TBD
- Full
tradescolumn inventory in prod —shares/notional/run_id/ trim_price and other ALTERs used in queries but not all present ind1-schema.sqlCREATE; confirm withPRAGMA table_info(trades)on prod. - Equity broker manifest table / KV schema —
broker_remaining_qty,sync_drift_count, suppress flags; exact storage object not fully traced (skills/broker-bridge.md). - Complete Discord trade open/close embed field map — investor + digest covered; ST entry/exit and options DT embeds need a dedicated pass.
- Exhaustive KV key catalog — dozens of
timed:opt-dt:*,coo:*,bridge:*, investor stage keys; only operationally critical ones listed. - Research/backtest/calibration D1 surface — intentionally deferred.
timed:latestpayload field encyclopedia —tf_techalone is large; document incrementally via snapshot/rescore skills.