Files
Trading-Bot/src/web/api/v2/schemas/calibration_strategies.py

80 lines
1.9 KiB
Python

# src/web/api/v2/schemas/calibration_strategies.py
from typing import Any, Dict, List, Literal, Optional, Union
from pydantic import BaseModel, Field
from .calibration_risk import StopConfigSchema, RiskConfigSchema, GlobalRiskRulesSchema
ParameterValue = Union[int, float, bool, str]
class WalkForwardConfigSchema(BaseModel):
train_days: int = Field(..., gt=0)
test_days: int = Field(..., gt=0)
step_days: Optional[int] = Field(None, gt=0)
min_trades_test: int = Field(10, ge=0)
class StrategySelectionSchema(BaseModel):
strategy_id: str
parameters: Dict[str, ParameterValue]
class CalibrationStrategiesInspectRequest(BaseModel):
symbol: str
timeframe: str
# snapshot from Step 2 (closed)
stop: StopConfigSchema
risk: RiskConfigSchema
global_rules: GlobalRiskRulesSchema
account_equity: float = Field(..., gt=0)
strategies: List[StrategySelectionSchema]
wf: WalkForwardConfigSchema
commission: float = Field(0.001, ge=0)
slippage: float = Field(0.0005, ge=0)
class WindowRowSchema(BaseModel):
window: int
train_start: str
train_end: str
test_start: str
test_end: str
return_pct: float
sharpe: float
max_dd_pct: float
trades: int
params: Dict[str, Any]
class StrategyRunResultSchema(BaseModel):
strategy_id: str
status: Literal["ok", "warning", "fail"]
message: str
n_windows: int
oos_final_equity: float
oos_total_return_pct: float
oos_max_dd_worst_pct: float
degradation_sharpe: Optional[float] = None
windows: List[WindowRowSchema]
class CalibrationStrategiesInspectResponse(BaseModel):
valid: bool
status: Literal["ok", "warning", "fail"]
checks: Dict[str, Any]
message: str
results: List[StrategyRunResultSchema]
class CalibrationStrategiesValidateResponse(CalibrationStrategiesInspectResponse):
series: Dict[str, Any]