-- 015_adaptive_strategy_config.sql -- Adaptive Strategy Configuration with Hot-Reload Support -- Implements database-backed configuration for adaptive-strategy crate -- Replaces 50+ hardcoded Default implementations with PostgreSQL-based config -- Enable required extensions CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; -- ============================================================================ -- ENUMERATIONS -- ============================================================================ -- Position sizing methods CREATE TYPE position_sizing_method AS ENUM ( 'KELLY', 'FIXED_FRACTIONAL', 'FIXED_FRACTION', 'PPO', 'EQUAL_WEIGHT', 'RISK_PARITY', 'VOLATILITY_TARGET', 'CUSTOM' ); -- Regime detection methods CREATE TYPE regime_detection_method AS ENUM ( 'HMM', 'MARKOV_SWITCHING', 'THRESHOLD', 'ML_CLASSIFICATION', 'GMM', 'ML_CLASSIFIER' ); -- Execution algorithms CREATE TYPE execution_algorithm AS ENUM ( 'TWAP', 'VWAP', 'IS', 'IMPLEMENTATION_SHORTFALL', 'ARRIVAL_PRICE', 'POV' ); -- ============================================================================ -- MAIN CONFIGURATION TABLE -- ============================================================================ -- Adaptive strategy configuration table -- Stores all parameters previously hardcoded in adaptive-strategy/src/config.rs CREATE TABLE adaptive_strategy_config ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), strategy_id VARCHAR(100) UNIQUE NOT NULL, name VARCHAR(255) NOT NULL, description TEXT, -- ======================================================================== -- GENERAL CONFIGURATION (GeneralConfig) -- ======================================================================== execution_interval_ms INTEGER NOT NULL DEFAULT 100, error_backoff_duration_secs INTEGER NOT NULL DEFAULT 1, max_concurrent_operations INTEGER NOT NULL DEFAULT 10, strategy_timeout_secs INTEGER NOT NULL DEFAULT 30, -- ======================================================================== -- ENSEMBLE CONFIGURATION (EnsembleConfig) -- ======================================================================== max_parallel_models INTEGER NOT NULL DEFAULT 4, rebalancing_interval_secs INTEGER NOT NULL DEFAULT 300, min_model_weight DOUBLE PRECISION NOT NULL DEFAULT 0.01, max_model_weight DOUBLE PRECISION NOT NULL DEFAULT 0.5, -- ======================================================================== -- RISK CONFIGURATION (RiskConfig) -- ======================================================================== max_position_size DOUBLE PRECISION NOT NULL DEFAULT 0.1, max_leverage DOUBLE PRECISION NOT NULL DEFAULT 2.0, stop_loss_pct DOUBLE PRECISION NOT NULL DEFAULT 0.02, position_sizing_method position_sizing_method NOT NULL DEFAULT 'KELLY', max_portfolio_var DOUBLE PRECISION NOT NULL DEFAULT 0.02, max_drawdown_threshold DOUBLE PRECISION NOT NULL DEFAULT 0.05, kelly_fraction DOUBLE PRECISION NOT NULL DEFAULT 0.1, -- ======================================================================== -- MICROSTRUCTURE CONFIGURATION (MicrostructureConfig) -- ======================================================================== book_depth INTEGER NOT NULL DEFAULT 10, vpin_window INTEGER NOT NULL DEFAULT 50, trade_classification_threshold DOUBLE PRECISION NOT NULL DEFAULT 0.5, trade_size_buckets DOUBLE PRECISION[] NOT NULL DEFAULT ARRAY[10.0, 100.0, 1000.0, 10000.0], microstructure_features TEXT[] NOT NULL DEFAULT ARRAY['vpin', 'order_flow', 'bid_ask_spread'], -- ======================================================================== -- REGIME CONFIGURATION (RegimeConfig) -- ======================================================================== regime_detection_method regime_detection_method NOT NULL DEFAULT 'HMM', regime_lookback_window INTEGER NOT NULL DEFAULT 252, regime_transition_threshold DOUBLE PRECISION NOT NULL DEFAULT 0.7, regime_features TEXT[] NOT NULL DEFAULT ARRAY['volatility', 'momentum', 'volume'], -- ======================================================================== -- EXECUTION CONFIGURATION (ExecutionConfig) -- ======================================================================== execution_algorithm execution_algorithm NOT NULL DEFAULT 'TWAP', max_order_size DOUBLE PRECISION NOT NULL DEFAULT 10000.0, min_order_size DOUBLE PRECISION NOT NULL DEFAULT 100.0, order_timeout_secs INTEGER NOT NULL DEFAULT 30, max_slippage_bps DOUBLE PRECISION NOT NULL DEFAULT 10.0, smart_routing_enabled BOOLEAN NOT NULL DEFAULT true, dark_pool_preference DOUBLE PRECISION NOT NULL DEFAULT 0.3, -- ======================================================================== -- AUDIT TRAIL -- ======================================================================== active BOOLEAN NOT NULL DEFAULT true, version INTEGER NOT NULL DEFAULT 1, created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), created_by UUID, updated_by UUID, metadata JSONB DEFAULT '{}', -- Constraints CONSTRAINT valid_position_size CHECK (max_position_size > 0 AND max_position_size <= 1.0), CONSTRAINT valid_leverage CHECK (max_leverage > 0), CONSTRAINT valid_stop_loss CHECK (stop_loss_pct > 0 AND stop_loss_pct <= 1.0), CONSTRAINT valid_var CHECK (max_portfolio_var > 0), CONSTRAINT valid_drawdown CHECK (max_drawdown_threshold > 0 AND max_drawdown_threshold <= 1.0), CONSTRAINT valid_kelly CHECK (kelly_fraction > 0 AND kelly_fraction <= 1.0), CONSTRAINT valid_model_weights CHECK (min_model_weight >= 0 AND max_model_weight <= 1.0 AND min_model_weight <= max_model_weight), CONSTRAINT valid_dark_pool CHECK (dark_pool_preference >= 0 AND dark_pool_preference <= 1.0) ); -- ============================================================================ -- MODEL CONFIGURATIONS -- ============================================================================ -- Individual model configurations within an ensemble CREATE TABLE adaptive_strategy_models ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), strategy_config_id UUID NOT NULL REFERENCES adaptive_strategy_config(id) ON DELETE CASCADE, model_id VARCHAR(100) NOT NULL, model_name VARCHAR(255) NOT NULL, model_type VARCHAR(50) NOT NULL, -- 'mamba2', 'tlob', 'dqn', 'ppo', 'lstm', etc. -- Model parameters as flexible JSONB -- Examples: -- MAMBA-2: {"hidden_dim": 256, "state_size": 16, "num_layers": 4} -- TLOB: {"num_heads": 8, "num_layers": 6, "dropout": 0.1} -- DQN: {"learning_rate": 0.001, "gamma": 0.99, "epsilon": 0.1} parameters JSONB NOT NULL DEFAULT '{}', initial_weight DOUBLE PRECISION NOT NULL DEFAULT 0.25, enabled BOOLEAN NOT NULL DEFAULT true, -- Ordering within ensemble display_order INTEGER NOT NULL DEFAULT 0, created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), CONSTRAINT unique_model_per_strategy UNIQUE(strategy_config_id, model_id), CONSTRAINT valid_initial_weight CHECK (initial_weight >= 0 AND initial_weight <= 1.0) ); -- ============================================================================ -- FEATURE CONFIGURATIONS -- ============================================================================ -- Feature extraction configurations for models CREATE TABLE adaptive_strategy_features ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), strategy_config_id UUID NOT NULL REFERENCES adaptive_strategy_config(id) ON DELETE CASCADE, feature_name VARCHAR(100) NOT NULL, feature_type VARCHAR(50) NOT NULL, -- 'price', 'volume', 'orderbook', 'technical', 'regime' -- Feature-specific parameters as JSONB -- Examples: -- Moving average: {"window": 20, "type": "exponential"} -- Order book imbalance: {"levels": 5, "normalization": "minmax"} -- Volatility: {"window": 50, "method": "parkinson"} parameters JSONB NOT NULL DEFAULT '{}', enabled BOOLEAN NOT NULL DEFAULT true, required BOOLEAN NOT NULL DEFAULT false, -- If true, strategy fails without this feature created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), CONSTRAINT unique_feature_per_strategy UNIQUE(strategy_config_id, feature_name) ); -- ============================================================================ -- VERSION HISTORY -- ============================================================================ -- Configuration version history for audit trail CREATE TABLE adaptive_strategy_config_versions ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), strategy_id VARCHAR(100) NOT NULL, version INTEGER NOT NULL, -- Snapshot of configuration at this version (stored as JSONB) config_snapshot JSONB NOT NULL, -- Version metadata change_reason TEXT, changed_by UUID, changed_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), -- Link to current configuration current_config_id UUID REFERENCES adaptive_strategy_config(id) ON DELETE CASCADE, UNIQUE(strategy_id, version) ); -- ============================================================================ -- INDEXES -- ============================================================================ -- Main configuration table indexes CREATE INDEX idx_adaptive_strategy_config_active ON adaptive_strategy_config(active, strategy_id); CREATE INDEX idx_adaptive_strategy_config_updated ON adaptive_strategy_config(updated_at DESC); -- Model configuration indexes CREATE INDEX idx_adaptive_strategy_models_strategy ON adaptive_strategy_models(strategy_config_id); CREATE INDEX idx_adaptive_strategy_models_type ON adaptive_strategy_models(model_type, enabled); CREATE INDEX idx_adaptive_strategy_models_order ON adaptive_strategy_models(strategy_config_id, display_order); -- Feature configuration indexes CREATE INDEX idx_adaptive_strategy_features_strategy ON adaptive_strategy_features(strategy_config_id); CREATE INDEX idx_adaptive_strategy_features_type ON adaptive_strategy_features(feature_type, enabled); -- Version history indexes CREATE INDEX idx_adaptive_strategy_versions_strategy ON adaptive_strategy_config_versions(strategy_id, version DESC); CREATE INDEX idx_adaptive_strategy_versions_changed ON adaptive_strategy_config_versions(changed_at DESC); -- ============================================================================ -- TRIGGERS -- ============================================================================ -- Function to update updated_at timestamp CREATE OR REPLACE FUNCTION update_adaptive_strategy_updated_at() RETURNS TRIGGER AS $$ BEGIN NEW.updated_at = NOW(); RETURN NEW; END; $$ LANGUAGE plpgsql; -- Trigger for main config table CREATE TRIGGER adaptive_strategy_config_updated BEFORE UPDATE ON adaptive_strategy_config FOR EACH ROW EXECUTE FUNCTION update_adaptive_strategy_updated_at(); -- Trigger for model config table CREATE TRIGGER adaptive_strategy_models_updated BEFORE UPDATE ON adaptive_strategy_models FOR EACH ROW EXECUTE FUNCTION update_adaptive_strategy_updated_at(); -- Trigger for feature config table CREATE TRIGGER adaptive_strategy_features_updated BEFORE UPDATE ON adaptive_strategy_features FOR EACH ROW EXECUTE FUNCTION update_adaptive_strategy_updated_at(); -- ============================================================================ -- HOT-RELOAD SUPPORT (PostgreSQL NOTIFY/LISTEN) -- ============================================================================ -- Function to notify configuration changes CREATE OR REPLACE FUNCTION notify_adaptive_strategy_config_change() RETURNS TRIGGER AS $$ DECLARE payload JSON; BEGIN payload = json_build_object( 'table', TG_TABLE_NAME, 'action', TG_OP, 'strategy_id', COALESCE(NEW.strategy_id, OLD.strategy_id), 'timestamp', EXTRACT(EPOCH FROM NOW()) ); PERFORM pg_notify('adaptive_strategy_config_change', payload::text); RETURN NEW; END; $$ LANGUAGE plpgsql; -- Triggers for hot-reload notifications CREATE TRIGGER adaptive_strategy_config_notify AFTER INSERT OR UPDATE OR DELETE ON adaptive_strategy_config FOR EACH ROW EXECUTE FUNCTION notify_adaptive_strategy_config_change(); CREATE TRIGGER adaptive_strategy_models_notify AFTER INSERT OR UPDATE OR DELETE ON adaptive_strategy_models FOR EACH ROW EXECUTE FUNCTION notify_adaptive_strategy_config_change(); CREATE TRIGGER adaptive_strategy_features_notify AFTER INSERT OR UPDATE OR DELETE ON adaptive_strategy_features FOR EACH ROW EXECUTE FUNCTION notify_adaptive_strategy_config_change(); -- ============================================================================ -- VERSION ARCHIVING -- ============================================================================ -- Function to archive configuration version on update CREATE OR REPLACE FUNCTION archive_adaptive_strategy_version() RETURNS TRIGGER AS $$ BEGIN IF TG_OP = 'UPDATE' THEN INSERT INTO adaptive_strategy_config_versions ( strategy_id, version, config_snapshot, change_reason, changed_by, current_config_id ) VALUES ( OLD.strategy_id, OLD.version, row_to_json(OLD), COALESCE(NEW.metadata->>'change_reason', 'Configuration updated'), NEW.updated_by, NEW.id ); -- Increment version number NEW.version = OLD.version + 1; END IF; RETURN NEW; END; $$ LANGUAGE plpgsql; -- Trigger for version archiving CREATE TRIGGER adaptive_strategy_config_version_archive BEFORE UPDATE ON adaptive_strategy_config FOR EACH ROW EXECUTE FUNCTION archive_adaptive_strategy_version(); -- ============================================================================ -- DEFAULT CONFIGURATION -- ============================================================================ -- Insert default adaptive strategy configuration INSERT INTO adaptive_strategy_config ( strategy_id, name, description ) VALUES ( 'default', 'Default Adaptive Strategy', 'Default configuration for adaptive trading strategy with ensemble ML models' ); -- Insert default models for the default strategy INSERT INTO adaptive_strategy_models ( strategy_config_id, model_id, model_name, model_type, parameters, initial_weight, enabled, display_order ) SELECT id, 'mamba2_model', 'MAMBA-2 SSM Model', 'mamba2', '{"hidden_dim": 256, "state_size": 16, "num_layers": 4}'::jsonb, 0.25, true, 1 FROM adaptive_strategy_config WHERE strategy_id = 'default' UNION ALL SELECT id, 'tlob_model', 'TLOB Transformer Model', 'tlob', '{"num_heads": 8, "num_layers": 6, "dropout": 0.1}'::jsonb, 0.25, true, 2 FROM adaptive_strategy_config WHERE strategy_id = 'default'; -- Insert default features for the default strategy INSERT INTO adaptive_strategy_features ( strategy_config_id, feature_name, feature_type, parameters, enabled, required ) SELECT id, 'vpin', 'orderbook', '{"window": 50}'::jsonb, true, true FROM adaptive_strategy_config WHERE strategy_id = 'default' UNION ALL SELECT id, 'order_flow', 'orderbook', '{"depth": 10}'::jsonb, true, true FROM adaptive_strategy_config WHERE strategy_id = 'default' UNION ALL SELECT id, 'bid_ask_spread', 'orderbook', '{}'::jsonb, true, false FROM adaptive_strategy_config WHERE strategy_id = 'default'; -- ============================================================================ -- COMMENTS -- ============================================================================ COMMENT ON TABLE adaptive_strategy_config IS 'Main configuration table for adaptive trading strategies, replaces hardcoded defaults'; COMMENT ON TABLE adaptive_strategy_models IS 'Model configurations within ensemble strategies'; COMMENT ON TABLE adaptive_strategy_features IS 'Feature extraction configurations for strategy models'; COMMENT ON TABLE adaptive_strategy_config_versions IS 'Version history for configuration changes and audit trail'; COMMENT ON COLUMN adaptive_strategy_config.execution_interval_ms IS 'Strategy execution interval in milliseconds (default: 100ms)'; COMMENT ON COLUMN adaptive_strategy_config.max_position_size IS 'Maximum position size as fraction of portfolio (0.0-1.0)'; COMMENT ON COLUMN adaptive_strategy_config.kelly_fraction IS 'Kelly Criterion fraction for position sizing (0.0-1.0)'; COMMENT ON COLUMN adaptive_strategy_models.parameters IS 'Model-specific parameters as flexible JSONB structure'; COMMENT ON COLUMN adaptive_strategy_features.parameters IS 'Feature-specific parameters as flexible JSONB structure';