from __future__ import annotations from typing import Any, Dict, List from datetime import datetime, timezone import threading class DecisionStore: def __init__(self) -> None: self._lock = threading.Lock() self._items: List[Dict[str, Any]] = [] def add(self, item: Dict[str, Any]) -> None: with self._lock: self._items.append(item) if len(self._items) > 1000: # keep last 1000 self._items = self._items[-1000:] def latest(self, limit: int = 50) -> List[Dict[str, Any]]: with self._lock: return list(reversed(self._items[-limit:])) # singleton store store = DecisionStore() def log_decision( *, symbol: str, timeframe: str, style: str, recommendation: str, confidence: float, risk_level: str, rationale: str, inputs_hash: str | None = None, cost: Dict[str, Any] | None = None, ) -> Dict[str, Any]: now = datetime.now(timezone.utc).isoformat() item = { "id": f"dec_{int(datetime.now(timezone.utc).timestamp()*1000)}", "time": now, "symbol": symbol, "timeframe": timeframe, "style": style, "recommendation": recommendation, "confidence": confidence, "risk_level": risk_level, "rationale": rationale, "inputs_hash": inputs_hash, "cost": cost or {}, } store.add(item) return item