mirror of
https://github.com/NicolasBohn/NexQuant.git
synced 2026-08-01 17:37:43 +00:00
feat: EURUSD Trading-Verbesserungen (Phase 2 & 3)
Neue Module für fortgeschrittenes Trading: 1. Bull vs Bear vs Neutral Debatte (eurusd_debate.py) - Multi-Perspektiven-Analyse für bessere Entscheidungen - Bull Agent: Argumentiert für LONG - Bear Agent: Argumentiert für SHORT - Neutral Agent: Argumentiert für WAIT - Research Manager: Bewertet Debatte und trifft finale Entscheidung - Decision-Logik: LONG wenn Bull > 70% und > Bear + 20 2. EURUSD Macro Agent (eurusd_macro.py) - Stanley Druckenmiller Stil für Makro-Trading - Analysiert Zinsdifferential (Fed vs EZB) - Wirtschaftswachstum (BIP, PMI, NFP) - Momentum (DXY Trend) - Sentiment (Risk-On/Off, COT Report) - Asymmetrische Risk-Reward-Analyse - Bei hoher Conviction + asymmetrischer Chance: große Position 3. Reflection System (eurusd_reflection.py) - Lernt aus vergangenen Trades kontinuierlich - Analysiert was richtig/falsch lief - Extrahiert Lessons Learned - Speichert im BM25 Memory für ähnliche Situationen - Aggregierte Insights für letzte N Trades 4. Korrelations-Adjustierung (in eurusd_risk.py erweitert) - Berechnet Korrelation mit anderen Forex-Positionen - GBPUSD: +0.75, USDCHF: -0.70, DXY: -0.85 - Hohe Korrelation → Risk reduzieren (0.7x) - Negative Korrelation → natürlicher Hedge (1.1x) Alle Module getestet und funktionsfähig.
This commit is contained in:
@@ -0,0 +1,708 @@
|
||||
"""
|
||||
EURUSD Trading-Debatte: Bull vs Bear vs Neutral
|
||||
|
||||
Inspiriert von: TradingAgents/tradingagents/agents/researchers/
|
||||
|
||||
Multi-Perspektiven-Debatte für bessere Trading-Entscheidungen:
|
||||
- Bull Agent: Argumentiert für LONG EURUSD
|
||||
- Bear Agent: Argumentiert für SHORT EURUSD
|
||||
- Neutral Agent: Argumentiert für WAIT/Range-Trading
|
||||
|
||||
Jeder Agent analysiert die gleichen Daten aus seiner Perspektive.
|
||||
Ein Research Manager bewertet die Debatte und trifft die finale Entscheidung.
|
||||
"""
|
||||
|
||||
import json
|
||||
import sys
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
from typing import Dict, List, Literal, Optional
|
||||
|
||||
# Füge Parent-Directory zum Path hinzu für lokale Imports
|
||||
sys.path.insert(0, str(Path(__file__).parent))
|
||||
|
||||
from eurusd_llm import MultiProviderLLM
|
||||
|
||||
|
||||
@dataclass
|
||||
class TradingSignal:
|
||||
"""Trading-Signal mit Details."""
|
||||
action: Literal["LONG", "SHORT", "NEUTRAL"]
|
||||
confidence: int # 0-100
|
||||
reasoning: List[str]
|
||||
entry_price: Optional[float] = None
|
||||
stop_loss: Optional[float] = None
|
||||
take_profit: Optional[float] = None
|
||||
leverage: Optional[int] = None
|
||||
|
||||
|
||||
class EURUSDBullAgent:
|
||||
"""
|
||||
Bull Agent: Argumentiert für LONG EURUSD.
|
||||
|
||||
Sucht nach positiven Faktoren für EUR:
|
||||
- EZB hawkish (Zinserhöhungen)
|
||||
- Positive Wirtschaftsdaten aus Eurozone
|
||||
- USD-Schwäche (Fed dovish, schlechte US-Daten)
|
||||
- Technisches Setup (Support, bullish Patterns)
|
||||
- Positives Sentiment (Risk-On)
|
||||
"""
|
||||
|
||||
def __init__(self, llm: Optional[MultiProviderLLM] = None):
|
||||
self.llm = llm or MultiProviderLLM()
|
||||
|
||||
def analyze(self, market_data: dict) -> TradingSignal:
|
||||
"""
|
||||
Analysiert Marktdaten aus Bull-Perspektive.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
market_data : dict
|
||||
Marktdaten mit Keys:
|
||||
- price: aktueller EURUSD-Preis
|
||||
- hurst_regime: "MEAN_REVERSION", "NEUTRAL", "TRENDING"
|
||||
- rsi: RSI-Wert
|
||||
- macd: MACD-Signal
|
||||
- economic_data: Wirtschaftsdaten
|
||||
- sentiment: Marktstimmung
|
||||
|
||||
Returns
|
||||
-------
|
||||
TradingSignal
|
||||
Bull-Signal mit LONG-Empfehlung und Confidence
|
||||
"""
|
||||
prompt = self._build_bull_prompt(market_data)
|
||||
|
||||
system_prompt = """Du bist ein EURUSD Bull Analyst. Deine Aufgabe ist es,
|
||||
Argumente FÜR einen LONG EURUSD Trade zu finden.
|
||||
|
||||
Analysiere die Daten und finde positive Faktoren für EUR:
|
||||
- EZB hawkish vs Fed dovish
|
||||
- Positive Eurozone-Wirtschaftsdaten
|
||||
- USD-Schwäche
|
||||
- Bullische technische Signale
|
||||
- Risk-On Sentiment
|
||||
|
||||
Antworte IMMER im JSON-Format."""
|
||||
|
||||
try:
|
||||
response = self.llm.chat(
|
||||
prompt=prompt,
|
||||
system_prompt=system_prompt,
|
||||
temperature=0.1,
|
||||
max_tokens=500,
|
||||
json_mode=True
|
||||
)
|
||||
|
||||
result = json.loads(response["content"])
|
||||
|
||||
return TradingSignal(
|
||||
action="LONG",
|
||||
confidence=min(100, max(0, result.get("confidence", 50))),
|
||||
reasoning=result.get("reasons", []),
|
||||
entry_price=market_data.get("price"),
|
||||
stop_loss=result.get("stop_loss"),
|
||||
take_profit=result.get("take_profit"),
|
||||
leverage=result.get("leverage", 20)
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
# Fallback bei Fehlern
|
||||
return TradingSignal(
|
||||
action="LONG",
|
||||
confidence=50,
|
||||
reasoning=[f"Bull-Analyse fehlgeschlagen: {str(e)}"],
|
||||
entry_price=market_data.get("price")
|
||||
)
|
||||
|
||||
def _build_bull_prompt(self, data: dict) -> str:
|
||||
"""Erstellt Bull-spezifischen Prompt."""
|
||||
return f"""
|
||||
Analysiere EURUSD für LONG-Setup:
|
||||
|
||||
Aktuelle Daten:
|
||||
- Preis: {data.get('price', 'N/A')}
|
||||
- Hurst Regime: {data.get('hurst_regime', 'N/A')}
|
||||
- RSI: {data.get('rsi', 'N/A')}
|
||||
- MACD: {data.get('macd', 'N/A')}
|
||||
- Wirtschaftsdaten: {data.get('economic_data', 'N/A')}
|
||||
- Sentiment: {data.get('sentiment', 'N/A')}
|
||||
|
||||
Finde Argumente FÜR LONG EURUSD:
|
||||
1. Welche positiven Faktoren für EUR siehst du?
|
||||
2. Gibt es USD-Schwäche?
|
||||
3. Ist das technische Setup bullisch?
|
||||
4. Was ist das Risk/Reward?
|
||||
|
||||
Antworte als JSON:
|
||||
{{
|
||||
"confidence": 0-100,
|
||||
"reasons": ["Grund 1", "Grund 2", ...],
|
||||
"stop_loss": 1.0800,
|
||||
"take_profit": 1.0950,
|
||||
"leverage": 20
|
||||
}}
|
||||
"""
|
||||
|
||||
|
||||
class EURUSDBearAgent:
|
||||
"""
|
||||
Bear Agent: Argumentiert für SHORT EURUSD.
|
||||
|
||||
Sucht nach negativen Faktoren für EUR:
|
||||
- EZB dovish (Zinssenkungen)
|
||||
- Negative Wirtschaftsdaten aus Eurozone
|
||||
- USD-Stärke (Fed hawkish, gute US-Daten)
|
||||
- Technisches Setup (Resistance, bearish Patterns)
|
||||
- Negatives Sentiment (Risk-Off)
|
||||
"""
|
||||
|
||||
def __init__(self, llm: Optional[MultiProviderLLM] = None):
|
||||
self.llm = llm or MultiProviderLLM()
|
||||
|
||||
def analyze(self, market_data: dict) -> TradingSignal:
|
||||
"""
|
||||
Analysiert Marktdaten aus Bear-Perspektive.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
market_data : dict
|
||||
Gleiche Daten wie Bull Agent
|
||||
|
||||
Returns
|
||||
-------
|
||||
TradingSignal
|
||||
Bear-Signal mit SHORT-Empfehlung und Confidence
|
||||
"""
|
||||
prompt = self._build_bear_prompt(market_data)
|
||||
|
||||
system_prompt = """Du bist ein EURUSD Bear Analyst. Deine Aufgabe ist es,
|
||||
Argumente FÜR einen SHORT EURUSD Trade zu finden.
|
||||
|
||||
Analysiere die Daten und finde negative Faktoren für EUR:
|
||||
- EZB dovish vs Fed hawkish
|
||||
- Negative Eurozone-Wirtschaftsdaten
|
||||
- USD-Stärke
|
||||
- Bearische technische Signale
|
||||
- Risk-Off Sentiment
|
||||
|
||||
Antworte IMMER im JSON-Format."""
|
||||
|
||||
try:
|
||||
response = self.llm.chat(
|
||||
prompt=prompt,
|
||||
system_prompt=system_prompt,
|
||||
temperature=0.1,
|
||||
max_tokens=500,
|
||||
json_mode=True
|
||||
)
|
||||
|
||||
result = json.loads(response["content"])
|
||||
|
||||
return TradingSignal(
|
||||
action="SHORT",
|
||||
confidence=min(100, max(0, result.get("confidence", 50))),
|
||||
reasoning=result.get("reasons", []),
|
||||
entry_price=market_data.get("price"),
|
||||
stop_loss=result.get("stop_loss"),
|
||||
take_profit=result.get("take_profit"),
|
||||
leverage=result.get("leverage", 20)
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
return TradingSignal(
|
||||
action="SHORT",
|
||||
confidence=50,
|
||||
reasoning=[f"Bear-Analyse fehlgeschlagen: {str(e)}"],
|
||||
entry_price=market_data.get("price")
|
||||
)
|
||||
|
||||
def _build_bear_prompt(self, data: dict) -> str:
|
||||
"""Erstellt Bear-spezifischen Prompt."""
|
||||
return f"""
|
||||
Analysiere EURUSD für SHORT-Setup:
|
||||
|
||||
Aktuelle Daten:
|
||||
- Preis: {data.get('price', 'N/A')}
|
||||
- Hurst Regime: {data.get('hurst_regime', 'N/A')}
|
||||
- RSI: {data.get('rsi', 'N/A')}
|
||||
- MACD: {data.get('macd', 'N/A')}
|
||||
- Wirtschaftsdaten: {data.get('economic_data', 'N/A')}
|
||||
- Sentiment: {data.get('sentiment', 'N/A')}
|
||||
|
||||
Finde Argumente FÜR SHORT EURUSD:
|
||||
1. Welche negativen Faktoren für EUR siehst du?
|
||||
2. Gibt es USD-Stärke?
|
||||
3. Ist das technische Setup bearisch?
|
||||
4. Was ist das Risk/Reward?
|
||||
|
||||
Antworte als JSON:
|
||||
{{
|
||||
"confidence": 0-100,
|
||||
"reasons": ["Grund 1", "Grund 2", ...],
|
||||
"stop_loss": 1.0950,
|
||||
"take_profit": 1.0800,
|
||||
"leverage": 20
|
||||
}}
|
||||
"""
|
||||
|
||||
|
||||
class EURUSDNeutralAgent:
|
||||
"""
|
||||
Neutral Agent: Argumentiert für WAIT/Range-Trading.
|
||||
|
||||
Sucht nach Gründen für Abwarten:
|
||||
- Unklares Marktregime (Hurst 0.4-0.6)
|
||||
- Widersprüchliche Signale
|
||||
- Wichtige News bevorstehend (NFP, EZB, Fed)
|
||||
- Enge Range ohne klaren Ausbruch
|
||||
- Zu geringes Risk/Reward
|
||||
"""
|
||||
|
||||
def __init__(self, llm: Optional[MultiProviderLLM] = None):
|
||||
self.llm = llm or MultiProviderLLM()
|
||||
|
||||
def analyze(self, market_data: dict) -> TradingSignal:
|
||||
"""
|
||||
Analysiert Marktdaten aus Neutral-Perspektive.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
market_data : dict
|
||||
Gleiche Daten wie andere Agenten
|
||||
|
||||
Returns
|
||||
-------
|
||||
TradingSignal
|
||||
Neutral-Signal mit WAIT-Empfehlung
|
||||
"""
|
||||
prompt = self._build_neutral_prompt(market_data)
|
||||
|
||||
system_prompt = """Du bist ein EURUSD Neutral Analyst. Deine Aufgabe ist es,
|
||||
Argumente für ABWARTEN oder RANGE-TRADING zu finden.
|
||||
|
||||
Analysiere die Daten und finde Gründe für Vorsicht:
|
||||
- Unklares Marktregime
|
||||
- Widersprüchliche Signale
|
||||
- Wichtige News bevorstehend
|
||||
- Zu geringes Risk/Reward
|
||||
- Choppy Market
|
||||
|
||||
Antworte IMMER im JSON-Format."""
|
||||
|
||||
try:
|
||||
response = self.llm.chat(
|
||||
prompt=prompt,
|
||||
system_prompt=system_prompt,
|
||||
temperature=0.1,
|
||||
max_tokens=500,
|
||||
json_mode=True
|
||||
)
|
||||
|
||||
result = json.loads(response["content"])
|
||||
|
||||
return TradingSignal(
|
||||
action="NEUTRAL",
|
||||
confidence=min(100, max(0, result.get("confidence", 50))),
|
||||
reasoning=result.get("reasons", []),
|
||||
entry_price=market_data.get("price"),
|
||||
stop_loss=None,
|
||||
take_profit=None,
|
||||
leverage=0
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
return TradingSignal(
|
||||
action="NEUTRAL",
|
||||
confidence=50,
|
||||
reasoning=[f"Neutral-Analyse fehlgeschlagen: {str(e)}"],
|
||||
entry_price=market_data.get("price")
|
||||
)
|
||||
|
||||
def _build_neutral_prompt(self, data: dict) -> str:
|
||||
"""Erstellt Neutral-spezifischen Prompt."""
|
||||
return f"""
|
||||
Analysiere EURUSD für WAIT/Range-Trading:
|
||||
|
||||
Aktuelle Daten:
|
||||
- Preis: {data.get('price', 'N/A')}
|
||||
- Hurst Regime: {data.get('hurst_regime', 'N/A')}
|
||||
- RSI: {data.get('rsi', 'N/A')}
|
||||
- MACD: {data.get('macd', 'N/A')}
|
||||
- Wirtschaftsdaten: {data.get('economic_data', 'N/A')}
|
||||
- Sentiment: {data.get('sentiment', 'N/A')}
|
||||
|
||||
Finde Argumente für ABWARTEN:
|
||||
1. Ist das Marktregime unklar?
|
||||
2. Gibt es widersprüchliche Signale?
|
||||
3. Stehen wichtige News an (NFP, EZB, Fed)?
|
||||
4. Ist das Risk/Reward zu gering?
|
||||
|
||||
Antworte als JSON:
|
||||
{{
|
||||
"confidence": 0-100,
|
||||
"reasons": ["Grund 1", "Grund 2", ...],
|
||||
"range_low": 1.0820,
|
||||
"range_high": 1.0900
|
||||
}}
|
||||
"""
|
||||
|
||||
|
||||
class EURUSDResearchManager:
|
||||
"""
|
||||
Research Manager: Bewertet Bull/Bear/Neutral Debatte.
|
||||
|
||||
Analysiert alle drei Signale und trifft finale Entscheidung:
|
||||
- Wenn Bull Confidence >> Bear Confidence → LONG
|
||||
- Wenn Bear Confidence >> Bull Confidence → SHORT
|
||||
- Wenn Neutral Confidence hoch oder uneindeutig → NEUTRAL
|
||||
"""
|
||||
|
||||
def __init__(self, llm: Optional[MultiProviderLLM] = None):
|
||||
self.llm = llm or MultiProviderLLM()
|
||||
|
||||
def evaluate(
|
||||
self,
|
||||
bull_signal: TradingSignal,
|
||||
bear_signal: TradingSignal,
|
||||
neutral_signal: TradingSignal,
|
||||
market_data: dict
|
||||
) -> TradingSignal:
|
||||
"""
|
||||
Bewertet Debatte und trifft finale Entscheidung.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
bull_signal : TradingSignal
|
||||
Bull-Analyse
|
||||
bear_signal : TradingSignal
|
||||
Bear-Analyse
|
||||
neutral_signal : TradingSignal
|
||||
Neutral-Analyse
|
||||
market_data : dict
|
||||
Marktdaten
|
||||
|
||||
Returns
|
||||
-------
|
||||
TradingSignal
|
||||
Finale Trading-Entscheidung
|
||||
"""
|
||||
prompt = self._build_evaluation_prompt(
|
||||
bull_signal, bear_signal, neutral_signal, market_data
|
||||
)
|
||||
|
||||
system_prompt = """Du bist ein EURUSD Research Manager. Deine Aufgabe ist es,
|
||||
die Bull/Bear/Neutral-Analysen zu bewerten und eine finale Entscheidung zu treffen.
|
||||
|
||||
Entscheidungslogik:
|
||||
- Wenn Bull Confidence > 70 und > Bear Confidence + 20 → LONG
|
||||
- Wenn Bear Confidence > 70 und > Bull Confidence + 20 → SHORT
|
||||
- Wenn Neutral Confidence > 60 oder Differenz < 20 → NEUTRAL/WAIT
|
||||
- Berücksichtige auch Hurst-Regime und Risk/Reward
|
||||
|
||||
Antworte IMMER im JSON-Format."""
|
||||
|
||||
try:
|
||||
response = self.llm.chat(
|
||||
prompt=prompt,
|
||||
system_prompt=system_prompt,
|
||||
temperature=0.1,
|
||||
max_tokens=600,
|
||||
json_mode=True
|
||||
)
|
||||
|
||||
result = json.loads(response["content"])
|
||||
|
||||
action = result.get("action", "NEUTRAL")
|
||||
if action not in ["LONG", "SHORT", "NEUTRAL"]:
|
||||
action = "NEUTRAL"
|
||||
|
||||
return TradingSignal(
|
||||
action=action,
|
||||
confidence=min(100, max(0, result.get("confidence", 50))),
|
||||
reasoning=result.get("reasons", []),
|
||||
entry_price=market_data.get("price"),
|
||||
stop_loss=result.get("stop_loss"),
|
||||
take_profit=result.get("take_profit"),
|
||||
leverage=result.get("leverage", 0 if action == "NEUTRAL" else 20)
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
# Default zu NEUTRAL bei Fehlern
|
||||
return TradingSignal(
|
||||
action="NEUTRAL",
|
||||
confidence=50,
|
||||
reasoning=[f"Research Manager fehlgeschlagen: {str(e)}"],
|
||||
entry_price=market_data.get("price")
|
||||
)
|
||||
|
||||
def _build_evaluation_prompt(
|
||||
self,
|
||||
bull: TradingSignal,
|
||||
bear: TradingSignal,
|
||||
neutral: TradingSignal,
|
||||
data: dict
|
||||
) -> str:
|
||||
"""Erstellt Evaluations-Prompt."""
|
||||
return f"""
|
||||
Bewerte Bull/Bear/Neutral Debatte für EURUSD:
|
||||
|
||||
=== Bull Argumente (Confidence: {bull.confidence}) ===
|
||||
{chr(10).join(f"- {r}" for r in bull.reasoning)}
|
||||
Stop Loss: {bull.stop_loss}, Take Profit: {bull.take_profit}, Leverage: {bull.leverage}
|
||||
|
||||
=== Bear Argumente (Confidence: {bear.confidence}) ===
|
||||
{chr(10).join(f"- {r}" for r in bear.reasoning)}
|
||||
Stop Loss: {bear.stop_loss}, Take Profit: {bear.take_profit}, Leverage: {bear.leverage}
|
||||
|
||||
=== Neutral Argumente (Confidence: {neutral.confidence}) ===
|
||||
{chr(10).join(f"- {r}" for r in neutral.reasoning)}
|
||||
|
||||
=== Marktdaten ===
|
||||
- Preis: {data.get('price', 'N/A')}
|
||||
- Hurst Regime: {data.get('hurst_regime', 'N/A')}
|
||||
- RSI: {data.get('rsi', 'N/A')}
|
||||
|
||||
Treffe eine finale Entscheidung (LONG/SHORT/NEUTRAL):
|
||||
|
||||
Antworte als JSON:
|
||||
{{
|
||||
"action": "LONG" oder "SHORT" oder "NEUTRAL",
|
||||
"confidence": 0-100,
|
||||
"reasons": ["Warum diese Entscheidung", ...],
|
||||
"stop_loss": 1.0800,
|
||||
"take_profit": 1.0950,
|
||||
"leverage": 20
|
||||
}}
|
||||
"""
|
||||
|
||||
|
||||
class EURUSDDebateTeam:
|
||||
"""
|
||||
Komplettes Debate-Team für EURUSD Trading-Entscheidungen.
|
||||
|
||||
Verwendung:
|
||||
>>> debate = EURUSDDebateTeam()
|
||||
>>> market_data = {
|
||||
... "price": 1.0850,
|
||||
... "hurst_regime": "MEAN_REVERSION",
|
||||
... "rsi": 28,
|
||||
... "macd": "bullish",
|
||||
... "economic_data": "EZB hawkish, Fed pause",
|
||||
... "sentiment": "risk-on"
|
||||
... }
|
||||
>>> signal = debate.run_debate(market_data)
|
||||
>>> print(f"Signal: {signal.action} ({signal.confidence}%)")
|
||||
"""
|
||||
|
||||
def __init__(self, llm: Optional[MultiProviderLLM] = None):
|
||||
self.llm = llm or MultiProviderLLM()
|
||||
self.bull = EURUSDBullAgent(self.llm)
|
||||
self.bear = EURUSDBearAgent(self.llm)
|
||||
self.neutral = EURUSDNeutralAgent(self.llm)
|
||||
self.manager = EURUSDResearchManager(self.llm)
|
||||
|
||||
def run_debate(self, market_data: dict) -> TradingSignal:
|
||||
"""
|
||||
Führt komplette Bull/Bear/Neutral Debatte durch.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
market_data : dict
|
||||
Marktdaten für die Analyse
|
||||
|
||||
Returns
|
||||
-------
|
||||
TradingSignal
|
||||
Finale Trading-Entscheidung nach Debatte
|
||||
"""
|
||||
# Alle Agenten analysieren parallel (unabhängig)
|
||||
bull_signal = self.bull.analyze(market_data)
|
||||
bear_signal = self.bear.analyze(market_data)
|
||||
neutral_signal = self.neutral.analyze(market_data)
|
||||
|
||||
# Research Manager bewertet und entscheidet
|
||||
final_signal = self.manager.evaluate(
|
||||
bull_signal, bear_signal, neutral_signal, market_data
|
||||
)
|
||||
|
||||
return final_signal
|
||||
|
||||
def get_debate_summary(
|
||||
self,
|
||||
bull: TradingSignal,
|
||||
bear: TradingSignal,
|
||||
neutral: TradingSignal,
|
||||
final: TradingSignal
|
||||
) -> str:
|
||||
"""
|
||||
Erstellt Zusammenfassung der Debatte.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
bull, bear, neutral : TradingSignal
|
||||
Einzelne Agenten-Signale
|
||||
final : TradingSignal
|
||||
Finale Entscheidung
|
||||
|
||||
Returns
|
||||
-------
|
||||
str
|
||||
Formatierter Debatten-Bericht
|
||||
"""
|
||||
summary = []
|
||||
summary.append("=" * 60)
|
||||
summary.append("EURUSD DEBATE SUMMARY")
|
||||
summary.append("=" * 60)
|
||||
|
||||
summary.append(f"\n🐂 BULL (Confidence: {bull.confidence}%)")
|
||||
for reason in bull.reasoning[:3]:
|
||||
summary.append(f" • {reason}")
|
||||
|
||||
summary.append(f"\n🐻 BEAR (Confidence: {bear.confidence}%)")
|
||||
for reason in bear.reasoning[:3]:
|
||||
summary.append(f" • {reason}")
|
||||
|
||||
summary.append(f"\n😐 NEUTRAL (Confidence: {neutral.confidence}%)")
|
||||
for reason in neutral.reasoning[:3]:
|
||||
summary.append(f" • {reason}")
|
||||
|
||||
summary.append(f"\n{'=' * 60}")
|
||||
emoji = {"LONG": "📈", "SHORT": "📉", "NEUTRAL": "⏸️"}
|
||||
summary.append(f"FINALE ENTSCHEIDUNG: {emoji.get(final.action, '')} {final.action}")
|
||||
summary.append(f"Confidence: {final.confidence}%")
|
||||
summary.append(f"Leverage: {final.leverage}x")
|
||||
|
||||
if final.stop_loss and final.take_profit:
|
||||
summary.append(f"Stop Loss: {final.stop_loss}")
|
||||
summary.append(f"Take Profit: {final.take_profit}")
|
||||
|
||||
summary.append(f"\nBegründung:")
|
||||
for reason in final.reasoning[:3]:
|
||||
summary.append(f" • {reason}")
|
||||
|
||||
return "\n".join(summary)
|
||||
|
||||
|
||||
# Test-Funktion für lokale Validierung
|
||||
if __name__ == "__main__":
|
||||
print("=== EURUSD Debate Team Test (Mock Mode) ===\n")
|
||||
|
||||
# Test-Marktdaten
|
||||
test_market_data = {
|
||||
"price": 1.0850,
|
||||
"hurst_regime": "MEAN_REVERSION",
|
||||
"rsi": 28,
|
||||
"macd": "bullish",
|
||||
"economic_data": "EZB hawkish, Fed pause, Eurozone PMI beat",
|
||||
"sentiment": "risk-on"
|
||||
}
|
||||
|
||||
print("Marktdaten:")
|
||||
for key, value in test_market_data.items():
|
||||
print(f" {key}: {value}")
|
||||
|
||||
# Teste TradingSignal Dataclass
|
||||
print("\n=== Test 1: TradingSignal Dataclass ===")
|
||||
bull_signal = TradingSignal(
|
||||
action="LONG",
|
||||
confidence=75,
|
||||
reasoning=[
|
||||
"RSI < 30 in Mean-Reversion Regime = gute Long-Opportunity",
|
||||
"EZB hawkish unterstützt EUR",
|
||||
"Risk-On Sentiment begünstigt EUR"
|
||||
],
|
||||
entry_price=1.0850,
|
||||
stop_loss=1.0820,
|
||||
take_profit=1.0920,
|
||||
leverage=20
|
||||
)
|
||||
print(f"✓ Bull Signal erstellt: {bull_signal.action} @ {bull_signal.confidence}%")
|
||||
|
||||
bear_signal = TradingSignal(
|
||||
action="SHORT",
|
||||
confidence=45,
|
||||
reasoning=[
|
||||
"Widerstand bei 1.0900 stark",
|
||||
"US-Daten könnten besser werden"
|
||||
],
|
||||
entry_price=1.0850,
|
||||
stop_loss=1.0900,
|
||||
take_profit=1.0780,
|
||||
leverage=15
|
||||
)
|
||||
print(f"✓ Bear Signal erstellt: {bear_signal.action} @ {bear_signal.confidence}%")
|
||||
|
||||
neutral_signal = TradingSignal(
|
||||
action="NEUTRAL",
|
||||
confidence=60,
|
||||
reasoning=[
|
||||
"Warte auf NFP am Freitag",
|
||||
"Range-Trading zwischen 1.0800-1.0900 sinnvoller"
|
||||
],
|
||||
entry_price=1.0850
|
||||
)
|
||||
print(f"✓ Neutral Signal erstellt: {neutral_signal.action} @ {neutral_signal.confidence}%")
|
||||
|
||||
# Teste Research Manager Decision Logic (ohne LLM)
|
||||
print("\n=== Test 2: Research Manager Decision Logic ===")
|
||||
|
||||
# Simuliere Decision-Logik
|
||||
if bull_signal.confidence > 70 and bull_signal.confidence > bear_signal.confidence + 20:
|
||||
final_action = "LONG"
|
||||
final_confidence = bull_signal.confidence
|
||||
elif bear_signal.confidence > 70 and bear_signal.confidence > bull_signal.confidence + 20:
|
||||
final_action = "SHORT"
|
||||
final_confidence = bear_signal.confidence
|
||||
elif neutral_signal.confidence > 60 or abs(bull_signal.confidence - bear_signal.confidence) < 20:
|
||||
final_action = "NEUTRAL"
|
||||
final_confidence = neutral_signal.confidence
|
||||
else:
|
||||
# Höhere Confidence gewinnt
|
||||
if bull_signal.confidence > bear_signal.confidence:
|
||||
final_action = "LONG"
|
||||
final_confidence = bull_signal.confidence
|
||||
else:
|
||||
final_action = "SHORT"
|
||||
final_confidence = bear_signal.confidence
|
||||
|
||||
print(f"Decision Logic:")
|
||||
print(f" Bull: {bull_signal.confidence}%, Bear: {bear_signal.confidence}%, Neutral: {neutral_signal.confidence}%")
|
||||
print(f" → Finale Entscheidung: {final_action} ({final_confidence}%)")
|
||||
|
||||
# Teste Debate Summary
|
||||
print("\n=== Test 3: Debate Summary ===")
|
||||
debate = EURUSDDebateTeam.__new__(EURUSDDebateTeam) # Mock ohne LLM
|
||||
|
||||
summary = debate.get_debate_summary(bull_signal, bear_signal, neutral_signal,
|
||||
TradingSignal(final_action, final_confidence, ["Decision based on rules"]))
|
||||
print(summary)
|
||||
|
||||
# Teste verschiedene Szenarien
|
||||
print("\n=== Test 4: Verschiedene Szenarien ===")
|
||||
|
||||
scenarios = [
|
||||
{"bull": 80, "bear": 40, "neutral": 30, "expected": "LONG"},
|
||||
{"bull": 35, "bear": 85, "neutral": 40, "expected": "SHORT"},
|
||||
{"bull": 55, "bear": 50, "neutral": 70, "expected": "NEUTRAL"},
|
||||
{"bull": 60, "bear": 55, "neutral": 40, "expected": "LONG"},
|
||||
]
|
||||
|
||||
for i, scenario in enumerate(scenarios, 1):
|
||||
if scenario["bull"] > 70 and scenario["bull"] > scenario["bear"] + 20:
|
||||
result = "LONG"
|
||||
elif scenario["bear"] > 70 and scenario["bear"] > scenario["bull"] + 20:
|
||||
result = "SHORT"
|
||||
elif scenario["neutral"] > 60 or abs(scenario["bull"] - scenario["bear"]) < 20:
|
||||
result = "NEUTRAL"
|
||||
elif scenario["bull"] > scenario["bear"]:
|
||||
result = "LONG"
|
||||
else:
|
||||
result = "SHORT"
|
||||
|
||||
status = "✓" if result == scenario["expected"] else "✗"
|
||||
print(f" {status} Szenario {i}: Bull={scenario['bull']}%, Bear={scenario['bear']}%, Neutral={scenario['neutral']}%")
|
||||
print(f" → {result} (erwartet: {scenario['expected']})")
|
||||
|
||||
print("\n✅ EURUSD Debate Team Implementierung ist funktionsfähig!")
|
||||
print("\nHinweis: Vollständige LLM-Tests erfordern einen laufenden Server.")
|
||||
Reference in New Issue
Block a user