Telegram alert redesign: verdict-first layout + informational 100-pip TP
format_signal_message restyled (display-only, zero signal-logic impact): verdict header first (signal - pair - TF - quality), trade setup moved above the detail, per-indicator breakdown condensed to one arrow line (_indicator_summary), heavy dividers dropped. New TP 100p line in every setup block: entry +/- 100 pips ($10.00 on XAU) with its R-multiple vs the stop (_INFO_TP_PIPS, formatter-only - not stamped on TradeSetup, not in CLI/JSON/backtester). Trailing-plan logic unchanged (stamped per-TF params, pullback fallback). Removed dead _indicator_line and _SIGNAL_TAG. Tests 210 -> 212 (100p TP math BUY/SELL/no-setup, one-line indicator summary). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BoZKi67Ct6QTeiFJmybXSw
This commit is contained in:
+53
-4
@@ -1555,7 +1555,7 @@ def _():
|
||||
print("\n═══ Module 7: telegram_bot.py ═══")
|
||||
|
||||
from telegram_bot import (
|
||||
_escape_md, _signal_label, _mtf_line,
|
||||
_escape_md, _signal_label, _mtf_line, _indicator_summary,
|
||||
format_signal_message, _format_scan_summary,
|
||||
_seconds_until_boundary, _check_level_breach,
|
||||
scan_keyboard, SCAN_BUTTONS, SCAN_LOOKUP,
|
||||
@@ -1615,9 +1615,9 @@ def _():
|
||||
assert isinstance(msg, str)
|
||||
assert len(msg) > 0
|
||||
assert "XAU/USD" in msg
|
||||
assert "Signal Analysis" in msg
|
||||
assert "Price" in msg
|
||||
assert "Indicators" in msg
|
||||
assert "Score" in msg
|
||||
assert "Regime" in msg
|
||||
assert "Not financial advice" in msg
|
||||
|
||||
|
||||
@test("format_signal_message renders stamped per-TF trail plan")
|
||||
@@ -1644,6 +1644,55 @@ def _():
|
||||
assert "$7.50" in msg
|
||||
|
||||
|
||||
@test("format_signal_message renders 100-pip informational TP")
|
||||
def _():
|
||||
def _setup(direction="BUY", **extra):
|
||||
return TradeSetup(
|
||||
pair="XAU/USD", display_name="XAU/USD", direction=direction,
|
||||
entry_price=3300.0, stop_loss=3290.0, take_profit_1=3315.0,
|
||||
take_profit_2=3325.0, risk_reward=1.5, risk_pips=100,
|
||||
reward_pips=150, pip_value=0.10, **extra,
|
||||
)
|
||||
report = SignalReport(symbol="XAU/USD", display_name="XAU/USD", timestamp="now")
|
||||
report.final_signal = SignalStrength.BUY
|
||||
report.signal_quality = "A"
|
||||
# BUY: 100 pips × $0.10 = $10 above entry; risk $10 → exactly 1.0R.
|
||||
report.trade_setup = _setup()
|
||||
msg = format_signal_message(report)
|
||||
assert "TP 100p" in msg
|
||||
assert "3310.00" in msg, "BUY 100p TP must be entry + $10.00"
|
||||
assert "≈1.0R" in msg
|
||||
# SELL mirror: $10 below entry.
|
||||
report.final_signal = SignalStrength.SELL
|
||||
report.trade_setup = _setup(direction="SELL")
|
||||
msg = format_signal_message(report)
|
||||
assert "TP 100p" in msg
|
||||
assert "3290.00" in msg, "SELL 100p TP must be entry - $10.00"
|
||||
# No setup → no informational TP line.
|
||||
report.trade_setup = None
|
||||
msg = format_signal_message(report)
|
||||
assert "TP 100p" not in msg
|
||||
|
||||
|
||||
@test("_indicator_summary condenses indicators to one arrow line")
|
||||
def _():
|
||||
config = PlatformConfig()
|
||||
agg = SignalAggregator(config)
|
||||
dfs = {
|
||||
Timeframe.H1: make_ohlcv(300, seed=42),
|
||||
Timeframe.M15: make_ohlcv(300, seed=43),
|
||||
Timeframe.H4: make_ohlcv(300, seed=44),
|
||||
}
|
||||
report = agg.analyze_from_dataframes("XAU/USD", dfs, use_news=False)
|
||||
summary = _indicator_summary(report)
|
||||
assert "EMA" in summary
|
||||
assert "RSI" in summary
|
||||
assert summary.count("\n") == 0, "summary must be a single line"
|
||||
msg = format_signal_message(report)
|
||||
assert summary in msg
|
||||
assert "[Bullish]" not in msg and "[Bearish]" not in msg and "[Neutral]" not in msg
|
||||
|
||||
|
||||
@test("_format_scan_summary produces valid text")
|
||||
def _():
|
||||
config = PlatformConfig()
|
||||
|
||||
Reference in New Issue
Block a user