Die Vorhersage von Bitcoin-Kursbewegungen gehört zu den faszinierendsten Herausforderungen im quantitativen Trading. In diesem Tutorial zeige ich Ihnen, wie Sie Tardis-Daten – hochauflösende Kryptomarkt-Daten – nutzen, um ein LSTM-Netzwerk (Long Short-Term Memory) zur BTC-Kurzzeitprognose zu trainieren. Als Backend für die Datenverarbeitung und Modellschulung nutzen wir die leistungsstarke HolySheep AI API.
HolySheep vs. offizielle APIs vs. andere Relay-Dienste
| Kriterium | HolySheep AI | Offizielle APIs (OpenAI/Anthropic) | Andere Relay-Dienste |
|---|---|---|---|
| Preis pro 1M Tokens | GPT-4.1: $8 | Claude 4.5: $15 | Gemini 2.5 Flash: $2.50 | DeepSeek V3.2: $0.42 | GPT-4o: $15 | Claude 3.5: $18 | $5-20 (variiert) |
| Währung | ¥1 = $1 (85%+ günstiger für CNY-Nutzer) | Nur USD | Oft nur USD |
| Bezahlmethoden | WeChat Pay, Alipay, Kreditkarte | Nur Kreditkarte/USD | Kreditkarte (eingeschränkt) |
| Latenz | <50ms | 100-300ms | 80-200ms |
| Kostenlose Credits | ✅ Ja, bei Registrierung | ❌ Nein | Selten |
| Tardis-Integration | ✅ Nativ über API | ❌ Nicht verfügbar | ⚠️ Manuell |
| China-Verfügbarkeit | ✅ 100% stabil | ❌ Blockiert | ⚠️ Instabil |
Geeignet / Nicht geeignet für
✅ Perfekt geeignet für:
- Entwickler und Data Scientists, die BTC-Prognosemodelle entwickeln möchten
- Quant-Trader, die automatisierte Trading-Strategien backtesten
- Crypto-Enthusiasten mit Programmiererfahrung in Python
- Institutionelle Anleger, die hochfrequente Marktdaten analysieren
- Nutzer in China, die stabile AI-API-Zugriffe benötigen
❌ Nicht geeignet für:
- Vollständige Trading-Anfänger ohne Programmierkenntnisse
- Personen, die fertige Trading-Signale ohne eigene Analyse wünschen
- Langfristige Fundamentalanalysen (hier sind andere Tools besser)
Voraussetzungen
- Python 3.8+ installiert
- HolySheep AI Account mit API-Key
- Tardis.io Account für Marktdaten
- Grundkenntnisse in TensorFlow/Keras und LSTM-Netzwerken
Architektur: Tardis → HolySheep → LSTM → BTC-Prognose
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ Tardis.io │ │ HolySheep AI │ │ TensorFlow │
│ (Marktdaten) │ ──▶ │ (Text/LLM) │ ──▶ │ (LSTM-Modell) │
│ │ │ │ │ │
│ • Orderbooks │ │ • Feature- │ │ • Training │
│ • Trades │ │ Extraktion │ │ • Validation │
│ • OHLCV │ │ • Anomalie- │ │ • Inferenz │
└─────────────────┘ │ Erkennung │ └─────────────────┘
└──────────────────┘ │
▼
┌─────────────────────┐
│ BTC-Preisprognose │
│ (±0.5-2% Genauig- │
│ keit möglich) │
└─────────────────────┘
Schritt 1: Tardis-Daten abrufen
Tardis bietet historische und Echtzeit-Marktdaten von über 40 Kryptobörsen. Für BTC benötigen wir Trades und Orderbook-Daten.
# tardis_client.py
import requests
import pandas as pd
from datetime import datetime, timedelta
class TardisDataFetcher:
def __init__(self, api_key: str):
self.api_key = api_key
self.base_url = "https://api.tardis.dev/v1"
def get_btc_trades(self, exchange: str = "binance",
since: datetime = None,
until: datetime = None,
limit: int = 10000):
"""
Ruft BTC-Trade-Daten von Tardis ab.
Args:
exchange: Börse (binance, coinbase, kraken, etc.)
since: Startzeit
until: Endzeit
limit: Maximale Anzahl Trades
Returns:
DataFrame mit Trades
"""
if since is None:
since = datetime.now() - timedelta(hours=24)
if until is None:
until = datetime.now()
# Tardis API-Endpunkt
url = f"{self.base_url}/feeds/{exchange}:spot"
params = {
"api_key": self.api_key,
"symbol": "BTC-USD", # oder BTC-USDT für Binance
"since": int(since.timestamp() * 1000),
"until": int(until.timestamp() * 1000),
"limit": limit,
"format": "json"
}
response = requests.get(url, params=params)
response.raise_for_status()
trades = response.json()
# In DataFrame konvertieren
df = pd.DataFrame(trades)
df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms')
print(f"✅ {len(df)} Trades abgerufen von {exchange}")
return df
def get_orderbook_snapshot(self, exchange: str = "binance",
symbol: str = "BTC-USDT") -> dict:
"""
Ruft aktuellen Orderbook-Snapshot ab.
"""
url = f"{self.base_url}/feeds/{exchange}:spot"
params = {
"api_key": self.api_key,
"symbol": symbol,
"type": "book_snapshot",
"format": "json"
}
response = requests.get(url, params=params)
return response.json()
Verwendung
tardis = TardisDataFetcher(api_key="YOUR_TARDIS_API_KEY")
trades_df = tardis.get_btc_trades(exchange="binance", limit=50000)
print(trades_df.head())
Schritt 2: Feature-Engineering mit HolySheep AI
Der Clou: Wir nutzen HolySheep AI, um komplexe Marktindikatoren zu berechnen und Anomalien zu erkennen, die in rohen Daten schwer zu finden sind.
# feature_engineering.py
import pandas as pd
import numpy as np
from holy_sheep_client import HolySheepClient
class BTCFeatureEngineer:
def __init__(self, holy_sheep_key: str):
self.client = HolySheepClient(api_key=holy_sheep_key)
def calculate_technical_indicators(self, df: pd.DataFrame) -> pd.DataFrame:
"""
Berechnet technische Indikatoren für LSTM-Input.
"""
# Basis-Indikatoren
df['returns'] = df['price'].pct_change()
df['log_returns'] = np.log(df['price'] / df['price'].shift(1))
# Rolling Statistics
for window in [5, 15, 30, 60]:
df[f'sma_{window}'] = df['price'].rolling(window).mean()
df[f'std_{window}'] = df['price'].rolling(window).std()
df[f'volatility_{window}'] = df[f'std_{window}'] / df[f'sma_{window}']
# RSI (Relative Strength Index)
delta = df['price'].diff()
gain = (delta.where(delta > 0, 0)).rolling(window=14).mean()
loss = (-delta.where(delta < 0, 0)).rolling(window=14).mean()
rs = gain / loss
df['rsi'] = 100 - (100 / (1 + rs))
# MACD
exp1 = df['price'].ewm(span=12, adjust=False).mean()
exp2 = df['price'].ewm(span=26, adjust=False).mean()
df['macd'] = exp1 - exp2
df['macd_signal'] = df['macd'].ewm(span=9, adjust=False).mean()
df['macd_hist'] = df['macd'] - df['macd_signal']
# Bollinger Bands
df['bb_middle'] = df['price'].rolling(window=20).mean()
bb_std = df['price'].rolling(window=20).std()
df['bb_upper'] = df['bb_middle'] + (bb_std * 2)
df['bb_lower'] = df['bb_middle'] - (bb_std * 2)
df['bb_width'] = (df['bb_upper'] - df['bb_lower']) / df['bb_middle']
# Volumen-Indikatoren
if 'volume' in df.columns:
df['volume_sma_20'] = df['volume'].rolling(window=20).mean()
df['volume_ratio'] = df['volume'] / df['volume_sma_20']
# Preis-Momentum
df['momentum_5'] = df['price'] / df['price'].shift(5) - 1
df['momentum_15'] = df['price'] / df['price'].shift(15) - 1
return df.dropna()
def analyze_market_regime(self, df: pd.DataFrame) -> pd.DataFrame:
"""
Nutzt HolySheep AI, um Markt-Regime zu klassifizieren.
"""
# Erstelle Text-Zusammenfassung der letzten Daten
recent_data = df.tail(100).to_dict('records')
summary = f"""
BTC-Marktdaten der letzten Stunden:
- Durchschnittspreis: {df['price'].mean():.2f}
- Volatilität: {df['returns'].std():.4f}
- RSI: {df['rsi'].iloc[-1]:.2f}
- Trend: {'bullish' if df['sma_15'].iloc[-1] > df['sma_30'].iloc[-1] else 'bearish'}
"""
prompt = f"""Analysiere folgende BTC-Marktdaten und klassifiziere das aktuelle Markt-Regime:
{summary}
Gib mir eine kurze Analyse (max. 100 Wörter) mit:
1. Regime-Typ (Volatile/Range/Trending)
2. Risiko-Level (Niedrig/Mittel/Hoch)
3. Empfehlung für LSTM-Trainingsparameter
"""
# API-Call über HolySheep (Latein-1 kodierung für Sonderzeichen)
response = self.client.chat.completions.create(
model="gpt-4.1",
messages=[
{"role": "system", "content": "Du bist ein Krypto-Marktanalyst."},
{"role": "user", "content": prompt}
],
max_tokens=200,
temperature=0.3
)
analysis = response.choices[0].message.content
print(f"📊 Markt-Regime-Analyse: {analysis}")
# Regime-Feature hinzufügen basierend auf Analyse
df['market_regime'] = self._parse_regime(analysis)
return df
def _parse_regime(self, analysis: str) -> int:
"""Parst Regime aus LLM-Antwort."""
analysis_lower = analysis.lower()
if 'volatile' in analysis_lower or 'hoch' in analysis_lower:
return 2 # Hochvolatile
elif 'range' in analysis_lower:
return 1 # Range-bound
else:
return 0 # Trending
HolySheep Client-Klasse
class HolySheepClient:
def __init__(self, api_key: str):
self.api_key = api_key
self.base_url = "https://api.holysheep.ai/v1"
@property
def chat(self):
return ChatCompletions(self.api_key, self.base_url)
class ChatCompletions:
def __init__(self, api_key: str, base_url: str):
self.api_key = api_key
self.base_url = base_url
def create(self, model: str, messages: list, max_tokens: int = 1000,
temperature: float = 0.7) -> dict:
import requests
url = f"{self.base_url}/chat/completions"
headers = {
"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json"
}
payload = {
"model": model,
"messages": messages,
"max_tokens": max_tokens,
"temperature": temperature
}
response = requests.post(url, headers=headers, json=payload)
response.raise_for_status()
return response.json()
Verwendung
engineer = BTCFeatureEngineer(holy_sheep_key="YOUR_HOLYSHEEP_API_KEY")
features_df = engineer.calculate_technical_indicators(trades_df)
features_df = engineer.analyze_market_regime(features_df)
print(f"✅ Feature-DataFrame erstellt: {features_df.shape}")
Schritt 3: LSTM-Modellarchitektur
# lstm_model.py
import numpy as np
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import train_test_split
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense, Dropout, Bidirectional
from tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau
class BTCLSTMModel:
def __init__(self, sequence_length: int = 60):
self.sequence_length = sequence_length
self.scaler = MinMaxScaler(feature_range=(0, 1))
self.model = None
self.feature_columns = [
'price', 'returns', 'log_returns',
'sma_5', 'sma_15', 'sma_30', 'sma_60',
'volatility_5', 'volatility_15', 'volatility_30',
'rsi', 'macd', 'macd_signal', 'macd_hist',
'bb_width', 'momentum_5', 'momentum_15',
'volume_ratio', 'market_regime'
]
def prepare_sequences(self, df: pd.DataFrame) -> tuple:
"""
Erstellt Sequences für LSTM-Training.
Args:
df: DataFrame mit Features
Returns:
X, y: Trainingsdaten
"""
# Features skalieren
feature_data = df[self.feature_columns].values
scaled_data = self.scaler.fit_transform(feature_data)
X, y = [], []
for i in range(self.sequence_length, len(scaled_data)):
# Input: Alle Features der letzten sequence_length Zeitschritte
X.append(scaled_data[i-self.sequence_length:i])
# Target: Normalisierter Preis (erste Spalte)
# Vorhersage: Nächster Preis oder Preisänderung
target_idx = 0 # 'price' ist erste Spalte
y.append(scaled_data[i, target_idx])
return np.array(X), np.array(y)
def build_model(self, input_shape: tuple) -> Sequential:
"""
Erstellt Bidirectional LSTM-Architektur.
"""
model = Sequential([
# Bidirectional LSTM für bessere Pattern-Erkennung
Bidirectional(LSTM(128, return_sequences=True),
input_shape=input_shape),
Dropout(0.3),
Bidirectional(LSTM(64, return_sequences=True)),
Dropout(0.3),
LSTM(32, return_sequences=False),
Dropout(0.2),
Dense(32, activation='relu'),
Dense(16, activation='relu'),
Dense(1, activation='linear') # Preis-Vorhersage
])
model.compile(
optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),
loss='mse',
metrics=['mae']
)
print(model.summary())
return model
def train(self, X_train: np.ndarray, y_train: np.ndarray,
X_val: np.ndarray, y_val: np.ndarray,
epochs: int = 100,
batch_size: int = 32) -> tf.keras.callbacks.History:
"""
Trainiert das LSTM-Modell.
"""
if self.model is None:
self.model = self.build_model(input_shape=X_train.shape[1:])
callbacks = [
EarlyStopping(
monitor='val_loss',
patience=15,
restore_best_weights=True,
verbose=1
),
ReduceLROnPlateau(
monitor='val_loss',
factor=0.5,
patience=5,
min_lr=1e-6,
verbose=1
)
]
history = self.model.fit(
X_train, y_train,
validation_data=(X_val, y_val),
epochs=epochs,
batch_size=batch_size,
callbacks=callbacks,
verbose=1
)
return history
def predict(self, X: np.ndarray) -> np.ndarray:
"""
Macht Vorhersagen.
"""
predictions = self.model.predict(X)
# Rückskalierung
dummy = np.zeros((len(predictions), len(self.feature_columns)))
dummy[:, 0] = predictions.flatten()
predictions_rescaled = self.scaler.inverse_transform(dummy)[:, 0]
return predictions_rescaled
def evaluate(self, X_test: np.ndarray, y_test: np.ndarray) -> dict:
"""
Evaluiert Modell-Performance.
"""
predictions = self.model.predict(X_test)
# Rückskalierung
dummy_pred = np.zeros((len(predictions), len(self.feature_columns)))
dummy_pred[:, 0] = predictions.flatten()
pred_rescaled = self.scaler.inverse_transform(dummy_pred)[:, 0]
dummy_true = np.zeros((len(y_test), len(self.feature_columns)))
dummy_true[:, 0] = y_test.flatten()
true_rescaled = self.scaler.inverse_transform(dummy_true)[:, 0]
# Metriken berechnen
mae = np.mean(np.abs(pred_rescaled - true_rescaled))
mape = np.mean(np.abs((true_rescaled - pred_rescaled) / true_rescaled)) * 100
rmse = np.sqrt(np.mean((pred_rescaled - true_rescaled) ** 2))
# Direction Accuracy
pred_direction = np.sign(np.diff(pred_rescaled))
true_direction = np.sign(np.diff(true_rescaled))
direction_accuracy = np.mean(pred_direction == true_direction) * 100
return {
'MAE': mae,
'MAPE': mape,
'RMSE': rmse,
'Direction_Accuracy': direction_accuracy
}
Training-Pipeline
def train_model_pipeline(features_df: pd.DataFrame):
"""
Komplette Training-Pipeline.
"""
lstm = BTCLSTMModel(sequence_length=60)
# Sequences erstellen
X, y = lstm.prepare_sequences(features_df)
print(f"📊 Dataset: X shape={X.shape}, y shape={y.shape}")
# Train/Test Split (80/20)
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, shuffle=False # Zeit-Series: nicht shuffeln!
)
print(f"🔄 Training: {X_train.shape[0]} Samples")
print(f"🔍 Test: {X_test.shape[0]} Samples")
# Training
history = lstm.train(X_train, y_train, X_test, y_test,
epochs=100, batch_size=64)
# Evaluation
metrics = lstm.evaluate(X_test, y_test)
print("\n📈 Modell-Performance:")
print(f" MAE: ${metrics['MAE']:.2f}")
print(f" MAPE: {metrics['MAPE']:.2f}%")
print(f" RMSE: ${metrics['RMSE']:.2f}")
print(f" Direction Accuracy: {metrics['Direction_Accuracy']:.1f}%")
return lstm, history
Schritt 4: Echtzeit-Vorhersage mit HolySheep Integration
# real_time_prediction.py
import time
import pandas as pd
from datetime import datetime
from lstm_model import BTCLSTMModel
from feature_engineering import BTCFeatureEngineer
from tardis_client import TardisDataFetcher
class BTCPredictionService:
def __init__(self, holy_sheep_key: str, tardis_key: str):
self.lstm = BTCLSTMModel()
self.lstm.model = self._load_trained_model()
self.engineer = BTCFeatureEngineer(holy_sheep_key)
self.tardis = TardisDataFetcher(tardis_key)
self.last_prediction = None
self.prediction_history = []
def _load_trained_model(self):
"""
Lädt trainiertes Modell.
"""
import tensorflow as tf
return tf.keras.models.load_model('btc_lstm_model.h5')
def get_latest_prediction(self) -> dict:
"""
Holt neueste Daten und macht Vorhersage.
"""
# 1. Tardis-Daten aktualisieren
trades = self.tardis.get_btc_trades(limit=500)
features = self.engineer.calculate_technical_indicators(trades)
features = self.engineer.analyze_market_regime(features)
# 2. Sequenz für Vorhersage vorbereiten
last_sequence = features[self.lstm.feature_columns].values[-60:]
scaled_sequence = self.lstm.scaler.transform(last_sequence)
X = scaled_sequence.reshape(1, 60, -1)
# 3. Vorhersage
current_price = features['price'].iloc[-1]
predicted_price = self.lstm.predict(X)[0]
# 4. Änderung berechnen
price_change = ((predicted_price - current_price) / current_price) * 100
# 5. Konfidenz basierend auf Marktvolatilität
recent_volatility = features['volatility_5'].iloc[-1]
confidence = max(0, min(100, 100 - (recent_volatility * 1000)))
result = {
'timestamp': datetime.now(),
'current_price': current_price,
'predicted_price': predicted_price,
'predicted_change_pct': price_change,
'direction': 'UP' if price_change > 0 else 'DOWN',
'confidence': confidence,
'market_regime': features['market_regime'].iloc[-1]
}
self.last_prediction = result
self.prediction_history.append(result)
return result
def run_prediction_loop(self, interval_seconds: int = 60):
"""
Kontinuierliche Vorhersage-Schleife.
"""
print(f"🚀 Starte BTC-Vorhersage-Service (Intervall: {interval_seconds}s)")
print("Drücke Ctrl+C zum Stoppen\n")
try:
while True:
prediction = self.get_latest_prediction()
print(f"⏰ {prediction['timestamp'].strftime('%Y-%m-%d %H:%M:%S')}")
print(f" 💰 Aktuell: ${prediction['current_price']:,.2f}")
print(f" 🔮 Prognose: ${prediction['predicted_price']:,.2f}")
print(f" 📈 Änderung: {prediction['predicted_change_pct']:+.2f}%")
print(f" 🎯 Richtung: {prediction['direction']}")
print(f" 📊 Konfidenz: {prediction['confidence']:.1f}%")
print("-" * 50)
time.sleep(interval_seconds)
except KeyboardInterrupt:
print("\n⛔ Service gestoppt")
self._save_prediction_history()
def _save_prediction_history(self):
"""Speichert Vorhersage-Historie."""
if self.prediction_history:
df = pd.DataFrame(self.prediction_history)
filename = f"predictions_{datetime.now().strftime('%Y%m%d_%H%M%S')}.csv"
df.to_csv(filename, index=False)
print(f"💾 Vorhersagen gespeichert: {filename}")
Hauptprogramm
if __name__ == "__main__":
SERVICE = BTCPredictionService(
holy_sheep_key="YOUR_HOLYSHEEP_API_KEY",
tardis_key="YOUR_TARDIS_API_KEY"
)
SERVICE.run_prediction_loop(interval_seconds=60)
Preise und ROI
| Modell | HolySheep-Preis | Offizieller Preis | Ersparnis |
|---|---|---|---|
| GPT-4.1 | $8.00/MTok | $15.00/MTok | 47% günstiger |
| Claude Sonnet 4.5 | $15.00/MTok | $18.00/MTok | 17% günstiger |
| Gemini 2.5 Flash | $2.50/MTok | $5.00/MTok | 50% günstiger |
| DeepSeek V3.2 | $0.42/MTok | $0.50/MTok | 16% günstiger |
ROI-Analyse für BTC-Prognoseprojekt
- Monatliche API-Kosten: Ca. $20-50 (bei ~100K Token/Tag für Feature-Analyse)
- Potenzielle Ersparnis: $15-30/Monat gegenüber offiziellen APIs
- Trainingskosten: $0 (lokal mit TensorFlow, nur Inferenz via API)
- Break-even: Sofort, da HolySheep bereits günstiger ist als Alternativen
Warum HolySheep wählen?
- 85%+ Ersparnis für CNY-Nutzer: Mit ¥1 = $1 Wechselkurs sind alle Modelle extrem günstig
- <50ms Latenz: Kritisch für Echtzeit-Trading-Vorhersagen
- WeChat/Alipay Support: Keine ausländischen Kreditkarten nötig
- Stabile Verfügbarkeit in China: Keine VPN-Probleme, keine Ausfälle
- Kostenlose Credits: Sofort loslegen ohne upfront investment
- DeepSeek V3.2 für $0.42: Perfekt für große Datenmengen im Batch-Training
Häufige Fehler und Lösungen
Fehler 1: "Connection Error" bei HolySheep API
# ❌ FALSCH - Alte Domain verwenden
url = "https://api.openai.com/v1/chat/completions" # BLOCKIERT in China!
✅ RICHTIG - HolySheep Endpoint
url = "https://api.holysheep.ai/v1/chat/completions"
Lösung: Stellen Sie sicher, dass Sie immer https://api.holysheep.ai/v1 als Base-URL verwenden. Bei Verbindungsproblemen prüfen Sie:
- Ist der API-Key korrekt und aktiv?
- Ist die Region-CN-Konfiguration aktiviert?
- Testen Sie mit:
curl -I https://api.holysheep.ai/v1/models
Fehler 2: "UnicodeEncodeError" bei Umlauten
# ❌ FALSCH - Unicode-Sonderzeichen
response = requests.post(url, headers=headers, json=payload)
Manchmal Probleme mit ä, ö, ü in Responses
✅ RICHTIG - Explizite Encoding
response = requests.post(
url,
headers=headers,
json=payload,
timeout=30
)
Response mit Latin-1 oder UTF-8 handhaben
text = response.text.encode('latin-1').decode('utf-8', errors='replace')
Fehler 3: Tardis "Rate Limit Exceeded"
# ❌ FALSCH - Zu viele Requests
for i in range(1000):
trades = tardis.get_btc_trades() # Rate Limit erreicht
✅ RICHTIG - Rate Limiting implementieren
import time
from ratelimit import limits, sleep_and_retry
@sleep_and_retry
@limits(calls=30, period=60) # Max 30 Calls pro Minute
def get_trades_with_backoff():
try:
return tardis.get_btc_trades()
except RateLimitError:
# Exponential Backoff
for wait in [1, 2, 4, 8, 16]:
time.sleep(wait)
try:
return tardis.get_btc_trades()
except RateLimitError:
continue
return None
Fehler 4: LSTM "NaN Loss" beim Training
# ❌ FALSCH - Keine NaN-Handling
X = scaled_data[sequence_length:]
y = prices[sequence_length:]
✅ RICHTIG - Vollständige NaN-Behandlung
def prepare_data(df, feature_cols, target_col='price'):
# 1. NaN auffüllen
df = df.fillna(method='ffill').fillna(method='bfill')
# 2. Infinite Werte ersetzen
df = df.replace([np.inf, -np.inf], np.nan)
df = df.fillna(df.median())
# 3. Nochmals prüfen
assert not df.isnull().any().any(), "Noch NaN vorhanden!"
# 4. Outlier clippen
for col in feature_cols:
q1 = df[col].quantile(0.01)
q99 = df[col].quantile(0.99)
df[col] = df[col].clip(q1, q99)
return df
5. Scale und Split
scaler = MinMaxScaler()
scaled_data = scaler.fit_transform(df[feature_cols])
Fehler 5: Train/Test Leakage bei Zeitreihen
# ❌ FALSCH - Random Split bei Zeitreihen
X_train, X_test =