96b1924fd5
[live] 实盘模拟 vnpy+miniQMT 直连(supervisor 轮询, 前后端): - sanguo_live: LiveTradingEngine + AShareCtaTemplate(定寸/禁做空) + runner_supervisor(DB驱动) + persistence(4表WAL) - sanguo_api/routes_live: 9路由(create/start/stop/positions/trades/account/status) - frontend live: New/List/Monitor + api/live.ts; config/live.yaml [portfolio] 组合回测 MVP(BulletTrade, 链路代码完成待验证): - runner_backtest 加 JSON 入口(--json, BacktestEngine 顶层 import) - sanguo_api/routes_portfolio: POST /portfolio/backtest SSH 触发 VPS 跑 - frontend PortfolioBacktest.vue + api/portfolio.ts: 表单+结果+净值曲线 - 路由/菜单注册(/backtest/portfolio 组合回测) - 已知: MVP 链路未端到端验证, agent 改至中途被停; 待 Mac 起服务联调
55 lines
2.1 KiB
Python
55 lines
2.1 KiB
Python
"""
|
||
FastAPI application factory for Sanguo Quant API
|
||
"""
|
||
from fastapi import FastAPI
|
||
from .routes import router, set_orchestrator, set_auth_config
|
||
from .routes_paper import router as paper_router, set_db_path as set_paper_db_path
|
||
from .routes_live import router as live_router, set_db_path as set_live_db_path
|
||
from .routes_portfolio import router as portfolio_router
|
||
from .auth import set_jwt_config
|
||
from .ws import manager
|
||
from sanguo_orchestrator.runner import Orchestrator
|
||
|
||
|
||
def create_app(db_path: str, file_dir=None, auth_config=None, max_workers: int = 2) -> FastAPI:
|
||
"""Create FastAPI application with orchestrator and optional authentication"""
|
||
app = FastAPI(title="Sanguo Quant API")
|
||
|
||
# Initialize orchestrator
|
||
orch = Orchestrator(db_path=db_path, file_dir=file_dir, max_workers=max_workers)
|
||
|
||
# Set up WebSocket stage callback
|
||
async def _on_stage(task_id, stage):
|
||
"""Broadcast stage updates to WebSocket subscribers"""
|
||
await manager.broadcast(task_id, {"task_id": task_id, "stage": stage})
|
||
|
||
orch.set_on_stage(_on_stage)
|
||
set_orchestrator(orch)
|
||
|
||
# Configure authentication if provided
|
||
if auth_config:
|
||
set_auth_config(auth_config)
|
||
set_jwt_config(
|
||
auth_config.get("jwt_secret", "x"),
|
||
auth_config.get("expire_minutes", 60)
|
||
)
|
||
|
||
# Include routes
|
||
app.include_router(router, prefix="/api/v1")
|
||
app.include_router(paper_router, prefix="/api/v1")
|
||
app.include_router(live_router, prefix="/api/v1")
|
||
app.include_router(portfolio_router, prefix="/api/v1")
|
||
set_paper_db_path(db_path)
|
||
set_live_db_path(db_path)
|
||
|
||
@app.on_event("startup")
|
||
def _register_live_step():
|
||
"""容器启动:注册每日 20:30 全局实走 step job(C-S3,遍历 live accounts)。"""
|
||
try:
|
||
from sanguo_trader.scheduler import register_live_step_job
|
||
register_live_step_job(db_path)
|
||
except Exception as e: # noqa: BLE001 本机无 apscheduler 时跳过
|
||
import logging
|
||
logging.getLogger(__name__).warning("register_live_step_job 失败: %s", e)
|
||
|
||
return app |