2025-12-26 17:46:58 +01:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
"""
|
|
|
|
|
🎯 Session-Specific Confidence Filter
|
|
|
|
|
Wrapper für execute_trade_v2_adaptive mit session-spezifischen Confidence Thresholds
|
|
|
|
|
|
|
|
|
|
PERFORMANCE-VERBESSERUNG:
|
|
|
|
|
- Asian: >=95% Confidence (läuft perfekt, 97.8% WR)
|
|
|
|
|
- NY: >=97% Confidence (verbessert WR von 43.3% auf 56.5%!)
|
|
|
|
|
- London/Overlap: blockiert
|
|
|
|
|
|
|
|
|
|
ERWARTETER IMPACT:
|
|
|
|
|
- NY: 7 schlechte Trades eliminiert (<97% Confidence)
|
|
|
|
|
- Profit: +$292 mehr ($1,655 statt $1,363)
|
|
|
|
|
- Win-Rate gesamt: von 67.8% auf ~71%
|
|
|
|
|
- NY Win-Rate: von 43.3% auf 56.5%
|
|
|
|
|
"""
|
|
|
|
|
|
2026-05-12 10:12:25 +02:00
|
|
|
import logging
|
|
|
|
|
from functools import wraps
|
|
|
|
|
from adaptive_rhythm_manager import AdaptiveRhythmManager
|
2025-12-26 17:46:58 +01:00
|
|
|
from session_filter_patch import (
|
|
|
|
|
SESSION_WHITELIST_CONFIG,
|
|
|
|
|
get_session_confidence_threshold,
|
|
|
|
|
is_confidence_sufficient,
|
|
|
|
|
is_session_allowed
|
|
|
|
|
)
|
|
|
|
|
|
2026-05-12 10:12:25 +02:00
|
|
|
logger = logging.getLogger(__name__)
|
2025-12-26 17:46:58 +01:00
|
|
|
|
2026-05-12 10:12:25 +02:00
|
|
|
|
|
|
|
|
def create_session_confidence_filter(execute_trade_func, rhythm_manager=None):
|
2025-12-26 17:46:58 +01:00
|
|
|
"""
|
|
|
|
|
Erstellt gefilterte Version von execute_trade_v2_adaptive
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
execute_trade_func: Original execute_trade_v2_adaptive Funktion
|
2026-05-12 10:12:25 +02:00
|
|
|
rhythm_manager: Optional bestehende AdaptiveRhythmManager Instanz
|
2025-12-26 17:46:58 +01:00
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
Gefilterte Funktion mit session-spezifischen Confidence-Checks
|
|
|
|
|
"""
|
2026-05-12 10:12:25 +02:00
|
|
|
# Reuse provided instance or create one (not per-call)
|
|
|
|
|
_rhythm_mgr = rhythm_manager or AdaptiveRhythmManager()
|
2025-12-26 17:46:58 +01:00
|
|
|
|
2026-05-12 10:12:25 +02:00
|
|
|
@wraps(execute_trade_func)
|
2025-12-26 17:46:58 +01:00
|
|
|
def execute_trade_with_session_confidence_filter(
|
|
|
|
|
symbol="XAUUSD",
|
|
|
|
|
strategy_name="V1.6_Adaptive",
|
|
|
|
|
max_positions=1,
|
2026-05-12 10:12:25 +02:00
|
|
|
base_confidence=None,
|
2025-12-26 17:46:58 +01:00
|
|
|
max_risk_per_trade=None,
|
2026-05-12 10:12:25 +02:00
|
|
|
use_pullback_entry=False,
|
|
|
|
|
**kwargs
|
2025-12-26 17:46:58 +01:00
|
|
|
):
|
2026-05-12 10:12:25 +02:00
|
|
|
current_session = _rhythm_mgr.get_current_session()
|
2025-12-26 17:46:58 +01:00
|
|
|
|
|
|
|
|
# 1. Prüfe ob Session erlaubt ist
|
|
|
|
|
session_allowed, session_reason = is_session_allowed(current_session)
|
|
|
|
|
if not session_allowed:
|
2026-05-12 10:12:25 +02:00
|
|
|
logger.info(f"Trading SKIP (session): {session_reason}")
|
2025-12-26 17:46:58 +01:00
|
|
|
return
|
|
|
|
|
|
2026-05-12 10:12:25 +02:00
|
|
|
# 2. Hole Signal-Info für Confidence-Check
|
|
|
|
|
# NOTE: extended_top_down_v2_adaptive is defined in the notebook, not as a
|
|
|
|
|
# standalone module. This import will fail when called outside the notebook.
|
|
|
|
|
# In that context, the function is already in scope via the notebook's namespace.
|
2025-12-26 17:46:58 +01:00
|
|
|
try:
|
2026-05-12 10:12:25 +02:00
|
|
|
from extended_top_down_v2_adaptive import extended_top_down_v2_adaptive as _signal_fn
|
|
|
|
|
signal_info = _signal_fn(symbol)
|
2025-12-26 17:46:58 +01:00
|
|
|
confidence = signal_info.get("confidence", 0)
|
2026-05-12 10:12:25 +02:00
|
|
|
except ImportError:
|
|
|
|
|
logger.debug("extended_top_down_v2_adaptive not importable — skipping confidence pre-check")
|
|
|
|
|
confidence = base_confidence or SESSION_WHITELIST_CONFIG.get('base_confidence', 95)
|
2025-12-26 17:46:58 +01:00
|
|
|
except Exception as e:
|
2026-05-12 10:12:25 +02:00
|
|
|
logger.warning(f"Trading SKIP: Could not get signal info: {e}")
|
2025-12-26 17:46:58 +01:00
|
|
|
return
|
|
|
|
|
|
|
|
|
|
# 3. Prüfe session-spezifischen Confidence Threshold
|
2026-05-12 10:12:25 +02:00
|
|
|
conf_sufficient, conf_reason = is_confidence_sufficient(current_session, confidence)
|
2025-12-26 17:46:58 +01:00
|
|
|
if not conf_sufficient:
|
|
|
|
|
required_conf = get_session_confidence_threshold(current_session)
|
2026-05-12 10:12:25 +02:00
|
|
|
logger.info(f"Trading SKIP (confidence): {current_session.upper()} "
|
|
|
|
|
f"requires >={required_conf}%, got {confidence:.1f}%")
|
2025-12-26 17:46:58 +01:00
|
|
|
return
|
|
|
|
|
|
2026-05-12 10:12:25 +02:00
|
|
|
logger.debug(f"Confidence check passed: {conf_reason}")
|
2025-12-26 17:46:58 +01:00
|
|
|
|
2026-05-12 10:12:25 +02:00
|
|
|
effective_confidence = base_confidence if base_confidence is not None \
|
|
|
|
|
else SESSION_WHITELIST_CONFIG.get('base_confidence', 95)
|
2025-12-26 17:46:58 +01:00
|
|
|
if max_risk_per_trade is None:
|
|
|
|
|
max_risk_per_trade = SESSION_WHITELIST_CONFIG.get('max_risk_per_trade', 0.02)
|
|
|
|
|
|
|
|
|
|
return execute_trade_func(
|
|
|
|
|
symbol=symbol,
|
|
|
|
|
strategy_name=strategy_name,
|
|
|
|
|
max_positions=max_positions,
|
2026-05-12 10:12:25 +02:00
|
|
|
base_confidence=effective_confidence,
|
2025-12-26 17:46:58 +01:00
|
|
|
max_risk_per_trade=max_risk_per_trade,
|
2026-05-12 10:12:25 +02:00
|
|
|
use_pullback_entry=use_pullback_entry,
|
|
|
|
|
**kwargs
|
2025-12-26 17:46:58 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
return execute_trade_with_session_confidence_filter
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# ==========================================
|
|
|
|
|
# DIREKTER USAGE (falls nicht als Wrapper)
|
|
|
|
|
# ==========================================
|
|
|
|
|
|
|
|
|
|
def check_session_confidence(session_name, confidence):
|
|
|
|
|
"""
|
|
|
|
|
Standalone-Funktion zum Checken von Session + Confidence
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
session_name: 'asian', 'london', 'overlap', 'ny'
|
|
|
|
|
confidence: Signal Confidence (0-100)
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
(allowed: bool, reason: str)
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
# 1. Prüfe Session
|
|
|
|
|
session_allowed, session_reason = is_session_allowed(session_name)
|
|
|
|
|
|
|
|
|
|
if not session_allowed:
|
|
|
|
|
return False, f"Session blocked: {session_reason}"
|
|
|
|
|
|
|
|
|
|
# 2. Prüfe Confidence
|
|
|
|
|
conf_sufficient, conf_reason = is_confidence_sufficient(session_name, confidence)
|
|
|
|
|
|
|
|
|
|
if not conf_sufficient:
|
|
|
|
|
return False, f"Confidence insufficient: {conf_reason}"
|
|
|
|
|
|
|
|
|
|
# Both checks passed
|
|
|
|
|
return True, f"Trade allowed: {session_reason} AND {conf_reason}"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# ==========================================
|
|
|
|
|
# TESTING
|
|
|
|
|
# ==========================================
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
print("=" * 80)
|
|
|
|
|
print("🧪 SESSION CONFIDENCE FILTER - TEST")
|
|
|
|
|
print("=" * 80)
|
|
|
|
|
print()
|
|
|
|
|
|
|
|
|
|
# Test verschiedene Szenarien
|
|
|
|
|
test_cases = [
|
|
|
|
|
('asian', 96.0, True, "Asian mit 96% sollte OK sein (>=95%)"),
|
|
|
|
|
('asian', 94.0, False, "Asian mit 94% sollte blockiert werden (<95%)"),
|
|
|
|
|
('ny', 98.0, True, "NY mit 98% sollte OK sein (>=97%)"),
|
|
|
|
|
('ny', 96.0, False, "NY mit 96% sollte blockiert werden (<97%)"),
|
|
|
|
|
('london', 99.0, False, "London ist komplett blockiert"),
|
|
|
|
|
('overlap', 99.0, False, "Overlap ist komplett blockiert"),
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
for session, conf, expected_pass, description in test_cases:
|
|
|
|
|
allowed, reason = check_session_confidence(session, conf)
|
|
|
|
|
status = "✅ PASS" if allowed == expected_pass else "❌ FAIL"
|
|
|
|
|
print(f"{status} | {description}")
|
|
|
|
|
print(f" Session: {session}, Confidence: {conf}%")
|
|
|
|
|
print(f" Result: {'ALLOWED' if allowed else 'BLOCKED'}")
|
|
|
|
|
print(f" Reason: {reason}")
|
|
|
|
|
print()
|
|
|
|
|
|
|
|
|
|
print("=" * 80)
|
|
|
|
|
print("AKTUELLE THRESHOLDS:")
|
|
|
|
|
print("=" * 80)
|
|
|
|
|
for session in ['asian', 'ny', 'london', 'overlap']:
|
|
|
|
|
threshold = get_session_confidence_threshold(session)
|
|
|
|
|
enabled = SESSION_WHITELIST_CONFIG['enabled_sessions'].get(session, False)
|
|
|
|
|
status = "✅ ENABLED" if enabled else "❌ DISABLED"
|
|
|
|
|
print(f"{status} | {session.upper():8} >= {threshold}% Confidence")
|
|
|
|
|
print()
|