Spaces:
Build error
Build error
| """LRU scenario cache keyed by state hash. | |
| Caches simulation results to avoid recomputing identical | |
| or near-identical market states within the same event window. | |
| """ | |
| from __future__ import annotations | |
| import hashlib | |
| import json | |
| import time | |
| from collections import OrderedDict | |
| from dataclasses import dataclass, field | |
| from typing import Any, Dict, List, Optional | |
| class CachedScenario: | |
| """A cached simulation result.""" | |
| state_hash: str | |
| branches: List[List[Dict[str, float]]] | |
| scores: List[float] | |
| expected_value: float | |
| var_95: float | |
| timestamp: float = field(default_factory=time.time) | |
| hit_count: int = 0 | |
| class ScenarioCache: | |
| """LRU cache for simulation results. | |
| Keyed by a hash of the market state vector. Evicts least | |
| recently used entries when capacity is exceeded. | |
| """ | |
| def __init__(self, capacity: int = 1024, ttl_seconds: float = 300.0): | |
| self.capacity = capacity | |
| self.ttl = ttl_seconds | |
| self._cache: OrderedDict[str, CachedScenario] = OrderedDict() | |
| self._hits = 0 | |
| self._misses = 0 | |
| def state_hash(self, state: Dict[str, Any]) -> str: | |
| """Compute deterministic hash of a market state.""" | |
| serialized = json.dumps(state, sort_keys=True, default=str) | |
| return hashlib.sha256(serialized.encode()).hexdigest()[:16] | |
| def get(self, state: Dict[str, Any]) -> Optional[CachedScenario]: | |
| """Retrieve cached scenario, or None on miss.""" | |
| h = self.state_hash(state) | |
| if h in self._cache: | |
| entry = self._cache[h] | |
| if time.time() - entry.timestamp > self.ttl: | |
| del self._cache[h] | |
| self._misses += 1 | |
| return None | |
| self._cache.move_to_end(h) | |
| entry.hit_count += 1 | |
| self._hits += 1 | |
| return entry | |
| self._misses += 1 | |
| return None | |
| def put(self, state: Dict[str, Any], scenario: CachedScenario) -> None: | |
| """Store a scenario result.""" | |
| h = self.state_hash(state) | |
| scenario.state_hash = h | |
| if h in self._cache: | |
| self._cache.move_to_end(h) | |
| self._cache[h] = scenario | |
| while len(self._cache) > self.capacity: | |
| self._cache.popitem(last=False) | |
| def hit_rate(self) -> float: | |
| total = self._hits + self._misses | |
| return self._hits / total if total > 0 else 0.0 | |
| def clear(self) -> None: | |
| self._cache.clear() | |
| self._hits = 0 | |
| self._misses = 0 | |