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
+57 -1
View File
@@ -1,8 +1,64 @@
import { useEffect, useState } from "react";
import { apiFetch } from "../api/client";
type Summary = {
groups: number;
wins: number;
win_rate: number;
total_pnl: number;
total_fees: number;
total_slip: number;
close_reasons: Record<string, number>;
equity_curve: { group_id: string; realized_pnl: number }[];
};
export default function StatsPage() {
const [s, setS] = useState<Summary | null>(null);
const [err, setErr] = useState("");
useEffect(() => {
apiFetch<Summary>("/api/stats/summary")
.then(setS)
.catch((e) => setErr(e instanceof Error ? e.message : String(e)));
}, []);
return (
<div className="card">
<h2 style={{ marginTop: 0 }}></h2>
<p style={{ color: "var(--muted)" }}> / / 线</p>
{err ? <div className="err">{err}</div> : null}
{!s ? (
<p style={{ color: "var(--muted)" }}></p>
) : (
<>
<div className="kv">
<span> / </span>
<span className="mono">
{s.groups} / {(s.win_rate * 100).toFixed(1)}%
</span>
</div>
<div className="kv">
<span></span>
<span className="mono">{s.total_pnl.toFixed(2)}</span>
</div>
<div className="kv">
<span> / </span>
<span className="mono">
{s.total_fees.toFixed(2)} / {s.total_slip.toFixed(2)}
</span>
</div>
<div className="kv">
<span></span>
<span className="mono">{JSON.stringify(s.close_reasons)}</span>
</div>
<h3></h3>
{s.equity_curve.map((x) => (
<div key={x.group_id} className="kv">
<span className="mono">{x.group_id}</span>
<span className="mono">{x.realized_pnl.toFixed(2)}</span>
</div>
))}
</>
)}
</div>
);
}