ttzzs's picture
Deploy Chronos2 Forecasting API v3.0.0 with new SOLID architecture
c40c447 verified
"""
Backtesting API endpoints.
Responsabilidad: Manejar requests de backtesting (evaluaci贸n de modelos).
"""
from fastapi import APIRouter, Depends, HTTPException, status
from app.api.dependencies import get_backtest_use_case
from app.application.use_cases.backtest_use_case import BacktestUseCase
from app.application.dtos.backtest_dtos import (
BacktestRequestDTO,
BacktestResponseDTO
)
from app.utils.logger import setup_logger
logger = setup_logger(__name__)
router = APIRouter(prefix="/backtest", tags=["Backtesting"])
@router.post(
"/simple",
response_model=BacktestResponseDTO,
status_code=status.HTTP_200_OK,
summary="Backtesting simple",
description="Eval煤a pron贸stico comparando con valores reales"
)
async def backtest_simple(
request: BacktestRequestDTO,
use_case: BacktestUseCase = Depends(get_backtest_use_case)
):
"""
Backtesting simple (hold-out).
Divide la serie en train/test, genera pron贸stico con train,
y compara con test para calcular m茅tricas de error.
Args:
request: Serie completa y par谩metros de backtesting
use_case: Caso de uso inyectado
Returns:
M茅tricas de error (MAE, MAPE, RMSE) y comparaci贸n forecast vs actual
Example:
```json
{
"full_series": [100, 102, 105, 103, 108, 112, 115, 118],
"test_size": 3,
"freq": "D",
"quantile_levels": [0.1, 0.5, 0.9]
}
```
"""
try:
logger.info(
f"Backtest request: {len(request.full_series)} values, "
f"test_size={request.test_size}"
)
# Ejecutar use case
response = use_case.execute(request)
logger.info(
f"Backtest completed: MAE={response.metrics.mae:.2f}, "
f"MAPE={response.metrics.mape:.2f}%"
)
return response
except ValueError as e:
logger.error(f"Validation error: {e}")
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=str(e)
)
except Exception as e:
logger.error(f"Unexpected error in backtest: {e}", exc_info=True)
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Error interno en backtesting"
)