-- ============================================================================
-- OrbiQuant IA - Esquema TRADING
-- ============================================================================
-- Archivo: 03_trading_schema.sql
-- Descripción: Bots, señales, estrategias y operaciones de trading
-- Fecha: 2025-12-05
-- ============================================================================

SET search_path TO trading;

-- ============================================================================
-- TIPOS ENUMERADOS
-- ============================================================================

CREATE TYPE bot_status_enum AS ENUM ('active', 'paused', 'stopped', 'error', 'maintenance');
CREATE TYPE signal_status_enum AS ENUM ('pending', 'active', 'triggered', 'expired', 'cancelled');
CREATE TYPE position_status_enum AS ENUM ('open', 'closed', 'pending');
CREATE TYPE timeframe_enum AS ENUM ('1m', '5m', '15m', '30m', '1h', '4h', '1d', '1w');
CREATE TYPE amd_phase_enum AS ENUM ('accumulation', 'manipulation', 'distribution', 'unknown');
CREATE TYPE volatility_regime_enum AS ENUM ('low', 'medium', 'high', 'extreme');

-- ============================================================================
-- TABLA: symbols
-- Descripción: Instrumentos financieros disponibles
-- ============================================================================
CREATE TABLE IF NOT EXISTS symbols (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),

    -- Identificación
    symbol VARCHAR(20) NOT NULL UNIQUE, -- 'XAUUSD', 'EURUSD', 'BTCUSD'
    name VARCHAR(100) NOT NULL,
    description TEXT,

    -- Clasificación
    asset_class VARCHAR(50), -- 'forex', 'crypto', 'commodities', 'indices', 'stocks'
    base_currency VARCHAR(10),
    quote_currency VARCHAR(10),

    -- Trading info
    pip_value DECIMAL(10,6),
    lot_size DECIMAL(10,2),
    min_lot DECIMAL(10,4),
    max_lot DECIMAL(10,2),
    tick_size DECIMAL(10,6),

    -- Estado
    is_active BOOLEAN DEFAULT TRUE,
    trading_hours JSONB, -- [{day, open, close}]

    -- Data provider
    data_provider VARCHAR(50),
    provider_symbol VARCHAR(50),

    created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX idx_symbols_symbol ON symbols(symbol);
CREATE INDEX idx_symbols_asset_class ON symbols(asset_class);

-- ============================================================================
-- TABLA: strategies
-- Descripción: Estrategias de trading disponibles
-- ============================================================================
CREATE TABLE IF NOT EXISTS strategies (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),

    name VARCHAR(100) NOT NULL,
    slug VARCHAR(100) NOT NULL UNIQUE,
    description TEXT,

    -- Tipo
    strategy_type VARCHAR(50), -- 'intraday', 'swing', 'scalping', 'position'

    -- Configuración
    default_timeframe timeframe_enum DEFAULT '15m',
    supported_symbols TEXT[], -- NULL = todos
    risk_reward_ratio DECIMAL(4,2) DEFAULT 2.0,

    -- Parámetros configurables (JSON Schema)
    parameters_schema JSONB,
    default_parameters JSONB,

    -- ML Model asociado
    uses_ml_model BOOLEAN DEFAULT TRUE,
    ml_model_id UUID, -- Referencia a ml.models

    -- AMD
    uses_amd BOOLEAN DEFAULT TRUE,
    favorable_phases amd_phase_enum[],

    -- Estado
    is_active BOOLEAN DEFAULT TRUE,

    created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX idx_strategies_slug ON strategies(slug);

-- ============================================================================
-- TABLA: bots (Agentes de Trading)
-- Descripción: Instancias de bots/agentes de trading
-- ============================================================================
CREATE TABLE IF NOT EXISTS bots (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),

    -- Identificación
    name VARCHAR(100) NOT NULL,
    slug VARCHAR(100) NOT NULL UNIQUE,
    description TEXT,
    avatar_url TEXT,

    -- Perfil de riesgo
    risk_profile public.risk_profile_enum NOT NULL,

    -- Objetivos
    target_monthly_return DECIMAL(5,2), -- % objetivo
    max_drawdown DECIMAL(5,2),          -- % máximo
    max_position_size DECIMAL(5,2),     -- % del capital

    -- Estrategias
    strategy_id UUID REFERENCES strategies(id),
    strategy_parameters JSONB,

    -- Configuración
    supported_symbols TEXT[],
    default_timeframe timeframe_enum DEFAULT '15m',
    min_confidence DECIMAL(3,2) DEFAULT 0.55,

    -- Horarios de operación
    trading_schedule JSONB, -- Horarios permitidos

    -- Estado
    status bot_status_enum DEFAULT 'stopped',
    last_activity_at TIMESTAMPTZ,
    error_message TEXT,

    -- Métricas globales (actualizadas periódicamente)
    total_trades INT DEFAULT 0,
    winning_trades INT DEFAULT 0,
    total_profit DECIMAL(15,2) DEFAULT 0,
    sharpe_ratio DECIMAL(5,2),
    sortino_ratio DECIMAL(5,2),
    max_drawdown_actual DECIMAL(5,2),

    -- Público
    is_public BOOLEAN DEFAULT TRUE, -- Visible para asignar a cuentas

    created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX idx_bots_slug ON bots(slug);
CREATE INDEX idx_bots_risk_profile ON bots(risk_profile);
CREATE INDEX idx_bots_status ON bots(status);

-- ============================================================================
-- TABLA: signals
-- Descripción: Señales de trading generadas
-- ============================================================================
CREATE TABLE IF NOT EXISTS signals (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),

    -- Origen
    bot_id UUID REFERENCES bots(id),
    strategy_id UUID REFERENCES strategies(id),
    symbol_id UUID REFERENCES symbols(id),
    symbol VARCHAR(20) NOT NULL,

    -- Señal
    direction public.trade_direction_enum NOT NULL,
    timeframe timeframe_enum NOT NULL,

    -- Precios
    entry_price DECIMAL(20,8) NOT NULL,
    stop_loss DECIMAL(20,8) NOT NULL,
    take_profit DECIMAL(20,8) NOT NULL,
    current_price DECIMAL(20,8),

    -- Predicción ML
    predicted_delta_high DECIMAL(20,8),
    predicted_delta_low DECIMAL(20,8),
    prob_tp_first DECIMAL(5,4), -- Probabilidad de tocar TP antes que SL
    confidence_score DECIMAL(5,4),

    -- Contexto de mercado
    amd_phase amd_phase_enum,
    volatility_regime volatility_regime_enum,
    market_context JSONB, -- Datos adicionales del contexto

    -- R:R
    risk_reward_ratio DECIMAL(4,2),
    risk_pips DECIMAL(10,4),
    reward_pips DECIMAL(10,4),

    -- Estado
    status signal_status_enum DEFAULT 'pending',
    triggered_at TIMESTAMPTZ,
    expired_at TIMESTAMPTZ,

    -- Resultado (si se operó)
    outcome VARCHAR(20), -- 'tp_hit', 'sl_hit', 'manual_close', 'expired'
    pnl DECIMAL(15,2),

    -- Timestamps
    valid_until TIMESTAMPTZ,
    created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX idx_signals_bot ON signals(bot_id);
CREATE INDEX idx_signals_symbol ON signals(symbol);
CREATE INDEX idx_signals_status ON signals(status);
CREATE INDEX idx_signals_created ON signals(created_at DESC);
CREATE INDEX idx_signals_direction ON signals(direction);

-- ============================================================================
-- TABLA: positions
-- Descripción: Posiciones de trading (abiertas y cerradas)
-- ============================================================================
CREATE TABLE IF NOT EXISTS positions (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),

    -- Referencias
    bot_id UUID REFERENCES bots(id),
    signal_id UUID REFERENCES signals(id),
    investment_account_id UUID, -- Referencia a investment.accounts
    symbol_id UUID REFERENCES symbols(id),
    symbol VARCHAR(20) NOT NULL,

    -- Posición
    direction public.trade_direction_enum NOT NULL,
    lot_size DECIMAL(10,4) NOT NULL,

    -- Precios
    entry_price DECIMAL(20,8) NOT NULL,
    stop_loss DECIMAL(20,8),
    take_profit DECIMAL(20,8),
    exit_price DECIMAL(20,8),

    -- Broker
    broker_order_id VARCHAR(100),
    broker_position_id VARCHAR(100),

    -- Estado
    status position_status_enum DEFAULT 'open',
    opened_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
    closed_at TIMESTAMPTZ,
    close_reason VARCHAR(50), -- 'tp', 'sl', 'manual', 'forced', 'margin_call'

    -- P&L
    realized_pnl DECIMAL(15,2),
    unrealized_pnl DECIMAL(15,2),
    commission DECIMAL(10,2) DEFAULT 0,
    swap DECIMAL(10,2) DEFAULT 0,

    -- Metadata
    metadata JSONB,

    created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX idx_positions_bot ON positions(bot_id);
CREATE INDEX idx_positions_signal ON positions(signal_id);
CREATE INDEX idx_positions_account ON positions(investment_account_id);
CREATE INDEX idx_positions_status ON positions(status);
CREATE INDEX idx_positions_opened ON positions(opened_at DESC);

-- ============================================================================
-- TABLA: price_alerts
-- Descripción: Alertas de precio configuradas por usuarios
-- ============================================================================
CREATE TYPE alert_condition_enum AS ENUM ('above', 'below', 'crosses_above', 'crosses_below');

CREATE TABLE IF NOT EXISTS price_alerts (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,

    symbol VARCHAR(20) NOT NULL,
    condition alert_condition_enum NOT NULL,
    price DECIMAL(20,8) NOT NULL,
    note TEXT,

    -- Estado
    is_active BOOLEAN DEFAULT TRUE,
    triggered_at TIMESTAMPTZ,
    triggered_price DECIMAL(20,8),

    -- Notificación
    notify_email BOOLEAN DEFAULT TRUE,
    notify_push BOOLEAN DEFAULT TRUE,

    -- Recurrencia
    is_recurring BOOLEAN DEFAULT FALSE, -- Si se reactiva después de triggear

    created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX idx_price_alerts_user ON price_alerts(user_id);
CREATE INDEX idx_price_alerts_symbol ON price_alerts(symbol);
CREATE INDEX idx_price_alerts_active ON price_alerts(is_active) WHERE is_active = TRUE;

-- ============================================================================
-- TABLA: watchlists
-- Descripción: Listas de seguimiento de usuarios
-- ============================================================================
CREATE TABLE IF NOT EXISTS watchlists (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,

    name VARCHAR(100) NOT NULL,
    is_default BOOLEAN DEFAULT FALSE,

    created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX idx_watchlists_user ON watchlists(user_id);

-- ============================================================================
-- TABLA: watchlist_items
-- Descripción: Items en watchlists
-- ============================================================================
CREATE TABLE IF NOT EXISTS watchlist_items (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    watchlist_id UUID NOT NULL REFERENCES watchlists(id) ON DELETE CASCADE,

    symbol VARCHAR(20) NOT NULL,
    sort_order INT DEFAULT 0,
    notes TEXT,

    created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,

    UNIQUE(watchlist_id, symbol)
);

CREATE INDEX idx_watchlist_items_watchlist ON watchlist_items(watchlist_id);

-- ============================================================================
-- TABLA: paper_trading_accounts
-- Descripción: Cuentas de paper trading (simulación)
-- ============================================================================
CREATE TABLE IF NOT EXISTS paper_trading_accounts (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,

    name VARCHAR(100) DEFAULT 'Paper Account',
    initial_balance DECIMAL(15,2) NOT NULL DEFAULT 100000,
    current_balance DECIMAL(15,2) NOT NULL DEFAULT 100000,
    currency CHAR(3) DEFAULT 'USD',

    -- Métricas
    total_trades INT DEFAULT 0,
    winning_trades INT DEFAULT 0,
    total_pnl DECIMAL(15,2) DEFAULT 0,
    max_drawdown DECIMAL(5,2) DEFAULT 0,

    is_active BOOLEAN DEFAULT TRUE,

    created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX idx_paper_accounts_user ON paper_trading_accounts(user_id);

-- ============================================================================
-- TABLA: paper_trading_positions
-- Descripción: Posiciones de paper trading
-- ============================================================================
CREATE TABLE IF NOT EXISTS paper_trading_positions (
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    account_id UUID NOT NULL REFERENCES paper_trading_accounts(id) ON DELETE CASCADE,
    user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,

    symbol VARCHAR(20) NOT NULL,
    direction public.trade_direction_enum NOT NULL,
    lot_size DECIMAL(10,4) NOT NULL,

    entry_price DECIMAL(20,8) NOT NULL,
    stop_loss DECIMAL(20,8),
    take_profit DECIMAL(20,8),
    exit_price DECIMAL(20,8),

    status position_status_enum DEFAULT 'open',
    opened_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
    closed_at TIMESTAMPTZ,
    close_reason VARCHAR(50),

    realized_pnl DECIMAL(15,2),

    created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX idx_paper_positions_account ON paper_trading_positions(account_id);
CREATE INDEX idx_paper_positions_user ON paper_trading_positions(user_id);
CREATE INDEX idx_paper_positions_status ON paper_trading_positions(status);

-- ============================================================================
-- TRIGGERS
-- ============================================================================

CREATE TRIGGER update_symbols_updated_at
    BEFORE UPDATE ON symbols
    FOR EACH ROW
    EXECUTE FUNCTION public.update_updated_at_column();

CREATE TRIGGER update_strategies_updated_at
    BEFORE UPDATE ON strategies
    FOR EACH ROW
    EXECUTE FUNCTION public.update_updated_at_column();

CREATE TRIGGER update_bots_updated_at
    BEFORE UPDATE ON bots
    FOR EACH ROW
    EXECUTE FUNCTION public.update_updated_at_column();

CREATE TRIGGER update_signals_updated_at
    BEFORE UPDATE ON signals
    FOR EACH ROW
    EXECUTE FUNCTION public.update_updated_at_column();

CREATE TRIGGER update_positions_updated_at
    BEFORE UPDATE ON positions
    FOR EACH ROW
    EXECUTE FUNCTION public.update_updated_at_column();
