feat: Add Trend Reversal Detector with multi-signal analysis
Deploy to Windows VPS / deploy (push) Has been cancelled

New features:
- Reversal Detector with 5 detection signals:
  - RSI Divergence (bearish/bullish)
  - EMA Slope Change detection
  - Volume Spike analysis
  - Candlestick patterns (Doji, Engulfing, Hammer, Pin Bar)
  - Break of Structure detection
- Integrated into enhanced_trading_check_wrapper (SCHRITT 2.5)
- Defensive mode: blocks trades at 70%+ reversal score
- Lot size reduction at 30-69% reversal score
- Enable Overlap session (13:00-16:00 UTC)

Files added:
- reversal_detector.py: Core detection algorithms
- reversal_integration.py: Bot integration wrapper
- REVERSAL_DETECTOR_INTEGRATION.md: Documentation

Modified:
- TradingBot notebook: Added reversal check integration
- session_filter_patch.py: Enabled overlap session

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-30 09:46:40 +01:00
co-authored by Claude Opus 4.5
parent b5b91224df
commit ce4e961541
5 changed files with 1623 additions and 177 deletions
+287
View File
@@ -0,0 +1,287 @@
#!/usr/bin/env python3
"""
🔄 REVERSAL DETECTOR INTEGRATION
Integriert den Reversal Detector in den Trading Bot
VERWENDUNG IM NOTEBOOK:
# Am Anfang importieren (nach den anderen Imports):
from reversal_integration import reversal_detector, check_reversal_risk
# In enhanced_trading_check_wrapper nach Signal Analysis:
reversal_result = check_reversal_risk(signal_info, symbol)
if not reversal_result['should_trade']:
print(f"⛔ TRADE BLOCKIERT durch Reversal Detector")
return None
# Lot Multiplier anpassen:
lot_multiplier *= reversal_result['lot_multiplier']
"""
import logging
from typing import Dict, Optional
import pandas as pd
# Import the reversal detector
from reversal_detector import ReversalDetector
logger = logging.getLogger(__name__)
# ==========================================
# GLOBAL REVERSAL DETECTOR INSTANCE
# ==========================================
# Initialize with defensive mode (blocks/reduces trades at high reversal risk)
reversal_detector = ReversalDetector(
rsi_period=14,
ema_fast=9,
ema_slow=21,
volume_spike_mult=2.0,
divergence_lookback=10,
mode="defensive" # "defensive" or "info"
)
# ==========================================
# CONFIGURATION
# ==========================================
REVERSAL_CONFIG = {
'enabled': True, # Reversal Check aktiviert
'block_threshold': 70, # Score >= 70 = Trade blockieren
'reduce_threshold': 50, # Score >= 50 = Lot reduzieren
'caution_threshold': 30, # Score >= 30 = Warnung
'use_m15_data': True, # M15 für Analyse verwenden
'use_h1_confirmation': True, # H1 für Bestätigung
}
# ==========================================
# INTEGRATION FUNCTION
# ==========================================
def check_reversal_risk(signal_info: Dict, symbol: str = "XAUUSD") -> Dict:
"""
Prüft Reversal-Risiko basierend auf Signal-Info
Args:
signal_info: Dict von extended_top_down_v2_adaptive()
symbol: Trading Symbol
Returns:
Dict mit:
- should_trade: bool
- reversal_score: int (0-100)
- lot_multiplier: float (1.0, 0.75, 0.5, 0.0)
- action: str (ALLOW, CAUTION, REDUCE, BLOCK)
- reason: str
"""
if not REVERSAL_CONFIG['enabled']:
return {
'should_trade': True,
'reversal_score': 0,
'lot_multiplier': 1.0,
'action': 'ALLOW',
'reason': 'Reversal check disabled'
}
if signal_info is None:
return {
'should_trade': True,
'reversal_score': 0,
'lot_multiplier': 1.0,
'action': 'ALLOW',
'reason': 'No signal info available'
}
try:
# Bestimme aktuellen Trend
entry_signal = signal_info.get('entry_signal', 0)
standard_trend = signal_info.get('standard_trend', 'sideways')
# Trend aus entry_signal ableiten falls standard_trend nicht verfügbar
if standard_trend == 'sideways' and entry_signal != 0:
current_trend = 'uptrend' if entry_signal == 1 else 'downtrend'
else:
current_trend = standard_trend
# Hole M15 DataFrame aus trend_info
trend_info = signal_info.get('trend_info', {})
df_m15 = None
df_h1 = None
# Versuche M15 Daten zu holen
if REVERSAL_CONFIG['use_m15_data'] and 'M15' in trend_info:
m15_info = trend_info['M15']
if isinstance(m15_info, dict) and 'df' in m15_info:
df_m15 = m15_info['df']
elif hasattr(m15_info, 'df'):
df_m15 = m15_info.df
# Versuche H1 Daten zu holen
if REVERSAL_CONFIG['use_h1_confirmation'] and 'H1' in trend_info:
h1_info = trend_info['H1']
if isinstance(h1_info, dict) and 'df' in h1_info:
df_h1 = h1_info['df']
elif hasattr(h1_info, 'df'):
df_h1 = h1_info.df
# Falls keine DataFrame verfügbar, versuche get_rates
if df_m15 is None:
try:
# Import get_rates falls verfügbar
import sys
if 'get_rates' in dir(sys.modules.get('__main__', {})):
from __main__ import get_rates
df_m15 = get_rates('m15', 100, symbol)
except Exception as e:
logger.debug(f"Could not get M15 data: {e}")
if df_m15 is None or len(df_m15) < 50:
print(f"⚠️ Reversal Check: Not enough M15 data, skipping")
return {
'should_trade': True,
'reversal_score': 0,
'lot_multiplier': 1.0,
'action': 'ALLOW',
'reason': 'Insufficient data for reversal check'
}
# Führe Reversal-Analyse durch
result = reversal_detector.analyze(
df=df_m15,
current_trend=current_trend,
df_higher_tf=df_h1
)
reversal_score = result['reversal_score']
# Bestimme Aktion basierend auf Config-Thresholds
if reversal_score >= REVERSAL_CONFIG['block_threshold']:
action = 'BLOCK'
lot_multiplier = 0.0
should_trade = False
reason = f"High reversal risk ({reversal_score}% >= {REVERSAL_CONFIG['block_threshold']}%)"
elif reversal_score >= REVERSAL_CONFIG['reduce_threshold']:
action = 'REDUCE'
lot_multiplier = 0.5
should_trade = True
reason = f"Moderate reversal risk ({reversal_score}%), lot reduced to 50%"
elif reversal_score >= REVERSAL_CONFIG['caution_threshold']:
action = 'CAUTION'
lot_multiplier = 0.75
should_trade = True
reason = f"Low reversal risk ({reversal_score}%), lot reduced to 75%"
else:
action = 'ALLOW'
lot_multiplier = 1.0
should_trade = True
reason = f"No significant reversal risk ({reversal_score}%)"
return {
'should_trade': should_trade,
'reversal_score': reversal_score,
'lot_multiplier': lot_multiplier,
'action': action,
'reason': reason,
'reversal_type': result.get('reversal_type', 'NONE'),
'signals': result.get('signals', {})
}
except Exception as e:
logger.error(f"Reversal check error: {e}")
print(f"⚠️ Reversal Check Error: {e}")
return {
'should_trade': True,
'reversal_score': 0,
'lot_multiplier': 1.0,
'action': 'ALLOW',
'reason': f'Error: {e}'
}
def get_reversal_status() -> str:
"""Gibt aktuellen Reversal Detector Status zurück"""
status = []
status.append("=" * 60)
status.append("🔄 REVERSAL DETECTOR STATUS")
status.append("=" * 60)
status.append(f" Enabled: {REVERSAL_CONFIG['enabled']}")
status.append(f" Mode: {reversal_detector.mode}")
status.append(f" Block Threshold: {REVERSAL_CONFIG['block_threshold']}%")
status.append(f" Reduce Threshold: {REVERSAL_CONFIG['reduce_threshold']}%")
status.append(f" Caution Threshold: {REVERSAL_CONFIG['caution_threshold']}%")
status.append("=" * 60)
return "\n".join(status)
def enable_reversal_check():
"""Aktiviert den Reversal Check"""
REVERSAL_CONFIG['enabled'] = True
print("✅ Reversal Check ENABLED")
def disable_reversal_check():
"""Deaktiviert den Reversal Check"""
REVERSAL_CONFIG['enabled'] = False
print("⚠️ Reversal Check DISABLED")
def set_reversal_mode(mode: str):
"""
Setzt den Reversal Detector Mode
Args:
mode: "defensive" (blockiert Trades) oder "info" (nur Logging)
"""
global reversal_detector
reversal_detector = ReversalDetector(
rsi_period=14,
ema_fast=9,
ema_slow=21,
volume_spike_mult=2.0,
divergence_lookback=10,
mode=mode
)
print(f"✅ Reversal Detector mode set to: {mode.upper()}")
# ==========================================
# STANDALONE TEST
# ==========================================
if __name__ == "__main__":
print(get_reversal_status())
# Test mit simulierten Daten
import numpy as np
np.random.seed(42)
n = 100
prices = np.linspace(100, 110, n) + np.random.normal(0, 0.5, n)
df = pd.DataFrame({
'open': prices - np.random.uniform(0, 0.3, n),
'high': prices + np.random.uniform(0.3, 0.8, n),
'low': prices - np.random.uniform(0.3, 0.8, n),
'close': prices,
'tick_volume': np.random.randint(100, 500, n)
})
# Simuliere signal_info
mock_signal_info = {
'entry_signal': 1,
'standard_trend': 'uptrend',
'trend_info': {
'M15': {'df': df}
}
}
print("\n🧪 Testing Reversal Check...")
result = check_reversal_risk(mock_signal_info, "XAUUSD")
print(f"\n📊 Result:")
print(f" Should Trade: {result['should_trade']}")
print(f" Reversal Score: {result['reversal_score']}%")
print(f" Action: {result['action']}")
print(f" Lot Multiplier: {result['lot_multiplier']}")
print(f" Reason: {result['reason']}")