Spaces:
Running on Zero
Running on Zero
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":
|
| 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
|
| 237 |
-
|
| 238 |
-
|
|
|
|
|
|
|
|
|
|
| 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 |
-
|
| 336 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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":
|
| 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
|