-- Autonomous Trading Engine -- Adds tables for trading engine configuration, reserve pool management, -- risk tier history, circuit breakers, trading decisions, stop levels, -- portfolio snapshots, backtesting, tax lots, earnings calendar, -- correlation matrix cache, and notifications. -- ============================================================ -- Trading Engine Configuration -- ============================================================ CREATE TABLE trading_engine_config ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), enabled BOOLEAN NOT NULL DEFAULT FALSE, paused BOOLEAN NOT NULL DEFAULT FALSE, risk_tier VARCHAR(20) NOT NULL DEFAULT 'moderate', reserve_siphon_pct FLOAT NOT NULL DEFAULT 0.20, polling_interval_seconds INTEGER NOT NULL DEFAULT 60, gradual_entry_tranches INTEGER NOT NULL DEFAULT 3, gradual_entry_threshold_dollars FLOAT NOT NULL DEFAULT 30.0, gradual_entry_interval_minutes INTEGER NOT NULL DEFAULT 15, trading_window_start_minutes INTEGER NOT NULL DEFAULT 15, trading_window_end_minutes INTEGER NOT NULL DEFAULT 15, max_open_positions INTEGER NOT NULL DEFAULT 10, circuit_breaker_daily_loss_pct FLOAT NOT NULL DEFAULT 0.05, circuit_breaker_single_position_loss_pct FLOAT NOT NULL DEFAULT 0.15, circuit_breaker_ticker_cooldown_hours INTEGER NOT NULL DEFAULT 48, circuit_breaker_volatility_pause_hours INTEGER NOT NULL DEFAULT 2, circuit_breaker_stop_loss_hits_threshold INTEGER NOT NULL DEFAULT 3, circuit_breaker_stop_loss_window_minutes INTEGER NOT NULL DEFAULT 30, active_pool_minimum FLOAT NOT NULL DEFAULT 100.0, emergency_drawdown_threshold_pct FLOAT NOT NULL DEFAULT 0.40, reserve_high_water_pct FLOAT NOT NULL DEFAULT 0.30, absolute_position_cap FLOAT NOT NULL DEFAULT 50.0, correlation_reduction_threshold FLOAT NOT NULL DEFAULT 0.5, correlation_rejection_threshold FLOAT NOT NULL DEFAULT 0.8, earnings_pre_window_days INTEGER NOT NULL DEFAULT 3, earnings_post_cooldown_days INTEGER NOT NULL DEFAULT 1, micro_trading_enabled BOOLEAN NOT NULL DEFAULT FALSE, micro_trading_interval_seconds INTEGER NOT NULL DEFAULT 300, micro_trading_allocation_cap_pct FLOAT NOT NULL DEFAULT 0.03, micro_trading_max_daily INTEGER NOT NULL DEFAULT 10, micro_trading_max_hold_minutes INTEGER NOT NULL DEFAULT 120, notification_sms_enabled BOOLEAN NOT NULL DEFAULT FALSE, notification_email_enabled BOOLEAN NOT NULL DEFAULT FALSE, notification_phone_number VARCHAR(20), notification_email_recipient VARCHAR(200), notification_sns_topic_arn VARCHAR(300), notification_rate_limit_sms_per_hour INTEGER NOT NULL DEFAULT 10, notification_rate_limit_email_per_hour INTEGER NOT NULL DEFAULT 20, notification_daily_summary_time TIME NOT NULL DEFAULT '16:30', created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); -- ============================================================ -- Reserve Pool Ledger -- ============================================================ CREATE TABLE reserve_pool_ledger ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), amount FLOAT NOT NULL, balance_after FLOAT NOT NULL, trigger_type VARCHAR(30) NOT NULL, reference_id UUID, notes TEXT, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), CONSTRAINT chk_trigger_type CHECK ( trigger_type IN ('profit_siphon', 'emergency_liquidation', 'manual_adjustment', 'initial') ) ); CREATE INDEX idx_reserve_pool_ledger_created ON reserve_pool_ledger(created_at DESC); -- ============================================================ -- Risk Tier History -- ============================================================ CREATE TABLE risk_tier_history ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), previous_tier VARCHAR(20) NOT NULL, new_tier VARCHAR(20) NOT NULL, trigger_source VARCHAR(30) NOT NULL, trigger_metrics JSONB NOT NULL DEFAULT '{}', created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE INDEX idx_risk_tier_history_created ON risk_tier_history(created_at DESC); -- ============================================================ -- Circuit Breaker Events -- ============================================================ CREATE TABLE circuit_breaker_events ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), trigger_type VARCHAR(30) NOT NULL, threshold_value FLOAT, actual_value FLOAT, ticker VARCHAR(20), cooldown_expires TIMESTAMPTZ, resolved_at TIMESTAMPTZ, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), CONSTRAINT chk_cb_trigger_type CHECK ( trigger_type IN ('daily_loss', 'single_position', 'volatility', 'manual') ) ); CREATE INDEX idx_circuit_breaker_events_active ON circuit_breaker_events(created_at DESC) WHERE resolved_at IS NULL; -- ============================================================ -- Trading Decisions -- ============================================================ CREATE TABLE trading_decisions ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), recommendation_id UUID REFERENCES recommendations(id), decision VARCHAR(10) NOT NULL, skip_reason TEXT, ticker VARCHAR(20) NOT NULL, computed_position_size FLOAT, computed_share_quantity INTEGER, risk_tier_at_decision VARCHAR(20) NOT NULL, portfolio_heat_at_decision FLOAT, active_pool_at_decision FLOAT, reserve_pool_at_decision FLOAT, circuit_breaker_status VARCHAR(20) NOT NULL DEFAULT 'inactive', correlation_check_result JSONB DEFAULT '{}', sector_exposure_check_result JSONB DEFAULT '{}', earnings_proximity_flag BOOLEAN NOT NULL DEFAULT FALSE, is_micro_trade BOOLEAN NOT NULL DEFAULT FALSE, decision_trace JSONB NOT NULL DEFAULT '{}', created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE INDEX idx_trading_decisions_ticker ON trading_decisions(ticker, created_at DESC); CREATE INDEX idx_trading_decisions_rec ON trading_decisions(recommendation_id); CREATE INDEX idx_trading_decisions_decision ON trading_decisions(decision, created_at DESC); -- ============================================================ -- Position Stop Levels -- ============================================================ CREATE TABLE position_stop_levels ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), ticker VARCHAR(20) NOT NULL, entry_price FLOAT NOT NULL, stop_loss_price FLOAT NOT NULL, take_profit_price FLOAT NOT NULL, trailing_stop_active BOOLEAN NOT NULL DEFAULT FALSE, atr_value FLOAT NOT NULL, atr_multiplier FLOAT NOT NULL, reward_risk_ratio FLOAT NOT NULL, signal_confidence FLOAT, is_micro_trade BOOLEAN NOT NULL DEFAULT FALSE, active BOOLEAN NOT NULL DEFAULT TRUE, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE INDEX idx_position_stop_levels_ticker ON position_stop_levels(ticker) WHERE active = TRUE; -- ============================================================ -- Portfolio Snapshots -- ============================================================ CREATE TABLE portfolio_snapshots ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), snapshot_date DATE NOT NULL UNIQUE, portfolio_value FLOAT NOT NULL, active_pool FLOAT NOT NULL, reserve_pool FLOAT NOT NULL, daily_return FLOAT, cumulative_return FLOAT, unrealized_pnl FLOAT, realized_pnl FLOAT, win_count INTEGER NOT NULL DEFAULT 0, loss_count INTEGER NOT NULL DEFAULT 0, win_rate FLOAT, sharpe_ratio FLOAT, max_drawdown FLOAT, current_drawdown_pct FLOAT, portfolio_heat FLOAT, risk_tier VARCHAR(20), positions JSONB NOT NULL DEFAULT '[]', metrics JSONB NOT NULL DEFAULT '{}', created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE INDEX idx_portfolio_snapshots_date ON portfolio_snapshots(snapshot_date DESC); -- ============================================================ -- Backtest Runs -- ============================================================ CREATE TABLE backtest_runs ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), start_date DATE NOT NULL, end_date DATE NOT NULL, initial_capital FLOAT NOT NULL, risk_tier VARCHAR(20) NOT NULL, config JSONB NOT NULL DEFAULT '{}', total_return FLOAT, sharpe_ratio FLOAT, max_drawdown FLOAT, win_rate FLOAT, profit_factor FLOAT, trade_count INTEGER, equity_curve JSONB DEFAULT '[]', status VARCHAR(20) NOT NULL DEFAULT 'running', completed_at TIMESTAMPTZ, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); -- ============================================================ -- Backtest Trades -- ============================================================ CREATE TABLE backtest_trades ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), backtest_id UUID NOT NULL REFERENCES backtest_runs(id) ON DELETE CASCADE, ticker VARCHAR(20) NOT NULL, side VARCHAR(10) NOT NULL, entry_price FLOAT NOT NULL, exit_price FLOAT, quantity INTEGER NOT NULL, pnl FLOAT, pnl_pct FLOAT, entry_date DATE NOT NULL, exit_date DATE, hold_duration_days INTEGER, recommendation_id UUID, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE INDEX idx_backtest_trades_run ON backtest_trades(backtest_id); -- ============================================================ -- Tax Lots -- ============================================================ CREATE TABLE tax_lots ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), ticker VARCHAR(20) NOT NULL, quantity INTEGER NOT NULL, cost_basis_per_share FLOAT NOT NULL, acquisition_date DATE NOT NULL, status VARCHAR(10) NOT NULL DEFAULT 'open', closed_date DATE, exit_price FLOAT, realized_pnl FLOAT, wash_sale_flag BOOLEAN NOT NULL DEFAULT FALSE, wash_sale_details TEXT, order_id UUID REFERENCES orders(id), created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), CONSTRAINT chk_tax_lot_status CHECK (status IN ('open', 'closed', 'washed')) ); CREATE INDEX idx_tax_lots_ticker ON tax_lots(ticker, acquisition_date DESC); CREATE INDEX idx_tax_lots_status ON tax_lots(status) WHERE status = 'open'; -- ============================================================ -- Earnings Calendar -- ============================================================ CREATE TABLE earnings_calendar ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), ticker VARCHAR(20) NOT NULL, earnings_date DATE NOT NULL, source VARCHAR(30) NOT NULL DEFAULT 'manual', confirmed BOOLEAN NOT NULL DEFAULT FALSE, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), UNIQUE(ticker, earnings_date) ); CREATE INDEX idx_earnings_calendar_date ON earnings_calendar(earnings_date); CREATE INDEX idx_earnings_calendar_ticker ON earnings_calendar(ticker); -- ============================================================ -- Correlation Matrix Cache -- ============================================================ CREATE TABLE correlation_matrix_cache ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), ticker_a VARCHAR(20) NOT NULL, ticker_b VARCHAR(20) NOT NULL, correlation_coefficient FLOAT NOT NULL, lookback_days INTEGER NOT NULL DEFAULT 90, computed_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), UNIQUE(ticker_a, ticker_b) ); CREATE INDEX idx_correlation_cache_tickers ON correlation_matrix_cache(ticker_a, ticker_b); -- ============================================================ -- Notifications -- ============================================================ CREATE TABLE notifications ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), channel VARCHAR(10) NOT NULL, event_type VARCHAR(50) NOT NULL, message TEXT NOT NULL, delivery_status VARCHAR(20) NOT NULL DEFAULT 'pending', retry_count INTEGER NOT NULL DEFAULT 0, error_message TEXT, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), delivered_at TIMESTAMPTZ, CONSTRAINT chk_channel CHECK (channel IN ('sms', 'email')), CONSTRAINT chk_delivery_status CHECK ( delivery_status IN ('pending', 'delivered', 'failed', 'rate_limited') ) ); CREATE INDEX idx_notifications_created ON notifications(created_at DESC); CREATE INDEX idx_notifications_event ON notifications(event_type, created_at DESC); -- ============================================================ -- Default Data -- ============================================================ -- Insert default trading engine configuration (moderate tier defaults) INSERT INTO trading_engine_config ( enabled, paused, risk_tier, reserve_siphon_pct, polling_interval_seconds, gradual_entry_tranches, gradual_entry_threshold_dollars, gradual_entry_interval_minutes, trading_window_start_minutes, trading_window_end_minutes, max_open_positions, circuit_breaker_daily_loss_pct, circuit_breaker_single_position_loss_pct, circuit_breaker_ticker_cooldown_hours, circuit_breaker_volatility_pause_hours, circuit_breaker_stop_loss_hits_threshold, circuit_breaker_stop_loss_window_minutes, active_pool_minimum, emergency_drawdown_threshold_pct, reserve_high_water_pct, absolute_position_cap, correlation_reduction_threshold, correlation_rejection_threshold, earnings_pre_window_days, earnings_post_cooldown_days, micro_trading_enabled, micro_trading_interval_seconds, micro_trading_allocation_cap_pct, micro_trading_max_daily, micro_trading_max_hold_minutes, notification_sms_enabled, notification_email_enabled, notification_rate_limit_sms_per_hour, notification_rate_limit_email_per_hour, notification_daily_summary_time ) VALUES ( FALSE, FALSE, 'moderate', 0.20, 60, 3, 30.0, 15, 15, 15, 10, 0.05, 0.15, 48, 2, 3, 30, 100.0, 0.40, 0.30, 50.0, 0.5, 0.8, 3, 1, FALSE, 300, 0.03, 10, 120, FALSE, FALSE, 10, 20, '16:30' ); -- Insert initial reserve pool ledger entry with zero balance INSERT INTO reserve_pool_ledger (amount, balance_after, trigger_type, notes) VALUES (0.0, 0.0, 'initial', 'Initial reserve pool entry');