Enhance CLI with rich UI and update storage persistence

This commit is contained in:
Branko May Trinkwald
2026-01-05 18:02:50 +01:00
parent a7e2f85f09
commit f1797ad8d0
9 changed files with 333 additions and 237 deletions

13
.env Normal file
View File

@@ -0,0 +1,13 @@
# Gold Market Analysis - Umgebungsvariablen
# Qdrant Konfiguration
QDRANT_MODE=docker
QDRANT_HOST=localhost
QDRANT_PORT=6333
# QDRANT_API_KEY= # Nur für Cloud
# API Keys (optional)
# ALPHA_VANTAGE_KEY=your_key_here
# Logging
LOG_LEVEL=INFO

View File

@@ -69,7 +69,7 @@ system = GoldMarketAnalysisSystem()
# Sammle letzte 7 Tage mit stündlichen Daten
system.collect_and_store_market_data(
ticker_key="XAUUSD",
ticker_key="GC",
period="7d",
interval="1h"
)
@@ -104,7 +104,7 @@ from technical_indicators import TechnicalIndicatorCalculator
# Daten holen
collector = YahooFinanceGoldCollector()
df = collector.get_historical_data("XAUUSD", period="1mo", interval="1d")
df = collector.get_historical_data("GC", period="1mo", interval="1d")
# Indikatoren berechnen
calculator = TechnicalIndicatorCalculator()
@@ -123,9 +123,9 @@ Bearbeite `config.py` für:
### Andere Gold-Ticker hinzufügen
```python
GOLD_TICKER_SYMBOLS = {
"XAUUSD": "XAUUSD=X",
"GC": "GC=F",
"GOLD_EUR": "XAUEUR=X", # NEU: Gold in EUR
"SI": "SI=F", # Silber Futures
"GOLD_EUR": "GC=F", # (Beispiel für weitere)
}
```
@@ -165,7 +165,7 @@ print(f"Gespeicherte Datenpunkte: {stats['total_points']}")
from yahoo_collector import YahooFinanceGoldCollector
collector = YahooFinanceGoldCollector()
current = collector.get_realtime_data("XAUUSD")
current = collector.get_realtime_data("GC")
print(f"Aktueller Preis: ${current['current_price']:.2f}")
```

View File

@@ -1,11 +1,11 @@
# Gold Market Analysis System mit Qdrant
Ein umfassendes Python-System zur Analyse des internationalen Goldmarktes (XAUUSD) mit Vektordatenbank-Integration für langfristige Beziehungsanalysen.
Ein umfassendes Python-System zur Analyse des internationalen Goldmarktes (Gold Futures GC=F) mit Vektordatenbank-Integration für langfristige Beziehungsanalysen.
## 🎯 Projektübersicht
Dieses System sammelt, analysiert und speichert:
- **Stündliche XAUUSD-Kursdaten** von Yahoo Finance
- **Stündliche Gold-Futures-Kursdaten (GC=F)** von Yahoo Finance
- **Technische Indikatoren** (SMA, EMA, RSI, MACD, Bollinger Bands, etc.)
- **Markt-News** mit Sentiment-Analyse
- **Handelssession-Analysen** (COMEX, London, Shanghai, Tokyo)
@@ -17,7 +17,7 @@ Alle Daten werden in **Qdrant** als Vektoren gespeichert, um semantische Suchen
### Datensammlung
- ✅ Yahoo Finance Integration (yfinance)
- XAUUSD, Gold Futures (GC=F), Gold/Silver Index
- ✅ Gold Futures (GC=F), Gold/Silver Index (^XAU)
- ✅ Stündliche, tägliche, wöchentliche Daten
- ✅ Echtzeit-Updates
@@ -106,7 +106,7 @@ from main import GoldMarketAnalysisSystem
system = GoldMarketAnalysisSystem()
system.collect_and_store_market_data(
ticker_key="XAUUSD",
ticker_key="GC",
period="1mo", # 1 Monat
interval="1h" # Stündlich
)
@@ -130,7 +130,7 @@ for result in results:
from datetime import datetime
analysis = system.get_session_analysis(
ticker_key="XAUUSD",
ticker_key="GC",
date=datetime(2025, 1, 5)
)
@@ -160,7 +160,7 @@ Jeder Datenpunkt in Qdrant enthält:
```python
{
"timestamp": "2025-01-05T10:00:00",
"ticker": "XAUUSD",
"ticker": "GC",
"open": 2650.50,
"high": 2655.30,
"low": 2648.20,
@@ -256,7 +256,7 @@ from yahoo_collector import YahooFinanceGoldCollector
collector = YahooFinanceGoldCollector()
data = collector.get_multiple_tickers(
ticker_keys=["XAUUSD", "GC", "XAU"],
ticker_keys=["GC", "GOLD", "XAU"],
period="1mo",
interval="1h"
)
@@ -272,7 +272,7 @@ end = datetime.now()
results = system.db.search_by_time_range(
start_time=start,
end_time=end,
ticker="XAUUSD",
ticker="GC",
limit=1000
)
```

View File

@@ -3,6 +3,10 @@ Konfigurationsdatei für das Gold-Markt-Analyse-System mit Qdrant
"""
import os
from datetime import datetime
from dotenv import load_dotenv
# .env Datei laden
load_dotenv()
# ===========================================
# QDRANT KONFIGURATION

View File

@@ -3,44 +3,49 @@ Beispiel-Skript für Gold Market Analysis System
Demonstriert typische Anwendungsfälle mit GC=F (Gold Futures)
"""
import logging
import time
from datetime import datetime, timedelta
from rich.console import Console
from rich.panel import Panel
from rich.table import Table
from rich.layout import Layout
from rich import print as rprint
from rich.text import Text
from main import GoldMarketAnalysisSystem
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Rich Console initialisieren
console = Console()
def header(text: str, style: str = "bold gold1"):
console.print(Panel(Text(text, justify="center"), style=style, expand=False))
def section(text: str):
console.print(f"\n[bold cyan]>>> {text}[/bold cyan]")
def beispiel_1_historische_daten_sammeln():
"""
Beispiel 1: Historische Daten sammeln und in Qdrant speichern
"""
print("\n" + "="*80)
print("BEISPIEL 1: Historische Daten sammeln (GC=F Gold Futures)")
print("="*80)
header("BEISPIEL 1: Historische Daten sammeln (GC=F Gold Futures)")
system = GoldMarketAnalysisSystem()
# Sammle letzte 30 Tage mit stündlichen Daten
count = system.collect_and_store_market_data(
ticker_key="GC", # Gold Futures
period="1mo",
interval="1h"
)
with console.status("[bold green]Sammle Daten für die letzten 30 Tage...[/bold green]"):
count = system.collect_and_store_market_data(
ticker_key="GC", # Gold Futures
period="1mo",
interval="1h"
)
print(f"\n{count} Datenpunkte gesammelt und gespeichert")
console.print(f"\n[bold green]{count} Datenpunkte gesammelt und gespeichert[/bold green]")
def beispiel_2_aehnliche_marktbedingungen():
"""
Beispiel 2: Finde ähnliche Marktbedingungen
"""
print("\n" + "="*80)
print("BEISPIEL 2: Ähnliche Marktbedingungen finden")
print("="*80)
header("BEISPIEL 2: Ähnliche Marktbedingungen finden")
system = GoldMarketAnalysisSystem()
# Verschiedene Szenarien suchen
szenarien = [
"hohe Volatilität mit steigendem Gold-Preis und positiver News-Stimmung",
"RSI über 70 zeigt überkaufte Bedingungen während London Session",
@@ -49,167 +54,190 @@ def beispiel_2_aehnliche_marktbedingungen():
]
for szenario in szenarien:
print(f"\n🔍 Suche: '{szenario}'")
results = system.analyze_market_conditions(
query=szenario,
limit=3
)
section(f"Suche nach Szenario: '{szenario}'")
with console.status("[bold blue]Suche in Vektor-Datenbank...[/"):
results = system.analyze_market_conditions(
query=szenario,
limit=3
)
if results:
print(f" Gefunden: {len(results)} ähnliche Situationen")
table = Table(title=f"Gefundene Situationen für: {szenario}", border_style="blue")
table.add_column("Rank", style="dim", width=4)
table.add_column("Score", justify="right", style="magenta")
table.add_column("Datum", style="cyan")
table.add_column("Preis", justify="right", style="green")
table.add_column("Session", style="yellow")
table.add_column("RSI", justify="right")
for i, result in enumerate(results, 1):
payload = result["payload"]
print(f"\n {i}. Score: {result['score']:.3f}")
print(f" Datum: {payload.get('timestamp', 'N/A')}")
print(f" Preis: ${payload.get('close', 0):.2f}")
print(f" Session: {payload.get('trading_session', 'N/A')}")
print(f" RSI: {payload.get('indicators', {}).get('RSI_14', 'N/A')}")
rsi_val = payload.get('indicators', {}).get('RSI_14', 'N/A')
if isinstance(rsi_val, (int, float)):
rsi_str = f"{rsi_val:.1f}"
else:
rsi_str = str(rsi_val)
table.add_row(
str(i),
f"{result['score']:.3f}",
payload.get('timestamp', 'N/A'),
f"${payload.get('close', 0):.2f}",
payload.get('trading_session', 'N/A'),
rsi_str
)
console.print(table)
else:
print(" Keine ähnlichen Situationen gefunden")
console.print("[yellow]Keine ähnlichen Situationen gefunden[/yellow]")
def beispiel_3_session_vergleich():
"""
Beispiel 3: Vergleiche Trading Sessions
"""
print("\n" + "="*80)
print("BEISPIEL 3: Trading Session Vergleich")
print("="*80)
header("BEISPIEL 3: Trading Session Vergleich")
system = GoldMarketAnalysisSystem()
# Sammle Daten der letzten 5 Tage
system.collect_and_store_market_data(
ticker_key="GC", # Gold Futures
period="5d",
interval="1h"
)
with console.status("[bold green]Sammle frische Daten (5 Tage)...[/]"):
system.collect_and_store_market_data(
ticker_key="GC",
period="5d",
interval="1h"
)
# Analysiere verschiedene Tage
for i in range(5):
date = datetime.now() - timedelta(days=i)
print(f"\n📅 Datum: {date.date()}")
console.print(f"\n[bold]📅 Datum: {date.date()}[/bold]")
session_data = system.get_session_analysis(ticker_key="GC", date=date)
if session_data:
for session_name, stats in session_data.items():
print(f"\n {session_name}:")
print(f" Durchschnittspreis: ${stats['avg_price']:.2f}")
print(f" Preisspanne: ${stats['price_range']:.2f}")
print(f" Gesamtvolumen: {stats['total_volume']:,.0f}")
print(f" Preisänderung: ${stats['price_change']:+.2f}")
print(f" Volatilität: {stats['volatility']:.2f}")
table = Table(border_style="cyan")
table.add_column("Session", style="bold yellow")
table.add_column("Avg Preis", justify="right", style="green")
table.add_column("Volumen", justify="right")
table.add_column("Änderung", justify="right")
table.add_column("Volatilität", justify="right", style="red")
# Finde Session mit höchster Volatilität
max_vol_session = max(session_data.items(),
key=lambda x: x[1]['volatility'])
print(f"\n 🔥 Höchste Volatilität: {max_vol_session[0]} "
f"({max_vol_session[1]['volatility']:.2f})")
for session_name, stats in session_data.items():
change_color = "green" if stats['price_change'] >= 0 else "red"
table.add_row(
session_name,
f"${stats['avg_price']:.2f}",
f"{stats['total_volume']:,.0f}",
f"[{change_color}]${stats['price_change']:+.2f}[/{change_color}]",
f"{stats['volatility']:.2f}"
)
console.print(table)
# Max Volatility
max_vol_session = max(session_data.items(), key=lambda x: x[1]['volatility'])
console.print(f"[bold red]🔥 Höchste Volatilität: {max_vol_session[0]} ({max_vol_session[1]['volatility']:.2f})[/bold red]")
def beispiel_4_news_und_sentiment():
"""
Beispiel 4: News & Sentiment Analyse
"""
print("\n" + "="*80)
print("BEISPIEL 4: News & Sentiment Analyse")
print("="*80)
header("BEISPIEL 4: News & Sentiment Analyse")
system = GoldMarketAnalysisSystem()
# Sammle aktuelle News
news_articles = system.news_collector.get_all_news(hours_back=24)
with console.status("[bold yellow]Lade News und analysiere Sentiment...[/]"):
news_articles = system.news_collector.get_all_news(hours_back=24)
print(f"\n📰 {len(news_articles)} relevante News-Artikel gefunden")
console.print(f"\n[bold]📰 {len(news_articles)} relevante News-Artikel gefunden[/bold]")
if news_articles:
# Top 5 relevanteste Artikel
print("\n🔝 Top 5 Artikel nach Relevanz:")
for i, article in enumerate(news_articles[:5], 1):
print(f"\n{i}. {article['title'][:80]}...")
print(f" Quelle: {article['source']}")
print(f" Relevanz: {article['relevance_score']:.2f}")
print(f" Sentiment: {article['sentiment_label']} "
f"({article['sentiment_score']:+.2f})")
# Aggregiertes Sentiment
# Sentiment anzeigen
sentiment = system.news_collector.aggregate_sentiment(news_articles)
print(f"\n📊 Aggregiertes Sentiment:")
print(f" Label: {sentiment['sentiment_label']}")
print(f" Score: {sentiment['average_score']:+.2f}")
print(f" Artikel: {sentiment['article_count']}")
print(f" Positiv: {sentiment['positive_count']} | "
f"Negativ: {sentiment['negative_count']} | "
f"Neutral: {sentiment['neutral_count']}")
sent_color = "green" if sentiment['sentiment_label'] == "Positive" else "red" if sentiment['sentiment_label'] == "Negative" else "yellow"
panel = Panel(
f"[bold {sent_color}]Label: {sentiment['sentiment_label']}[/]\n"
f"Score: {sentiment['average_score']:+.2f}\n"
f"Artikel: {sentiment['article_count']}\n"
f"Positiv: {sentiment['positive_count']} | Negativ: {sentiment['negative_count']} | Neutral: {sentiment['neutral_count']}",
title="Aggregiertes Sentiment",
border_style=sent_color
)
console.print(panel)
# Events extrahieren
# Top Artikel
section("Top 5 Artikel")
for i, article in enumerate(news_articles[:5], 1):
sent_score = article['sentiment_score']
color = "green" if sent_score > 0 else "red" if sent_score < 0 else "yellow"
console.print(f"[bold]{i}. {article['title']}[/bold]")
console.print(f" Quelle: [italic]{article['source']}[/italic] | Relevanz: {article['relevance_score']:.2f}")
console.print(f" Sentiment: [{color}]{article['sentiment_label']} ({sent_score:+.2f})[/{color}]")
console.print("")
# Events
events = system.news_collector.extract_events_from_news(news_articles)
if events:
print(f"\n🎯 Extrahierte Events ({len(events)}):")
section(f"Extrahierte Events ({len(events)})")
for event in events[:5]:
print(f"{event}")
console.print(f"{event}")
else:
print("\n⚠️ Keine News verfügbar (Alpha Vantage API Key fehlt?)")
print("💡 System funktioniert auch ohne News - nur mit Marktdaten!")
console.print("[yellow]⚠️ Keine News verfügbar[/yellow]")
def beispiel_5_technische_signale():
"""
Beispiel 5: Technische Trading-Signale
"""
print("\n" + "="*80)
print("BEISPIEL 5: Technische Trading-Signale (GC=F)")
print("="*80)
header("BEISPIEL 5: Technische Trading-Signale (GC=F)")
system = GoldMarketAnalysisSystem()
# Hole aktuelle Daten
from yahoo_collector import YahooFinanceGoldCollector
collector = YahooFinanceGoldCollector()
df = collector.get_historical_data(
ticker_key="GC", # Gold Futures
period="5d",
interval="1h"
)
with console.status("[bold cyan]Analysiere Charts...[/]"):
df = collector.get_historical_data(ticker_key="GC", period="5d", interval="1h")
if df.empty:
print("❌ Keine Daten verfügbar")
return
if df.empty:
console.print("[bold red]❌ Keine Daten verfügbar[/bold red]")
return
# Berechne Indikatoren
df_with_indicators = system.indicator_calculator.calculate_all_indicators(df)
# Erkenne Signale
signals = system.indicator_calculator.detect_signals(df_with_indicators)
df_with_indicators = system.indicator_calculator.calculate_all_indicators(df)
signals = system.indicator_calculator.detect_signals(df_with_indicators)
if signals:
print(f"\n🚨 {len(signals)} Trading-Signale erkannt:")
for signal in signals:
print(f"\n {signal['type']}")
print(f" Indikator: {signal['indicator']}")
print(f" Wert: {signal['value']:.2f}")
print(f" 📝 {signal['message']}")
else:
print("\n✓ Keine kritischen Signale - normaler Markt")
console.print(f"\n[bold red]🚨 {len(signals)} Trading-Signale erkannt:[/bold red]")
table = Table(border_style="red")
table.add_column("Type", style="bold")
table.add_column("Indikator", style="cyan")
table.add_column("Wert", justify="right")
table.add_column("Nachricht", style="white")
# Zeige aktuelle Key-Indikatoren
print(f"\n📊 Aktuelle Indikatoren (letzter Wert):")
for signal in signals:
sig_color = "green" if "BUY" in signal['type'] or "BULLISH" in signal['type'] else "red"
table.add_row(
f"[{sig_color}]{signal['type']}[/{sig_color}]",
signal['indicator'],
f"{signal['value']:.2f}",
signal['message']
)
console.print(table)
else:
console.print("\n[bold green]✓ Keine kritischen Signale - normaler Markt[/bold green]")
# Indikatoren Übersicht
section("Indikatoren Snapshot")
indicators = system.indicator_calculator.get_indicators_summary(df_with_indicators)
ind_table = Table(show_header=False, box=None)
ind_table.add_column("Name", style="bold white")
ind_table.add_column("Value", style="cyan")
key_indicators = ['RSI_14', 'MACD_12_26', 'SMA_20', 'SMA_50', 'BB_upper_20', 'BB_lower_20']
for ind in key_indicators:
if ind in indicators:
print(f" {ind}: {indicators[ind]:.2f}")
ind_table.add_row(ind, f"{indicators[ind]:.2f}")
console.print(Panel(ind_table, title="Aktuelle Werte", fit=True))
def beispiel_6_zeitreihen_analyse():
"""
Beispiel 6: Zeitreihen-Analyse mit verschiedenen Zeitfenstern
"""
print("\n" + "="*80)
print("BEISPIEL 6: Zeitreihen-Analyse")
print("="*80)
header("BEISPIEL 6: Zeitreihen-Analyse")
system = GoldMarketAnalysisSystem()
@@ -220,95 +248,95 @@ def beispiel_6_zeitreihen_analyse():
]
for name, start_time, beschreibung in zeitfenster:
print(f"\n📅 {beschreibung}:")
section(beschreibung)
data_points = system.db.search_by_time_range(
start_time=start_time,
end_time=datetime.now(),
ticker="GC", # Gold Futures
ticker="GC",
limit=1000
)
if data_points:
prices = [dp.get('close', 0) for dp in data_points]
volumes = [dp.get('volume', 0) for dp in data_points]
if not prices:
console.print("[dim]Keine Preisdaten gefunden.[/dim]")
continue
print(f" Datenpunkte: {len(data_points)}")
print(f" Durchschnittspreis: ${sum(prices)/len(prices):.2f}")
print(f" Min/Max Preis: ${min(prices):.2f} / ${max(prices):.2f}")
print(f" Preisänderung: ${prices[-1] - prices[0]:+.2f} "
f"({((prices[-1]/prices[0] - 1) * 100):+.2f}%)")
print(f" Durchschnittsvolumen: {sum(volumes)/len(volumes):,.0f}")
start_price = prices[0]
end_price = prices[-1]
change_pct = ((end_price / start_price) - 1) * 100
color = "green" if change_pct >= 0 else "red"
# Session-Verteilung
table = Table(show_header=False)
table.add_row("Datenpunkte", str(len(data_points)))
table.add_row("Preisspanne", f"${min(prices):.2f} - ${max(prices):.2f}")
table.add_row("Performance", f"[{color}]${end_price - start_price:+.2f} ({change_pct:+.2f}%)[/{color}]")
console.print(table)
# Session Verteilung
sessions = {}
for dp in data_points:
session = dp.get('trading_session', 'UNKNOWN')
sessions[session] = sessions.get(session, 0) + 1
sess_text = []
for session, count in sorted(sessions.items(), key=lambda x: x[1], reverse=True):
sess_text.append(f"{session}: [bold]{count}[/bold] ({count/len(data_points)*100:.1f}%)")
console.print(Panel("\n".join(sess_text), title="Session Verteilung", border_style="dim"))
print(f" Session-Verteilung:")
for session, count in sorted(sessions.items(),
key=lambda x: x[1],
reverse=True):
print(f" {session}: {count} ({count/len(data_points)*100:.1f}%)")
else:
print(f" ⚠️ Keine Daten verfügbar")
console.print("[yellow]⚠️ Keine Daten verfügbar[/yellow]")
def main():
"""
Hauptmenü für Beispiele
"""
print("""
╔═══════════════════════════════════════════════════════════════╗
║ Gold Market Analysis - Beispiele (GC=F Futures) ║
╚═══════════════════════════════════════════════════════════════╝
Verfügbare Beispiele:
1. Historische Daten sammeln
2. Ähnliche Marktbedingungen finden
3. Trading Session Vergleich
4. News & Sentiment Analyse
5. Technische Trading-Signale
6. Zeitreihen-Analyse
7. Alle Beispiele durchlaufen
0. Beenden
""")
console.print()
console.print(Panel.fit(
"[bold gold1]Gold Market Analysis - Beispiele (GC=F Futures)[/bold gold1]\n"
"[dim]Powered by Qdrant & Rich[/dim]",
border_style="gold1"
))
beispiele = {
"1": beispiel_1_historische_daten_sammeln,
"2": beispiel_2_aehnliche_marktbedingungen,
"3": beispiel_3_session_vergleich,
"4": beispiel_4_news_und_sentiment,
"5": beispiel_5_technische_signale,
"6": beispiel_6_zeitreihen_analyse,
"1": ("Historische Daten sammeln", beispiel_1_historische_daten_sammeln),
"2": ("Ähnliche Marktbedingungen finden", beispiel_2_aehnliche_marktbedingungen),
"3": ("Trading Session Vergleich", beispiel_3_session_vergleich),
"4": ("News & Sentiment Analyse", beispiel_4_news_und_sentiment),
"5": ("Technische Trading-Signale", beispiel_5_technische_signale),
"6": ("Zeitreihen-Analyse", beispiel_6_zeitreihen_analyse),
}
while True:
console.print("\n[bold underline]Verfügbare Beispiele:[/bold underline]")
for key, (desc, _) in beispiele.items():
console.print(f" [cyan]{key}[/cyan]. {desc}")
console.print(" [cyan]7[/cyan]. Alle Beispiele durchlaufen")
console.print(" [dim]0. Beenden[/dim]")
try:
wahl = input("\nWählen Sie ein Beispiel (0-7): ").strip()
wahl = console.input("\n[bold]Wählen Sie ein Beispiel (0-7): [/bold]").strip()
if wahl == "0":
print("Auf Wiedersehen!")
console.print("[bold green]Auf Wiedersehen![/bold green]")
break
elif wahl == "7":
# Alle Beispiele durchlaufen
for func in beispiele.values():
for key, (_, func) in beispiele.items():
func()
input("\nEnter drücken für nächstes Beispiel...")
console.input("\n[dim]Enter drücken für nächstes Beispiel...[/dim]")
elif wahl in beispiele:
beispiele[wahl]()
beispiele[wahl][1]()
else:
print("Ungültige Auswahl!")
console.print("[bold red]Ungültige Auswahl![/bold red]")
except KeyboardInterrupt:
print("\n\nBeendet durch Benutzer.")
console.print("\n\n[bold red]Beendet durch Benutzer.[/bold red]")
break
except Exception as e:
logger.error(f"Fehler: {e}", exc_info=True)
console.print(f"[bold red]Ein Fehler ist aufgetreten: {e}[/bold red]")
if __name__ == "__main__":
main()

View File

@@ -267,12 +267,12 @@ class QdrantGoldMarketDB:
"""
query_vector = self.create_embedding(query_text)
results = self.client.search(
results = self.client.query_points(
collection_name=QDRANT_COLLECTION_NAME,
query_vector=query_vector,
query=query_vector,
limit=limit,
score_threshold=score_threshold,
)
).points
return [
{

135
main.py
View File

@@ -10,6 +10,13 @@ import time
import schedule
from pathlib import Path
from rich.console import Console
from rich.logging import RichHandler
from rich.panel import Panel
from rich.table import Table
from rich import print as rprint
from rich.text import Text
from config import (
LOG_LEVEL,
LOG_FILE,
@@ -22,15 +29,19 @@ from yahoo_collector import YahooFinanceGoldCollector
from technical_indicators import TechnicalIndicatorCalculator
from news_collector import GoldNewsCollector
# Rich Console
console = Console()
logging.basicConfig(
level=getattr(logging, LOG_LEVEL),
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
format="%(message)s",
datefmt="[%X]",
handlers=[
logging.FileHandler(LOG_FILE),
logging.StreamHandler(sys.stdout),
RichHandler(console=console, rich_tracebacks=True)
],
)
logger = logging.getLogger(__name__)
logger = logging.getLogger("gold_system")
class GoldMarketAnalysisSystem:
@@ -278,58 +289,94 @@ class GoldMarketAnalysisSystem:
def main():
print("""
╔═══════════════════════════════════════════════════════════════╗
Gold Market Analysis System mit Qdrant ║
Gold Futures (GC=F) Echtzeit-Analyse ║
╚═══════════════════════════════════════════════════════════════╝
""")
console.print()
console.print(Panel.fit(
"[bold gold1]Gold Market Analysis System[/bold gold1]\n"
"[dim]Realtime & Predictive Analytics powered by Qdrant[/dim]",
border_style="gold1",
subtitle="v1.0"
))
system = GoldMarketAnalysisSystem()
print("\nVerfügbare Modi:")
print("1. Einmalige Datensammlung")
print("2. Kontinuierlicher Betrieb")
print("3. Analyse-Abfrage")
print("4. Bericht generieren")
while True:
console.print("\n[bold underline]Verfügbare Modi:[/bold underline]")
console.print(" [cyan]1[/cyan]. Einmalige Datensammlung")
console.print(" [cyan]2[/cyan]. Kontinuierlicher Betrieb")
console.print(" [cyan]3[/cyan]. Analyse-Abfrage")
console.print(" [cyan]4[/cyan]. Bericht generieren")
console.print(" [dim]0. Beenden[/dim]")
try:
choice = input("\nWählen Sie einen Modus (1-4): ").strip()
try:
choice = console.input("\n[bold]Wählen Sie einen Modus (0-4): [/bold]").strip()
if choice == "1":
system.collect_and_store_market_data(
ticker_key=DEFAULT_TICKER,
period="7d",
interval="1h",
)
if choice == "0":
console.print("[bold green]System wird beendet. Auf Wiedersehen![/bold green]")
break
elif choice == "2":
interval = input("Update-Intervall in Minuten (default: 60): ").strip()
interval = int(interval) if interval else 60
system.run_continuous(update_interval_minutes=interval)
elif choice == "1":
with console.status("[bold green]Sammle historische Daten (7 Tage)...[/]"):
system.collect_and_store_market_data(
ticker_key=DEFAULT_TICKER,
period="7d",
interval="1h",
)
console.print("[bold green]✓ Datensammlung abgeschlossen[/bold green]")
elif choice == "3":
query = input("Geben Sie Ihre Analyse-Anfrage ein: ").strip()
if query:
results = system.analyze_market_conditions(query, limit=5)
print(f"\n{len(results)} ähnliche Situationen gefunden:")
for i, result in enumerate(results, 1):
payload = result["payload"]
print(f"\n{i}. Score: {result['score']:.3f}")
print(f" Datum: {payload.get('timestamp', 'N/A')}")
print(f" Preis: ${payload.get('close', 0):.2f}")
print(f" Session: {payload.get('trading_session', 'N/A')}")
elif choice == "2":
interval_input = console.input("Update-Intervall in Minuten (default: [bold]60[/bold]): ").strip()
interval = int(interval_input) if interval_input else 60
console.print(f"[bold yellow]Starte kontinuierlichen Betrieb (Intervall: {interval}min)...[/bold yellow]")
console.print("[dim]Drücken Sie Ctrl+C zum Stoppen[/dim]")
try:
system.run_continuous(update_interval_minutes=interval)
except KeyboardInterrupt:
console.print("\n[bold red]Kontinuierlicher Betrieb gestoppt[/bold red]")
elif choice == "4":
report = system.generate_report()
print("\n" + report)
elif choice == "3":
query = console.input("[bold]Geben Sie Ihre Analyse-Anfrage ein:[/bold] ").strip()
if query:
with console.status("[bold blue]Analysiere Markt...[/]"):
results = system.analyze_market_conditions(query, limit=5)
if results:
console.print(f"\n[bold]{len(results)} ähnliche Situationen gefunden:[/bold]")
table = Table(border_style="blue")
table.add_column("Score", style="magenta")
table.add_column("Datum", style="cyan")
table.add_column("Preis", justify="right", style="green")
table.add_column("Session", style="yellow")
for result in results:
payload = result["payload"]
table.add_row(
f"{result['score']:.3f}",
payload.get('timestamp', 'N/A'),
f"${payload.get('close', 0):.2f}",
payload.get('trading_session', 'N/A')
)
console.print(table)
else:
console.print("[yellow]Keine Ergebnisse gefunden.[/yellow]")
else:
print("Ungültige Auswahl!")
elif choice == "4":
with console.status("[bold yellow]Generiere Bericht...[/]"):
report = system.generate_report()
console.print(Panel(report, title="Marktbericht", border_style="white"))
except Exception as e:
logger.error(f"Fehler: {e}", exc_info=True)
else:
console.print("[bold red]Ungültige Auswahl![/bold red]")
except KeyboardInterrupt:
console.print("\n\n[bold red]Beendet durch Benutzer.[/bold red]")
break
except Exception as e:
logger.error(f"Fehler: {e}", exc_info=True)
console.print(f"[bold red]Ein Fehler ist aufgetreten: {e}[/bold red]")
if __name__ == "__main__":
main()

View File

@@ -23,6 +23,9 @@ python-dateutil>=2.8.2
# Visualization
matplotlib>=3.8.2
seaborn>=0.13.1
rich>=13.0.0
python-dotenv>=1.0.0
# HINWEIS: Wir verwenden KEINE externe TA-Bibliothek mehr!
# Alle technischen Indikatoren sind jetzt selbst implementiert

View File

@@ -78,6 +78,7 @@ if [ ! -f ".env" ]; then
# Gold Market Analysis - Umgebungsvariablen
# Qdrant Konfiguration
QDRANT_MODE=docker
QDRANT_HOST=localhost
QDRANT_PORT=6333
# QDRANT_API_KEY= # Nur für Cloud