持仓监控独立导航页,交易记录与复盘合并为同一页

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-06-15 15:06:18 +08:00
parent 5aa9f11733
commit 9ba9733523
8 changed files with 273 additions and 244 deletions
+25 -15
View File
@@ -728,11 +728,19 @@ def keys():
history = conn.execute(
"SELECT * FROM key_monitors WHERE status='archived' ORDER BY archived_at DESC LIMIT 100"
).fetchall()
positions = conn.execute(
conn.close()
return render_template("keys.html", keys=key_list, history=history)
@app.route("/positions")
@login_required
def positions():
conn = get_db()
pos_list = conn.execute(
"SELECT * FROM position_monitors WHERE status='active' ORDER BY id DESC"
).fetchall()
conn.close()
return render_template("keys.html", keys=key_list, history=history, positions=positions)
return render_template("positions.html", positions=pos_list)
@app.route("/add_key", methods=["POST"])
@@ -773,7 +781,7 @@ def add_position():
sina_code = d.get("sina_code", "").strip()
if not symbol or not market_code:
flash("请从下拉列表选择品种")
return redirect(url_for("keys"))
return redirect(url_for("positions"))
entry = float(d["entry_price"])
sl = float(d["stop_loss"])
tp = float(d["take_profit"])
@@ -796,7 +804,7 @@ def add_position():
conn.commit()
conn.close()
flash("持仓已添加")
return redirect(url_for("keys"))
return redirect(url_for("positions"))
@app.route("/del_position/<int:pid>")
@@ -813,7 +821,7 @@ def close_position(pid):
if not row:
conn.close()
flash("持仓不存在")
return redirect(url_for("keys"))
return redirect(url_for("positions"))
sym = row["symbol"]
market = row["market_code"] or ""
sina = row["sina_code"] or ""
@@ -828,7 +836,7 @@ def close_position(pid):
if close_price is None:
conn.close()
flash("无法获取现价,平仓失败")
return redirect(url_for("keys"))
return redirect(url_for("positions"))
capital = float(get_setting("live_capital", "0") or 0)
metrics = calc_position_metrics(direction, entry, sl, tp, lots, close_price, capital, sym)
pnl = metrics.get("float_pnl") or 0.0
@@ -850,16 +858,13 @@ def close_position(pid):
conn.commit()
conn.close()
flash(f"已平仓,盈亏 {pnl:.2f} 元,已记入交易记录")
return redirect(url_for("keys"))
return redirect(url_for("positions"))
@app.route("/trades")
@login_required
def trades():
conn = get_db()
rows = conn.execute("SELECT * FROM trade_logs ORDER BY id DESC LIMIT 500").fetchall()
conn.close()
return render_template("trades.html", trades=rows)
return redirect(url_for("records"))
@app.route("/update_trade/<int:tid>", methods=["POST"])
@@ -895,7 +900,7 @@ def update_trade(tid):
conn.commit()
conn.close()
flash("交易记录已核对保存")
return redirect(url_for("trades"))
return redirect(url_for("records"))
@app.route("/del_trade/<int:tid>")
@@ -906,7 +911,7 @@ def del_trade(tid):
conn.commit()
conn.close()
flash("已删除")
return redirect(url_for("trades"))
return redirect(url_for("records"))
@app.route("/fill_review/<int:tid>")
@@ -917,7 +922,7 @@ def fill_review_from_trade(tid):
conn.close()
if not row:
flash("记录不存在")
return redirect(url_for("trades"))
return redirect(url_for("records"))
q = {
"symbol": row["symbol"],
"symbol_name": row["symbol_name"] or row["symbol"],
@@ -933,7 +938,8 @@ def fill_review_from_trade(tid):
"close_time": row["close_time"],
"pnl": row["pnl"],
}
return redirect(url_for("records", **{k: v for k, v in q.items() if v is not None}))
params = {k: v for k, v in q.items() if v is not None}
return redirect(url_for("records", **params) + "#review-panel")
@app.route("/del_key/<int:pid>")
@@ -974,6 +980,9 @@ def records():
auto_list = conn.execute(
"SELECT * FROM trade_records ORDER BY id DESC LIMIT 30"
).fetchall()
trade_list = conn.execute(
"SELECT * FROM trade_logs ORDER BY id DESC LIMIT 500"
).fetchall()
conn.close()
trade_prefill_keys = (
@@ -986,6 +995,7 @@ def records():
return render_template(
"records.html",
reviews=review_list,
trades=trade_list,
auto_records=auto_list,
preset=preset,
start=start,