117 lines
3.1 KiB
Python
117 lines
3.1 KiB
Python
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 = []
|