fix(trend): align hub and four-exchange trend plan display
Unify gate_bot with shared enrich_trend_plan for strategy pages and hub monitor, reconcile DCA avg with live entry price, and fix missing fill price display. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+10
-106
@@ -3959,40 +3959,6 @@ def calc_trend_manual_breakeven_stop(direction, entry_price, offset_pct=None):
|
||||
return e * (1.0 + pct / 100.0)
|
||||
|
||||
|
||||
def enrich_active_trend_plan_row(row):
|
||||
d = row_to_dict(row)
|
||||
try:
|
||||
d["breakeven_applied"] = int(d.get("breakeven_applied") or 0) != 0
|
||||
except Exception:
|
||||
d["breakeven_applied"] = False
|
||||
ex_sym = d.get("exchange_symbol") or normalize_exchange_symbol(d.get("symbol") or "")
|
||||
direction = (d.get("direction") or "long").lower()
|
||||
m = get_live_position_exchange_metrics(ex_sym, direction)
|
||||
if m and m.get("unrealized_pnl") is not None:
|
||||
d["floating_pnl"] = float(m["unrealized_pnl"])
|
||||
else:
|
||||
d["floating_pnl"] = None
|
||||
if m and m.get("mark_price") is not None:
|
||||
d["floating_mark"] = float(m["mark_price"])
|
||||
else:
|
||||
d["floating_mark"] = None
|
||||
try:
|
||||
d["contract_size"] = float(get_contract_size(ex_sym))
|
||||
except (TypeError, ValueError):
|
||||
pass
|
||||
from strategy_snapshot_lib import attach_trend_dca_levels
|
||||
from strategy_trend_lib import calc_trend_plan_money_metrics
|
||||
|
||||
d = attach_trend_dca_levels(d)
|
||||
money = calc_trend_plan_money_metrics(d)
|
||||
if money.get("money_rr") is not None:
|
||||
d["money_rr"] = money["money_rr"]
|
||||
d["planned_rr"] = money["money_rr"]
|
||||
if money.get("risk_amount_u") is not None:
|
||||
d["risk_amount_u"] = money["risk_amount_u"]
|
||||
return d
|
||||
|
||||
|
||||
def opened_at_str_to_ms(opened_at_str):
|
||||
if not opened_at_str:
|
||||
return None
|
||||
@@ -5412,30 +5378,6 @@ def render_main_page(page="trade"):
|
||||
trend_active = conn.execute(
|
||||
"SELECT COUNT(*) FROM trend_pullback_plans WHERE status='active'"
|
||||
).fetchone()[0]
|
||||
trend_plans_raw = conn.execute(
|
||||
"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:
|
||||
enriched = enrich_active_trend_plan_row(r)
|
||||
trend_plans.append(enriched)
|
||||
except Exception as e:
|
||||
print(f"[render_main_page] enrich trend plan: {e}")
|
||||
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:
|
||||
@@ -5456,49 +5398,17 @@ def render_main_page(page="trade"):
|
||||
and active_count < MAX_ACTIVE_POSITIONS
|
||||
and int(trend_active or 0) == 0
|
||||
)
|
||||
trend_preview = None
|
||||
trend_preview_levels = []
|
||||
preview_expires_ms = None
|
||||
trend_preview_expired = False
|
||||
trend_preview_id_arg = ""
|
||||
if page in ("strategy", "strategy_trend", "strategy_roll"):
|
||||
_trend_cleanup_stale_previews(conn)
|
||||
if page in ("strategy", "strategy_trend"):
|
||||
trend_preview_id_arg = (request.args.get("preview_id") or "").strip()
|
||||
if trend_preview_id_arg:
|
||||
pr = conn.execute(
|
||||
"SELECT * FROM trend_pullback_previews WHERE id=?",
|
||||
(trend_preview_id_arg,),
|
||||
).fetchone()
|
||||
now_ms = int(time.time() * 1000)
|
||||
if pr and int(pr["expires_at_ms"] or 0) >= now_ms:
|
||||
from strategy_trend_lib import build_trend_preview_level_rows
|
||||
|
||||
trend_preview = row_to_dict(pr)
|
||||
preview_expires_ms = int(pr["expires_at_ms"])
|
||||
if not trend_preview.get("contract_size"):
|
||||
try:
|
||||
ensure_markets_loaded()
|
||||
ex_sym = trend_preview.get("exchange_symbol") or trend_preview.get("symbol")
|
||||
mk = exchange.market(ex_sym)
|
||||
trend_preview["contract_size"] = float(mk.get("contractSize") or 1)
|
||||
except Exception:
|
||||
pass
|
||||
trend_preview, trend_preview_levels = build_trend_preview_level_rows(trend_preview)
|
||||
elif pr:
|
||||
trend_preview_expired = True
|
||||
strategy_extra = {}
|
||||
if page == "strategy_records":
|
||||
if page in ("strategy", "strategy_trend", "strategy_roll", "strategy_records"):
|
||||
from strategy_ui import strategy_render_extras
|
||||
|
||||
strategy_extra = strategy_render_extras(conn, page)
|
||||
elif page in ("strategy", "strategy_trend", "strategy_roll"):
|
||||
from strategy_ui import fetch_roll_page_data
|
||||
|
||||
strategy_extra = fetch_roll_page_data(
|
||||
strategy_extra = strategy_render_extras(
|
||||
conn,
|
||||
page,
|
||||
default_risk_percent=float(RISK_PERCENT),
|
||||
count_active_trends=lambda c, ta=trend_active: int(ta or 0),
|
||||
request_obj=request,
|
||||
trend_cfg=app.extensions.get("strategy_trend_cfg"),
|
||||
)
|
||||
orphan_positions: list = []
|
||||
if page == "trade":
|
||||
@@ -5540,20 +5450,9 @@ def render_main_page(page="trade"):
|
||||
max_active_positions=MAX_ACTIVE_POSITIONS,
|
||||
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,
|
||||
trend_pullback_preview_ttl=TREND_PULLBACK_PREVIEW_TTL_SECONDS,
|
||||
trend_preview=trend_preview,
|
||||
trend_preview_levels=trend_preview_levels,
|
||||
preview_expires_ms=preview_expires_ms,
|
||||
trend_preview_expired=trend_preview_expired,
|
||||
trend_preview_id_arg=trend_preview_id_arg,
|
||||
trend_preview_max_drift_pct=TREND_PREVIEW_MAX_BALANCE_DRIFT_PCT,
|
||||
trend_manual_breakeven_offset_pct=TREND_PULLBACK_MANUAL_BREAKEVEN_OFFSET_PCT,
|
||||
list_window=list_window,
|
||||
list_window_presets={
|
||||
"utc_today": PRESET_UTC_TODAY,
|
||||
@@ -8032,6 +7931,11 @@ try:
|
||||
},
|
||||
ohlcv_fn=_hub_fetch_ohlcv,
|
||||
)
|
||||
from strategy_trend_register import build_trend_config, patch_trend_hub_enrich
|
||||
|
||||
_hub_trend_cfg = build_trend_config(sys.modules[__name__])
|
||||
app.extensions["strategy_trend_cfg"] = _hub_trend_cfg
|
||||
patch_trend_hub_enrich(app, _hub_trend_cfg)
|
||||
except Exception as _hub_err:
|
||||
print(f"[hub_bridge] gate_bot: {_hub_err}")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user