Implement P1 local matcher/ledger and P2 strategy engine.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-07-24 17:03:46 +08:00
parent 0fca5f025e
commit 51b8bb8f8a
30 changed files with 2086 additions and 150 deletions
+31 -6
View File
@@ -12,6 +12,8 @@ from fastapi.staticfiles import StaticFiles
from .api import router as api_router
from .config import get_settings
from .market import MarketGateway, set_gateway
from .models.db import Database, set_db
from .strategy import StrategyEngine, set_engine
logging.basicConfig(
level=logging.INFO,
@@ -22,7 +24,6 @@ logger = logging.getLogger("eth_hedge_sim")
def resolve_frontend_dist() -> Path:
here = Path(__file__).resolve()
# backend/app/main.py -> repo root is parents[2]
repo_root = here.parents[2]
return repo_root / "frontend" / "dist"
@@ -30,25 +31,39 @@ def resolve_frontend_dist() -> Path:
@asynccontextmanager
async def lifespan(app: FastAPI):
settings = get_settings()
if not settings.is_sim:
logger.warning("MODE=%s — still read-only market in current phase", settings.mode)
db = Database()
set_db(db)
engine = StrategyEngine()
set_engine(engine)
gw = MarketGateway(settings)
set_gateway(gw)
try:
await gw.start()
logger.info("market gateway started (SIM read-only)")
logger.info("market gateway started (SIM)")
except Exception:
logger.exception("market gateway failed to start")
yield
await engine.pause()
if engine._task and not engine._task.done():
engine._task.cancel()
try:
await engine._task
except Exception:
pass
await gw.stop()
set_gateway(None)
set_engine(None)
db.close()
set_db(None)
app = FastAPI(
title="eth_hedge_sim",
version="0.2.0",
description="ETH 自动对冲模拟盘",
version="0.3.0",
description="ETH 自动对冲模拟盘 P1/P2",
lifespan=lifespan,
)
app.add_middleware(
@@ -64,10 +79,15 @@ app.include_router(api_router)
@app.get("/health")
async def health() -> dict:
from .market import get_gateway
from .strategy import get_engine
settings = get_settings()
gw = get_gateway()
snap = gw.snapshot()
try:
st = get_engine().state()
except Exception:
st = None
return {
"ok": True,
"mode": settings.mode,
@@ -76,6 +96,11 @@ async def health() -> dict:
"market_connected": snap.connected,
"pair": snap.pair.to_dict() if snap.pair else None,
"updated_at_ms": snap.updated_at_ms,
"strategy": {
"running": st.get("running") if st else None,
"phase": st.get("phase") if st else None,
"rounds_done": st.get("rounds_done") if st else None,
},
}