"""期权复盘(含对冲) SQLite 表.""" from __future__ import annotations import sqlite3 SOURCE_OPTION = "option_spot" SOURCE_PERP_OPTIONS = "perp_options" SOURCE_OPTIONS_OPTIONS = "options_options" SOURCE_TYPES = (SOURCE_OPTION, SOURCE_PERP_OPTIONS, SOURCE_OPTIONS_OPTIONS) def init_options_review_tables(conn: sqlite3.Connection) -> None: conn.execute( """ CREATE TABLE IF NOT EXISTS options_review_trades ( id INTEGER PRIMARY KEY AUTOINCREMENT, source_type TEXT NOT NULL, history_key TEXT NOT NULL UNIQUE, underlying TEXT, opened_at TEXT, closed_at TEXT, hold_seconds INTEGER, realized_pnl_total REAL, status_raw TEXT, synced_at TEXT, -- 纯期权 pos_id TEXT, inst_id TEXT, opt_type TEXT, strike REAL, exp_time TEXT, sheets INTEGER, open_avg REAL, close_avg REAL, premium_paid REAL, realized_pnl REAL, -- 对冲计划 hedge_plan_id INTEGER, plan_close_reason TEXT, realized_pnl_perp REAL, realized_pnl_options REAL, premium_total REAL, direction TEXT, tp REAL, sl REAL, target_price REAL, target_price_up REAL, target_price_down REAL, legs_json TEXT, -- 双计防护:纯期权腿已归属对冲计划 linked_hedge_plan_id INTEGER, excluded_as_hedge_leg INTEGER DEFAULT 0 ) """ ) conn.execute( """ CREATE UNIQUE INDEX IF NOT EXISTS idx_options_review_trades_history_key ON options_review_trades(history_key) """ ) conn.execute( """ CREATE UNIQUE INDEX IF NOT EXISTS idx_options_review_trades_hedge_plan ON options_review_trades(hedge_plan_id) WHERE hedge_plan_id IS NOT NULL """ ) conn.execute( """ CREATE INDEX IF NOT EXISTS idx_options_review_trades_closed ON options_review_trades(closed_at) """ ) conn.execute( """ CREATE INDEX IF NOT EXISTS idx_options_review_trades_source ON options_review_trades(source_type) """ ) conn.execute( """ CREATE TABLE IF NOT EXISTS options_review_entries ( id INTEGER PRIMARY KEY AUTOINCREMENT, trade_id INTEGER NOT NULL UNIQUE, strategy_tag TEXT, direction_view TEXT, entry_logic TEXT, exit_reason TEXT, followed_plan TEXT, mistake_tags TEXT, result_tag TEXT, note TEXT, images_json TEXT, image TEXT, reviewed_at TEXT, updated_at TEXT, FOREIGN KEY(trade_id) REFERENCES options_review_trades(id) ) """ ) conn.execute( """ CREATE TABLE IF NOT EXISTS options_review_sync_state ( key TEXT PRIMARY KEY, value TEXT, updated_at TEXT ) """ ) conn.execute( """ CREATE TABLE IF NOT EXISTS options_review_hidden ( history_key TEXT PRIMARY KEY, inst_id TEXT, closed_at TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) """ ) conn.execute( """ CREATE INDEX IF NOT EXISTS idx_options_review_hidden_inst ON options_review_hidden(inst_id, closed_at) """ ) _ensure_column(conn, "options_review_trades", "linked_hedge_plan_id", "INTEGER") _ensure_column(conn, "options_review_trades", "excluded_as_hedge_leg", "INTEGER DEFAULT 0") _ensure_column(conn, "options_review_trades", "target_price_up", "REAL") _ensure_column(conn, "options_review_trades", "target_price_down", "REAL") _ensure_column(conn, "options_review_trades", "profit_rr", "REAL") _ensure_column(conn, "options_review_trades", "premium_ccy", "TEXT") _ensure_column(conn, "options_review_trades", "pnl_quote_ccy", "TEXT") _ensure_column(conn, "options_review_trades", "idx_px", "REAL") def _ensure_column(conn: sqlite3.Connection, table: str, col: str, typedef: str) -> None: rows = conn.execute(f"PRAGMA table_info({table})").fetchall() names: set[str] = set() for r in rows: try: names.add(str(r["name"])) except (TypeError, KeyError, IndexError): names.add(str(r[1])) if col not in names: conn.execute(f"ALTER TABLE {table} ADD COLUMN {col} {typedef}")