You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
106 lines
3.0 KiB
Python
106 lines
3.0 KiB
Python
"""SQLite table definitions for the paper trading system."""
|
|
from __future__ import annotations
|
|
|
|
import sqlite3
|
|
from pathlib import Path
|
|
|
|
SCHEMA_SQL = """
|
|
CREATE TABLE IF NOT EXISTS sessions (
|
|
session_id TEXT PRIMARY KEY,
|
|
session_name TEXT NOT NULL,
|
|
config_path TEXT NOT NULL,
|
|
initial_equity REAL NOT NULL,
|
|
created_at TEXT NOT NULL,
|
|
status TEXT NOT NULL DEFAULT 'active'
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS strategy_states (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
session_id TEXT NOT NULL REFERENCES sessions(session_id),
|
|
symbol TEXT NOT NULL,
|
|
event_id TEXT NOT NULL,
|
|
engine_id TEXT NOT NULL DEFAULT 'default',
|
|
order_id TEXT,
|
|
entry_date TEXT NOT NULL,
|
|
stop_price REAL NOT NULL,
|
|
target_price REAL NOT NULL,
|
|
current_stop REAL NOT NULL,
|
|
peak_price REAL NOT NULL,
|
|
days_held INTEGER NOT NULL DEFAULT 0,
|
|
trade_direction TEXT NOT NULL DEFAULT 'long',
|
|
candidate_json TEXT NOT NULL,
|
|
plan_json TEXT NOT NULL,
|
|
status TEXT NOT NULL DEFAULT 'open',
|
|
UNIQUE(session_id, symbol, status)
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS session_state (
|
|
session_id TEXT PRIMARY KEY REFERENCES sessions(session_id),
|
|
consecutive_losses INTEGER NOT NULL DEFAULT 0,
|
|
cooldown_remaining INTEGER NOT NULL DEFAULT 0,
|
|
kill_switch_triggered INTEGER NOT NULL DEFAULT 0,
|
|
daily_new_risk_used REAL NOT NULL DEFAULT 0.0,
|
|
last_processed_date TEXT
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS processed_events (
|
|
session_id TEXT NOT NULL,
|
|
event_id TEXT NOT NULL,
|
|
processed_date TEXT NOT NULL,
|
|
action TEXT NOT NULL,
|
|
skip_reason TEXT,
|
|
PRIMARY KEY (session_id, event_id)
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS trades (
|
|
trade_id TEXT PRIMARY KEY,
|
|
session_id TEXT NOT NULL,
|
|
symbol TEXT NOT NULL,
|
|
entry_date TEXT,
|
|
exit_date TEXT,
|
|
entry_price REAL,
|
|
exit_price REAL,
|
|
exit_reason TEXT,
|
|
shares INTEGER,
|
|
net_pnl REAL,
|
|
r_multiple REAL,
|
|
holding_days INTEGER
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS daily_snapshots (
|
|
session_id TEXT NOT NULL,
|
|
date TEXT NOT NULL,
|
|
equity REAL NOT NULL,
|
|
cash REAL NOT NULL,
|
|
market_value REAL NOT NULL,
|
|
daily_pnl REAL,
|
|
total_pnl REAL,
|
|
drawdown_pct REAL,
|
|
open_position_count INTEGER,
|
|
PRIMARY KEY (session_id, date)
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS processed_dates (
|
|
session_id TEXT NOT NULL,
|
|
date TEXT NOT NULL,
|
|
PRIMARY KEY (session_id, date)
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS processed_phases (
|
|
session_id TEXT NOT NULL,
|
|
date TEXT NOT NULL,
|
|
phase TEXT NOT NULL,
|
|
PRIMARY KEY (session_id, date, phase)
|
|
);
|
|
"""
|
|
|
|
|
|
def create_schema(db_path: str | Path) -> None:
|
|
"""Initialize the SQLite database with the paper trading schema."""
|
|
conn = sqlite3.connect(str(db_path))
|
|
try:
|
|
conn.executescript(SCHEMA_SQL)
|
|
conn.commit()
|
|
finally:
|
|
conn.close()
|