Harden Telegram bot, add EUR/GBP strategies, parallelize scans

Telegram reliability: rate-limited sends (1 msg/s), dashboard lock,
WebSocket JSON/price error handling, markdown escaping, level cache
TTL, cooldown cleanup, breach task tracking, graceful shutdown.

Telegram speed: parallelize 3-pair scans with asyncio.gather(),
increase thread pool 2→4, parallelize boot-up initial scan.

Strategy: add EUR/USD and GBP/USD pullback-buy strategies with
per-pair configs, optimize XAU TP to 0.9×ATR, block hours 8/9
for XAU and hour 17 for GBP.

Backtest: add --max-hours flag to evaluate.py for time-exit support.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
harwinder
2026-05-13 21:07:49 -04:00
parent 1f3f69c21d
commit 235241f95a
4 changed files with 494 additions and 66 deletions
+7 -2
View File
@@ -269,6 +269,7 @@ def evaluate_outcomes(
trades: List[Trade],
m5_data: Dict[str, pd.DataFrame],
max_bars: int = 500,
max_hours: int = 0,
) -> List[Trade]:
"""
For each trade, scan forward in M5 data to check if TP1 or SL hit first.
@@ -305,7 +306,9 @@ def evaluate_outcomes(
continue
start = int(start_indices[0])
end = min(start + max_bars, len(highs_gpu))
time_limit = max_hours * 12 if max_hours > 0 else max_bars
effective_max = min(time_limit, max_bars)
end = min(start + effective_max, len(highs_gpu))
if start >= end:
continue
@@ -532,6 +535,8 @@ def main():
help="Max M5 bars to scan for SL/TP hit (default: 1000 = ~83h)")
parser.add_argument("--pair", default=None,
help="Single pair to evaluate (EURUSD, USDJPY, GBPUSD, XAUUSD)")
parser.add_argument("--max-hours", type=int, default=0,
help="Max hours to hold a trade before time-exit (0 = disabled)")
args = parser.parse_args()
eval_tfs = EVAL_TIMEFRAMES
@@ -599,7 +604,7 @@ def main():
m5_data = {k: v for k, v in m5_data.items() if v is not None}
t2 = time.time()
all_trades = evaluate_outcomes(all_trades, m5_data, max_bars=args.max_outcome_bars)
all_trades = evaluate_outcomes(all_trades, m5_data, max_bars=args.max_outcome_bars, max_hours=args.max_hours)
print(f" Outcomes evaluated in {time.time() - t2:.3f}s")
# ── 4. Report ────────────────────────────────────────────────