-- Initial Schema Migration for Solana Copy-Trading Bot CREATE TABLE IF NOT EXISTS watched_wallets ( id VARCHAR(36) PRIMARY KEY, address VARCHAR(88) NOT NULL UNIQUE, name VARCHAR(255) NOT NULL, is_active BOOLEAN NOT NULL DEFAULT TRUE, created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW() ); CREATE TABLE IF NOT EXISTS tokens ( mint VARCHAR(88) PRIMARY KEY, symbol VARCHAR(50) NOT NULL, decimals INTEGER NOT NULL, name VARCHAR(255) NOT NULL, first_detected_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW() ); CREATE TABLE IF NOT EXISTS copy_signals ( id VARCHAR(36) PRIMARY KEY, correlation_id VARCHAR(36) NOT NULL UNIQUE, source_wallet VARCHAR(88) NOT NULL, token_mint VARCHAR(88) NOT NULL, side VARCHAR(10) NOT NULL, -- buy or sell source_transaction_signature VARCHAR(128) NOT NULL, source_transaction_timestamp TIMESTAMP WITH TIME ZONE NOT NULL, detected_timestamp TIMESTAMP WITH TIME ZONE NOT NULL, detected_slot BIGINT NOT NULL, source_amount_sol NUMERIC(20, 9), token_amount NUMERIC(38, 9), source_price_sol NUMERIC(20, 9), metadata JSONB NOT NULL DEFAULT '{}'::jsonb ); CREATE TABLE IF NOT EXISTS trades ( id VARCHAR(36) PRIMARY KEY, correlation_id VARCHAR(36) NOT NULL, latency_scenario INTEGER NOT NULL, -- in milliseconds status VARCHAR(20) NOT NULL, -- open or closed token_mint VARCHAR(88) NOT NULL, entry_triggered_timestamp TIMESTAMP WITH TIME ZONE NOT NULL, entry_price_sol NUMERIC(20, 9) NOT NULL, position_size_sol NUMERIC(20, 9) NOT NULL, token_amount_received NUMERIC(38, 9) NOT NULL, exit_triggered_timestamp TIMESTAMP WITH TIME ZONE, exit_price_sol NUMERIC(20, 9), pnl_sol NUMERIC(20, 9), mfe_sol NUMERIC(20, 9), mae_sol NUMERIC(20, 9), entry_price_penalty_sol NUMERIC(20, 9), latency_impact_sol NUMERIC(20, 9), starting_balance_sol NUMERIC(20, 9) NOT NULL, ending_balance_sol NUMERIC(20, 9), strategy_name VARCHAR(255) NOT NULL, strategy_version VARCHAR(50) NOT NULL, app_version VARCHAR(50) NOT NULL, git_commit VARCHAR(40) NOT NULL, config_hash VARCHAR(64) NOT NULL, UNIQUE(correlation_id, latency_scenario) ); CREATE TABLE IF NOT EXISTS simulated_executions ( id VARCHAR(36) PRIMARY KEY, correlation_id VARCHAR(36) NOT NULL, trade_id VARCHAR(36), latency_scenario INTEGER NOT NULL, step VARCHAR(20) NOT NULL, -- entry or exit execution_timestamp TIMESTAMP WITH TIME ZONE NOT NULL, price_sol NUMERIC(20, 9) NOT NULL, amount_sol NUMERIC(20, 9) NOT NULL, token_amount NUMERIC(38, 9) NOT NULL, status VARCHAR(20) NOT NULL ); CREATE TABLE IF NOT EXISTS strategy_runs ( id VARCHAR(36) PRIMARY KEY, correlation_id VARCHAR(36) NOT NULL, strategy_name VARCHAR(255) NOT NULL, strategy_version VARCHAR(50) NOT NULL, evaluated_timestamp TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), should_copy BOOLEAN NOT NULL, reason TEXT NOT NULL, payload JSONB NOT NULL DEFAULT '{}'::jsonb ); CREATE TABLE IF NOT EXISTS event_journal ( id VARCHAR(36) PRIMARY KEY, correlation_id VARCHAR(36) NOT NULL, timestamp TIMESTAMP WITH TIME ZONE NOT NULL, event_type VARCHAR(100) NOT NULL, strategy_name VARCHAR(255), strategy_version VARCHAR(50), application_version VARCHAR(50) NOT NULL, git_commit VARCHAR(40) NOT NULL, configuration_hash VARCHAR(64) NOT NULL, payload JSONB NOT NULL DEFAULT '{}'::jsonb ); -- Performance Optimization Indexes CREATE INDEX IF NOT EXISTS idx_copy_signals_correlation ON copy_signals(correlation_id); CREATE INDEX IF NOT EXISTS idx_trades_correlation ON trades(correlation_id); CREATE INDEX IF NOT EXISTS idx_trades_scenario ON trades(latency_scenario); CREATE INDEX IF NOT EXISTS idx_sim_executions_trade_id ON simulated_executions(trade_id); CREATE INDEX IF NOT EXISTS idx_event_journal_correlation ON event_journal(correlation_id); CREATE INDEX IF NOT EXISTS idx_event_journal_timestamp ON event_journal(timestamp); CREATE INDEX IF NOT EXISTS idx_strategy_runs_correlation ON strategy_runs(correlation_id);