fix(trend): surface DCA block reasons and ensure gate_bot poll thread

Log poll exceptions, diagnose live-trading and mark-price blocks on the trend page, start background monitors on app import, and add /api/trend_poll_status for debugging.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-06-07 17:46:26 +08:00
parent 0760873d9d
commit f5b4513ddb
3 changed files with 213 additions and 7 deletions
+66 -5
View File
@@ -5270,11 +5270,27 @@ def background_task():
check_roll_monitors(_roll_cfg)
check_order_monitors()
except:
pass
except Exception as e:
print(f"[background_task] error: {e}", flush=True)
time.sleep(MONITOR_POLL_SECONDS)
_BG_MONITORS_LOCK = threading.Lock()
_BG_MONITORS_STARTED = False
def _ensure_background_monitors_started():
global _BG_MONITORS_STARTED
with _BG_MONITORS_LOCK:
if _BG_MONITORS_STARTED:
return
_BG_MONITORS_STARTED = True
threading.Thread(
target=background_task, daemon=True, name="gate-bot-monitors"
).start()
print("[startup] background monitor thread started", flush=True)
# ====================== 登录路由 ======================
@app.route("/login", methods=["GET", "POST"])
def login():
@@ -5400,12 +5416,26 @@ def render_main_page(page="trade"):
"SELECT * FROM trend_pullback_plans WHERE status='active' ORDER BY id DESC"
).fetchall()
trend_plans = []
trend_dca_probes = []
_trend_cfg = app.extensions.get("strategy_trend_cfg")
for r in trend_plans_raw:
try:
trend_plans.append(enrich_active_trend_plan_row(r))
enriched = enrich_active_trend_plan_row(r)
trend_plans.append(enriched)
except Exception as e:
print(f"[render_main_page] enrich trend plan: {e}")
trend_plans.append(row_to_dict(r))
enriched = row_to_dict(r)
trend_plans.append(enriched)
if _trend_cfg and page in ("strategy", "strategy_trend", "strategy_roll"):
try:
from strategy_trend_register import summarize_trend_dca_probe
probe = summarize_trend_dca_probe(_trend_cfg, r)
trend_dca_probes.append(probe)
if isinstance(enriched, dict):
enriched["dca_probe"] = probe
except Exception as e:
print(f"[render_main_page] trend dca probe: {e}")
preview_snapshots = []
if page == "records":
try:
@@ -5511,6 +5541,8 @@ def render_main_page(page="trade"):
manual_min_planned_rr=MANUAL_MIN_PLANNED_RR,
can_trade=can_trade,
trend_plans=trend_plans,
trend_dca_probes=trend_dca_probes,
live_trading_enabled=LIVE_TRADING_ENABLED,
preview_snapshots=preview_snapshots,
exchange_sync_from_label=(EXCHANGE_POSITION_SYNC_FROM_BJ or "最近90天"),
trend_pullback_dca_legs=TREND_PULLBACK_DCA_LEGS,
@@ -8017,6 +8049,35 @@ def strategy_trend_page():
return redirect(f"/strategy?{qs}" if qs else "/strategy")
@app.route("/api/trend_poll_status")
@login_required
def api_trend_poll_status():
from strategy_trend_register import (
build_trend_config,
get_trend_poll_state,
summarize_trend_dca_probe,
)
cfg = app.extensions.get("strategy_trend_cfg") or build_trend_config(
sys.modules[__name__]
)
conn = get_db()
probes = []
for r in conn.execute(
"SELECT * FROM trend_pullback_plans WHERE status='active' ORDER BY id DESC"
).fetchall():
probes.append(summarize_trend_dca_probe(cfg, r))
conn.close()
return jsonify(
{
"poll": get_trend_poll_state(),
"probes": probes,
"live_trading_enabled": LIVE_TRADING_ENABLED,
"monitor_poll_seconds": MONITOR_POLL_SECONDS,
}
)
@app.route("/strategy/roll")
@login_required
def strategy_roll_page():
@@ -8035,9 +8096,9 @@ install_strategy_trading(
app.extensions["strategy_trend_cfg"] = build_trend_config(sys.modules[__name__])
_purge_key_monitors_if_full_margin()
_ensure_background_monitors_started()
# 启动
if __name__ == "__main__":
threading.Thread(target=background_task, daemon=True).start()
app.run(host=HOST, port=PORT, debug=DEBUG)