"""Routes for portfolio optimization (HRP, correlation, risk parity).""" from fastapi import APIRouter, HTTPException from pydantic import BaseModel, Field from models import ApiResponse from route_utils import safe import portfolio_service router = APIRouter(prefix="/api/v1/portfolio") class PortfolioOptimizeRequest(BaseModel): symbols: list[str] = Field(..., min_length=1, max_length=50) days: int = Field(default=365, ge=1, le=3650) @router.post("/optimize", response_model=ApiResponse) @safe async def portfolio_optimize(request: PortfolioOptimizeRequest): """Compute HRP optimal weights for a list of symbols.""" try: result = await portfolio_service.optimize_hrp( request.symbols, days=request.days ) except ValueError as exc: raise HTTPException(status_code=400, detail=str(exc)) return ApiResponse(data=result) @router.post("/correlation", response_model=ApiResponse) @safe async def portfolio_correlation(request: PortfolioOptimizeRequest): """Compute correlation matrix for a list of symbols.""" try: result = await portfolio_service.compute_correlation( request.symbols, days=request.days ) except ValueError as exc: raise HTTPException(status_code=400, detail=str(exc)) return ApiResponse(data=result) @router.post("/risk-parity", response_model=ApiResponse) @safe async def portfolio_risk_parity(request: PortfolioOptimizeRequest): """Compute equal risk contribution weights for a list of symbols.""" try: result = await portfolio_service.compute_risk_parity( request.symbols, days=request.days ) except ValueError as exc: raise HTTPException(status_code=400, detail=str(exc)) return ApiResponse(data=result)