83 lines
2.8 KiB
Python
83 lines
2.8 KiB
Python
import os
|
|
import pandas as pd
|
|
import pandas_ta as ta
|
|
from dotenv import load_dotenv
|
|
from datetime import datetime, timedelta
|
|
from alpaca.data.historical import StockHistoricalDataClient
|
|
from alpaca.data.requests import StockBarsRequest
|
|
from alpaca.data.timeframe import TimeFrame
|
|
|
|
# --- SETUP ---
|
|
load_dotenv()
|
|
API_KEY = os.getenv('ALPACA_API_KEY')
|
|
SECRET_KEY = os.getenv('ALPACA_SECRET_KEY')
|
|
data_client = StockHistoricalDataClient(API_KEY, SECRET_KEY)
|
|
|
|
def scan_markets(tickers, rsi_period=25):
|
|
results = []
|
|
print(f"--- Scanne {len(tickers)} Aktien auf Signale ---")
|
|
|
|
for symbol in tickers:
|
|
try:
|
|
# Daten für die letzten 30 Tage holen (reicht für RSI 14)
|
|
start_date = datetime.now() - timedelta(days=50)
|
|
request_params = StockBarsRequest(
|
|
symbol_or_symbols=[symbol],
|
|
timeframe=TimeFrame.Day,
|
|
start=start_date
|
|
)
|
|
|
|
bars = data_client.get_stock_bars(request_params).df
|
|
if bars.empty: continue
|
|
|
|
df = bars.reset_index(level=0, drop=True)
|
|
|
|
# RSI berechnen
|
|
df['RSI'] = ta.rsi(df['close'], length=rsi_period)
|
|
|
|
# Letzte Werte extrahieren
|
|
current_price = df['close'].iloc[-1]
|
|
current_rsi = df['RSI'].iloc[-1]
|
|
|
|
# Signal-Logik
|
|
signal = "NEUTRAL"
|
|
if current_rsi < 30:
|
|
signal = "KAUFEN (Überverkauft)"
|
|
elif current_rsi > 70:
|
|
signal = "VERKAUFEN (Überkauft)"
|
|
|
|
results.append({
|
|
'Symbol': symbol,
|
|
'Preis': round(current_price, 2),
|
|
'RSI': round(current_rsi, 2),
|
|
'Signal': signal,
|
|
'Zeitpunkt': datetime.now().strftime('%Y-%m-%d %H:%M')
|
|
})
|
|
print(f"{symbol}: RSI {current_rsi:.2f} -> {signal}")
|
|
|
|
except Exception as e:
|
|
print(f"Fehler beim Scannen von {symbol}: {e}")
|
|
|
|
# Ergebnisse in DataFrame umwandeln
|
|
scan_df = pd.DataFrame(results)
|
|
|
|
# Als Excel speichern
|
|
filename = f"markt_scan_{datetime.now().strftime('%Y%m%d')}.xlsx"
|
|
scan_df.to_excel(filename, index=False)
|
|
print(f"\n✅ Scan abgeschlossen. Ergebnisse gespeichert in: {filename}")
|
|
|
|
return scan_df
|
|
|
|
if __name__ == "__main__":
|
|
# Liste der zu scannenden Aktien
|
|
my_watchlist = ["AAPL", "TSLA", "MSFT", "AMZN", "GOOGL", "NVDA", "AMD", "META"]
|
|
|
|
scan_results = scan_markets(my_watchlist)
|
|
|
|
# Optional: Nur die echten Signale anzeigen
|
|
hits = scan_results[scan_results['Signal'] != "NEUTRAL"]
|
|
if not hits.empty:
|
|
print("\n🔥 AKTUELLE SIGNALE:")
|
|
print(hits)
|
|
else:
|
|
print("\nKeine extremen RSI-Werte gefunden.") |