Files
foxhunt/crates/database/schemas/001_initial.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

180 lines
6.5 KiB
PL/PgSQL

-- Foxhunt HFT Trading System - Initial Database Schema
-- Model Management Configuration Tables
-- Create extensions
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE EXTENSION IF NOT EXISTS "pg_notify";
-- Configuration table for system settings
CREATE TABLE IF NOT EXISTS config_entries (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
key VARCHAR(255) UNIQUE NOT NULL,
value TEXT NOT NULL,
description TEXT,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- Model configuration table for ML model management
CREATE TABLE IF NOT EXISTS model_config (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
name VARCHAR(255) NOT NULL,
version VARCHAR(50) NOT NULL,
s3_path TEXT NOT NULL,
cache_path TEXT,
metadata JSONB DEFAULT '{}',
is_active BOOLEAN DEFAULT false,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE(name, version)
);
-- Model versions table for version tracking
CREATE TABLE IF NOT EXISTS model_versions (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
model_config_id UUID NOT NULL REFERENCES model_config(id) ON DELETE CASCADE,
version VARCHAR(50) NOT NULL,
s3_path TEXT NOT NULL,
cache_path TEXT,
checksum VARCHAR(64),
size_bytes BIGINT,
performance_metrics JSONB DEFAULT '{}',
training_metadata JSONB DEFAULT '{}',
is_current BOOLEAN DEFAULT false,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE(model_config_id, version)
);
-- Trading positions
CREATE TABLE IF NOT EXISTS positions (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
symbol VARCHAR(50) NOT NULL,
quantity DECIMAL(18,8) NOT NULL,
entry_price DECIMAL(18,8) NOT NULL,
current_price DECIMAL(18,8),
pnl DECIMAL(18,8),
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- Order history
CREATE TABLE IF NOT EXISTS orders (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
symbol VARCHAR(50) NOT NULL,
order_type VARCHAR(20) NOT NULL,
side VARCHAR(10) NOT NULL,
quantity DECIMAL(18,8) NOT NULL,
price DECIMAL(18,8) NOT NULL,
status VARCHAR(20) NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- Indexes for fast lookups
-- Config entries indexes
CREATE INDEX IF NOT EXISTS idx_config_entries_key ON config_entries(key);
CREATE INDEX IF NOT EXISTS idx_config_entries_updated_at ON config_entries(updated_at);
-- Model config indexes
CREATE INDEX IF NOT EXISTS idx_model_config_name ON model_config(name);
CREATE INDEX IF NOT EXISTS idx_model_config_active ON model_config(is_active);
CREATE INDEX IF NOT EXISTS idx_model_config_name_version ON model_config(name, version);
CREATE INDEX IF NOT EXISTS idx_model_config_updated_at ON model_config(updated_at);
-- Model versions indexes
CREATE INDEX IF NOT EXISTS idx_model_versions_config_id ON model_versions(model_config_id);
CREATE INDEX IF NOT EXISTS idx_model_versions_current ON model_versions(is_current);
CREATE INDEX IF NOT EXISTS idx_model_versions_version ON model_versions(version);
CREATE INDEX IF NOT EXISTS idx_model_versions_created_at ON model_versions(created_at);
-- Trading indexes
CREATE INDEX IF NOT EXISTS idx_positions_symbol ON positions(symbol);
CREATE INDEX IF NOT EXISTS idx_positions_created_at ON positions(created_at);
CREATE INDEX IF NOT EXISTS idx_orders_symbol ON orders(symbol);
CREATE INDEX IF NOT EXISTS idx_orders_status ON orders(status);
CREATE INDEX IF NOT EXISTS idx_orders_created_at ON orders(created_at);
-- Update triggers for updated_at columns
CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ language 'plpgsql';
CREATE TRIGGER update_config_entries_updated_at
BEFORE UPDATE ON config_entries
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_model_config_updated_at
BEFORE UPDATE ON model_config
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_model_versions_updated_at
BEFORE UPDATE ON model_versions
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_positions_updated_at
BEFORE UPDATE ON positions
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_orders_updated_at
BEFORE UPDATE ON orders
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
-- Notification triggers for configuration hot-reload
CREATE OR REPLACE FUNCTION notify_config_change()
RETURNS TRIGGER AS $$
BEGIN
CASE TG_OP
WHEN 'INSERT', 'UPDATE' THEN
PERFORM pg_notify('config_change',
json_build_object(
'operation', TG_OP,
'table', TG_TABLE_NAME,
'id', NEW.id,
'key', COALESCE(NEW.key, NEW.name),
'timestamp', extract(epoch from NOW())
)::text
);
RETURN NEW;
WHEN 'DELETE' THEN
PERFORM pg_notify('config_change',
json_build_object(
'operation', TG_OP,
'table', TG_TABLE_NAME,
'id', OLD.id,
'key', COALESCE(OLD.key, OLD.name),
'timestamp', extract(epoch from NOW())
)::text
);
RETURN OLD;
END CASE;
END;
$$ language 'plpgsql';
-- Apply notification triggers
CREATE TRIGGER notify_config_entries_change
AFTER INSERT OR UPDATE OR DELETE ON config_entries
FOR EACH ROW EXECUTE FUNCTION notify_config_change();
CREATE TRIGGER notify_model_config_change
AFTER INSERT OR UPDATE OR DELETE ON model_config
FOR EACH ROW EXECUTE FUNCTION notify_config_change();
CREATE TRIGGER notify_model_versions_change
AFTER INSERT OR UPDATE OR DELETE ON model_versions
FOR EACH ROW EXECUTE FUNCTION notify_config_change();
-- Initial configuration data
INSERT INTO config_entries (key, value, description) VALUES
('system.latency_target_ns', '14', 'Target latency in nanoseconds'),
('trading.max_position_size', '1000000', 'Maximum position size in base currency'),
('risk.var_confidence', '0.95', 'VaR confidence level'),
('ml.model_cache_ttl', '3600', 'Model cache TTL in seconds'),
('s3.model_bucket', 'foxhunt-models', 'S3 bucket for model storage'),
('s3.model_prefix', 'models/', 'S3 prefix for models')
ON CONFLICT (key) DO NOTHING;