Spaces:
Sleeping
Sleeping
| """ | |
| db/database.py | |
| DuckDB schema + connection manager for Equity Workbench ETL. | |
| """ | |
| import duckdb | |
| import os | |
| from pathlib import Path | |
| from loguru import logger | |
| DB_PATH = os.getenv("DB_PATH", "./data/equity.duckdb") | |
| def get_connection() -> duckdb.DuckDBPyConnection: | |
| Path(DB_PATH).parent.mkdir(parents=True, exist_ok=True) | |
| conn = duckdb.connect(DB_PATH) | |
| # ββ Extension Setup βββββββββββββββββββββββββββββββββββββββββββ | |
| try: | |
| conn.execute("INSTALL vss;") | |
| conn.execute("LOAD vss;") | |
| conn.execute("SET hnsw_enable_experimental_persistence = true;") | |
| except Exception as e: | |
| logger.warning(f"Failed to load VSS extension: {e}") | |
| return conn | |
| def init_db(): | |
| """Create all tables if they don't exist.""" | |
| conn = get_connection() | |
| try: | |
| # ββ Stocks ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| conn.execute(""" | |
| CREATE SEQUENCE IF NOT EXISTS stock_quotes_id_seq; | |
| CREATE TABLE IF NOT EXISTS stock_quotes ( | |
| id INTEGER PRIMARY KEY DEFAULT nextval('stock_quotes_id_seq'), | |
| ticker TEXT NOT NULL, | |
| ts TEXT NOT NULL, -- ISO-8601 UTC | |
| bid REAL, | |
| ask REAL, | |
| last REAL, | |
| "close" REAL, | |
| volume INTEGER, | |
| "open" REAL, | |
| high REAL, | |
| low REAL, | |
| vwap REAL, | |
| created_at TIMESTAMP DEFAULT now() | |
| ) | |
| """) | |
| conn.execute(""" | |
| CREATE INDEX IF NOT EXISTS idx_sq_ticker_ts | |
| ON stock_quotes(ticker, ts) | |
| """) | |
| # ββ Options βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| conn.execute(""" | |
| CREATE SEQUENCE IF NOT EXISTS option_quotes_id_seq; | |
| CREATE TABLE IF NOT EXISTS option_quotes ( | |
| id INTEGER PRIMARY KEY DEFAULT nextval('option_quotes_id_seq'), | |
| ticker TEXT NOT NULL, -- underlying | |
| expiry TEXT NOT NULL, -- YYYYMMDD | |
| strike REAL NOT NULL, | |
| "right" TEXT NOT NULL, -- 'C' or 'P' | |
| ts TEXT NOT NULL, | |
| bid REAL, | |
| ask REAL, | |
| last REAL, | |
| volume INTEGER, | |
| open_interest INTEGER, | |
| implied_vol REAL, | |
| delta REAL, | |
| gamma REAL, | |
| theta REAL, | |
| vega REAL, | |
| und_price REAL, | |
| pv_dividend REAL, | |
| created_at TIMESTAMP DEFAULT now() | |
| ) | |
| """) | |
| conn.execute(""" | |
| CREATE INDEX IF NOT EXISTS idx_oq_ticker_expiry | |
| ON option_quotes(ticker, expiry, strike, "right") | |
| """) | |
| # ββ Option Chains (metadata) βββββββββββββββββββββββββββββββββββββββββββ | |
| conn.execute(""" | |
| CREATE TABLE IF NOT EXISTS option_chains ( | |
| ticker TEXT NOT NULL, | |
| expiry TEXT NOT NULL, | |
| strike REAL NOT NULL, | |
| "right" TEXT NOT NULL, | |
| exchange TEXT, | |
| fetched_at TIMESTAMP DEFAULT now(), | |
| UNIQUE(ticker, expiry, strike, "right") | |
| ) | |
| """) | |
| # ββ ETL Run Log ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| conn.execute(""" | |
| CREATE SEQUENCE IF NOT EXISTS etl_runs_id_seq; | |
| CREATE TABLE IF NOT EXISTS etl_runs ( | |
| id INTEGER PRIMARY KEY DEFAULT nextval('etl_runs_id_seq'), | |
| run_type TEXT NOT NULL, -- 'stocks' | 'options' | 'chain' | 'polygon_bars_bronze' | ... | |
| status TEXT NOT NULL, -- 'ok' | 'error' | |
| message TEXT, | |
| rows_written INTEGER DEFAULT 0, | |
| started_at TEXT NOT NULL, | |
| finished_at TEXT | |
| ) | |
| """) | |
| # ββ Polygon: OHLCV bars βββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| conn.execute(""" | |
| CREATE TABLE IF NOT EXISTS polygon_bars ( | |
| ticker TEXT NOT NULL, | |
| ts TEXT NOT NULL, -- bar open time, ISO-8601 UTC | |
| timespan TEXT NOT NULL, -- 'day' | 'minute' | 'hour' | |
| open REAL, | |
| high REAL, | |
| low REAL, | |
| close REAL, | |
| volume REAL, | |
| vwap REAL, | |
| transactions INTEGER, | |
| created_at TIMESTAMP DEFAULT now(), | |
| UNIQUE(ticker, ts, timespan) | |
| ) | |
| """) | |
| conn.execute(""" | |
| CREATE INDEX IF NOT EXISTS idx_pb_ticker_ts | |
| ON polygon_bars(ticker, ts, timespan) | |
| """) | |
| # ββ Polygon: real-time / delayed snapshots ββββββββββββββββββββββββββββββββ | |
| conn.execute(""" | |
| CREATE TABLE IF NOT EXISTS polygon_snapshots ( | |
| ticker TEXT NOT NULL, | |
| ts TEXT NOT NULL, | |
| bid REAL, | |
| ask REAL, | |
| last REAL, | |
| prev_close REAL, | |
| day_volume REAL, | |
| created_at TIMESTAMP DEFAULT now() | |
| ) | |
| """) | |
| conn.execute(""" | |
| CREATE INDEX IF NOT EXISTS idx_ps_ticker_ts | |
| ON polygon_snapshots(ticker, ts) | |
| """) | |
| # ββ Polygon: options chain snapshots ββββββββββββββββββββββββββββββββββββββ | |
| conn.execute(""" | |
| CREATE TABLE IF NOT EXISTS polygon_option_snapshots ( | |
| underlying TEXT NOT NULL, | |
| expiry TEXT NOT NULL, -- YYYY-MM-DD | |
| strike REAL NOT NULL, | |
| "right" TEXT NOT NULL, -- 'call' | 'put' | |
| ts TEXT NOT NULL, | |
| day_open REAL, | |
| day_close REAL, | |
| day_volume INTEGER, | |
| open_interest INTEGER, | |
| implied_vol REAL, | |
| delta REAL, | |
| gamma REAL, | |
| theta REAL, | |
| vega REAL, | |
| created_at TIMESTAMP DEFAULT now() | |
| ) | |
| """) | |
| conn.execute(""" | |
| CREATE INDEX IF NOT EXISTS idx_pos_underlying | |
| ON polygon_option_snapshots(underlying, expiry, strike, "right") | |
| """) | |
| # ββ Polygon: ticker reference / metadata ββββββββββββββββββββββββββββββββββ | |
| conn.execute(""" | |
| CREATE TABLE IF NOT EXISTS polygon_tickers ( | |
| ticker TEXT NOT NULL UNIQUE, | |
| name TEXT, | |
| market TEXT, | |
| primary_exchange TEXT, | |
| type TEXT, | |
| active INTEGER, | |
| currency TEXT, | |
| description TEXT, | |
| updated_at TEXT NOT NULL | |
| ) | |
| """) | |
| # ββ Polygon: historical options OHLCV bars βββββββββββββββββββββββββββ | |
| conn.execute(""" | |
| CREATE TABLE IF NOT EXISTS polygon_option_bars ( | |
| option_ticker TEXT NOT NULL, -- e.g. O:AAPL240119C00150000 | |
| underlying TEXT NOT NULL, | |
| expiry TEXT, -- YYYY-MM-DD | |
| strike REAL, | |
| "right" TEXT, -- 'call' | 'put' | |
| ts TEXT NOT NULL, -- bar open time, ISO-8601 UTC | |
| timespan TEXT NOT NULL, -- 'day' | 'minute' | |
| open REAL, | |
| high REAL, | |
| low REAL, | |
| close REAL, | |
| volume REAL, | |
| vwap REAL, | |
| transactions INTEGER, | |
| created_at TIMESTAMP DEFAULT now(), | |
| UNIQUE(option_ticker, ts, timespan) | |
| ) | |
| """) | |
| conn.execute(""" | |
| CREATE INDEX IF NOT EXISTS idx_pob_underlying | |
| ON polygon_option_bars(underlying, expiry, strike, "right") | |
| """) | |
| conn.execute(""" | |
| CREATE INDEX IF NOT EXISTS idx_pob_ticker_ts | |
| ON polygon_option_bars(option_ticker, ts) | |
| """) | |
| # ββ Polygon: individual trade ticks ββββββββββββββββββββββββββββββββββ | |
| conn.execute(""" | |
| CREATE TABLE IF NOT EXISTS polygon_trades ( | |
| ticker TEXT NOT NULL, | |
| ts TEXT NOT NULL, -- SIP timestamp, ISO-8601 microsecond UTC | |
| price REAL, | |
| size REAL, | |
| conditions TEXT, -- comma-separated condition codes | |
| exchange INTEGER, | |
| tape TEXT, | |
| created_at TIMESTAMP DEFAULT now(), | |
| UNIQUE(ticker, ts, exchange) | |
| ) | |
| """) | |
| conn.execute(""" | |
| CREATE INDEX IF NOT EXISTS idx_ptrades_ticker_ts | |
| ON polygon_trades(ticker, ts) | |
| """) | |
| # ββ EDGAR: filing metadata ββββββββββββββββββββββββββββββββββββββββββββ | |
| conn.execute(""" | |
| CREATE TABLE IF NOT EXISTS edgar_filings ( | |
| ticker TEXT NOT NULL, | |
| cik TEXT NOT NULL, | |
| form_type TEXT NOT NULL, | |
| filed_date TEXT, | |
| accession_number TEXT NOT NULL, | |
| primary_doc TEXT, | |
| created_at TIMESTAMP DEFAULT now(), | |
| UNIQUE(accession_number) | |
| ) | |
| """) | |
| conn.execute(""" | |
| CREATE INDEX IF NOT EXISTS idx_ef_ticker_form | |
| ON edgar_filings(ticker, form_type, filed_date) | |
| """) | |
| # ββ EDGAR: XBRL financial facts βββββββββββββββββββββββββββββββββββββββ | |
| conn.execute(""" | |
| CREATE TABLE IF NOT EXISTS edgar_facts ( | |
| ticker TEXT NOT NULL, | |
| cik TEXT NOT NULL, | |
| taxonomy TEXT NOT NULL, | |
| concept TEXT NOT NULL, | |
| label TEXT, | |
| unit TEXT, | |
| value REAL, | |
| period_start TEXT, | |
| period_end TEXT, | |
| form_type TEXT, | |
| filed_date TEXT, | |
| accession_number TEXT, | |
| created_at TIMESTAMP DEFAULT now(), | |
| UNIQUE(ticker, concept, unit, period_end, form_type) | |
| ) | |
| """) | |
| conn.execute(""" | |
| CREATE INDEX IF NOT EXISTS idx_edgar_facts_ticker | |
| ON edgar_facts(ticker, concept, period_end) | |
| """) | |
| # ββ COT: Commitments of Traders (CFTC) ββββββββββββββββββββββββββββββββ | |
| conn.execute(""" | |
| CREATE TABLE IF NOT EXISTS cot_reports ( | |
| market_name TEXT NOT NULL, | |
| ticker TEXT, -- Optional mapping to IBKR ticker | |
| report_date TEXT NOT NULL, -- ISO-8601 | |
| noncomm_long INTEGER, | |
| noncomm_short INTEGER, | |
| comm_long INTEGER, | |
| comm_short INTEGER, | |
| total_long INTEGER, | |
| total_short INTEGER, | |
| noncomm_spreads INTEGER, | |
| open_interest INTEGER, | |
| created_at TIMESTAMP DEFAULT now(), | |
| UNIQUE(market_name, report_date) | |
| ) | |
| """) | |
| conn.execute(""" | |
| CREATE INDEX IF NOT EXISTS idx_cot_market_date | |
| ON cot_reports(market_name, report_date) | |
| """) | |
| # ββ Vector Storage ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| conn.execute(""" | |
| CREATE TABLE IF NOT EXISTS ticker_embeddings ( | |
| ticker TEXT PRIMARY KEY, | |
| industry TEXT, | |
| source TEXT, | |
| text TEXT, | |
| embedding FLOAT[384], -- all-MiniLM-L6-v2 dimension | |
| updated_at TIMESTAMP DEFAULT now() | |
| ) | |
| """) | |
| try: | |
| conn.execute(""" | |
| CREATE INDEX IF NOT EXISTS idx_ticker_emb | |
| ON ticker_embeddings USING HNSW (embedding) | |
| WITH (metric = 'cosine') | |
| """) | |
| except Exception as e: | |
| logger.warning(f"Failed to create HNSW index on ticker_embeddings: {e}") | |
| conn.execute(""" | |
| CREATE SEQUENCE IF NOT EXISTS edgar_embeddings_id_seq; | |
| CREATE TABLE IF NOT EXISTS edgar_embeddings ( | |
| id INTEGER PRIMARY KEY DEFAULT nextval('edgar_embeddings_id_seq'), | |
| ticker TEXT, | |
| accession TEXT, | |
| text TEXT, | |
| embedding FLOAT[384], | |
| updated_at TIMESTAMP DEFAULT now() | |
| ) | |
| """) | |
| try: | |
| conn.execute(""" | |
| CREATE INDEX IF NOT EXISTS idx_edgar_emb | |
| ON edgar_embeddings USING HNSW (embedding) | |
| WITH (metric = 'cosine') | |
| """) | |
| except Exception as e: | |
| logger.warning(f"Failed to create HNSW index on edgar_embeddings: {e}") | |
| # ββ SILVER LAYER βββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # Derived, recomputable feature tables built from bronze bars. | |
| # Grain: one row per entity per trading day. Rebuilt with INSERT OR REPLACE. | |
| # ββ Silver: per-stock daily technical features βββββββββββββββββββββββββ | |
| # Source: polygon_bars WHERE timespan='day'. Windows are trailing N days. | |
| conn.execute(""" | |
| CREATE TABLE IF NOT EXISTS silver_stock_features ( | |
| ticker TEXT NOT NULL, | |
| ts TEXT NOT NULL, -- trading day, ISO-8601 (bronze join key) | |
| trade_date DATE, -- typed date for window ordering | |
| close DOUBLE, -- from bronze polygon_bars (day) | |
| volume DOUBLE, | |
| daily_return DOUBLE, -- close / prev_close - 1 | |
| -- simple moving averages of close | |
| ma_20 DOUBLE, | |
| ma_50 DOUBLE, | |
| ma_100 DOUBLE, | |
| -- rolling sample standard deviation of close | |
| std_20 DOUBLE, | |
| std_50 DOUBLE, | |
| std_100 DOUBLE, | |
| pct_change DOUBLE, -- daily_return * 100 (percent) | |
| -- price z-score = (close - ma_N) / std_N | |
| zscore_20 DOUBLE, | |
| zscore_50 DOUBLE, | |
| zscore_100 DOUBLE, | |
| -- sigma band flag on price: '+3s' | 'normal' | '-3s' | NULL | |
| sigma_flag_20 TEXT, | |
| sigma_flag_50 TEXT, | |
| sigma_flag_100 TEXT, | |
| -- return z-score = (pct_change - mean_ret_N) / std_ret_N | |
| zscore_ret_20 DOUBLE, | |
| zscore_ret_50 DOUBLE, | |
| zscore_ret_100 DOUBLE, | |
| -- sigma band flag on returns | |
| sigma_flag_ret_20 TEXT, | |
| sigma_flag_ret_50 TEXT, | |
| sigma_flag_ret_100 TEXT, | |
| -- rolling VWAP = sum(typical_price*volume)/sum(volume), typical=(h+l+c)/3 | |
| vwap_20 DOUBLE, | |
| vwap_50 DOUBLE, | |
| vwap_100 DOUBLE, | |
| computed_at TIMESTAMP DEFAULT now(), | |
| UNIQUE(ticker, ts) | |
| ) | |
| """) | |
| # ββ Migrate: add sigma_flag columns if they don't exist yet βββββββββββ | |
| for col in ("sigma_flag_20", "sigma_flag_50", "sigma_flag_100"): | |
| try: | |
| conn.execute(f"ALTER TABLE silver_stock_features ADD COLUMN {col} TEXT") | |
| logger.info(f"Migrated silver_stock_features: added {col}") | |
| except Exception: | |
| pass # column already exists | |
| for col in ("pct_change",): | |
| try: | |
| conn.execute(f"ALTER TABLE silver_stock_features ADD COLUMN {col} DOUBLE") | |
| logger.info(f"Migrated silver_stock_features: added {col}") | |
| except Exception: | |
| pass | |
| for col in ("zscore_ret_20", "zscore_ret_50", "zscore_ret_100"): | |
| try: | |
| conn.execute(f"ALTER TABLE silver_stock_features ADD COLUMN {col} DOUBLE") | |
| logger.info(f"Migrated silver_stock_features: added {col}") | |
| except Exception: | |
| pass | |
| for col in ("sigma_flag_ret_20", "sigma_flag_ret_50", "sigma_flag_ret_100"): | |
| try: | |
| conn.execute(f"ALTER TABLE silver_stock_features ADD COLUMN {col} TEXT") | |
| logger.info(f"Migrated silver_stock_features: added {col}") | |
| except Exception: | |
| pass | |
| conn.execute(""" | |
| CREATE INDEX IF NOT EXISTS idx_ssf_ticker_date | |
| ON silver_stock_features(ticker, trade_date) | |
| """) | |
| # ββ View: latest z-score alerts per ticker βββββββββββββββββββββββββββββ | |
| # Query this view to see which tickers are currently outside +-3 std devs. | |
| # sigma_flag values: '+3s' (above), '-3s' (below), 'normal', NULL (warm-up) | |
| conn.execute("DROP VIEW IF EXISTS v_zscore_alerts") | |
| conn.execute(""" | |
| CREATE VIEW v_zscore_alerts AS | |
| WITH latest AS ( | |
| SELECT *, | |
| ROW_NUMBER() OVER (PARTITION BY ticker ORDER BY trade_date DESC) AS rn | |
| FROM silver_stock_features | |
| ) | |
| SELECT | |
| ticker, | |
| trade_date, | |
| close, | |
| pct_change, | |
| zscore_20, sigma_flag_20, | |
| zscore_50, sigma_flag_50, | |
| zscore_100, sigma_flag_100, | |
| zscore_ret_20, sigma_flag_ret_20, | |
| zscore_ret_50, sigma_flag_ret_50, | |
| zscore_ret_100, sigma_flag_ret_100, | |
| CASE | |
| WHEN sigma_flag_20 IN ('+3s', '-3s') | |
| OR sigma_flag_50 IN ('+3s', '-3s') | |
| OR sigma_flag_100 IN ('+3s', '-3s') | |
| OR sigma_flag_ret_20 IN ('+3s', '-3s') | |
| OR sigma_flag_ret_50 IN ('+3s', '-3s') | |
| OR sigma_flag_ret_100 IN ('+3s', '-3s') | |
| THEN true ELSE false | |
| END AS any_breach, | |
| GREATEST( | |
| ABS(COALESCE(zscore_20, 0)), | |
| ABS(COALESCE(zscore_50, 0)), | |
| ABS(COALESCE(zscore_100, 0)), | |
| ABS(COALESCE(zscore_ret_20, 0)), | |
| ABS(COALESCE(zscore_ret_50, 0)), | |
| ABS(COALESCE(zscore_ret_100, 0)) | |
| ) AS max_abs_zscore | |
| FROM latest | |
| WHERE rn = 1 | |
| ORDER BY max_abs_zscore DESC | |
| """) | |
| # ββ Silver: per-contract daily option greeks (Black-Scholes-Merton) ββββ | |
| # Source: polygon_option_bars (option price) JOIN polygon_bars (underlying | |
| # close). implied_vol solved from the option's market close; greeks analytic. | |
| conn.execute(""" | |
| CREATE TABLE IF NOT EXISTS silver_option_greeks ( | |
| option_ticker TEXT NOT NULL, -- OPRA symbol | |
| underlying TEXT NOT NULL, | |
| expiry TEXT, -- YYYY-MM-DD | |
| strike DOUBLE, | |
| "right" TEXT, -- 'call' | 'put' | |
| ts TEXT NOT NULL, -- trading day, ISO-8601 | |
| trade_date DATE, | |
| option_close DOUBLE, -- option price from bronze bar | |
| und_close DOUBLE, -- underlying close (S) | |
| time_to_expiry DOUBLE, -- years to expiry (ACT/365) | |
| moneyness DOUBLE, -- und_close / strike | |
| risk_free_rate DOUBLE, -- r assumption used | |
| dividend_yield DOUBLE, -- q assumption used (default 0) | |
| implied_vol DOUBLE, -- sigma solved from option_close | |
| delta DOUBLE, | |
| gamma DOUBLE, | |
| theta DOUBLE, -- per calendar day | |
| vega DOUBLE, -- per 1 vol point | |
| rho DOUBLE, | |
| computed_at TIMESTAMP DEFAULT now(), | |
| UNIQUE(option_ticker, ts) | |
| ) | |
| """) | |
| conn.execute(""" | |
| CREATE INDEX IF NOT EXISTS idx_sog_underlying_date | |
| ON silver_option_greeks(underlying, trade_date) | |
| """) | |
| # -- Silver: per-underlying daily options POSITIONING -- | |
| conn.execute(""" | |
| CREATE TABLE IF NOT EXISTS silver_option_positioning ( | |
| underlying TEXT NOT NULL, | |
| ts TEXT NOT NULL, | |
| trade_date DATE, | |
| total_volume DOUBLE, | |
| call_volume DOUBLE, | |
| put_volume DOUBLE, | |
| put_call_ratio DOUBLE, | |
| atm_iv DOUBLE, | |
| call_iv_25d DOUBLE, | |
| put_iv_25d DOUBLE, | |
| iv_skew_25d DOUBLE, | |
| n_contracts INTEGER, | |
| computed_at TIMESTAMP DEFAULT now(), | |
| UNIQUE(underlying, ts) | |
| ) | |
| """) | |
| conn.execute(""" | |
| CREATE INDEX IF NOT EXISTS idx_sop_underlying_date | |
| ON silver_option_positioning(underlying, trade_date) | |
| """) | |
| # ββ Silver: COT (Commitments of Traders) positioning features βββββββββ | |
| # Source: cot_reports (Bronze, weekly). Grain: one row per (ticker, report_date). | |
| conn.execute(""" | |
| CREATE TABLE IF NOT EXISTS silver_cot_features ( | |
| report_date DATE NOT NULL, | |
| ticker TEXT NOT NULL, | |
| noncomm_long BIGINT, | |
| noncomm_short BIGINT, | |
| noncomm_net BIGINT, | |
| comm_long BIGINT, | |
| comm_short BIGINT, | |
| comm_net BIGINT, | |
| n_weeks INTEGER, | |
| net_pos_mean_52w DOUBLE, | |
| net_pos_std_52w DOUBLE, | |
| net_pos_zscore_52w DOUBLE, | |
| comm_net_mean_52w DOUBLE, | |
| comm_net_std_52w DOUBLE, | |
| comm_net_zscore_52w DOUBLE, | |
| spec_comm_divergence DOUBLE, | |
| crowd_flag TEXT, | |
| computed_at TIMESTAMP DEFAULT now(), | |
| PRIMARY KEY (report_date, ticker) | |
| ) | |
| """) | |
| conn.execute(""" | |
| CREATE INDEX IF NOT EXISTS idx_scf_ticker_date | |
| ON silver_cot_features(ticker, report_date) | |
| """) | |
| # ββ Silver: futures continuous-contract price features ββββββββββββββββ | |
| # Source: polygon_bars (Bronze, day bars) for continuous futures tickers | |
| # like 'ES1:COM'. Grain: one row per (ticker, trade_date). | |
| conn.execute(""" | |
| CREATE TABLE IF NOT EXISTS silver_futures_features ( | |
| trade_date DATE NOT NULL, | |
| ticker TEXT NOT NULL, | |
| open_price DOUBLE, | |
| high_price DOUBLE, | |
| low_price DOUBLE, | |
| close_price DOUBLE, | |
| volume BIGINT, | |
| n20 INTEGER, | |
| ma_20 DOUBLE, | |
| std_20 DOUBLE, | |
| zscore_20 DOUBLE, | |
| n_ret20 INTEGER, | |
| ret DOUBLE, | |
| mean_ret_20 DOUBLE, | |
| std_ret_20 DOUBLE, | |
| zscore_ret_20 DOUBLE, | |
| vx_term_slope DOUBLE, | |
| regime_flag TEXT, | |
| computed_at TIMESTAMP DEFAULT now(), | |
| PRIMARY KEY (trade_date, ticker) | |
| ) | |
| """) | |
| conn.execute(""" | |
| CREATE INDEX IF NOT EXISTS idx_sff_ticker_date | |
| ON silver_futures_features(ticker, trade_date) | |
| """) | |
| # ββ View: latest COT positioning + futures price context per ticker βββ | |
| conn.execute("DROP VIEW IF EXISTS v_cot_positioning") | |
| conn.execute(""" | |
| CREATE VIEW v_cot_positioning AS | |
| WITH latest_cot AS ( | |
| SELECT *, ROW_NUMBER() OVER (PARTITION BY ticker ORDER BY report_date DESC) AS rn | |
| FROM silver_cot_features | |
| ), | |
| latest_fut AS ( | |
| SELECT *, ROW_NUMBER() OVER (PARTITION BY ticker ORDER BY trade_date DESC) AS rn | |
| FROM silver_futures_features | |
| ) | |
| SELECT | |
| c.ticker, | |
| c.report_date, | |
| c.noncomm_net, | |
| c.net_pos_zscore_52w, | |
| c.comm_net_zscore_52w, | |
| c.spec_comm_divergence, | |
| c.crowd_flag, | |
| f.trade_date AS futures_date, | |
| f.close_price AS futures_close, | |
| f.zscore_20 AS futures_zscore_20, | |
| f.vx_term_slope, | |
| f.regime_flag | |
| FROM latest_cot c | |
| LEFT JOIN latest_fut f ON f.ticker = c.ticker || '1:COM' AND f.rn = 1 | |
| WHERE c.rn = 1 | |
| ORDER BY ABS(COALESCE(c.net_pos_zscore_52w, 0)) DESC | |
| """) | |
| # ββ GOLD LAYER ββββββββββββββββββββ | |
| # Backtest results: runs, trades, portfolio snapshots, metrics, signals. | |
| # ββ Gold: backtest run metadata βββββββββββββββββββββββββββββββββββββββ | |
| conn.execute(""" | |
| CREATE TABLE IF NOT EXISTS gold_backtest_runs ( | |
| run_id TEXT NOT NULL PRIMARY KEY, | |
| config TEXT, | |
| universe TEXT, | |
| start_date DATE NOT NULL, | |
| end_date DATE NOT NULL, | |
| created_at TIMESTAMP DEFAULT now(), | |
| fold_id INTEGER, -- walk-forward OOS fold (NULL = plain run) | |
| wf_run_id TEXT -- parent walk-forward run (NULL = plain run) | |
| ) | |
| """) | |
| # ββ Migrate: add fold_id / wf_run_id if the table predates walk-forward | |
| try: | |
| conn.execute("ALTER TABLE gold_backtest_runs ADD COLUMN fold_id INTEGER") | |
| logger.info("Migrated gold_backtest_runs: added fold_id") | |
| except Exception: | |
| pass # column already exists | |
| try: | |
| conn.execute("ALTER TABLE gold_backtest_runs ADD COLUMN wf_run_id TEXT") | |
| logger.info("Migrated gold_backtest_runs: added wf_run_id") | |
| except Exception: | |
| pass # column already exists | |
| # ββ Gold: individual simulated trades βββββββββββββββββββββββββββββββββ | |
| conn.execute(""" | |
| CREATE TABLE IF NOT EXISTS gold_trades ( | |
| trade_id TEXT NOT NULL PRIMARY KEY, | |
| run_id TEXT NOT NULL, | |
| ticker TEXT NOT NULL, | |
| entry_date DATE NOT NULL, | |
| exit_date DATE, | |
| direction INTEGER NOT NULL, | |
| shares DOUBLE, | |
| entry_price DOUBLE, | |
| exit_price DOUBLE, | |
| gross_pnl DOUBLE, | |
| slippage_cost DOUBLE, | |
| commission_cost DOUBLE, | |
| net_pnl DOUBLE, | |
| entry_regime TEXT, | |
| exit_regime TEXT, | |
| signal_type TEXT | |
| ) | |
| """) | |
| conn.execute(""" | |
| CREATE INDEX IF NOT EXISTS idx_gt_run_ticker | |
| ON gold_trades(run_id, ticker, entry_date) | |
| """) | |
| # ββ Gold: daily portfolio snapshots βββββββββββββββββββββββββββββββββββ | |
| conn.execute(""" | |
| CREATE TABLE IF NOT EXISTS gold_portfolio ( | |
| run_id TEXT NOT NULL, | |
| trade_date DATE NOT NULL, | |
| nav DOUBLE, | |
| cash DOUBLE, | |
| drawdown_pct DOUBLE, | |
| n_positions INTEGER, | |
| UNIQUE(run_id, trade_date) | |
| ) | |
| """) | |
| conn.execute(""" | |
| CREATE INDEX IF NOT EXISTS idx_gp_run_date | |
| ON gold_portfolio(run_id, trade_date) | |
| """) | |
| # ββ Gold: aggregated metrics per run ββββββββββββββββββββββββββββββββββ | |
| conn.execute(""" | |
| CREATE TABLE IF NOT EXISTS gold_metrics ( | |
| run_id TEXT NOT NULL PRIMARY KEY, | |
| sharpe DOUBLE, | |
| sortino DOUBLE, | |
| mdd_pct DOUBLE, | |
| mdd_duration_days INTEGER, | |
| mdd_recovery_days INTEGER, | |
| calmar DOUBLE, | |
| win_rate DOUBLE, | |
| profit_factor DOUBLE, | |
| expectancy DOUBLE, | |
| cost_drag DOUBLE, | |
| ann_return DOUBLE, | |
| ann_vol DOUBLE | |
| ) | |
| """) | |
| # ββ Gold: walk-forward OOS aggregate summary per walk-forward run βββββ | |
| conn.execute(""" | |
| CREATE TABLE IF NOT EXISTS gold_oos_summary ( | |
| run_id TEXT NOT NULL, | |
| run_ts TIMESTAMPTZ DEFAULT current_timestamp, | |
| n_folds INTEGER, | |
| mean_sharpe DOUBLE, | |
| consistency_ratio DOUBLE, | |
| combined_sharpe DOUBLE, | |
| worst_fold_mdd DOUBLE, | |
| split_type TEXT, | |
| embargo_days INTEGER, | |
| PRIMARY KEY (run_id) | |
| ) | |
| """) | |
| # ββ Gold: immutable signal audit log ββββββββββββββββββββββββββββββββββ | |
| conn.execute(""" | |
| CREATE TABLE IF NOT EXISTS gold_signals ( | |
| signal_id TEXT NOT NULL PRIMARY KEY, | |
| run_id TEXT NOT NULL, | |
| ticker TEXT NOT NULL, | |
| signal_date DATE NOT NULL, | |
| direction INTEGER NOT NULL, | |
| strength DOUBLE, | |
| signal_type TEXT, | |
| computed_at TIMESTAMP DEFAULT now() | |
| ) | |
| """) | |
| conn.execute(""" | |
| CREATE INDEX IF NOT EXISTS idx_gs_run_date | |
| ON gold_signals(run_id, signal_date, ticker) | |
| """) | |
| finally: | |
| conn.close() | |
| logger.info(f"Database initialised at {DB_PATH}") | |