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("output/"+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.")