Sharif2615 commited on
Commit
b063d09
·
1 Parent(s): fd351a3

fix(telegram): dynamic TP1 calibration and pre-dispatch PEISF validation [LOG-20260922-037]

Browse files
autonomous_market_scanner.py CHANGED
@@ -508,6 +508,15 @@ def dispatch_top_pick_proposal(candidate):
508
  strat = candidate.get('strategy', 'PRECISION_SNIPER')
509
  matched_cnt = candidate.get('matched_count', len(candidate.get('matched_rules', [])) or 8)
510
 
 
 
 
 
 
 
 
 
 
511
  # Set as pending proposal in telegram copilot
512
  # 🏛️ Smart Deduplication & Rejection Cooldown (Pillar 5 of Master Plan)
513
  # 1. Anti-Spam Rejection Cooldown: If Sharif Bhai rejected this exact setup within 180s, don't spam him
@@ -550,6 +559,17 @@ def dispatch_top_pick_proposal(candidate):
550
  "timestamp": time.time(),
551
  "status": "AWAITING_APPROVAL"
552
  }
 
 
 
 
 
 
 
 
 
 
 
553
  telegram_copilot_service.set_pending_signal(sig_dict)
554
  try:
555
  trading_mode_manager.set_pending_signal_for_asset(asset, sig_dict)
@@ -1015,6 +1035,13 @@ def _scanner_worker():
1015
  dir_ = trigger_res["direction"]
1016
  dist = abs(entry_p - sl_p)
1017
 
 
 
 
 
 
 
 
1018
  # 🏛️ Sharif Bhai's 2-Tier Pyramiding Guard ($2+2=4)
1019
  tier_st = get_asset_trade_tier_status(a)
1020
  if not tier_st["can_open"]:
@@ -1029,7 +1056,7 @@ def _scanner_worker():
1029
  "direction": dir_,
1030
  "entry_price": entry_p,
1031
  "sl": sl_p,
1032
- "tp1": tp_p,
1033
  "tp2": round(entry_p + (dist * (1.5 if tier_num == 2 else 2.8)), 3) if dir_ == "BUY" else round(entry_p - (dist * (1.5 if tier_num == 2 else 2.8)), 3),
1034
  "tp3": round(entry_p + (dist * (1.5 if tier_num == 2 else 4.5)), 3) if dir_ == "BUY" else round(entry_p - (dist * (1.5 if tier_num == 2 else 4.5)), 3),
1035
  "lot": lot_size,
 
508
  strat = candidate.get('strategy', 'PRECISION_SNIPER')
509
  matched_cnt = candidate.get('matched_count', len(candidate.get('matched_rules', [])) or 8)
510
 
511
+ # 🏛️ Institutional Minimum 1:1.50 RR Calibration on TP1 ($2+2=4 Law)
512
+ dist = abs(price - sl)
513
+ if dist > 0:
514
+ min_tp1 = round(price + (dist * 1.5), 3) if direction == "BUY" else round(price - (dist * 1.5), 3)
515
+ if direction == "BUY":
516
+ tp1 = max(tp1, min_tp1)
517
+ else:
518
+ tp1 = min(tp1, min_tp1) if tp1 > 0 else min_tp1
519
+
520
  # Set as pending proposal in telegram copilot
521
  # 🏛️ Smart Deduplication & Rejection Cooldown (Pillar 5 of Master Plan)
522
  # 1. Anti-Spam Rejection Cooldown: If Sharif Bhai rejected this exact setup within 180s, don't spam him
 
559
  "timestamp": time.time(),
560
  "status": "AWAITING_APPROVAL"
561
  }
562
+
563
+ # 🏛️ Pre-Flight PEISF Invalidation Check BEFORE Telegram Dispatch ($2+2=4 Law)
564
+ try:
565
+ from core_shared.database_guard import validate_proposal_pre_execution
566
+ is_safe, peisf_err = validate_proposal_pre_execution(sig_dict, current_live_price=price)
567
+ if not is_safe:
568
+ print(f"[AutonomousScanner] ⚠️ Proposal for {asset} held from Telegram dispatch: {peisf_err}", flush=True)
569
+ return False
570
+ except Exception as _peisf_e:
571
+ print(f"[AutonomousScanner] Pre-dispatch PEISF check notice: {_peisf_e}", flush=True)
572
+
573
  telegram_copilot_service.set_pending_signal(sig_dict)
574
  try:
575
  trading_mode_manager.set_pending_signal_for_asset(asset, sig_dict)
 
1035
  dir_ = trigger_res["direction"]
1036
  dist = abs(entry_p - sl_p)
1037
 
1038
+ # 🏛️ Institutional Invariant: Guarantee TP1 >= 1.5R at exact 1M entry price ($2+2=4 Law)
1039
+ min_tp1 = round(entry_p + (dist * 1.5), 3) if dir_ == "BUY" else round(entry_p - (dist * 1.5), 3)
1040
+ if dir_ == "BUY":
1041
+ final_tp1 = max(tp_p, min_tp1)
1042
+ else:
1043
+ final_tp1 = min(tp_p, min_tp1) if tp_p > 0 else min_tp1
1044
+
1045
  # 🏛️ Sharif Bhai's 2-Tier Pyramiding Guard ($2+2=4)
1046
  tier_st = get_asset_trade_tier_status(a)
1047
  if not tier_st["can_open"]:
 
1056
  "direction": dir_,
1057
  "entry_price": entry_p,
1058
  "sl": sl_p,
1059
+ "tp1": final_tp1,
1060
  "tp2": round(entry_p + (dist * (1.5 if tier_num == 2 else 2.8)), 3) if dir_ == "BUY" else round(entry_p - (dist * (1.5 if tier_num == 2 else 2.8)), 3),
1061
  "tp3": round(entry_p + (dist * (1.5 if tier_num == 2 else 4.5)), 3) if dir_ == "BUY" else round(entry_p - (dist * (1.5 if tier_num == 2 else 4.5)), 3),
1062
  "lot": lot_size,
core_shared/database_guard.py CHANGED
@@ -233,8 +233,11 @@ def validate_proposal_pre_execution(
233
  else:
234
  risk = sl - entry
235
  reward = entry - tp1
236
- if risk > 0 and (reward / risk) < 1.5:
237
- rr_actual = round(reward / risk, 2)
238
- return False, f"🛑 RR রেশিও অপর্যাপ্ত ({rr_actual:.2f}:1 < 1.5:1 নূন্যতম)! ঝুঁকি-পুরস্কার অনুপাত সংবিধান লঙ্ঘন।"
 
 
 
239
 
240
  return True, "VALIDATED_SAFE"
 
233
  else:
234
  risk = sl - entry
235
  reward = entry - tp1
236
+ if risk > 0:
237
+ rr_ratio = reward / risk
238
+ # Floating-point representation tolerance: round(rr_ratio, 2) >= 1.50
239
+ if round(rr_ratio, 2) < 1.5 and rr_ratio < 1.49:
240
+ rr_actual = round(rr_ratio, 2)
241
+ return False, f"🛑 RR রেশিও অপর্যাপ্ত ({rr_actual:.2f}:1 < 1.5:1 নূন্যতম)! ঝুঁকি-পুরস্কার অনুপাত সংবিধান লঙ্ঘন।"
242
 
243
  return True, "VALIDATED_SAFE"
core_shared/tri_timeframe_sniper_engine.py CHANGED
@@ -332,8 +332,18 @@ class TriTimeframeSniperEngine:
332
 
333
  tight_sl = thesis["invalidation_level"]
334
  risk_distance = abs(execution_price - tight_sl)
335
- reward_distance = abs(thesis["target_profit"] - execution_price)
336
- rr_ratio = round(reward_distance / risk_distance, 2) if risk_distance > 0 else 1.0
 
 
 
 
 
 
 
 
 
 
337
 
338
  self.states[asset_u] = TradeState.TRIGGERED
339
  event = {
@@ -343,7 +353,7 @@ class TriTimeframeSniperEngine:
343
  "direction": thesis["direction"],
344
  "entry_price": execution_price,
345
  "stop_loss": tight_sl,
346
- "take_profit": thesis["target_profit"],
347
  "risk_pips": round(risk_distance * 10, 1),
348
  "reward_pips": round(reward_distance * 10, 1),
349
  "risk_reward_ratio": f"1:{rr_ratio}",
 
332
 
333
  tight_sl = thesis["invalidation_level"]
334
  risk_distance = abs(execution_price - tight_sl)
335
+
336
+ # 🏛️ Institutional Invariant: RR to TP1 MUST NEVER fall below 1:1.50 ($2+2=4 Law)
337
+ if thesis["direction"] == "BUY":
338
+ min_tp1 = round(execution_price + (risk_distance * 1.5), 3)
339
+ calibrated_tp = max(float(thesis.get("target_profit", min_tp1)), min_tp1)
340
+ else:
341
+ min_tp1 = round(execution_price - (risk_distance * 1.5), 3)
342
+ orig_tp = float(thesis.get("target_profit", min_tp1))
343
+ calibrated_tp = min(orig_tp, min_tp1) if orig_tp > 0 else min_tp1
344
+
345
+ reward_distance = abs(calibrated_tp - execution_price)
346
+ rr_ratio = round(reward_distance / risk_distance, 2) if risk_distance > 0 else 1.5
347
 
348
  self.states[asset_u] = TradeState.TRIGGERED
349
  event = {
 
353
  "direction": thesis["direction"],
354
  "entry_price": execution_price,
355
  "stop_loss": tight_sl,
356
+ "take_profit": calibrated_tp,
357
  "risk_pips": round(risk_distance * 10, 1),
358
  "reward_pips": round(reward_distance * 10, 1),
359
  "risk_reward_ratio": f"1:{rr_ratio}",
gemini_telegram_copilot/telegram_copilot_service.py CHANGED
@@ -1349,6 +1349,17 @@ def handle_signal_action(action: str, asset: str, signal_id: Optional[str] = Non
1349
  strat = pending.get('strategy_code', 'STRAT_1_SMC_GOLDEN_SNIPER')
1350
  rules = pending.get('rules_verified') or [{"rule": "10-Rules", "status": "PASSED"}]
1351
 
 
 
 
 
 
 
 
 
 
 
 
1352
  # Institutional Pre-Execution Guard (Strict 300s / 5m TTL & SL breach check)
1353
  try:
1354
  from core_shared.database_guard import validate_proposal_pre_execution
 
1349
  strat = pending.get('strategy_code', 'STRAT_1_SMC_GOLDEN_SNIPER')
1350
  rules = pending.get('rules_verified') or [{"rule": "10-Rules", "status": "PASSED"}]
1351
 
1352
+ # 🏛️ Self-Healing TP1 Invariant ($2+2=4 Law):
1353
+ # Guarantee that pending['tp1'] maintains minimum 1:1.50 RR from entry_price
1354
+ dist = abs(entry_price - sl)
1355
+ if dist > 0:
1356
+ min_tp1 = round(entry_price + (dist * 1.5), 3) if direction == 'BUY' else round(entry_price - (dist * 1.5), 3)
1357
+ cur_tp1 = float(pending.get('tp1', 0.0))
1358
+ if direction == 'BUY':
1359
+ pending['tp1'] = max(cur_tp1, min_tp1)
1360
+ else:
1361
+ pending['tp1'] = min(cur_tp1, min_tp1) if cur_tp1 > 0 else min_tp1
1362
+
1363
  # Institutional Pre-Execution Guard (Strict 300s / 5m TTL & SL breach check)
1364
  try:
1365
  from core_shared.database_guard import validate_proposal_pre_execution