"""Bar Replay API(M9-6):POST /api/replays —— 线性重放选股/信号时间线。""" from __future__ import annotations from datetime import date from fastapi import APIRouter, HTTPException from pydantic import BaseModel, Field from app.api.deps import ReplayServiceDep from app.domain.entities.replay import ReplayResult from app.domain.entities.selection import SelectionQuery from app.domain.entities.signal import SignalRules router = APIRouter(prefix="/replays", tags=["replays"]) class ReplayRequest(BaseModel): query: SelectionQuery rules: SignalRules = SignalRules() start: date end: date top_n: int = Field(default=5, ge=1, le=20) @router.post("", response_model=ReplayResult, summary="线性重放(as_of 逐日,仅用当时数据)") def run_replay(req: ReplayRequest, service: ReplayServiceDep) -> ReplayResult: if req.start >= req.end: raise HTTPException(status_code=400, detail="start 必须早于 end") try: return service.replay(req.query, req.rules, req.start, req.end, req.top_n) except ValueError as exc: raise HTTPException(status_code=400, detail=str(exc)) from exc