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
68 lines
1.8 KiB
Python
68 lines
1.8 KiB
Python
"""
|
|
Strategy optimizer API router.
|
|
"""
|
|
from fastapi import APIRouter, Depends, HTTPException
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.api.deps import CurrentUser
|
|
from app.core.database import get_db
|
|
from app.schemas.optimizer import (
|
|
DEFAULT_GRIDS,
|
|
STRATEGY_TYPES,
|
|
OptimizeRequest,
|
|
OptimizeResponse,
|
|
)
|
|
from app.services.optimizer import OptimizerService
|
|
|
|
router = APIRouter(prefix="/api/optimizer", tags=["optimizer"])
|
|
|
|
|
|
@router.post("", response_model=OptimizeResponse)
|
|
async def run_optimization(
|
|
request: OptimizeRequest,
|
|
current_user: CurrentUser,
|
|
db: Session = Depends(get_db),
|
|
):
|
|
"""Run grid-search optimization for a strategy."""
|
|
if request.strategy_type not in STRATEGY_TYPES:
|
|
raise HTTPException(
|
|
status_code=400,
|
|
detail=f"Unknown strategy_type: {request.strategy_type}. "
|
|
f"Valid types: {STRATEGY_TYPES}",
|
|
)
|
|
|
|
service = OptimizerService(db)
|
|
try:
|
|
return service.optimize(request)
|
|
except ValueError as e:
|
|
raise HTTPException(status_code=400, detail=str(e))
|
|
|
|
|
|
@router.get("/presets/{strategy_type}")
|
|
async def get_preset(
|
|
strategy_type: str,
|
|
current_user: CurrentUser,
|
|
):
|
|
"""Get default parameter grid preset for a strategy type."""
|
|
if strategy_type not in DEFAULT_GRIDS:
|
|
raise HTTPException(
|
|
status_code=404,
|
|
detail=f"No preset for strategy_type: {strategy_type}",
|
|
)
|
|
return {
|
|
"strategy_type": strategy_type,
|
|
"param_grid": DEFAULT_GRIDS[strategy_type],
|
|
}
|
|
|
|
|
|
@router.get("/presets")
|
|
async def list_presets(
|
|
current_user: CurrentUser,
|
|
):
|
|
"""List all available strategy presets."""
|
|
return {
|
|
"presets": {
|
|
st: DEFAULT_GRIDS[st] for st in STRATEGY_TYPES
|
|
}
|
|
}
|