feat: cycle
This commit is contained in:
@@ -169,6 +169,23 @@ def init_db():
|
||||
"ALTER TABLE wavelet_watchlist_signals ADD COLUMN energy REAL",
|
||||
"ALTER TABLE wavelet_watchlist_signals ADD COLUMN ridge_period_days REAL",
|
||||
"ALTER TABLE wavelet_watchlist_signals ADD COLUMN params_json TEXT",
|
||||
# Cycle Actions — standalone "refresh-price-data" action, OHLCV cache
|
||||
"""CREATE TABLE IF NOT EXISTS price_data_cache (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
ticker TEXT NOT NULL,
|
||||
date TEXT NOT NULL,
|
||||
open REAL, high REAL, low REAL, close REAL, volume REAL,
|
||||
cached_at TEXT DEFAULT (datetime('now')),
|
||||
UNIQUE(ticker, date)
|
||||
)""",
|
||||
# Cycle Actions — standalone "compute-indicators" action, one row per call per ticker
|
||||
"""CREATE TABLE IF NOT EXISTS instrument_indicators (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
ticker TEXT NOT NULL,
|
||||
computed_at TEXT DEFAULT (datetime('now')),
|
||||
horizon_days INTEGER,
|
||||
indicators_json TEXT DEFAULT '{}'
|
||||
)""",
|
||||
]:
|
||||
try:
|
||||
c.execute(_sql)
|
||||
@@ -183,6 +200,14 @@ def init_db():
|
||||
c.execute("CREATE INDEX IF NOT EXISTS idx_atp_session_status ON ai_trade_proposals(session_id, status)")
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
c.execute("CREATE INDEX IF NOT EXISTS idx_pdc_ticker_date ON price_data_cache(ticker, date DESC)")
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
c.execute("CREATE INDEX IF NOT EXISTS idx_ii_ticker_date ON instrument_indicators(ticker, computed_at DESC)")
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
try:
|
||||
c.execute("CREATE INDEX IF NOT EXISTS idx_chat_session_date ON ai_chat_messages(session_id, created_at)")
|
||||
@@ -3441,6 +3466,72 @@ def resolve_ai_trade_proposal(proposal_id: str, status: str, portfolio_id: Optio
|
||||
conn.close()
|
||||
|
||||
|
||||
# ── Cycle Actions — standalone price data cache + indicator snapshots ──────────
|
||||
|
||||
def upsert_price_data(ticker: str, rows: List[Dict[str, Any]]) -> int:
|
||||
"""rows: [{date, open, high, low, close, volume}, ...]. Returns rows written."""
|
||||
if not rows:
|
||||
return 0
|
||||
conn = get_conn()
|
||||
n = 0
|
||||
for r in rows:
|
||||
conn.execute(
|
||||
"""INSERT INTO price_data_cache (ticker, date, open, high, low, close, volume, cached_at)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, datetime('now'))
|
||||
ON CONFLICT(ticker, date) DO UPDATE SET
|
||||
open=excluded.open, high=excluded.high, low=excluded.low,
|
||||
close=excluded.close, volume=excluded.volume, cached_at=excluded.cached_at""",
|
||||
(ticker.upper(), r.get("date"), r.get("open"), r.get("high"), r.get("low"), r.get("close"), r.get("volume")),
|
||||
)
|
||||
n += 1
|
||||
conn.commit()
|
||||
conn.close()
|
||||
return n
|
||||
|
||||
|
||||
def get_cached_price_data(ticker: str, limit: int = 90) -> List[Dict[str, Any]]:
|
||||
conn = get_conn()
|
||||
rows = conn.execute(
|
||||
"SELECT * FROM price_data_cache WHERE ticker=? ORDER BY date DESC LIMIT ?",
|
||||
(ticker.upper(), limit),
|
||||
).fetchall()
|
||||
conn.close()
|
||||
return [dict(r) for r in rows]
|
||||
|
||||
|
||||
def save_instrument_indicators(ticker: str, horizon_days: int, indicators: Dict[str, Any]) -> None:
|
||||
conn = get_conn()
|
||||
conn.execute(
|
||||
"INSERT INTO instrument_indicators (ticker, horizon_days, indicators_json) VALUES (?, ?, ?)",
|
||||
(ticker.upper(), horizon_days, json.dumps(indicators)),
|
||||
)
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
|
||||
def get_latest_instrument_indicators() -> List[Dict[str, Any]]:
|
||||
"""Most recent indicators row per ticker."""
|
||||
conn = get_conn()
|
||||
rows = conn.execute(
|
||||
"""SELECT i.* FROM instrument_indicators i
|
||||
INNER JOIN (
|
||||
SELECT ticker, MAX(computed_at) AS max_computed_at
|
||||
FROM instrument_indicators GROUP BY ticker
|
||||
) latest ON i.ticker = latest.ticker AND i.computed_at = latest.max_computed_at
|
||||
ORDER BY i.ticker"""
|
||||
).fetchall()
|
||||
conn.close()
|
||||
out = []
|
||||
for r in rows:
|
||||
d = dict(r)
|
||||
try:
|
||||
d["indicators"] = json.loads(d.pop("indicators_json") or "{}")
|
||||
except Exception:
|
||||
d["indicators"] = {}
|
||||
out.append(d)
|
||||
return out
|
||||
|
||||
|
||||
# ── System Logs ───────────────────────────────────────────────────────────────
|
||||
|
||||
def log_system_event(
|
||||
|
||||
Reference in New Issue
Block a user