Skip to content

Commit c7f8cc3

Browse files
authored
Compact runtime Telegram notifications (#31)
Compact Telegram runtime summaries while keeping detailed output in Cloud Logging.
1 parent 2e8120b commit c7f8cc3

2 files changed

Lines changed: 74 additions & 11 deletions

File tree

application/rebalance_service.py

Lines changed: 70 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,39 @@ def build_dashboard(
379379
)
380380

381381

382+
def _first_prefixed_line(prefix: str, text: str, *, translator) -> str | None:
383+
localized = _localize_notification_text(text, translator=translator)
384+
lines = _format_prefixed_text(prefix, localized)
385+
return lines[0] if lines else None
386+
387+
388+
def _build_compact_message(
389+
*,
390+
title: str,
391+
strategy_display_name: str | None,
392+
signal_desc: str,
393+
status_desc: str,
394+
status_icon: str,
395+
translator,
396+
separator: str,
397+
body_lines,
398+
) -> str:
399+
lines = [title]
400+
strategy_name = _format_text(strategy_display_name, fallback="<unknown>")
401+
lines.append(translator("strategy_label", name=strategy_name))
402+
status_line = _first_prefixed_line(status_icon, status_desc, translator=translator)
403+
if status_line:
404+
lines.append(status_line)
405+
signal_line = _first_prefixed_line("🎯", signal_desc, translator=translator)
406+
if signal_line:
407+
lines.append(signal_line)
408+
compact_body = [str(line).strip() for line in body_lines or () if str(line).strip()]
409+
if compact_body:
410+
lines.append(separator)
411+
lines.extend(compact_body)
412+
return "\n".join(lines)
413+
414+
382415
def run_strategy_core(
383416
*,
384417
connect_ib,
@@ -448,9 +481,19 @@ def run_strategy_core(
448481
+ json.dumps({"path": str(record_path), "status": record.get("execution_status"), "no_op_reason": record.get("no_op_reason")}, ensure_ascii=False),
449482
flush=True,
450483
)
451-
message = f"{translator('heartbeat_title')}\n{dashboard}\n{separator}\n{no_op_text}"
452-
send_tg_message(message)
453-
print(message, flush=True)
484+
detailed_message = f"{translator('heartbeat_title')}\n{dashboard}\n{separator}\n{no_op_text}"
485+
compact_message = _build_compact_message(
486+
title=translator("heartbeat_title"),
487+
strategy_display_name=strategy_display_name,
488+
signal_desc=signal_desc,
489+
status_desc=status_desc,
490+
status_icon=signal_metadata.get("status_icon", "🐤"),
491+
translator=translator,
492+
separator=separator,
493+
body_lines=[no_op_text],
494+
)
495+
print(detailed_message, flush=True)
496+
send_tg_message(compact_message)
454497
if callable(result_hook):
455498
result_hook(
456499
{
@@ -508,17 +551,37 @@ def run_strategy_core(
508551
translator=translator,
509552
)
510553
trade_lines = "\n".join(notification_trade_lines)
511-
message = (
554+
detailed_message = (
512555
f"{translator('rebalance_title')}\n"
513556
f"{dashboard}\n"
514557
f"{separator}\n"
515558
f"{trade_lines}"
516559
)
560+
compact_message = _build_compact_message(
561+
title=translator("rebalance_title"),
562+
strategy_display_name=strategy_display_name,
563+
signal_desc=signal_desc,
564+
status_desc=status_desc,
565+
status_icon=signal_metadata.get("status_icon", "🐤"),
566+
translator=translator,
567+
separator=separator,
568+
body_lines=notification_trade_lines,
569+
)
517570
else:
518-
message = f"{translator('heartbeat_title')}\n{dashboard}\n{separator}\n{translator('no_trades')}"
571+
detailed_message = f"{translator('heartbeat_title')}\n{dashboard}\n{separator}\n{translator('no_trades')}"
572+
compact_message = _build_compact_message(
573+
title=translator("heartbeat_title"),
574+
strategy_display_name=strategy_display_name,
575+
signal_desc=signal_desc,
576+
status_desc=status_desc,
577+
status_icon=signal_metadata.get("status_icon", "🐤"),
578+
translator=translator,
579+
separator=separator,
580+
body_lines=[translator("no_trades")],
581+
)
519582

520-
send_tg_message(message)
521-
print(message, flush=True)
583+
print(detailed_message, flush=True)
584+
send_tg_message(compact_message)
522585
if callable(result_hook):
523586
result_hook(
524587
{

tests/test_rebalance_service.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -220,11 +220,11 @@ def fake_execute_rebalance(
220220
assert observed["strategy_symbols"] == ("AAA", "BOXX")
221221
assert observed["signal_metadata"]["managed_symbols"] == ("AAA", "BOXX")
222222
assert observed["messages"]
223-
assert "Account Summary" in observed["messages"][0]
224-
assert "Current Positions" in observed["messages"][0]
225-
assert "Execution Summary" in observed["messages"][0]
223+
assert "Account Summary" not in observed["messages"][0]
224+
assert "Current Positions" not in observed["messages"][0]
225+
assert "Execution Summary" not in observed["messages"][0]
226226
assert "📏 breadth=60.0%" in observed["messages"][0]
227-
assert "Target Weights" in observed["messages"][0]
227+
assert "Target Weights" not in observed["messages"][0]
228228

229229

230230
def test_run_strategy_core_writes_reconciliation_record(tmp_path):

0 commit comments

Comments
 (0)