Enhance CLI with rich UI and update storage persistence
This commit is contained in:
13
.env
Normal file
13
.env
Normal 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
|
||||
@@ -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}")
|
||||
```
|
||||
|
||||
|
||||
16
README.md
16
README.md
@@ -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
|
||||
)
|
||||
```
|
||||
|
||||
@@ -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
|
||||
|
||||
382
examples.py
382
examples.py
@@ -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()
|
||||
|
||||
@@ -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
135
main.py
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user