-- Migration: Create backtesting tables -- Version: 001 -- Description: Initial database schema for backtesting service -- Backtests table - stores backtest metadata CREATE TABLE IF NOT EXISTS backtests ( id SERIAL PRIMARY KEY, backtest_id VARCHAR(255) UNIQUE NOT NULL, strategy_name VARCHAR(255) NOT NULL, symbols TEXT NOT NULL, -- JSON array of symbols start_date TIMESTAMPTZ NOT NULL, end_date TIMESTAMPTZ NOT NULL, initial_capital DECIMAL(20, 8) NOT NULL, parameters TEXT, -- JSON object of strategy parameters description TEXT, status VARCHAR(50) NOT NULL DEFAULT 'queued', error_message TEXT, -- Performance summary (filled when completed) total_return DECIMAL(10, 6), sharpe_ratio DECIMAL(10, 6), max_drawdown DECIMAL(10, 6), total_trades BIGINT, win_rate DECIMAL(10, 6), profit_factor DECIMAL(10, 6), -- Timestamps created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ DEFAULT NOW(), started_at TIMESTAMPTZ, completed_at TIMESTAMPTZ ); -- Indexes for backtests CREATE INDEX IF NOT EXISTS idx_backtests_backtest_id ON backtests(backtest_id); CREATE INDEX IF NOT EXISTS idx_backtests_strategy_name ON backtests(strategy_name); CREATE INDEX IF NOT EXISTS idx_backtests_status ON backtests(status); CREATE INDEX IF NOT EXISTS idx_backtests_created_at ON backtests(created_at); -- Backtest trades table - stores individual trade executions CREATE TABLE IF NOT EXISTS backtest_trades ( id SERIAL PRIMARY KEY, backtest_id VARCHAR(255) NOT NULL, trade_id VARCHAR(255) NOT NULL, symbol VARCHAR(50) NOT NULL, side VARCHAR(10) NOT NULL, -- 'Buy' or 'Sell' quantity DECIMAL(20, 8) NOT NULL, entry_price DECIMAL(20, 8) NOT NULL, exit_price DECIMAL(20, 8) NOT NULL, entry_time TIMESTAMPTZ NOT NULL, exit_time TIMESTAMPTZ NOT NULL, pnl DECIMAL(20, 8) NOT NULL, return_percent DECIMAL(10, 6) NOT NULL, entry_signal TEXT, exit_signal TEXT, -- Foreign key FOREIGN KEY (backtest_id) REFERENCES backtests(backtest_id) ON DELETE CASCADE ); -- Indexes for backtest_trades CREATE INDEX IF NOT EXISTS idx_trades_backtest_id ON backtest_trades(backtest_id); CREATE INDEX IF NOT EXISTS idx_trades_symbol ON backtest_trades(symbol); CREATE INDEX IF NOT EXISTS idx_trades_entry_time ON backtest_trades(entry_time); CREATE INDEX IF NOT EXISTS idx_trades_pnl ON backtest_trades(pnl); -- Backtest metrics table - stores detailed performance metrics CREATE TABLE IF NOT EXISTS backtest_metrics ( id SERIAL PRIMARY KEY, backtest_id VARCHAR(255) UNIQUE NOT NULL, -- Return metrics total_return DECIMAL(10, 6) NOT NULL, annualized_return DECIMAL(10, 6) NOT NULL, -- Risk metrics sharpe_ratio DECIMAL(10, 6) NOT NULL, sortino_ratio DECIMAL(10, 6) NOT NULL, max_drawdown DECIMAL(10, 6) NOT NULL, volatility DECIMAL(10, 6) NOT NULL, calmar_ratio DECIMAL(10, 6) NOT NULL, -- Trade metrics win_rate DECIMAL(10, 6) NOT NULL, profit_factor DECIMAL(10, 6) NOT NULL, total_trades BIGINT NOT NULL, winning_trades BIGINT NOT NULL, losing_trades BIGINT NOT NULL, avg_win DECIMAL(20, 8) NOT NULL, avg_loss DECIMAL(20, 8) NOT NULL, largest_win DECIMAL(20, 8) NOT NULL, largest_loss DECIMAL(20, 8) NOT NULL, -- Risk measures var_95 DECIMAL(10, 6), expected_shortfall DECIMAL(10, 6), -- Benchmark comparison (optional) beta DECIMAL(10, 6), alpha DECIMAL(10, 6), information_ratio DECIMAL(10, 6), -- Timestamps created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), -- Foreign key FOREIGN KEY (backtest_id) REFERENCES backtests(backtest_id) ON DELETE CASCADE ); -- Index for backtest_metrics CREATE INDEX IF NOT EXISTS idx_metrics_backtest_id ON backtest_metrics(backtest_id); -- Equity curve table - stores equity progression over time CREATE TABLE IF NOT EXISTS backtest_equity_curve ( id SERIAL PRIMARY KEY, backtest_id VARCHAR(255) NOT NULL, timestamp TIMESTAMPTZ NOT NULL, equity DECIMAL(20, 8) NOT NULL, drawdown DECIMAL(10, 6) NOT NULL, benchmark_equity DECIMAL(20, 8), -- Foreign key FOREIGN KEY (backtest_id) REFERENCES backtests(backtest_id) ON DELETE CASCADE ); -- Indexes for backtest_equity_curve CREATE INDEX IF NOT EXISTS idx_equity_backtest_id ON backtest_equity_curve(backtest_id); CREATE INDEX IF NOT EXISTS idx_equity_timestamp ON backtest_equity_curve(timestamp); CREATE UNIQUE INDEX IF NOT EXISTS idx_equity_backtest_timestamp ON backtest_equity_curve(backtest_id, timestamp); -- Drawdown periods table - stores significant drawdown periods CREATE TABLE IF NOT EXISTS backtest_drawdown_periods ( id SERIAL PRIMARY KEY, backtest_id VARCHAR(255) NOT NULL, start_time TIMESTAMPTZ NOT NULL, end_time TIMESTAMPTZ NOT NULL, peak_value DECIMAL(20, 8) NOT NULL, trough_value DECIMAL(20, 8) NOT NULL, drawdown_percent DECIMAL(10, 6) NOT NULL, duration_days INTEGER NOT NULL, -- Foreign key FOREIGN KEY (backtest_id) REFERENCES backtests(backtest_id) ON DELETE CASCADE ); -- Indexes for backtest_drawdown_periods CREATE INDEX IF NOT EXISTS idx_drawdown_backtest_id ON backtest_drawdown_periods(backtest_id); CREATE INDEX IF NOT EXISTS idx_drawdown_start_time ON backtest_drawdown_periods(start_time); CREATE INDEX IF NOT EXISTS idx_drawdown_percent ON backtest_drawdown_periods(drawdown_percent); -- Market data table - stores historical market data for backtesting CREATE TABLE IF NOT EXISTS market_data ( id SERIAL PRIMARY KEY, symbol VARCHAR(50) NOT NULL, timestamp TIMESTAMPTZ NOT NULL, timeframe VARCHAR(10) NOT NULL, -- '1m', '5m', '1h', '1d', etc. open_price DECIMAL(20, 8) NOT NULL, high_price DECIMAL(20, 8) NOT NULL, low_price DECIMAL(20, 8) NOT NULL, close_price DECIMAL(20, 8) NOT NULL, volume DECIMAL(20, 8) NOT NULL, vwap DECIMAL(20, 8) ); -- Indexes for market_data CREATE INDEX IF NOT EXISTS idx_market_data_symbol ON market_data(symbol); CREATE INDEX IF NOT EXISTS idx_market_data_timestamp ON market_data(timestamp); CREATE INDEX IF NOT EXISTS idx_market_data_timeframe ON market_data(timeframe); CREATE UNIQUE INDEX IF NOT EXISTS idx_market_data_symbol_timestamp_timeframe ON market_data(symbol, timestamp, timeframe); -- Strategy configurations table - stores strategy parameter sets CREATE TABLE IF NOT EXISTS strategy_configurations ( id SERIAL PRIMARY KEY, strategy_name VARCHAR(255) NOT NULL, configuration_name VARCHAR(255) NOT NULL, parameters TEXT NOT NULL, -- JSON object description TEXT, is_default BOOLEAN DEFAULT FALSE, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ DEFAULT NOW() ); -- Indexes for strategy_configurations CREATE INDEX IF NOT EXISTS idx_strategy_configs_name ON strategy_configurations(strategy_name); CREATE UNIQUE INDEX IF NOT EXISTS idx_strategy_config_unique ON strategy_configurations(strategy_name, configuration_name); -- Backtest performance comparison table - for benchmark comparisons CREATE TABLE IF NOT EXISTS backtest_comparisons ( id SERIAL PRIMARY KEY, backtest_id VARCHAR(255) NOT NULL, benchmark_symbol VARCHAR(50) NOT NULL, correlation DECIMAL(10, 6), beta DECIMAL(10, 6), alpha DECIMAL(10, 6), tracking_error DECIMAL(10, 6), information_ratio DECIMAL(10, 6), created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), -- Foreign key FOREIGN KEY (backtest_id) REFERENCES backtests(backtest_id) ON DELETE CASCADE ); -- Indexes for backtest_comparisons CREATE INDEX IF NOT EXISTS idx_comparisons_backtest_id ON backtest_comparisons(backtest_id); CREATE INDEX IF NOT EXISTS idx_comparisons_benchmark ON backtest_comparisons(benchmark_symbol);