Files
foxhunt/crates/database/schemas/003_asset_classification.sql
jgrusewski 9c3d741a08 refactor: restructure repo — crates/, bin/, testing/ layout
Move 17 library crates into crates/, CLI binary into bin/fxt,
consolidate 10 test crates into testing/, split config crate
from deployment config files.

Root directory reduced from 38+ to ~17 directories.
All Cargo.toml paths and build.rs proto refs updated.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 11:56:00 +01:00

295 lines
14 KiB
PL/PgSQL

-- Asset Classification Schema
-- Comprehensive database schema for dynamic asset classification and trading parameters
-- Asset Classes Table - Define hierarchical asset classifications
CREATE TABLE asset_classes (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name VARCHAR(255) NOT NULL UNIQUE,
parent_id UUID REFERENCES asset_classes(id),
classification_data JSONB NOT NULL,
description TEXT,
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- Create index for hierarchical queries
CREATE INDEX idx_asset_classes_parent_id ON asset_classes(parent_id);
CREATE INDEX idx_asset_classes_active ON asset_classes(is_active);
CREATE INDEX idx_asset_classes_classification ON asset_classes USING GIN(classification_data);
-- Asset Configurations Table - Pattern-based symbol classification rules
CREATE TABLE asset_configurations (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name VARCHAR(255) NOT NULL,
symbol_pattern VARCHAR(1000) NOT NULL,
asset_class_data JSONB NOT NULL,
volatility_profile JSONB NOT NULL,
trading_parameters JSONB NOT NULL,
priority INTEGER NOT NULL DEFAULT 100,
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
trading_hours JSONB,
settlement_config JSONB NOT NULL DEFAULT '{"settlement_days": 2, "settlement_currency": "USD", "physical_settlement": false}'::jsonb
);
-- Create indexes for performance
CREATE INDEX idx_asset_configurations_priority ON asset_configurations(priority DESC, is_active);
CREATE INDEX idx_asset_configurations_active ON asset_configurations(is_active);
CREATE INDEX idx_asset_configurations_pattern ON asset_configurations(symbol_pattern);
CREATE INDEX idx_asset_configurations_asset_class ON asset_configurations USING GIN(asset_class_data);
-- Symbol Mappings Table - Explicit symbol to asset class mappings
CREATE TABLE symbol_mappings (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
symbol VARCHAR(50) NOT NULL UNIQUE,
asset_class_data JSONB NOT NULL,
volatility_override JSONB,
trading_parameters_override JSONB,
source VARCHAR(100) DEFAULT 'manual',
confidence_score DECIMAL(3,2) DEFAULT 1.00,
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
expires_at TIMESTAMP WITH TIME ZONE
);
-- Indexes for symbol lookups
CREATE INDEX idx_symbol_mappings_symbol ON symbol_mappings(upper(symbol));
CREATE INDEX idx_symbol_mappings_active ON symbol_mappings(is_active);
CREATE INDEX idx_symbol_mappings_expires ON symbol_mappings(expires_at) WHERE expires_at IS NOT NULL;
-- Volatility Profiles Table - Reusable volatility profile templates
CREATE TABLE volatility_profiles (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name VARCHAR(255) NOT NULL UNIQUE,
base_annual_volatility DECIMAL(6,4) NOT NULL,
stress_volatility_multiplier DECIMAL(4,2) NOT NULL DEFAULT 2.0,
intraday_pattern JSONB NOT NULL DEFAULT '[]'::jsonb,
volatility_persistence DECIMAL(4,3) NOT NULL DEFAULT 0.85,
jump_risk JSONB NOT NULL DEFAULT '{"jump_probability": 0.01, "jump_magnitude": 0.05, "max_jump_size": 0.15}'::jsonb,
description TEXT,
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- Trading Parameters Templates Table - Reusable trading parameter sets
CREATE TABLE trading_parameters_templates (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name VARCHAR(255) NOT NULL UNIQUE,
position_limits JSONB NOT NULL,
risk_thresholds JSONB NOT NULL,
execution_config JSONB NOT NULL,
market_making_config JSONB,
description TEXT,
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- Asset Classification Cache Table - For performance optimization
CREATE TABLE asset_classification_cache (
symbol VARCHAR(50) PRIMARY KEY,
asset_class_data JSONB NOT NULL,
configuration_id UUID REFERENCES asset_configurations(id),
cached_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
expires_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() + INTERVAL '1 hour'
);
-- Index for cache expiration cleanup
CREATE INDEX idx_asset_classification_cache_expires ON asset_classification_cache(expires_at);
-- Asset Classification Audit Log
CREATE TABLE asset_classification_audit (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
symbol VARCHAR(50) NOT NULL,
old_classification JSONB,
new_classification JSONB NOT NULL,
changed_by VARCHAR(255),
change_reason TEXT,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- Index for audit queries
CREATE INDEX idx_asset_classification_audit_symbol ON asset_classification_audit(symbol);
CREATE INDEX idx_asset_classification_audit_created ON asset_classification_audit(created_at);
-- Configuration Change Notifications Table
CREATE TABLE config_change_notifications (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
notification_type VARCHAR(50) NOT NULL,
table_name VARCHAR(100) NOT NULL,
record_id UUID NOT NULL,
change_data JSONB NOT NULL,
processed BOOLEAN DEFAULT false,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- Index for notification processing
CREATE INDEX idx_config_change_notifications_processed ON config_change_notifications(processed, created_at);
-- Create triggers for automatic timestamp updates
CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ language 'plpgsql';
-- Apply update triggers to all configuration tables
CREATE TRIGGER update_asset_classes_updated_at BEFORE UPDATE ON asset_classes FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_asset_configurations_updated_at BEFORE UPDATE ON asset_configurations FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_symbol_mappings_updated_at BEFORE UPDATE ON symbol_mappings FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_volatility_profiles_updated_at BEFORE UPDATE ON volatility_profiles FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_trading_parameters_templates_updated_at BEFORE UPDATE ON trading_parameters_templates FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
-- Notification trigger function for configuration changes
CREATE OR REPLACE FUNCTION notify_config_change()
RETURNS TRIGGER AS $$
BEGIN
INSERT INTO config_change_notifications (notification_type, table_name, record_id, change_data)
VALUES (
TG_OP,
TG_TABLE_NAME,
COALESCE(NEW.id, OLD.id),
CASE
WHEN TG_OP = 'DELETE' THEN row_to_json(OLD)
ELSE row_to_json(NEW)
END
);
-- Send PostgreSQL NOTIFY for real-time updates
PERFORM pg_notify('config_change', json_build_object(
'table', TG_TABLE_NAME,
'operation', TG_OP,
'id', COALESCE(NEW.id, OLD.id)
)::text);
RETURN COALESCE(NEW, OLD);
END;
$$ language 'plpgsql';
-- Apply notification triggers
CREATE TRIGGER notify_asset_configurations_change AFTER INSERT OR UPDATE OR DELETE ON asset_configurations FOR EACH ROW EXECUTE FUNCTION notify_config_change();
CREATE TRIGGER notify_symbol_mappings_change AFTER INSERT OR UPDATE OR DELETE ON symbol_mappings FOR EACH ROW EXECUTE FUNCTION notify_config_change();
CREATE TRIGGER notify_volatility_profiles_change AFTER INSERT OR UPDATE OR DELETE ON volatility_profiles FOR EACH ROW EXECUTE FUNCTION notify_config_change();
CREATE TRIGGER notify_trading_parameters_templates_change AFTER INSERT OR UPDATE OR DELETE ON trading_parameters_templates FOR EACH ROW EXECUTE FUNCTION notify_config_change();
-- Cache maintenance function
CREATE OR REPLACE FUNCTION cleanup_asset_classification_cache()
RETURNS void AS $$
BEGIN
DELETE FROM asset_classification_cache WHERE expires_at < NOW();
END;
$$ language 'plpgsql';
-- Views for easier querying
-- Active Asset Configurations View
CREATE VIEW active_asset_configurations AS
SELECT
id,
name,
symbol_pattern,
asset_class_data,
volatility_profile,
trading_parameters,
priority,
trading_hours,
settlement_config,
created_at,
updated_at
FROM asset_configurations
WHERE is_active = true
ORDER BY priority DESC;
-- Symbol Classification Summary View
CREATE VIEW symbol_classification_summary AS
SELECT
sm.symbol,
sm.asset_class_data,
sm.confidence_score,
sm.source,
ac.name as configuration_name,
ac.priority,
sm.created_at
FROM symbol_mappings sm
LEFT JOIN asset_configurations ac ON sm.source = 'pattern:' || ac.id::text
WHERE sm.is_active = true;
-- Asset Class Statistics View
CREATE VIEW asset_class_statistics AS
SELECT
asset_class_data->>'asset_class' as asset_class,
COUNT(*) as symbol_count,
AVG((volatility_profile->>'base_annual_volatility')::decimal) as avg_volatility,
MIN(created_at) as first_configured,
MAX(updated_at) as last_updated
FROM symbol_mappings
WHERE is_active = true
GROUP BY asset_class_data->>'asset_class';
-- Insert default volatility profiles
INSERT INTO volatility_profiles (name, base_annual_volatility, stress_volatility_multiplier, volatility_persistence, jump_risk, description) VALUES
('BlueChip', 0.2500, 2.0, 0.85, '{"jump_probability": 0.01, "jump_magnitude": 0.03, "max_jump_size": 0.10}', 'Large cap, stable companies'),
('Growth', 0.3500, 2.5, 0.88, '{"jump_probability": 0.02, "jump_magnitude": 0.05, "max_jump_size": 0.15}', 'High growth stocks'),
('CryptoMajor', 0.8000, 3.0, 0.92, '{"jump_probability": 0.05, "jump_magnitude": 0.10, "max_jump_size": 0.30}', 'Major cryptocurrencies like BTC, ETH'),
('CryptoAlt', 1.2000, 4.0, 0.90, '{"jump_probability": 0.08, "jump_magnitude": 0.15, "max_jump_size": 0.50}', 'Alternative cryptocurrencies'),
('ForexMajor', 0.1200, 2.0, 0.80, '{"jump_probability": 0.005, "jump_magnitude": 0.02, "max_jump_size": 0.08}', 'Major currency pairs'),
('ForexJPY', 0.1000, 2.2, 0.82, '{"jump_probability": 0.008, "jump_magnitude": 0.025, "max_jump_size": 0.06}', 'JPY currency pairs'),
('Commodity', 0.3000, 2.8, 0.86, '{"jump_probability": 0.03, "jump_magnitude": 0.08, "max_jump_size": 0.20}', 'Commodity futures and ETFs');
-- Insert default trading parameter templates
INSERT INTO trading_parameters_templates (name, position_limits, risk_thresholds, execution_config, description) VALUES
('Conservative',
'{"max_position_fraction": 0.10, "max_leverage": 1.5, "concentration_limit": 0.20, "min_position_size": 100}',
'{"var_limit": 0.02, "daily_loss_limit": 0.015, "stop_loss_threshold": 0.05, "volatility_circuit_breaker": 0.03, "max_drawdown_threshold": 0.08}',
'{"preferred_order_types": ["Limit", "Market"], "tick_size": "0.01", "min_order_size": "1", "max_order_size": "5000", "time_in_force_default": "Day", "slippage_tolerance": 0.001}',
'Conservative trading parameters for low-risk strategies'),
('Aggressive',
'{"max_position_fraction": 0.25, "max_leverage": 3.0, "concentration_limit": 0.40, "min_position_size": 500}',
'{"var_limit": 0.08, "daily_loss_limit": 0.05, "stop_loss_threshold": 0.12, "volatility_circuit_breaker": 0.08, "max_drawdown_threshold": 0.20}',
'{"preferred_order_types": ["Market", "Limit"], "tick_size": "0.01", "min_order_size": "1", "max_order_size": "20000", "time_in_force_default": "GTC", "slippage_tolerance": 0.003}',
'Aggressive trading parameters for high-return strategies'),
('HighFrequency',
'{"max_position_fraction": 0.05, "max_leverage": 10.0, "concentration_limit": 0.15, "min_position_size": 1000}',
'{"var_limit": 0.01, "daily_loss_limit": 0.008, "stop_loss_threshold": 0.02, "volatility_circuit_breaker": 0.01, "max_drawdown_threshold": 0.05}',
'{"preferred_order_types": ["Limit", "Hidden"], "tick_size": "0.001", "min_order_size": "100", "max_order_size": "100000", "time_in_force_default": "IOC", "slippage_tolerance": 0.0001}',
'High-frequency trading parameters with tight risk controls');
-- Insert some default asset configurations
INSERT INTO asset_configurations (name, symbol_pattern, asset_class_data, volatility_profile, trading_parameters, priority) VALUES
('Blue Chip US Equities',
'^(AAPL|MSFT|GOOGL|AMZN|META|TSLA|NVDA|JPM|JNJ|V|PG|UNH|HD|BAC|DIS)$',
'{"asset_class": "Equity", "sector": "Technology", "market_cap": "LargeCap", "region": "NorthAmerica"}',
(SELECT row_to_json(vp) FROM volatility_profiles vp WHERE name = 'BlueChip'),
(SELECT row_to_json(tpt) FROM trading_parameters_templates tpt WHERE name = 'Conservative'),
100),
('Major Cryptocurrencies',
'^(BTC|ETH|BTCUSD|ETHUSD|BTCUSDT|ETHUSDT).*$',
'{"asset_class": "Crypto", "network": "Bitcoin", "crypto_type": "Bitcoin", "market_cap_rank": 1}',
(SELECT row_to_json(vp) FROM volatility_profiles vp WHERE name = 'CryptoMajor'),
(SELECT row_to_json(tpt) FROM trading_parameters_templates tpt WHERE name = 'Aggressive'),
90),
('Major Forex Pairs',
'^(EUR|GBP|USD|JPY|AUD|CAD|CHF)(USD|EUR|GBP|JPY)$',
'{"asset_class": "Forex", "base": "EUR", "quote": "USD", "pair_type": "Major"}',
(SELECT row_to_json(vp) FROM volatility_profiles vp WHERE name = 'ForexMajor'),
(SELECT row_to_json(tpt) FROM trading_parameters_templates tpt WHERE name = 'HighFrequency'),
80);
-- Comments for documentation
COMMENT ON TABLE asset_configurations IS 'Pattern-based asset classification configurations with trading parameters';
COMMENT ON TABLE symbol_mappings IS 'Explicit symbol to asset class mappings for fast lookup';
COMMENT ON TABLE volatility_profiles IS 'Reusable volatility profile templates for different asset types';
COMMENT ON TABLE trading_parameters_templates IS 'Reusable trading parameter configurations';
COMMENT ON TABLE asset_classification_cache IS 'Performance cache for symbol classifications';
COMMENT ON TABLE asset_classification_audit IS 'Audit trail for asset classification changes';
COMMENT ON COLUMN asset_configurations.symbol_pattern IS 'Regular expression pattern for matching symbols';
COMMENT ON COLUMN asset_configurations.priority IS 'Pattern matching priority (higher numbers checked first)';
COMMENT ON COLUMN symbol_mappings.confidence_score IS 'Confidence score for classification (0.0-1.0)';
COMMENT ON COLUMN symbol_mappings.expires_at IS 'Optional expiration for temporary classifications';