Hide manual trade by default, block open while running, auto-refresh auth token.

Also fix flat-side reconcile to check both long and short residuals; document in 更新说明.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-07-26 22:43:38 +08:00
parent 0cf3756b09
commit 16efa44ffb
13 changed files with 304 additions and 38 deletions
+35 -22
View File
@@ -144,11 +144,11 @@ export default function PlanPage() {
<div style={{ display: "flex", flexWrap: "wrap", gap: 8, marginBottom: 12 }}>
<button
className="btn"
className={plan?.running ? "btn btn-running" : "btn"}
type="button"
disabled={
!!busy ||
plan?.running ||
!!plan?.running ||
(plan?.mode === "LIVE" && plan.live_ready === false)
}
title={
@@ -158,7 +158,7 @@ export default function PlanPage() {
}
onClick={() => act("/api/plan/start", "start")}
>
{plan?.running ? "启动中" : "启动策略"}
</button>
<button
className="btn ghost"
@@ -168,26 +168,39 @@ export default function PlanPage() {
>
</button>
{plan?.show_manual_trade_buttons ? (
<>
<button
className="btn ghost"
type="button"
disabled={
!!busy ||
!!plan?.running ||
(plan?.mode === "LIVE" && plan.live_ready === false)
}
title={
plan?.running
? "策略自动运行中,禁止手动开仓"
: plan?.mode === "LIVE" && plan.live_ready === false
? plan.live_ready_reason || "LIVE 未就绪"
: undefined
}
onClick={() => act("/api/sim/open-group", "open")}
>
</button>
<button
className="btn ghost"
type="button"
disabled={!!busy}
onClick={() => act("/api/sim/close-group", "close")}
>
</button>
</>
) : null}
<button
className="btn ghost"
type="button"
disabled={
!!busy || (plan?.mode === "LIVE" && plan.live_ready === false)
}
onClick={() => act("/api/sim/open-group", "open")}
>
</button>
<button
className="btn ghost"
type="button"
disabled={!!busy}
onClick={() => act("/api/sim/close-group", "close")}
>
</button>
<button
className="btn ghost"
className="btn danger"
type="button"
disabled={!!busy}
onClick={() => act("/api/plan/emergency-close", "emg")}