Spaces:
Running
Running
File size: 11,891 Bytes
57384dd a88e030 57384dd c4717f1 57384dd d60ae27 2a8ebf2 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 | -- ============================================================
-- Stock Signal SQLite Schema
-- Consolidated schema
--
-- This replaces the older schema.sql + phase2/phase3/phase4
-- migration chain for NEW database initialization.
--
-- Canonical lifecycle:
-- prediction -> resolution -> metrics -> retrain flag
-- ============================================================
-- ============================================================
-- 1. PREDICTIONS
-- ============================================================
CREATE TABLE IF NOT EXISTS predictions (
id INTEGER PRIMARY KEY AUTOINCREMENT,
-- Model / feature provenance
model_version TEXT NOT NULL,
feature_version TEXT NOT NULL,
-- Prediction timing
prediction_date DATE NOT NULL,
prediction_timestamp TIMESTAMP NOT NULL DEFAULT (STRFTIME('%Y-%m-%dT%H:%M:%fZ', 'now')),
-- Stock
symbol TEXT NOT NULL,
-- Model output
predicted_probability REAL NOT NULL,
"rank" INTEGER NOT NULL,
-- Target contract
target_threshold REAL NOT NULL DEFAULT 0.03,
target_horizon_days INTEGER NOT NULL DEFAULT 5,
-- Price at prediction time
prediction_close REAL,
-- Resolution / forward evaluation
entry_date DATE,
entry_open REAL,
max_close_5d REAL,
evaluation_end_date DATE,
actual_return REAL,
actual_label INTEGER,
resolved_at TIMESTAMP,
created_at TIMESTAMP NOT NULL DEFAULT (STRFTIME('%Y-%m-%dT%H:%M:%fZ', 'now')),
-- One prediction per symbol/model/date.
CONSTRAINT uq_predictions_date_symbol_model
UNIQUE (prediction_date, symbol, model_version),
CONSTRAINT predictions_probability_check
CHECK (
predicted_probability >= 0
AND predicted_probability <= 1
),
-- Binary classification target.
CONSTRAINT predictions_actual_label_check
CHECK (actual_label IS NULL OR actual_label IN (0, 1)),
-- Target contract validation.
CONSTRAINT predictions_target_threshold_check
CHECK (target_threshold >= 0),
CONSTRAINT predictions_target_horizon_check
CHECK (target_horizon_days > 0),
-- Rank must be positive.
CONSTRAINT predictions_rank_check
CHECK ("rank" > 0)
);
CREATE INDEX IF NOT EXISTS idx_predictions_date
ON predictions (prediction_date);
CREATE INDEX IF NOT EXISTS idx_predictions_symbol
ON predictions (symbol);
CREATE INDEX IF NOT EXISTS idx_predictions_unresolved
ON predictions (prediction_date, symbol)
WHERE actual_label IS NULL;
CREATE INDEX IF NOT EXISTS idx_predictions_resolution
ON predictions (prediction_date, symbol, actual_label);
CREATE INDEX IF NOT EXISTS idx_predictions_model_date
ON predictions (model_version, prediction_date);
-- ============================================================
-- 2. JOB RUNS
-- ============================================================
CREATE TABLE IF NOT EXISTS job_runs (
id INTEGER PRIMARY KEY AUTOINCREMENT,
job_name TEXT NOT NULL,
run_date DATE NOT NULL,
started_at TIMESTAMP NOT NULL DEFAULT (STRFTIME('%Y-%m-%dT%H:%M:%fZ', 'now')),
finished_at TIMESTAMP,
status TEXT NOT NULL
CHECK (
status IN (
'RUNNING',
'SUCCESS',
'FAILED',
'SKIPPED'
)
),
rows_processed INTEGER NOT NULL DEFAULT 0,
total_rows INTEGER NOT NULL DEFAULT 0,
resolved_rows INTEGER NOT NULL DEFAULT 0,
failed_rows INTEGER NOT NULL DEFAULT 0,
last_updated_at TIMESTAMP,
error_message TEXT
);
CREATE INDEX IF NOT EXISTS idx_job_runs_name_date
ON job_runs (job_name, run_date);
-- Cross-process lease locks for singleton SQLite jobs. The token prevents an
-- expired owner from releasing a newer owner's lease.
CREATE TABLE IF NOT EXISTS job_locks (
lock_name TEXT PRIMARY KEY,
owner_token TEXT NOT NULL,
locked_until TIMESTAMP NOT NULL
);
-- ============================================================
-- 3. PREDICTION METRICS
-- ============================================================
CREATE TABLE IF NOT EXISTS prediction_metrics (
id INTEGER PRIMARY KEY AUTOINCREMENT,
window_start DATE NOT NULL,
window_end DATE NOT NULL,
prediction_days INTEGER NOT NULL,
resolved_predictions INTEGER NOT NULL,
precision REAL,
pr_auc REAL,
hit_rate REAL,
positive_rate REAL,
average_return REAL,
metrics_json TEXT NOT NULL DEFAULT '{}',
calculated_at TIMESTAMP NOT NULL DEFAULT (STRFTIME('%Y-%m-%dT%H:%M:%fZ', 'now')),
model_version TEXT NOT NULL,
CONSTRAINT prediction_metrics_window_uq
UNIQUE (model_version, window_start, window_end),
CONSTRAINT prediction_metrics_window_ck
CHECK (window_start <= window_end),
CONSTRAINT prediction_metrics_prediction_days_ck
CHECK (prediction_days > 0),
CONSTRAINT prediction_metrics_resolved_ck
CHECK (resolved_predictions >= 0)
);
CREATE INDEX IF NOT EXISTS idx_prediction_metrics_window_end
ON prediction_metrics (window_end DESC);
-- ============================================================
-- 4. RETRAIN FLAGS
-- ============================================================
CREATE TABLE IF NOT EXISTS retrain_flags (
id INTEGER PRIMARY KEY AUTOINCREMENT,
model_version TEXT NOT NULL,
triggered_at TIMESTAMP NOT NULL DEFAULT (STRFTIME('%Y-%m-%dT%H:%M:%fZ', 'now')),
metric_window_start DATE NOT NULL,
metric_window_end DATE NOT NULL,
baseline_precision REAL NOT NULL,
current_precision REAL NOT NULL,
deterioration REAL NOT NULL,
deterioration_threshold REAL NOT NULL DEFAULT 0.15,
status TEXT NOT NULL DEFAULT 'PENDING'
CHECK (
status IN (
'PENDING',
'ACKNOWLEDGED',
'RESOLVED',
'IGNORED'
)
),
reason TEXT NOT NULL,
resolved_at TIMESTAMP,
notes TEXT,
CONSTRAINT retrain_flags_window_uq
UNIQUE (model_version, metric_window_start, metric_window_end)
);
CREATE INDEX IF NOT EXISTS idx_retrain_flags_status
ON retrain_flags (status, triggered_at DESC);
-- ============================================================
-- END OF CONSOLIDATED SCHEMA
-- ============================================================
-- ============================================================
-- 5. MARKET DATA REGISTRY AND YFINANCE OHLCV
-- ============================================================
CREATE TABLE IF NOT EXISTS market_tickers (
id INTEGER PRIMARY KEY AUTOINCREMENT,
symbol TEXT NOT NULL UNIQUE,
yfinance_symbol TEXT NOT NULL UNIQUE,
market TEXT NOT NULL CHECK (market IN ('NSE', 'US', 'CONTEXT')),
name TEXT,
industry TEXT,
active BOOLEAN NOT NULL DEFAULT TRUE,
created_at TIMESTAMP NOT NULL DEFAULT (STRFTIME('%Y-%m-%dT%H:%M:%fZ', 'now')),
updated_at TIMESTAMP NOT NULL DEFAULT (STRFTIME('%Y-%m-%dT%H:%M:%fZ', 'now'))
);
CREATE TABLE IF NOT EXISTS market_ohlcv (
ticker_id INTEGER NOT NULL REFERENCES market_tickers(id) ON DELETE CASCADE,
trading_date DATE NOT NULL,
open REAL NOT NULL,
high REAL NOT NULL,
low REAL NOT NULL,
close REAL NOT NULL,
volume INTEGER,
source TEXT NOT NULL DEFAULT 'yfinance',
fetched_at TIMESTAMP NOT NULL DEFAULT (STRFTIME('%Y-%m-%dT%H:%M:%fZ', 'now')),
PRIMARY KEY (ticker_id, trading_date)
);
CREATE INDEX IF NOT EXISTS idx_market_ohlcv_ticker_date
ON market_ohlcv (ticker_id, trading_date DESC);
-- ============================================================
-- 6. MARKET DATA BY DATASET
--
-- The legacy market_ohlcv table remains only as a migration source for an
-- existing installation. New reads and writes use these dataset tables.
-- ============================================================
CREATE TABLE IF NOT EXISTS ohlcv (
ticker_id INTEGER NOT NULL REFERENCES market_tickers(id) ON DELETE CASCADE,
trading_date DATE NOT NULL,
open REAL NOT NULL, high REAL NOT NULL, low REAL NOT NULL, close REAL NOT NULL,
volume INTEGER, source TEXT NOT NULL DEFAULT 'yfinance',
fetched_at TIMESTAMP NOT NULL DEFAULT (STRFTIME('%Y-%m-%dT%H:%M:%fZ', 'now')),
PRIMARY KEY (ticker_id, trading_date)
);
CREATE TABLE IF NOT EXISTS nifty_ohlcv (
ticker_id INTEGER NOT NULL REFERENCES market_tickers(id) ON DELETE CASCADE,
trading_date DATE NOT NULL,
open REAL NOT NULL, high REAL NOT NULL, low REAL NOT NULL, close REAL NOT NULL,
volume INTEGER, source TEXT NOT NULL DEFAULT 'yfinance',
fetched_at TIMESTAMP NOT NULL DEFAULT (STRFTIME('%Y-%m-%dT%H:%M:%fZ', 'now')),
PRIMARY KEY (ticker_id, trading_date)
);
CREATE TABLE IF NOT EXISTS india_vix_ohlcv (
ticker_id INTEGER NOT NULL REFERENCES market_tickers(id) ON DELETE CASCADE,
trading_date DATE NOT NULL,
open REAL NOT NULL, high REAL NOT NULL, low REAL NOT NULL, close REAL NOT NULL,
volume INTEGER, source TEXT NOT NULL DEFAULT 'yfinance',
fetched_at TIMESTAMP NOT NULL DEFAULT (STRFTIME('%Y-%m-%dT%H:%M:%fZ', 'now')),
PRIMARY KEY (ticker_id, trading_date)
);
CREATE TABLE IF NOT EXISTS us_stocks_ohlcv (
ticker_id INTEGER NOT NULL REFERENCES market_tickers(id) ON DELETE CASCADE,
trading_date DATE NOT NULL,
open REAL NOT NULL, high REAL NOT NULL, low REAL NOT NULL, close REAL NOT NULL,
volume INTEGER, source TEXT NOT NULL DEFAULT 'yfinance',
fetched_at TIMESTAMP NOT NULL DEFAULT (STRFTIME('%Y-%m-%dT%H:%M:%fZ', 'now')),
PRIMARY KEY (ticker_id, trading_date)
);
CREATE TABLE IF NOT EXISTS macro_ohlcv (
ticker_id INTEGER NOT NULL REFERENCES market_tickers(id) ON DELETE CASCADE,
macro_type TEXT NOT NULL CHECK (macro_type IN ('gold', 'brent_crude_oil', 'usd_inr')),
trading_date DATE NOT NULL,
open REAL NOT NULL, high REAL NOT NULL, low REAL NOT NULL, close REAL NOT NULL,
volume INTEGER, source TEXT NOT NULL DEFAULT 'yfinance',
fetched_at TIMESTAMP NOT NULL DEFAULT (STRFTIME('%Y-%m-%dT%H:%M:%fZ', 'now')),
PRIMARY KEY (ticker_id, trading_date)
);
CREATE VIEW IF NOT EXISTS all_market_ohlcv AS
SELECT ticker_id, trading_date, open, high, low, close, volume, source, fetched_at FROM ohlcv
UNION ALL SELECT ticker_id, trading_date, open, high, low, close, volume, source, fetched_at FROM nifty_ohlcv
UNION ALL SELECT ticker_id, trading_date, open, high, low, close, volume, source, fetched_at FROM india_vix_ohlcv
UNION ALL SELECT ticker_id, trading_date, open, high, low, close, volume, source, fetched_at FROM us_stocks_ohlcv
UNION ALL SELECT ticker_id, trading_date, open, high, low, close, volume, source, fetched_at FROM macro_ohlcv;
-- Copy legacy data exactly once when upgrading an existing database.
INSERT OR IGNORE INTO ohlcv SELECT o.* FROM market_ohlcv o JOIN market_tickers t ON t.id = o.ticker_id WHERE t.market = 'NSE';
INSERT OR IGNORE INTO nifty_ohlcv SELECT o.* FROM market_ohlcv o JOIN market_tickers t ON t.id = o.ticker_id WHERE t.symbol = 'NIFTY';
INSERT OR IGNORE INTO india_vix_ohlcv SELECT o.* FROM market_ohlcv o JOIN market_tickers t ON t.id = o.ticker_id WHERE t.symbol = 'INDIA_VIX';
INSERT OR IGNORE INTO us_stocks_ohlcv SELECT o.* FROM market_ohlcv o JOIN market_tickers t ON t.id = o.ticker_id WHERE t.market = 'US';
INSERT OR IGNORE INTO macro_ohlcv (ticker_id, macro_type, trading_date, open, high, low, close, volume, source, fetched_at)
SELECT o.ticker_id, CASE t.symbol WHEN 'GOLD' THEN 'gold' WHEN 'BRENT' THEN 'brent_crude_oil' WHEN 'USDINR' THEN 'usd_inr' END,
o.trading_date, o.open, o.high, o.low, o.close, o.volume, o.source, o.fetched_at
FROM market_ohlcv o JOIN market_tickers t ON t.id = o.ticker_id WHERE t.symbol IN ('GOLD', 'BRENT', 'USDINR');
-- Derived feature data lives in Parquet beside this database, under
-- data/db/feature_store (or the equivalent directory for DATABASE_URL).
|