99 lines
3.1 KiB
Python
Executable File
99 lines
3.1 KiB
Python
Executable File
"""
|
|
自动化回测服务 - API路由
|
|
"""
|
|
from typing import Optional
|
|
from fastapi import APIRouter, Query
|
|
from .models import (
|
|
BacktestTask,
|
|
BacktestTaskWithId,
|
|
BacktestResult,
|
|
TaskListResponse,
|
|
ApiResponse,
|
|
HealthCheckResponse,
|
|
TaskStatus,
|
|
)
|
|
from .task_queue import task_queue
|
|
from .result_storage import storage
|
|
from .executor import executor
|
|
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
@router.post("/submit", summary="提交回测任务")
|
|
def submit_task(task: BacktestTask) -> ApiResponse[BacktestTaskWithId]:
|
|
"""提交一个新的回测任务"""
|
|
task_with_id = task_queue.submit_task(task)
|
|
storage.save_task(task_with_id)
|
|
return ApiResponse(
|
|
code=0,
|
|
msg="任务提交成功",
|
|
data=task_with_id
|
|
)
|
|
|
|
|
|
@router.get("/list", summary="列出回测任务")
|
|
def list_tasks(
|
|
page: int = Query(1, ge=1, description="页码"),
|
|
page_size: int = Query(10, ge=1, le=100, description="每页数量"),
|
|
status: Optional[str] = Query(None, description="状态过滤 pending/running/completed/failed")
|
|
) -> ApiResponse[TaskListResponse]:
|
|
"""列出回测任务,支持分页和状态过滤"""
|
|
result = task_queue.list_tasks(page, page_size, status)
|
|
return ApiResponse(
|
|
code=0,
|
|
msg="success",
|
|
data=TaskListResponse(**result)
|
|
)
|
|
|
|
|
|
@router.get("/status/{task_id}", summary="查询任务状态")
|
|
def get_status(task_id: str) -> ApiResponse[Optional[BacktestTaskWithId]]:
|
|
"""查询单个任务状态"""
|
|
task = task_queue.get_task(task_id)
|
|
if not task:
|
|
return ApiResponse(code=404, msg="任务不存在", data=None)
|
|
return ApiResponse(code=0, msg="success", data=task)
|
|
|
|
|
|
@router.get("/result/{task_id}", summary="获取回测结果")
|
|
def get_result(task_id: str) -> ApiResponse[Optional[BacktestResult]]:
|
|
"""获取回测完整结果"""
|
|
task = task_queue.get_task(task_id)
|
|
if not task:
|
|
return ApiResponse(code=404, msg="任务不存在", data=None)
|
|
|
|
# 根据状态找结果
|
|
if task.status == TaskStatus.COMPLETED:
|
|
result = storage.load_result(task_id, "completed")
|
|
elif task.status == TaskStatus.FAILED:
|
|
result = storage.load_result(task_id, "failed")
|
|
else:
|
|
result = None
|
|
|
|
return ApiResponse(code=0, msg="success", data=result)
|
|
|
|
|
|
@router.delete("/delete/{task_id}", summary="删除回测任务")
|
|
def delete_task(task_id: str) -> ApiResponse[None]:
|
|
"""删除一个回测任务"""
|
|
# TODO: 实现物理删除
|
|
# 现在只返回成功,后续实现
|
|
return ApiResponse(code=0, msg="删除成功(待实现物理删除)", data=None)
|
|
|
|
|
|
@router.get("/health", summary="健康检查")
|
|
def health_check() -> ApiResponse[HealthCheckResponse]:
|
|
"""服务健康检查,返回任务统计信息"""
|
|
return ApiResponse(
|
|
code=0,
|
|
msg="ok",
|
|
data=HealthCheckResponse(
|
|
pending_count=len(task_queue.pending_tasks),
|
|
running_count=len(task_queue.running_tasks),
|
|
completed_count=len(task_queue.completed_tasks),
|
|
failed_count=len(task_queue.failed_tasks),
|
|
max_workers=task_queue.max_workers
|
|
)
|
|
)
|