galaxis-po/backend/app/schemas/optimizer.py
머니페니 12d235a1f1 feat: add 9 new modules - notification alerts, trading journal, position sizing, pension allocation, drawdown monitoring, benchmark dashboard, tax simulation, correlation analysis, parameter optimizer
Phase 1:
- Real-time signal alerts (Discord/Telegram webhook)
- Trading journal with entry/exit tracking
- Position sizing calculator (Fixed/Kelly/ATR)

Phase 2:
- Pension asset allocation (DC/IRP 70% risk limit)
- Drawdown monitoring with SVG gauge
- Benchmark dashboard (portfolio vs KOSPI vs deposit)

Phase 3:
- Tax benefit simulation (Korean pension tax rules)
- Correlation matrix heatmap
- Parameter optimizer with grid search + overfit detection
2026-03-29 10:03:08 +09:00

87 lines
2.5 KiB
Python

"""
Strategy optimizer schemas.
"""
from datetime import date
from decimal import Decimal
from typing import Annotated, Any, Dict, List, Optional
from pydantic import BaseModel, Field, PlainSerializer
FloatDecimal = Annotated[
Decimal,
PlainSerializer(lambda v: float(v), return_type=float, when_used="json"),
]
# --- Default parameter grids per strategy type ---
KJB_DEFAULT_GRID: Dict[str, List[Any]] = {
"stop_loss_pct": [0.03, 0.05, 0.07],
"target1_pct": [0.05, 0.07, 0.10],
"rs_lookback": [10, 20, 30],
}
MULTI_FACTOR_DEFAULT_GRID: Dict[str, List[Any]] = {
"weights.value": [0.15, 0.25, 0.35],
"weights.quality": [0.15, 0.25, 0.35],
"weights.momentum": [0.15, 0.25, 0.35],
}
QUALITY_DEFAULT_GRID: Dict[str, List[Any]] = {
"min_fscore": [5, 6, 7, 8],
}
VALUE_MOMENTUM_DEFAULT_GRID: Dict[str, List[Any]] = {
"value_weight": [0.3, 0.4, 0.5, 0.6, 0.7],
"momentum_weight": [0.3, 0.4, 0.5, 0.6, 0.7],
}
DEFAULT_GRIDS: Dict[str, Dict[str, List[Any]]] = {
"kjb": KJB_DEFAULT_GRID,
"multi_factor": MULTI_FACTOR_DEFAULT_GRID,
"quality": QUALITY_DEFAULT_GRID,
"value_momentum": VALUE_MOMENTUM_DEFAULT_GRID,
}
STRATEGY_TYPES = ["kjb", "multi_factor", "quality", "value_momentum"]
class OptimizeRequest(BaseModel):
strategy_type: str = Field(
...,
description="Strategy type: kjb, multi_factor, quality, value_momentum",
)
param_grid: Optional[Dict[str, List[Any]]] = Field(
default=None,
description="Parameter grid. If None, uses default preset for the strategy type.",
)
start_date: date
end_date: date
initial_capital: Decimal = Field(default=Decimal("100000000"), gt=0)
commission_rate: Decimal = Field(default=Decimal("0.00015"), ge=0, le=1)
slippage_rate: Decimal = Field(default=Decimal("0.001"), ge=0, le=1)
benchmark: str = Field(default="KOSPI")
top_n: int = Field(default=30, ge=1, le=100)
rank_by: str = Field(
default="sharpe_ratio",
description="Metric to rank results by: sharpe_ratio, cagr, total_return, mdd",
)
class OptimizeResultItem(BaseModel):
rank: int
params: Dict[str, Any]
total_return: FloatDecimal
cagr: FloatDecimal
mdd: FloatDecimal
sharpe_ratio: FloatDecimal
volatility: FloatDecimal
benchmark_return: FloatDecimal
excess_return: FloatDecimal
class OptimizeResponse(BaseModel):
strategy_type: str
total_combinations: int
results: List[OptimizeResultItem]
best_params: Dict[str, Any]