-- =====================================================
-- ML SCHEMA - LLM SIGNALS TABLE
-- =====================================================
-- Description: Logs ML signals and LLM decisions for feedback and fine-tuning
-- Schema: ml
-- Author: ML-Specialist (NEXUS v4.0)
-- Date: 2026-01-25
-- Module: OQI-007-llm-strategy-agent
-- =====================================================

CREATE TABLE ml.llm_signals (
    id SERIAL PRIMARY KEY,
    signal_id UUID NOT NULL UNIQUE DEFAULT gen_random_uuid(),

    -- Symbol and timing
    symbol VARCHAR(20) NOT NULL,
    timestamp TIMESTAMPTZ NOT NULL,

    -- ML Predictions (from metamodel)
    ml_prediction JSONB,
    -- Expected structure:
    -- {
    --   "direction": "BULLISH"|"BEARISH"|"NEUTRAL",
    --   "magnitude": 0.5,
    --   "confidence": 0.75,
    --   "delta_high": 10.5,
    --   "delta_low": 8.2,
    --   "volatility_regime": "HIGH"|"MEDIUM"|"LOW",
    --   "market_phase": "accumulation"|"distribution"|"manipulation"|"trend"
    -- }

    -- Strategy predictions (individual strategies)
    strategy_predictions JSONB,
    -- Expected structure:
    -- [
    --   {"name": "PVA", "direction": "BULLISH", "confidence": 0.8, "weight": 0.25},
    --   {"name": "MRD", "direction": "NEUTRAL", "confidence": 0.5, "weight": 0.20},
    --   ...
    -- ]

    -- LLM interaction
    llm_prompt TEXT,
    llm_response TEXT,

    -- Parsed decision from LLM
    decision JSONB,
    -- Expected structure:
    -- {
    --   "action": "TRADE"|"NO_TRADE"|"WAIT",
    --   "direction": "LONG"|"SHORT"|null,
    --   "entry": 2340.50,
    --   "stop_loss": 2335.00,
    --   "take_profit": [2350.00, 2360.00],
    --   "position_size": 1.0,
    --   "reasoning": "...",
    --   "is_valid": true
    -- }

    -- Trade result (updated after trade closes)
    trade_result JSONB,
    -- Expected structure:
    -- {
    --   "result": "WIN"|"LOSS"|"BREAKEVEN"|"PARTIAL",
    --   "pnl": 50.00,
    --   "pnl_pct": 5.0,
    --   "entry_price": 2340.50,
    --   "exit_price": 2350.00,
    --   "stop_loss_hit": false,
    --   "take_profit_hit": true,
    --   "duration_minutes": 45,
    --   "exit_reason": "TP1"
    -- }

    -- Timestamps
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- Indices for common queries
CREATE INDEX idx_llm_signals_symbol ON ml.llm_signals(symbol);
CREATE INDEX idx_llm_signals_timestamp ON ml.llm_signals(timestamp DESC);
CREATE INDEX idx_llm_signals_created_at ON ml.llm_signals(created_at DESC);

-- Index for finding signals with results (for training data export)
CREATE INDEX idx_llm_signals_with_results ON ml.llm_signals(timestamp DESC)
    WHERE trade_result IS NOT NULL;

-- Index for decision types
CREATE INDEX idx_llm_signals_decision_action ON ml.llm_signals((decision->>'action'));

-- GIN index for JSONB queries
CREATE INDEX idx_llm_signals_ml_prediction ON ml.llm_signals USING GIN (ml_prediction);
CREATE INDEX idx_llm_signals_trade_result ON ml.llm_signals USING GIN (trade_result);

-- Trigger to update updated_at
CREATE OR REPLACE FUNCTION ml.update_llm_signals_updated_at()
RETURNS TRIGGER AS $$
BEGIN
    NEW.updated_at = NOW();
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER trg_llm_signals_updated_at
    BEFORE UPDATE ON ml.llm_signals
    FOR EACH ROW
    EXECUTE FUNCTION ml.update_llm_signals_updated_at();

-- Comments
COMMENT ON TABLE ml.llm_signals IS 'Logs ML signals and LLM decisions for performance tracking and fine-tuning dataset generation';

COMMENT ON COLUMN ml.llm_signals.id IS 'Auto-incrementing primary key';
COMMENT ON COLUMN ml.llm_signals.signal_id IS 'Unique UUID for external reference';
COMMENT ON COLUMN ml.llm_signals.symbol IS 'Trading symbol (e.g., XAUUSD, EURUSD)';
COMMENT ON COLUMN ml.llm_signals.timestamp IS 'Timestamp of the signal generation';
COMMENT ON COLUMN ml.llm_signals.ml_prediction IS 'JSONB with metamodel prediction output';
COMMENT ON COLUMN ml.llm_signals.strategy_predictions IS 'JSONB array with individual strategy predictions';
COMMENT ON COLUMN ml.llm_signals.llm_prompt IS 'Full prompt sent to the LLM';
COMMENT ON COLUMN ml.llm_signals.llm_response IS 'Raw response from the LLM';
COMMENT ON COLUMN ml.llm_signals.decision IS 'JSONB with parsed trading decision';
COMMENT ON COLUMN ml.llm_signals.trade_result IS 'JSONB with trade outcome (null until trade closes)';
COMMENT ON COLUMN ml.llm_signals.created_at IS 'Record creation timestamp';
COMMENT ON COLUMN ml.llm_signals.updated_at IS 'Record last update timestamp';
