diff --git a/lib/common/static/hedge_plan.js b/lib/common/static/hedge_plan.js
index 5ca1baa..faf5904 100644
--- a/lib/common/static/hedge_plan.js
+++ b/lib/common/static/hedge_plan.js
@@ -109,7 +109,7 @@
b.classList.toggle("active", on);
b.setAttribute("aria-selected", on ? "true" : "false");
});
- ["perp_options", "options_options", "history", "stats"].forEach(function (id) {
+ ["perp_options", "options_options", "active", "history", "stats"].forEach(function (id) {
const panel = $("hp-tab-" + id);
if (!panel) return;
const on = id === tab;
@@ -720,6 +720,8 @@
syncTabUI();
if (state.tab === "perp_options" || state.tab === "options_options") {
void loadGates();
+ } else if (state.tab === "active") {
+ void loadActivePlans();
} else if (state.tab === "history") {
void loadHistory();
} else if (state.tab === "stats") {
@@ -868,6 +870,60 @@
}
}
+ function activeTargetLabel(p) {
+ if (p.plan_type === "perp_options") {
+ return "止盈 " + fmt(p.tp) + " · 止损 " + fmt(p.sl);
+ }
+ return "上破 " + fmt(p.target_price_up || p.target_price) + " · 下破 " + fmt(p.target_price_down || p.target_price);
+ }
+
+ async function loadActivePlans() {
+ const tbody = $("hp-active-tbody");
+ if (!tbody) return;
+ try {
+ const d = await apiJson("/api/hedge-plan/active");
+ const rows = d.plans || [];
+ if (!rows.length) {
+ tbody.innerHTML = '
| 暂无进行中的计划 |
';
+ return;
+ }
+ tbody.innerHTML = "";
+ rows.forEach(function (p) {
+ const tr = document.createElement("tr");
+ const typeLabel = p.plan_type === "perp_options" ? "永期" : "期期";
+ const contracts = p.contracts_summary || "—";
+ tr.innerHTML =
+ "#" +
+ p.id +
+ " | " +
+ typeLabel +
+ " | " +
+ (p.underlying || "") +
+ " | " +
+ contracts +
+ " | " +
+ (p.status || "") +
+ " | " +
+ activeTargetLabel(p) +
+ " | " +
+ (p.opened_at || "—") +
+ ' | | ';
+ tbody.appendChild(tr);
+ });
+ tbody.querySelectorAll(".hp-btn-detail").forEach(function (btn) {
+ btn.addEventListener("click", function () {
+ void showPlanDetail(Number(btn.getAttribute("data-id")));
+ });
+ });
+ } catch (e) {
+ tbody.innerHTML = '| ' + (e.message || e) + " |
";
+ }
+ }
+
function reasonLabel(r) {
const map = {
perp_tp: "永续止盈",
diff --git a/lib/hedge_plan/hedge_plan_register.py b/lib/hedge_plan/hedge_plan_register.py
index 0c17f83..5a7e26a 100644
--- a/lib/hedge_plan/hedge_plan_register.py
+++ b/lib/hedge_plan/hedge_plan_register.py
@@ -522,6 +522,28 @@ def register_hedge_plan_routes(app: Flask, cfg: dict[str, Any]) -> None:
conn.close()
return jsonify({"ok": True, "plans": merged})
+ @app.route("/api/hedge-plan/active")
+ @lr
+ def api_hedge_active():
+ from lib.hedge_plan.hedge_plan_db import (
+ attach_legs_to_plans,
+ init_hedge_plan_tables,
+ list_plans,
+ )
+
+ conn = cfg["get_db"]()
+ try:
+ init_hedge_plan_tables(conn)
+ rows = []
+ for status in ("opening", "active", "partial"):
+ rows.extend(list_plans(conn, status=status, limit=80))
+ rows.sort(key=lambda row: int(row.get("id") or 0), reverse=True)
+ plans = attach_legs_to_plans(conn, rows)
+ conn.commit()
+ finally:
+ conn.close()
+ return jsonify({"ok": True, "plans": plans})
+
@app.route("/api/hedge-plan/stats")
@lr
def api_hedge_stats():
diff --git a/lib/hedge_plan/templates/hedge_plan_panel.html b/lib/hedge_plan/templates/hedge_plan_panel.html
index a97ff5b..20176e0 100644
--- a/lib/hedge_plan/templates/hedge_plan_panel.html
+++ b/lib/hedge_plan/templates/hedge_plan_panel.html
@@ -21,6 +21,7 @@
+
@@ -198,6 +199,25 @@
+
+
+
进行中的计划
+
仅显示已启动但尚未结束的计划;可查看每条腿的当前记录状态。
+
+
+
+
+ | ID | 类型 | 标的 | 合约 | 状态 | 目标/止盈止损 | 开仓 | 操作 |
+
+
+
+ | 加载中… |
+
+
+
+
+
+
-
+