from __future__ import annotations from dataclasses import dataclass, field from typing import List, Dict, Any, Optional from datetime import datetime @dataclass class Asset: # Accept legacy and newer naming conventions used across tests id: Optional[str] = None type: Optional[str] = None # e.g., "equity", "option" symbol: Optional[str] = None asset_class: Optional[str] = None # alias for type venue: Optional[str] = None asset_type: Optional[str] = None # legacy alias for type def __post_init__(self): # If asset_class is provided but type is not, map it to type if self.asset_class is not None and self.type is None: self.type = self.asset_class # Backward-compatible alias: asset_type maps to type if self.asset_type is not None and self.type is None: self.type = self.asset_type @dataclass class MarketSignal: asset: Asset timestamp: float | int price: float confidence: float = 0.0 source: str = "unknown" @dataclass class SharedSignals: version: int signals: List[MarketSignal] privacy_tag: str = "public" @dataclass class LocalArbProblem: id: str venue: str assets: List[Asset] objective: str # e.g., "delta-hedge", "calendar-spread" constraints: Dict[str, Any] = field(default_factory=dict) solver_hint: Optional[str] = None @dataclass class PlanDelta: # Backwards/forwards compatibility: some code uses "deltas" (list of StrategyDelta), # some uses "delta" (list of dicts). Support both and keep them in sync. deltas: Optional[List[Any]] = None delta: Optional[List[Any]] = None timestamp: float | int = 0.0 author: Optional[str] = None contract_id: Optional[str] = None actions: List[Any] = field(default_factory=list) dual_vars: Dict[str, Any] = field(default_factory=dict) safety_tags: List[str] = field(default_factory=list) def __post_init__(self): # synchronize the two representations if self.deltas is None and self.delta is not None: self.deltas = self.delta if self.delta is None and self.deltas is not None: self.delta = self.deltas if self.deltas is None: self.deltas = [] if self.delta is None: self.delta = self.deltas @dataclass class DualVariables: multipliers: Dict[str, float] @dataclass class PrivacyBudget: budget: float expiry: float | int leakage_bound: float @dataclass class AuditLog: entry: str signer: str timestamp: float | int contract_id: str version: int @dataclass class PolicyBlock: safety: str exposure_controls: Dict[str, Any] = field(default_factory=dict) @dataclass class StrategyDelta: """Represents a concrete strategy delta to be aggregated by the coordinator.""" id: Optional[str] = None assets: List[Asset] = field(default_factory=list) delta_positions: Optional[Dict[str, float]] = None objectives: Optional[Dict[str, Any]] = None notes: str = "" # Convenience alias for tests that use delta_positions def __post_init__(self): if self.assets is None: self.assets = []