-- ===================================================== -- ML SCHEMA - LLM PREDICTION OUTCOMES TABLE -- ===================================================== -- Description: Actual outcomes for LLM predictions to track accuracy -- Schema: ml -- Author: Database Agent -- Date: 2026-01-04 -- Module: OQI-010-llm-trading-integration -- ===================================================== CREATE TABLE ml.llm_prediction_outcomes ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), -- Reference to prediction prediction_id UUID NOT NULL REFERENCES ml.llm_predictions(id) ON DELETE CASCADE, -- Actual market results actual_direction VARCHAR(10), actual_high DECIMAL(20,8), actual_low DECIMAL(20,8), -- Evaluation metrics direction_correct BOOLEAN, target_reached BOOLEAN, stop_hit BOOLEAN, -- PnL metrics pnl_pips DECIMAL(10,2), pnl_percentage DECIMAL(10,4), -- Resolution timing resolved_at TIMESTAMPTZ, resolution_candles INTEGER, -- Timestamps created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), -- Constraints CONSTRAINT unique_llm_prediction_outcome UNIQUE(prediction_id), CONSTRAINT chk_llm_outcomes_actual_direction CHECK ( actual_direction IS NULL OR actual_direction IN ('UP', 'DOWN', 'FLAT') ), CONSTRAINT chk_llm_outcomes_resolution CHECK ( (resolved_at IS NOT NULL AND (direction_correct IS NOT NULL OR target_reached IS NOT NULL OR stop_hit IS NOT NULL)) OR resolved_at IS NULL ), CONSTRAINT chk_llm_outcomes_high_low CHECK ( (actual_high IS NULL AND actual_low IS NULL) OR (actual_high IS NOT NULL AND actual_low IS NOT NULL AND actual_high >= actual_low) ), CONSTRAINT chk_llm_outcomes_resolution_candles CHECK ( resolution_candles IS NULL OR resolution_candles >= 0 ) ); -- Indices CREATE INDEX idx_llm_outcomes_prediction ON ml.llm_prediction_outcomes(prediction_id); CREATE INDEX idx_llm_outcomes_resolved ON ml.llm_prediction_outcomes(resolved_at DESC) WHERE resolved_at IS NOT NULL; CREATE INDEX idx_llm_outcomes_direction_correct ON ml.llm_prediction_outcomes(direction_correct) WHERE direction_correct IS NOT NULL; CREATE INDEX idx_llm_outcomes_target_reached ON ml.llm_prediction_outcomes(target_reached) WHERE target_reached IS NOT NULL; CREATE INDEX idx_llm_outcomes_stop_hit ON ml.llm_prediction_outcomes(stop_hit) WHERE stop_hit IS NOT NULL; CREATE INDEX idx_llm_outcomes_pnl ON ml.llm_prediction_outcomes(pnl_pips DESC) WHERE pnl_pips IS NOT NULL; CREATE INDEX idx_llm_outcomes_created ON ml.llm_prediction_outcomes(created_at DESC); -- Index for accuracy calculations (joins with predictions) CREATE INDEX idx_llm_outcomes_accuracy_calc ON ml.llm_prediction_outcomes(prediction_id, direction_correct, target_reached, pnl_pips) WHERE resolved_at IS NOT NULL; -- Comments COMMENT ON TABLE ml.llm_prediction_outcomes IS 'Actual outcomes for LLM predictions, used for model accuracy tracking and fine-tuning feedback'; COMMENT ON COLUMN ml.llm_prediction_outcomes.id IS 'Unique identifier for the outcome record'; COMMENT ON COLUMN ml.llm_prediction_outcomes.prediction_id IS 'Reference to the original LLM prediction'; COMMENT ON COLUMN ml.llm_prediction_outcomes.actual_direction IS 'Actual price direction: UP, DOWN, or FLAT'; COMMENT ON COLUMN ml.llm_prediction_outcomes.actual_high IS 'Highest price reached during prediction window'; COMMENT ON COLUMN ml.llm_prediction_outcomes.actual_low IS 'Lowest price reached during prediction window'; COMMENT ON COLUMN ml.llm_prediction_outcomes.direction_correct IS 'Whether the predicted direction matched actual direction'; COMMENT ON COLUMN ml.llm_prediction_outcomes.target_reached IS 'Whether the take profit level was reached'; COMMENT ON COLUMN ml.llm_prediction_outcomes.stop_hit IS 'Whether the stop loss level was hit'; COMMENT ON COLUMN ml.llm_prediction_outcomes.pnl_pips IS 'Profit/loss in pips if trade was taken'; COMMENT ON COLUMN ml.llm_prediction_outcomes.pnl_percentage IS 'Profit/loss as percentage of entry price'; COMMENT ON COLUMN ml.llm_prediction_outcomes.resolved_at IS 'Timestamp when the prediction outcome was determined'; COMMENT ON COLUMN ml.llm_prediction_outcomes.resolution_candles IS 'Number of candles until resolution (target/stop hit or expiry)'; COMMENT ON COLUMN ml.llm_prediction_outcomes.created_at IS 'Timestamp when outcome record was created';