65 lines
2.0 KiB
Python
65 lines
2.0 KiB
Python
"""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())
|