76 lines
2.2 KiB
Python
76 lines
2.2 KiB
Python
"""SQLite schema(可迁移设计)。时间戳存 UTC ms。"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import sqlite3
|
|
from pathlib import Path
|
|
|
|
SCHEMA_SQL = """
|
|
CREATE TABLE IF NOT EXISTS option_quotes (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
ts_ms INTEGER NOT NULL,
|
|
exchange TEXT NOT NULL,
|
|
underlying TEXT NOT NULL,
|
|
inst_id TEXT NOT NULL,
|
|
expiry_ymd TEXT NOT NULL,
|
|
strike REAL NOT NULL,
|
|
side TEXT NOT NULL,
|
|
index_px REAL NOT NULL,
|
|
ask REAL,
|
|
bid REAL,
|
|
ask_sz REAL,
|
|
bid_sz REAL,
|
|
leverage REAL,
|
|
created_at_ms INTEGER NOT NULL
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_oq_ts ON option_quotes(ts_ms);
|
|
CREATE INDEX IF NOT EXISTS idx_oq_side_ts ON option_quotes(side, ts_ms);
|
|
CREATE INDEX IF NOT EXISTS idx_oq_expiry ON option_quotes(expiry_ymd);
|
|
|
|
CREATE TABLE IF NOT EXISTS index_ticks (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
ts_ms INTEGER NOT NULL,
|
|
exchange TEXT NOT NULL,
|
|
underlying TEXT NOT NULL,
|
|
index_px REAL NOT NULL,
|
|
created_at_ms INTEGER NOT NULL
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_it_ts ON index_ticks(ts_ms);
|
|
CREATE INDEX IF NOT EXISTS idx_it_u_ts ON index_ticks(underlying, ts_ms);
|
|
|
|
CREATE TABLE IF NOT EXISTS expiry_settlements (
|
|
expiry_ymd TEXT PRIMARY KEY,
|
|
settle_ts_ms INTEGER NOT NULL,
|
|
settle_index_px REAL NOT NULL,
|
|
exchange TEXT NOT NULL,
|
|
underlying TEXT NOT NULL,
|
|
created_at_ms INTEGER NOT NULL
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS collector_heartbeat (
|
|
id INTEGER PRIMARY KEY CHECK (id = 1),
|
|
last_ok_ts_ms INTEGER,
|
|
last_error TEXT,
|
|
last_error_ts_ms INTEGER,
|
|
consecutive_failures INTEGER NOT NULL DEFAULT 0,
|
|
meta_json TEXT
|
|
);
|
|
"""
|
|
|
|
|
|
def init_db(db_path: str | Path) -> sqlite3.Connection:
|
|
path = Path(db_path)
|
|
path.parent.mkdir(parents=True, exist_ok=True)
|
|
conn = sqlite3.connect(str(path), check_same_thread=False)
|
|
conn.row_factory = sqlite3.Row
|
|
conn.execute("PRAGMA journal_mode=WAL;")
|
|
conn.execute("PRAGMA synchronous=NORMAL;")
|
|
conn.executescript(SCHEMA_SQL)
|
|
conn.execute(
|
|
"INSERT OR IGNORE INTO collector_heartbeat (id, consecutive_failures) VALUES (1, 0)"
|
|
)
|
|
conn.commit()
|
|
return conn
|