mirror of
https://github.com/NicolasBohn/NexQuant.git
synced 2026-07-27 23:47:46 +00:00
bb450f7740
- Updated QWEN.md with English-only comment policy - Translated all German comments in: * eurusd_regime.py * eurusd_llm.py * eurusd_reflection.py * eurusd_memory.py * eurusd_macro.py * eurusd_debate.py * predix_dashboard.py - All comments, docstrings, and print statements now in English - Ensures consistency with commit messages and documentation Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
750 lines
24 KiB
Python
750 lines
24 KiB
Python
"""
|
|
EURUSD Trading-Debatte: Bull vs Bear vs Neutral
|
|
|
|
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 datetime import datetime, timezone
|
|
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
|
|
from fx_config import get_fx_config
|
|
|
|
|
|
def get_current_session_info() -> dict:
|
|
"""
|
|
Gibt Informationen zur aktuellen FX-Session.
|
|
|
|
Returns
|
|
-------
|
|
dict
|
|
Session-Info mit Name, Stunden, Charakteristika, empfohlene Strategie
|
|
"""
|
|
config = get_fx_config()
|
|
current_session = config.get_current_session()
|
|
session_desc = config.get_session_description(current_session)
|
|
|
|
# Aktuelle UTC Zeit hinzufügen
|
|
hour_utc = datetime.now(timezone.utc).hour
|
|
|
|
return {
|
|
"session": current_session,
|
|
"name": session_desc["name"],
|
|
"hours": session_desc["hours"],
|
|
"current_utc_hour": hour_utc,
|
|
"characteristics": session_desc["characteristics"],
|
|
"recommended_strategy": session_desc["recommended_strategy"],
|
|
"avoid": session_desc["avoid"]
|
|
}
|
|
|
|
|
|
@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
|
|
"""
|
|
# Session-Info hinzufügen
|
|
session_info = get_current_session_info()
|
|
market_data["session"] = session_info
|
|
|
|
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."""
|
|
session = data.get("session", {})
|
|
session_str = f"""
|
|
=== Aktuelle Session ===
|
|
- Session: {session.get('name', 'N/A')} ({session.get('hours', '')})
|
|
- Charakteristika: {session.get('characteristics', '')}
|
|
- Empfohlene Strategie: {session.get('recommended_strategy', '')}
|
|
|
|
""" if session else ""
|
|
|
|
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')}
|
|
{session_str}
|
|
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. Passt der Trade zur aktuellen Session?
|
|
5. 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} Scenario {i}: Bull={scenario['bull']}%, Bear={scenario['bear']}%, Neutral={scenario['neutral']}%")
|
|
print(f" → {result} (expected: {scenario['expected']})")
|
|
|
|
print("\n✅ EURUSD Debate Team implementation is functional!")
|
|
print("\nNote: Full LLM tests require a running server.")
|