Download algotrader/types.py from ParallelLLC/algorithmic_trading: direct link, hf CLI and curl.
- Browser
- Download file 2.91 kB
-
https://huggingface.co/ParallelLLC/algorithmic_trading/resolve/main/algotrader/types.py
- Command line
-
hf download hf://ParallelLLC/algorithmic_trading/algotrader/types.py
-
curl -L -o types.py https://huggingface.co/ParallelLLC/algorithmic_trading/resolve/main/algotrader/types.py
2.91 kB
| """Core data types shared across the algotrader 2.0 stack. | |
| Everything downstream (engine, validation, UI) speaks these types, so they are | |
| deliberately small, immutable-ish and free of framework dependencies. | |
| """ | |
| from __future__ import annotations | |
| from dataclasses import dataclass, field | |
| from typing import Any, Dict, Optional | |
| import pandas as pd | |
| OHLCV_COLUMNS = ("open", "high", "low", "close", "volume") | |
| class MarketData: | |
| """A validated OHLCV series plus provenance. | |
| Provenance matters here: the app is about honesty, so the UI always tells | |
| the user whether they are looking at real prices or a simulation. | |
| """ | |
| symbol: str | |
| df: pd.DataFrame | |
| source: str # "yfinance" | "bundled" | "synthetic" | |
| interval: str = "1d" | |
| note: str = "" | |
| def is_real(self) -> bool: | |
| return self.source in ("yfinance", "bundled") | |
| def start(self) -> pd.Timestamp: | |
| return self.df.index[0] | |
| def end(self) -> pd.Timestamp: | |
| return self.df.index[-1] | |
| def __len__(self) -> int: # pragma: no cover - trivial | |
| return len(self.df) | |
| class CostModel: | |
| """Round-trip friction. All values are one-way, in basis points.""" | |
| commission_bps: float = 1.0 | |
| slippage_bps: float = 2.0 | |
| short_borrow_bps: float = 50.0 # annualised, charged on short exposure | |
| def one_way_bps(self) -> float: | |
| return self.commission_bps + self.slippage_bps | |
| class BacktestResult: | |
| """Output of a single backtest run.""" | |
| equity: pd.Series | |
| returns: pd.Series # net of costs | |
| gross_returns: pd.Series | |
| position: pd.Series # exposure actually held during each bar | |
| target: pd.Series # exposure requested by the strategy | |
| costs: pd.Series | |
| benchmark_equity: pd.Series | |
| metrics: Dict[str, float] = field(default_factory=dict) | |
| benchmark_metrics: Dict[str, float] = field(default_factory=dict) | |
| meta: Dict[str, Any] = field(default_factory=dict) | |
| def sharpe(self) -> float: | |
| return float(self.metrics.get("sharpe", 0.0)) | |
| def n_trades(self) -> int: | |
| return int(self.metrics.get("n_trades", 0)) | |
| class ValidationReport: | |
| """Everything we know about how much of a backtest is luck.""" | |
| permutation_p_value: Optional[float] = None | |
| permutation_null: Optional[Any] = None # np.ndarray of null Sharpes | |
| deflated_sharpe: Optional[float] = None | |
| probabilistic_sharpe: Optional[float] = None | |
| min_track_record_years: Optional[float] = None | |
| n_trials: int = 1 | |
| pbo: Optional[float] = None | |
| pbo_detail: Dict[str, Any] = field(default_factory=dict) | |
| walkforward: Dict[str, Any] = field(default_factory=dict) | |
| reality_score: float = 0.0 | |
| grade: str = "?" | |
| verdict: str = "" | |
| flags: list = field(default_factory=list) | |