ShadowDecision already carries the V3.4 5-factor breakdown (base_leverage, dc_lev_mult, regime_size_mult, market_ob_mult, esof_size_mult), but the journal row and CH DDL dropped it — so a DARK soak would record decisions WITHOUT the factor decomposition that V3.4 exists to expose. Thread it through: - 22_violet_decisions.sql: 5 additive Nullable(Float64) breakdown columns. NULL on the legacy base-only path; populated once the launcher feeds live factor planes. Note added: on a pre-existing table use ALTER ... ADD COLUMN instead of the CREATE IF NOT EXISTS (no live table yet — VIOLET is DARK, never soaked). - shadow_journal.py: DecisionRow gains the 5 Optional[float] fields (ge=0.0, finite-guarded); journal() populates them via getattr(..., None) so the base-only path and duck-typed reject tests stay NULL/rejected rather than raising on attribute access. - test_violet_shadow_journal.py: breakdown round-trips on the full path; NULL on base-only; a negative multiplier is rejected at the row guard. The existing DecisionRow-fields == DDL-columns parity test still holds with the new columns. violet-only; no shared-file edits; no soak. 29 violet tests green (7 journal + 22 engine/DDL-apply). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
36 lines
1.6 KiB
SQL
36 lines
1.6 KiB
SQL
-- VIOLET V3e: shadow decision journal. One row per ACTUATED ShadowDecision the
|
||
-- VioletDecisionEngine emits (the muted "what BLUE would do this scan"). NEVER an
|
||
-- order — execution stays off behind the ObserveOnlyVenue guard. session_id is a
|
||
-- boot-time UUID (mono_ns is meaningless across restarts without it).
|
||
-- Apply via apply_violet_ddl.py (one statement per HTTP POST).
|
||
|
||
CREATE TABLE IF NOT EXISTS dolphin_violet.violet_decisions
|
||
(
|
||
`ts` DateTime64(3, 'UTC'),
|
||
`session_id` String,
|
||
`scan_number` UInt64,
|
||
`mono_ns` UInt64,
|
||
`asset` LowCardinality(String),
|
||
`side` LowCardinality(String),
|
||
`vel_div` Float64,
|
||
`fraction` Float64,
|
||
`conviction_leverage` Float64,
|
||
`notional_fraction` Float64,
|
||
`target_exposure` Float64,
|
||
`ars_score` Float64,
|
||
`bucket_idx` UInt8,
|
||
`actuated` UInt8,
|
||
-- V3.4 full-sizing breakdown: conviction = base × dc × regime(ACB) × ob × esof,
|
||
-- capped @9. NULL on the legacy base-only path (no live SizingFactors); populated
|
||
-- when the launcher feeds live factor planes. Additive columns — on a pre-existing
|
||
-- table apply the matching `ALTER TABLE ... ADD COLUMN IF NOT EXISTS` instead.
|
||
`base_leverage` Nullable(Float64),
|
||
`dc_lev_mult` Nullable(Float64),
|
||
`regime_size_mult` Nullable(Float64),
|
||
`market_ob_mult` Nullable(Float64),
|
||
`esof_size_mult` Nullable(Float64)
|
||
)
|
||
ENGINE = MergeTree
|
||
ORDER BY (asset, ts)
|
||
TTL toDate(ts) + toIntervalDay(180);
|