"""Indicators router — technical analysis endpoints.""" from datetime import date from fastapi import APIRouter, Depends, Query from sqlalchemy.ext.asyncio import AsyncSession from app.dependencies import get_db, require_access from app.schemas.common import APIEnvelope from app.schemas.indicator import ( EMACrossResponse, EMACrossResult, IndicatorResponse, IndicatorResult, ) from app.services.indicator_service import get_ema_cross, get_indicator router = APIRouter(tags=["indicators"]) # NOTE: ema-cross must be registered BEFORE {indicator_type} to avoid # FastAPI matching "ema-cross" as an indicator_type path parameter. @router.get("/indicators/{symbol}/ema-cross", response_model=APIEnvelope) async def read_ema_cross( symbol: str, start_date: date | None = Query(None), end_date: date | None = Query(None), short_period: int = Query(20), long_period: int = Query(50), _user=Depends(require_access), db: AsyncSession = Depends(get_db), ) -> APIEnvelope: """Compute EMA cross signal for a symbol.""" result = await get_ema_cross( db, symbol, start_date, end_date, short_period, long_period ) data = EMACrossResponse( symbol=symbol.upper(), ema_cross=EMACrossResult(**result), ) return APIEnvelope(status="success", data=data.model_dump()) @router.get("/indicators/{symbol}/{indicator_type}", response_model=APIEnvelope) async def read_indicator( symbol: str, indicator_type: str, start_date: date | None = Query(None), end_date: date | None = Query(None), period: int | None = Query(None), _user=Depends(require_access), db: AsyncSession = Depends(get_db), ) -> APIEnvelope: """Compute a technical indicator for a symbol.""" result = await get_indicator( db, symbol, indicator_type, start_date, end_date, period ) data = IndicatorResponse( symbol=symbol.upper(), indicator=IndicatorResult(**result), ) return APIEnvelope(status="success", data=data.model_dump())