47 lines
1.3 KiB
Python
47 lines
1.3 KiB
Python
from __future__ import annotations
|
|
from dataclasses import dataclass, field
|
|
from typing import Dict, List
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class Asset:
|
|
symbol: str # e.g., AAPL, SPY, ES
|
|
asset_class: str # e.g., equity, option, future
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class MarketSignal:
|
|
asset: Asset
|
|
price: float
|
|
timestamp: float # epoch seconds
|
|
|
|
|
|
@dataclass
|
|
class StrategyDelta:
|
|
# Simple representation of target changes in positions
|
|
delta_positions: Dict[str, float] # symbol -> target share/contract delta
|
|
cash_delta: float = 0.0
|
|
notes: str = ""
|
|
|
|
def validate(self) -> bool:
|
|
# basic sanity: keys exist and values are finite numbers
|
|
try:
|
|
for k, v in self.delta_positions.items():
|
|
if not isinstance(k, str) or not isinstance(v, (int, float)):
|
|
return False
|
|
return True
|
|
except Exception:
|
|
return False
|
|
|
|
|
|
@dataclass
|
|
class PlanDelta:
|
|
# A plan composed of a sequence of actions to reach target deltas
|
|
actions: List[str] = field(default_factory=list)
|
|
deltas: List[StrategyDelta] = field(default_factory=list)
|
|
# Simple, fake signature placeholder for tamper-evidence in MVP
|
|
signature: str = ""
|
|
|
|
def add_action(self, action: str) -> None:
|
|
self.actions.append(action)
|