diff --git a/install_trading.py b/install_trading.py index 537a24b..e03878d 100644 --- a/install_trading.py +++ b/install_trading.py @@ -288,7 +288,18 @@ def install_trading(app, *, login_required, get_db, get_setting, set_setting, fe capital = _capital(conn) risk = get_risk_status(conn) ctp_acc = _ctp_account(mode) if ctp_st.get("connected") else {} + recommend_rows = list_product_recommendations(capital, _main_price) + active_trend = conn.execute( + "SELECT * FROM trend_pullback_plans WHERE status='active' ORDER BY id DESC LIMIT 1" + ).fetchone() + monitor_count = conn.execute( + "SELECT COUNT(*) AS n FROM trade_order_monitors WHERE status='active'" + ).fetchone()["n"] + roll_count = conn.execute( + "SELECT COUNT(*) AS n FROM roll_groups WHERE status='active'" + ).fetchone()["n"] conn.close() + sizing = get_sizing_mode(get_setting) return render_template( "trade.html", trading_mode=mode, @@ -297,8 +308,20 @@ def install_trading(app, *, login_required, get_db, get_setting, set_setting, fe risk_status=risk, ctp_status=ctp_st, ctp_account=ctp_acc, + recommend_rows=recommend_rows, + active_trend=dict(active_trend) if active_trend else None, + monitor_count=monitor_count, + roll_count=roll_count, + sizing_mode=sizing, + sizing_mode_label="以损定仓" if sizing == MODE_RISK else "固定张数", + risk_percent=get_risk_percent(get_setting), ) + @app.route("/recommend") + @login_required + def recommend_page(): + return redirect(url_for("positions") + "#recommend") + @app.route("/api/trading/live") @login_required def api_trading_live(): @@ -313,6 +336,7 @@ def install_trading(app, *, login_required, get_db, get_setting, set_setting, fe "capital": _capital(get_db()), "ctp_status": ctp_st, "trading_mode_label": trading_mode_label(get_setting), + "risk_status": get_risk_status(get_db()), }) @app.route("/api/trading/close", methods=["POST"]) @@ -357,14 +381,6 @@ def install_trading(app, *, login_required, get_db, get_setting, set_setting, fe conn.close() return jsonify({"ok": False, "error": str(exc)}), 400 - @app.route("/recommend") - @login_required - def recommend_page(): - conn = get_db() - capital = _capital(conn) - conn.close() - rows = list_product_recommendations(capital, _main_price) - return render_template("recommend.html", capital=capital, rows=rows, trading_mode_label=trading_mode_label(get_setting)) @app.route("/strategy") @login_required diff --git a/static/css/trade.css b/static/css/trade.css index 29d9822..092ad5e 100644 --- a/static/css/trade.css +++ b/static/css/trade.css @@ -1,9 +1,14 @@ -.trade-page{max-width:960px;margin:0 auto} -.trade-top-bar{display:flex;flex-wrap:wrap;gap:.65rem;align-items:center;margin-bottom:1rem} -.trade-subnav{display:flex;gap:1rem;margin-bottom:1rem;font-size:.88rem} -.trade-subnav span.active{color:var(--accent);font-weight:600;border-bottom:2px solid var(--accent);padding-bottom:.25rem} -.trade-subnav a{color:var(--text-muted);text-decoration:none} +.trade-page{max-width:1100px;margin:0 auto} +.trade-top-bar{display:flex;flex-wrap:wrap;gap:.65rem;align-items:center;margin-bottom:1.25rem} +.trade-dashboard{display:flex;flex-direction:column;gap:1.25rem} +.trade-card{margin-bottom:0} +.trade-card h2{margin-bottom:.65rem} +.trade-order-status{display:grid;gap:.55rem;margin:.75rem 0;padding:.85rem 1rem;background:var(--card-inner);border:1px solid var(--card-border);border-radius:8px;font-size:.85rem} +.trade-order-status .status-row{display:flex;flex-wrap:wrap;align-items:center;gap:.35rem .65rem} +.trade-order-status .trend-active{padding-top:.35rem;border-top:1px dashed var(--card-border)} +.trade-order-actions{display:flex;flex-wrap:wrap;align-items:center;gap:.75rem 1rem;margin-top:1rem} .trade-footer{background:var(--card-inner);border-radius:8px;padding:.75rem 1rem;font-size:.82rem;line-height:1.55;border:1px solid var(--card-border);margin-top:1rem} .trade-footer strong{color:var(--accent)} .rec-blocked td{opacity:.55} .rec-ok td:first-child{font-weight:600} +#positions .card-body{max-height:520px} diff --git a/static/js/trade.js b/static/js/trade.js index 814ea46..7c7d797 100644 --- a/static/js/trade.js +++ b/static/js/trade.js @@ -114,6 +114,13 @@ .then(function (data) { var cap = document.getElementById('cap-display'); if (cap && data.capital != null) cap.textContent = Number(data.capital).toFixed(2); + var recCap = document.getElementById('rec-capital'); + if (recCap && data.capital != null) recCap.textContent = Number(data.capital).toFixed(2); + var riskBadge = document.getElementById('risk-badge'); + if (riskBadge && data.risk_status) { + riskBadge.textContent = data.risk_status.status_label; + riskBadge.className = 'badge ' + (data.risk_status.can_trade ? 'profit' : 'loss'); + } var ctpBadge = document.getElementById('ctp-badge'); if (ctpBadge && data.ctp_status) { ctpBadge.textContent = data.ctp_status.connected ? 'CTP 已连接' : 'CTP 未连接'; @@ -121,7 +128,7 @@ } var rows = data.rows || []; if (!rows.length) { - list.innerHTML = '
暂无持仓。请先在「策略交易」开仓,或连接 CTP 同步柜台持仓。
'; + list.innerHTML = '
暂无持仓。请通过上方「期货下单 → 策略交易」开仓,或连接 CTP 同步柜台持仓。
'; return; } list.innerHTML = rows.map(buildPosCard).join(''); diff --git a/templates/base.html b/templates/base.html index 39e54bf..21b98ec 100644 --- a/templates/base.html +++ b/templates/base.html @@ -483,8 +483,7 @@

国内期货 · 交易监控 + 复盘FUTURES MONITOR SYSTEM