diff --git a/services/api_gateway/src/auth/jwt/service.rs b/services/api_gateway/src/auth/jwt/service.rs index 75f5b7108..e6bf1d03c 100644 --- a/services/api_gateway/src/auth/jwt/service.rs +++ b/services/api_gateway/src/auth/jwt/service.rs @@ -124,7 +124,8 @@ impl JwtConfig { warn!( "JWT secret loaded from environment variable - consider using JWT_SECRET_FILE for production" ); - return Ok(secret); + // WAVE 149 Agent 411: Trim whitespace to match file loading behavior (line 103) + return Ok(secret.trim().to_string()); } Err(anyhow::anyhow!( diff --git a/services/backtesting_service/migrations/001_create_tables_fixed.sql b/services/backtesting_service/migrations/001_create_tables_fixed.sql new file mode 100644 index 000000000..a77559a66 --- /dev/null +++ b/services/backtesting_service/migrations/001_create_tables_fixed.sql @@ -0,0 +1,205 @@ +-- 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);