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:
Harwinder
2026-05-13 18:51:02 -04:00
parent f99fcc60b9
commit 67a9169eb3
+23 -12
View File
@@ -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: def _format_stats_dashboard() -> str:
if not _signal_stats: if not _signal_stats:
return "📊 *Live Dashboard*\n\n_Waiting for first scan…_" 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") now = datetime.now(timezone.utc).strftime("%H:%M:%S UTC")
lines = [f"📊 *Live Dashboard* — {now}", ""] lines = [f"📊 *Live Dashboard* — {now}", ""]
tf_order = ["M15", "1h", "4h"]
for symbol in SCAN_PAIRS: for symbol in SCAN_PAIRS:
display = PAIR_INFO.get(symbol, {}).get("display", symbol) display = PAIR_INFO.get(symbol, {}).get("display", symbol)
pair_data = _signal_stats.get(symbol, {}) pair_data = _signal_stats.get(symbol, {})
ws_price = _last_prices.get(symbol) ws_price = _last_prices.get(symbol)
latest = None latest = None
for tf in reversed(tf_order): for tf in reversed(_DASH_TFS):
if tf in pair_data: if tf.value in pair_data:
latest = pair_data[tf] latest = pair_data[tf.value]
break break
price = ws_price or (latest.current_price if latest else 0) 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 "" regime = latest.market_regime.replace("_", " ").title() if latest else ""
tf_parts = [] tf_parts = []
for tf in tf_order: for tf in _DASH_TFS:
r = pair_data.get(tf) label = _TF_DISPLAY.get(tf.value, tf.value)
r = pair_data.get(tf.value)
if not r: if not r:
tf_parts.append(f"{tf}: ⬜—") tf_parts.append(f"{label}: ⬜—")
continue continue
emoji = _SIGNAL_EMOJI.get(r.final_signal, "⬜") emoji = _SIGNAL_EMOJI.get(r.final_signal, "⬜")
sig = _SHORT_SIGNAL.get(r.final_signal, "Neutral") 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(f"*{display}* {price_str} _{regime}_")
lines.append(" | ".join(tf_parts)) lines.append(" | ".join(tf_parts))
@@ -377,7 +380,7 @@ def _format_stats_dashboard() -> str:
lines.append("") lines.append("")
lines.append("_🔄 auto-refresh 60s_") lines.append("_🔄 live refresh_")
return "\n".join(lines) return "\n".join(lines)
@@ -385,6 +388,8 @@ def _format_stats_dashboard() -> str:
_dashboard_msg_ids: Dict[int, int] = {} _dashboard_msg_ids: Dict[int, int] = {}
_dashboard_task: Optional[asyncio.Task] = None _dashboard_task: Optional[asyncio.Task] = None
_last_dashboard_refresh: float = 0
_DASHBOARD_THROTTLE = 5
async def _send_dashboard(bot, chat_id: int) -> None: 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}") 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() text = _format_stats_dashboard()
for chat_id in list(_autoscan_chats): for chat_id in list(_autoscan_chats):
msg_id = _dashboard_msg_ids.get(chat_id) msg_id = _dashboard_msg_ids.get(chat_id)
@@ -419,7 +430,7 @@ async def _refresh_dashboard(bot) -> None:
async def _dashboard_loop(bot) -> None: async def _dashboard_loop(bot) -> None:
try: try:
while _autoscan_chats: while _autoscan_chats:
await asyncio.sleep(60) await asyncio.sleep(5)
if not _autoscan_chats: if not _autoscan_chats:
break break
await _refresh_dashboard(bot) await _refresh_dashboard(bot)