Fix dashboard TF key mismatch, increase refresh to 5s
Timeframe keys stored as enum values (15min/1h/4h) but dashboard looked for M15/1h/4h — GBP/USD showed no price or signal text. Now uses Timeframe enum directly with display labels. Reduced dashboard refresh from 60s to 5s with throttle guard.
This commit is contained in:
+23
-12
@@ -325,6 +325,10 @@ _SHORT_SIGNAL = {
|
||||
}
|
||||
|
||||
|
||||
_TF_DISPLAY = {"5min": "M5", "15min": "M15", "1h": "H1", "4h": "H4", "1d": "D1"}
|
||||
_DASH_TFS = [Timeframe.M15, Timeframe.H1, Timeframe.H4]
|
||||
|
||||
|
||||
def _format_stats_dashboard() -> str:
|
||||
if not _signal_stats:
|
||||
return "📊 *Live Dashboard*\n\n_Waiting for first scan…_"
|
||||
@@ -332,17 +336,15 @@ def _format_stats_dashboard() -> str:
|
||||
now = datetime.now(timezone.utc).strftime("%H:%M:%S UTC")
|
||||
lines = [f"📊 *Live Dashboard* — {now}", ""]
|
||||
|
||||
tf_order = ["M15", "1h", "4h"]
|
||||
|
||||
for symbol in SCAN_PAIRS:
|
||||
display = PAIR_INFO.get(symbol, {}).get("display", symbol)
|
||||
pair_data = _signal_stats.get(symbol, {})
|
||||
|
||||
ws_price = _last_prices.get(symbol)
|
||||
latest = None
|
||||
for tf in reversed(tf_order):
|
||||
if tf in pair_data:
|
||||
latest = pair_data[tf]
|
||||
for tf in reversed(_DASH_TFS):
|
||||
if tf.value in pair_data:
|
||||
latest = pair_data[tf.value]
|
||||
break
|
||||
|
||||
price = ws_price or (latest.current_price if latest else 0)
|
||||
@@ -354,14 +356,15 @@ def _format_stats_dashboard() -> str:
|
||||
regime = latest.market_regime.replace("_", " ").title() if latest else ""
|
||||
|
||||
tf_parts = []
|
||||
for tf in tf_order:
|
||||
r = pair_data.get(tf)
|
||||
for tf in _DASH_TFS:
|
||||
label = _TF_DISPLAY.get(tf.value, tf.value)
|
||||
r = pair_data.get(tf.value)
|
||||
if not r:
|
||||
tf_parts.append(f"{tf}: ⬜—")
|
||||
tf_parts.append(f"{label}: ⬜—")
|
||||
continue
|
||||
emoji = _SIGNAL_EMOJI.get(r.final_signal, "⬜")
|
||||
sig = _SHORT_SIGNAL.get(r.final_signal, "Neutral")
|
||||
tf_parts.append(f"{tf}: {emoji}{sig}")
|
||||
tf_parts.append(f"{label}: {emoji}{sig}")
|
||||
|
||||
lines.append(f"*{display}* {price_str} _{regime}_")
|
||||
lines.append(" | ".join(tf_parts))
|
||||
@@ -377,7 +380,7 @@ def _format_stats_dashboard() -> str:
|
||||
|
||||
lines.append("")
|
||||
|
||||
lines.append("_🔄 auto-refresh 60s_")
|
||||
lines.append("_🔄 live refresh_")
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
@@ -385,6 +388,8 @@ def _format_stats_dashboard() -> str:
|
||||
|
||||
_dashboard_msg_ids: Dict[int, int] = {}
|
||||
_dashboard_task: Optional[asyncio.Task] = None
|
||||
_last_dashboard_refresh: float = 0
|
||||
_DASHBOARD_THROTTLE = 5
|
||||
|
||||
|
||||
async def _send_dashboard(bot, chat_id: int) -> None:
|
||||
@@ -396,7 +401,13 @@ async def _send_dashboard(bot, chat_id: int) -> None:
|
||||
logger.exception(f"Failed to send dashboard to {chat_id}")
|
||||
|
||||
|
||||
async def _refresh_dashboard(bot) -> None:
|
||||
async def _refresh_dashboard(bot, force: bool = False) -> None:
|
||||
global _last_dashboard_refresh
|
||||
now = time.time()
|
||||
if not force and (now - _last_dashboard_refresh) < _DASHBOARD_THROTTLE:
|
||||
return
|
||||
_last_dashboard_refresh = now
|
||||
|
||||
text = _format_stats_dashboard()
|
||||
for chat_id in list(_autoscan_chats):
|
||||
msg_id = _dashboard_msg_ids.get(chat_id)
|
||||
@@ -419,7 +430,7 @@ async def _refresh_dashboard(bot) -> None:
|
||||
async def _dashboard_loop(bot) -> None:
|
||||
try:
|
||||
while _autoscan_chats:
|
||||
await asyncio.sleep(60)
|
||||
await asyncio.sleep(5)
|
||||
if not _autoscan_chats:
|
||||
break
|
||||
await _refresh_dashboard(bot)
|
||||
|
||||
Reference in New Issue
Block a user