"""Core data contracts for BeVault.""" from __future__ import annotations import json import time from dataclasses import asdict, dataclass, field from typing import Any, Dict, List, Optional @dataclass class LocalArbProblem: asset: str objective: str # e.g., 'min_cost', 'maximize_profit' risk_budget: float constraints: Dict[str, Any] = field(default_factory=dict) def validate(self) -> None: if not self.asset: raise ValueError("asset is required") if self.risk_budget < 0: raise ValueError("risk_budget must be non-negative") def to_dict(self) -> Dict[str, Any]: return asdict(self) @dataclass class SharedSignals: asset: str price: float latency_ms: float timestamp: float = field(default_factory=lambda: time.time()) metadata: Dict[str, Any] = field(default_factory=dict) def to_dict(self) -> Dict[str, Any]: return asdict(self) def is_fresh(self, max_age_seconds: float, now: Optional[float] = None) -> bool: now = time.time() if now is None else now return (now - self.timestamp) <= max_age_seconds @dataclass class HedgeDelta: asset: str hedge_size: float timestamp: float = field(default_factory=lambda: time.time()) policy_tag: str = "default" signature: Optional[str] = None version_vector: Dict[str, int] = field(default_factory=dict) audit_ref: Optional[str] = None def to_signable_dict(self) -> Dict[str, Any]: return { "asset": self.asset, "hedge_size": self.hedge_size, "timestamp": self.timestamp, "policy_tag": self.policy_tag, "version_vector": self.version_vector, "audit_ref": self.audit_ref, } def to_json(self) -> str: return json.dumps(self.to_signable_dict(), sort_keys=True, separators=(",", ":")) @dataclass class AuditLog: events: List[Dict[str, Any]] = field(default_factory=list) entry_ts: float = field(default_factory=lambda: time.time()) def record(self, event_type: str, payload: Optional[Dict[str, Any]] = None) -> None: self.events.append( { "event_type": event_type, "payload": payload or {}, "timestamp": time.time(), } ) @dataclass class PrivacyBudget: asset: str remaining: float reset_epoch: float = field(default_factory=lambda: time.time()) def consume(self, amount: float) -> bool: if amount < 0: raise ValueError("amount must be non-negative") if amount > self.remaining: return False self.remaining -= amount return True __all__ = [ "LocalArbProblem", "SharedSignals", "HedgeDelta", "AuditLog", "PrivacyBudget", # Toy DSL seed helper (MVP utility) "generate_toy_seed", ] def generate_toy_seed(asset: str = "AAPL", price: float = 100.0): """Generate a minimal toy DSL seed pair for MVP testing. Returns a tuple of (LocalArbProblem, SharedSignals) suitable for driving a toy cross-venue hedge scenario and deterministic delta-sync tests without requiring real market data. This helper is intentionally lightweight and is meant for local testing and documentation purposes within the MVP boundaries. """ local = LocalArbProblem( asset=asset, objective="min_cost", risk_budget=float(price) * 0.1, constraints={}, ) signals = SharedSignals( asset=asset, price=price, latency_ms=0.5, timestamp=time.time(), metadata={"toy_seed": True}, ) return local, signals