Python ist die Standardsprache im Algo-Trading, also dem regelbasierten, automatisierten Handel. Mit wenigen Bibliotheken, das sind fertige Code-Bausteine, und etwas Hintergrundwissen baust du einen einfachen Trading-Bot, der Marktdaten auswertet und Handelssignale nach festen Regeln erzeugt.
In dieser Anleitung zeige ich dir Schritt für Schritt, wie das geht. Du bekommst den kompletten Beispielcode einer SMA200-Strategie als historischen Backtest am Nasdaq 100 und erfährst, wie du mit KI-Unterstützung weiterarbeitest und was ein echter Live-Bot zusätzlich braucht. Fortgeschrittene Programmierkenntnisse brauchst du dafür nicht. Dieser Artikel entspricht unseren redaktionellen Richtlinien.
Python Trading Bot: das Wichtigste in 30 Sekunden
- Mit Python programmierst du einen einfachen Trading-Bot auf Basis der SMA200-Trendfolge. Der komplette Beispielcode steht in vier Blöcken in diesem Artikel.
- Drei Bibliotheken reichen für den Start: yfinance für Kursdaten, pandas für die Datenverarbeitung, matplotlib für die Auswertung. Getestet ausschließlich mit Python 3.13; andere Versionen sind nicht verifiziert.
- Der Beispielcode ist ein Backtest: Er prüft die Regeln an historischen Daten und sendet keine echten Orders. Für den Live-Betrieb brauchst du zusätzlich eine Broker-API und ein Demokonto.
- KI-Tools wie ChatGPT oder Claude beschleunigen die Entwicklung. Sie schreiben Python-Code auf Zuruf, ersetzen aber weder Backtest noch Risikomanagement.
Was ist ein Python Trading Bot?
Ein Python Trading Bot ist ein in Python programmiertes Handelssystem, das Marktdaten auswertet und nach festen Regeln Orders über eine Handelsanbindung übermitteln kann. Diese Anleitung entwickelt zunächst nur den Backtest der Strategie; eine Orderanbindung ist noch nicht enthalten.
Der Unterschied zu fertigen Bot-Plattformen liegt in der Zugänglichkeit zum Code: Bei einem gekauften Trading-Bot übernimmst du die Logik des Anbieters. Beim eigenen Python-Bot liegt der Code offen vor dir und du kannst ihn ändern. Ob du ihn dann auch wirklich verstehst, ist eine zweite Frage, und sie entscheidet, ob du dem Ergebnis trauen kannst. Fertige Bot-Angebote ersparen dir einen Teil der Programmierung, müssen aber ebenfalls geprüft werden. Bei Pionex ist insbesondere die BaFin-Warnung zu beachten; die Hintergründe erklärt unser Pionex-Erfahrungsbericht.
Ein Bot besteht im Kern aus drei Teilen: einem Datenabruf, der aktuelle oder historische Kurse lädt, einer Handelslogik, die daraus Signale berechnet, und einer Ausführungsebene, die Orders platziert oder, wie in unserem Beispiel, die Ergebnisse als Backtest auswertet.
Als erstes Projekt eignet sich eine Strategie mit eindeutigen Regeln. Die Ansätze aus dem Guide Mean-Reversion-Regeln lassen sich direkt in Code übersetzen.
Warum ist Python ideal fürs Algo-Trading?
Python ist im Algo-Trading so verbreitet, weil es Einfachheit, Leistungsfähigkeit und Flexibilität verbindet. Das gilt für den ersten Einstieg genauso wie für komplexe Strategien.
Kurz gesagt: Python ist die richtige Wahl, wenn dein Trading-Bot Daten analysieren, Strategien testen und automatisiert Orders ausführen soll. Der Aufwand bleibt dabei überschaubar.
Ein komplettes Anwendungsbeispiel ist der Python-Backtest unserer DAX-Breakoutstrategie, bei dem TradingView an seine Grenzen stieß.
Python Trading Bot programmieren: Schritt-für-Schritt-Anleitung
In diesem Abschnitt zeige ich dir, wie du mit Python einen einfachen Trading-Bot programmierst, der auf der SMA200 Long-Only-Strategie basiert. Long-Only heißt: Der Bot kauft nur und verkauft nie leer. Wir gehen den Code Schritt für Schritt durch, damit du ihn verstehst und direkt selbst umsetzen kannst.
Setup: Python-Umgebung einrichten
Bevor der Code läuft, brauchst du eine Python-Umgebung. Dieser Artikel wurde ausschließlich mit Python 3.13 getestet; andere Versionen sind nicht verifiziert und können abweichendes Verhalten zeigen. Die folgenden Zeilen funktionieren unter macOS und Linux; unter Windows aktivierst du die Umgebung in PowerShell mit .\.venv\Scripts\Activate.ps1:
python3 -m venv .venv
source .venv/bin/activate
pip install yfinance pandas matplotlib
Lege eine Datei namens sma200_bot.py an und speichere die vier Code-Blöcke weiter unten in dieser Reihenfolge dort hinein. Starte sie mit python3 sma200_bot.py. Die erwartete Ausgabe nennt den Daten-Bezugszeitraum, die Anzahl der Trades sowie Rendite und maximalen Drawdown für Strategie und Vergleichslinie Kaufen-und-Halten. Das Skript schreibt zusätzlich eine trades.csv mit allen Transaktionen und einen Chart sma200_vergleich.png. Wenn Yahoo Finance mit HTTP 429 antwortet, wiederhole den Lauf nach einigen Minuten. Für einen reproduzierbaren Lauf aus einem lokalen Cache akzeptiert Block 1 die Umgebungsvariable NDX_CSV: speichere einen erfolgreichen Download einmalig per hist.to_csv("ndx.csv") und starte spätere Läufe mit NDX_CSV=ndx.csv python3 sma200_bot.py. Nimm nicht einfach ein anderes Zeitfenster, sonst passt das Ergebnis nicht mehr zum Rest des Artikels. Mehr zu Umgebungen findest du in der offiziellen venv-Dokumentation.
Was der Code modelliert und was nicht: ein hypothetisches, bruchteilbares Positions-Konto am Nasdaq-100-Index. Der Index selbst ist nicht handelbar, es gibt keine Entsprechung mit identischen Kosten. Dividenden, Spreads, Steuern und Finanzierungs- oder Cash-Zinsen werden NICHT modelliert. Die Transaktionsgebühr FEE_RATE ist eine illustrative Annahme (5 Basispunkte), kein nachgewiesener ETF-Preis. Teileinheiten mit sechs Nachkommastellen vereinfachen die Buchführung; je nach Instrument und Broker handelst du ganze Einheiten (z. B. ein Futures-Kontrakt) oder bruchteilige (viele Krypto-Börsen und einige Aktienbroker für fractional shares). Die Endpunkt-Liquidation am letzten Handelstag ist eine vordeklarierte Backtest-Annahme, kein Strategiesignal. Benchmark und Strategie bekommen dieselbe Gebühr.
Was macht der Code?
Dieser Bot folgt einer Trendfolge-Strategie mit dem SMA200 (Simple Moving Average). Die Idee ist, langfristige Aufwärtstrends im Markt zu nutzen und klare Regeln für Käufe und Verkäufe festzulegen:
Kaufen: Eine Long-Position wird eröffnet, wenn der Schlusskurs an drei aufeinanderfolgenden Tagen über dem SMA200 liegt. Das Signal entsteht am dritten Tagesschluss; die Order wird frühestens zum nächsten verfügbaren Eröffnungskurs simuliert.
Verkaufen: Spiegelbildlich wird verkauft, wenn der Schlusskurs an drei aufeinanderfolgenden Tagen unter den SMA200 fällt. Ein Schlusskurs genau auf dem SMA200 unterbricht beide Bestätigungsserien. Fehlende Daten zählen nicht als Signal.


Der Fokus liegt auf einem sehr einfachen Regelwerk, das sich leicht nachvollziehen lässt. Genau richtig für den Einstieg ins Algo-Trading.
Warum der SMA200 als Indikator?
Der SMA200 ist der einfache gleitende Durchschnitt der letzten 200 Schlusskurse. Er ist ein verbreiteter langfristiger Trendfilter.
Der SMA200 ist einer der meistgenutzten gleitenden Durchschnitte im Trading. Liegt der Kurs über dem SMA200, erfüllt er das Einstiegskriterium dieser Strategie. Fällt er darunter, signalisiert das potenzielle Schwäche; einen intakten Trend beweist die Lage zur SMA200 allein jedoch nicht. Die drei-Tage-Bestätigung kann kurze Fehlsignale abfangen, verzögert aber jeden Entry und Exit; ob sie das Ergebnis verbessert, zeigt der Backtest.
Schritt 1: Bibliotheken importieren und Daten abrufen
Zuerst importieren wir die benötigten Python-Bibliotheken und laden die historischen Kursdaten für den Nasdaq 100 aus Yahoo Finance. Als Testfenster nehmen wir den 1. Januar 2007 bis 2. Oktober 2026. Die SMA braucht die ersten 200 Handelstage zum Warmlaufen; der Backtest startet effektiv Mitte Oktober 2007.
# === BLOCK 1 ===
# Schritt 1: Bibliotheken importieren und Daten vorbereiten
import csv
import math
import os
import numpy as np
import pandas as pd
import yfinance as yf
TICKER = "^NDX"
START = "2007-01-01"
END = "2026-10-03" # exklusiv
INITIAL_CASH = 500.0
FEE_RATE = 0.0005 # 5 Basispunkte je Transaktion (illustrative Annahme)
CONFIRM = 3
WINDOW = 200
CSV_CACHE = os.environ.get("NDX_CSV") # optional: lokaler CSV-Pfad fuer offline-Lauf
if CSV_CACHE:
hist = pd.read_csv(CSV_CACHE, index_col=0, parse_dates=True)
else:
hist = yf.download(
TICKER, start=START, end=END, interval="1d",
auto_adjust=False, actions=False, progress=False, threads=False,
)
if isinstance(hist.columns, pd.MultiIndex):
hist.columns = [c[0] for c in hist.columns]
if getattr(hist.index, "tz", None) is not None:
hist.index = hist.index.tz_localize(None)
Erklärung:
yfinance ruft Kursdaten über die inoffizielle Yahoo-Schnittstelle ab. Die Bibliothek ist nicht mit Yahoo verbunden; die Daten unterliegen den Yahoo-Nutzungsbedingungen.
pandas hält die Zeitreihe im DataFrame und berechnet SMAs und Rollings.
matplotlib rendert das Ergebnis als Bilddatei. Alternativ liefert plotly interaktive HTML-Charts; der im Artikel abgedruckte Code benutzt matplotlib.
Zeitraum: Der Code lädt tägliche Kursdaten für den Nasdaq 100 Index über rund 20 Jahre.
Schritt 2: Berechnung des SMA200
Der SMA200 wird berechnet, indem der Durchschnitt der letzten 200 Schlusskurse gebildet wird. Mit min_periods=200 bleibt die SMA während des Warm-ups bewusst leer, damit kein Signal auf halben Daten entsteht.
# === BLOCK 2 ===
# Schritt 2: Datenvalidierung (ohne stilles Droppen) UND SMA200 berechnen
def _validate(df, min_window):
"""Lehnt empty, missing-column, NaN, unsortiert, Dubletten, OHLC-Verletzung ab.
Prueft nur die vier Pflichtspalten (Open/High/Low/Close); evtl. zusaetzliche
Spalten (z. B. Volume aus yfinance) werden ignoriert, aber nicht entfernt.
"""
if df.empty:
raise ValueError("Leerer Datensatz: Daten konnten nicht geladen werden.")
required = {"Open", "High", "Low", "Close"}
missing = required - set(df.columns)
if missing:
raise ValueError(f"Fehlende Spalten im Datensatz: {sorted(missing)}")
if not df.index.is_monotonic_increasing:
raise ValueError("Zeitreihe ist nicht aufsteigend sortiert.")
if df.index.duplicated().any():
raise ValueError("Zeitreihe enthaelt doppelte Zeitstempel.")
for col in sorted(required):
v = df[col].astype(float)
if not np.isfinite(v).all():
raise ValueError(f"Spalte {col} enthaelt nicht-endliche Werte.")
if (v <= 0).any():
raise ValueError(f"Spalte {col} enthaelt nicht-positive Werte.")
o = df["Open"].astype(float)
h = df["High"].astype(float)
l_ = df["Low"].astype(float)
c = df["Close"].astype(float)
if ((h < o) | (h < c)).any():
raise ValueError("OHLC-Verletzung: High < max(Open, Close).")
if ((l_ > o) | (l_ > c)).any():
raise ValueError("OHLC-Verletzung: Low > min(Open, Close).")
if (h < l_).any():
raise ValueError("OHLC-Verletzung: High < Low.")
if len(df) < min_window + 1:
raise ValueError(f"Datensatz zu kurz: {len(df)} < {min_window + 1}.")
_validate(hist, min_window=WINDOW)
hist["SMA200"] = hist["Close"].rolling(window=WINDOW, min_periods=WINDOW).mean()
Schritt 3: Kauf- und Verkaufsregeln sauber buchen
Jetzt definieren wir die Regeln der Strategie. Wichtig: Das Signal entsteht am Schluss des dritten bestätigten Tages, die Ausführung simulieren wir zum nächsten Eröffnungskurs. Position, Cash und Equity werden täglich zum Close bewertet. Equality bricht die Serie, fehlende SMA-Werte zählen nicht als Signal.
# === BLOCK 3 ===
# Schritt 3: Signal, Fill, Buchfuehrung, Endpunkt-Liquidation
close_ok = hist["Close"].notna()
sma_ok = hist["SMA200"].notna()
valid = close_ok & sma_ok
above = (hist["Close"] > hist["SMA200"]) & valid
below = (hist["Close"] < hist["SMA200"]) & valid
def _consec(mask):
groups = (~mask).cumsum()
return mask.astype(int).groupby(groups).cumsum()
entry_signal = (_consec(above) >= CONFIRM).to_numpy()
exit_signal = (_consec(below) >= CONFIRM).to_numpy()
cash = INITIAL_CASH
units = 0.0
equity = []
held_before_eod = []
trades = [] # (signal_date, fill_date, side, price, size, fee, reason)
for i, ts in enumerate(hist.index):
today_open = float(hist["Open"].iloc[i])
if i > 0:
if units == 0.0 and entry_signal[i - 1]:
size = math.floor(cash / (today_open * (1 + FEE_RATE)) * 1e6) / 1e6
if size > 0:
cost = size * today_open
fee = cost * FEE_RATE
cash -= cost + fee
units += size
trades.append((hist.index[i - 1], ts, "BUY", today_open, size, fee,
f"{CONFIRM} Closes > SMA{WINDOW}"))
elif units > 0.0 and exit_signal[i - 1]:
proceeds = units * today_open
fee = proceeds * FEE_RATE
cash += proceeds - fee
trades.append((hist.index[i - 1], ts, "SELL", today_open, units, fee,
f"{CONFIRM} Closes < SMA{WINDOW}"))
units = 0.0
held_before_eod.append(units > 0.0)
equity.append(cash + units * float(hist["Close"].iloc[i]))
# Endpunkt-Liquidation (vordeklariert, kein Signal)
if units > 0.0:
last_close = float(hist["Close"].iloc[-1])
proceeds = units * last_close
fee = proceeds * FEE_RATE
cash += proceeds - fee
trades.append((hist.index[-1], hist.index[-1], "SELL_END", last_close, units, fee,
"Endpunkt-Liquidation (vordeklarierte Backtest-Annahme, kein Signal)"))
units = 0.0
equity[-1] = cash
hist["Equity"] = equity
Schritt 4: Ergebnis anzeigen und ehrlich einordnen
Zur Auswertung zeichnen wir zwei Charts: einen Depotvergleich zwischen Strategie und Kaufen-und-Halten (gleiches Startkapital) und darunter die zugehörigen Drawdowns.
# === BLOCK 4 ===
# Schritt 4: Benchmark Kaufen-und-Halten mit identischer Gebuehr, Metriken, Konsolen-Summary
first_valid = int(valid.to_numpy().argmax())
bh_entry = float(hist["Open"].iloc[first_valid])
bh_size = math.floor(INITIAL_CASH / (bh_entry * (1 + FEE_RATE)) * 1e6) / 1e6
bh_cash_after_entry = INITIAL_CASH - bh_size * bh_entry * (1 + FEE_RATE)
bh = [float("nan")] * first_valid
for j in range(first_valid, len(hist)):
bh.append(bh_cash_after_entry + bh_size * float(hist["Close"].iloc[j]))
last_close = float(hist["Close"].iloc[-1])
bh[-1] = bh_cash_after_entry + bh_size * last_close * (1 - FEE_RATE)
hist["BuyAndHold"] = bh
eval_start = hist.index[first_valid]
eval_end = hist.index[-1]
days = (eval_end - eval_start).days
years = days / 365.25
def _ann(total):
return (1 + total) ** (1 / years) - 1 if years > 0 else float("nan")
def _max_dd(curve):
# Peak = beobachtetes Hoch, mindestens Startkapital. Erster Wert wird NICHT
# ueberschrieben, sonst wuerde ein Erst-Tag unter Startkapital unsichtbar.
peak = curve.cummax().clip(lower=INITIAL_CASH)
return float((curve / peak - 1.0).min())
strat_curve = hist["Equity"].iloc[first_valid:]
bh_curve = hist["BuyAndHold"].iloc[first_valid:]
strat_total = float(strat_curve.iloc[-1]) / INITIAL_CASH - 1
bh_total = float(bh_curve.iloc[-1]) / INITIAL_CASH - 1
exposure = sum(held_before_eod[first_valid:]) / len(held_before_eod[first_valid:])
print(f"Zeitraum: {eval_start.date()} bis {eval_end.date()} ({days} Tage, Warm-up ausgeschlossen)")
print(f"Strategie Endstand: {strat_curve.iloc[-1]:.2f} USD "
f"({strat_total*100:.2f} %, {_ann(strat_total)*100:.2f} % p.a., Max-DD {_max_dd(strat_curve)*100:.2f} %)")
print(f"Kaufen-und-Halten: {bh_curve.iloc[-1]:.2f} USD "
f"({bh_total*100:.2f} %, {_ann(bh_total)*100:.2f} % p.a., Max-DD {_max_dd(bh_curve)*100:.2f} %)")
print(f"Trades: {sum(1 for t in trades if t[2]=='BUY')} Entries, "
f"{sum(1 for t in trades if t[2]=='SELL')} Signal-Exits, "
f"{sum(1 for t in trades if t[2]=='SELL_END')} Endpunkt-Liquidation; "
f"Exposure {exposure*100:.1f} % der Evaluierungstage")
# Transaktionslog mit csv.writer; Reasons koennen Kommas enthalten (SELL_END).
with open("trades.csv", "w", newline="") as fh:
writer = csv.writer(fh, quoting=csv.QUOTE_MINIMAL)
writer.writerow(["signal_date", "fill_date", "side", "price", "size", "fee", "reason"])
for sig, fill, side, price, size, fee, reason in trades:
writer.writerow([
sig.date().isoformat(),
fill.date().isoformat(),
side,
f"{price:.4f}",
f"{size:.6f}",
f"{fee:.6f}",
reason,
])
print("Transaktionen gespeichert: trades.csv")
# Chart: Depotverlauf gegen Kaufen-und-Halten mit Drawdown-Panel.
import matplotlib
matplotlib.use("Agg") # headless, keine GUI
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
dd_s = strat_curve / strat_curve.cummax().clip(lower=INITIAL_CASH) - 1.0
dd_bh = bh_curve / bh_curve.cummax().clip(lower=INITIAL_CASH) - 1.0
fig, (ax1, ax2) = plt.subplots(
2, 1, figsize=(10, 6.6),
gridspec_kw={"height_ratios": [3, 1.3], "hspace": 0.14},
sharex=True,
)
ax1.plot(strat_curve.index, strat_curve, color="#0052FF", linewidth=1.9,
label=f"SMA200-Strategie (Endstand {strat_curve.iloc[-1]:.0f} USD)")
ax1.plot(bh_curve.index, bh_curve, color="#5B616E", linewidth=1.6,
label=f"Kaufen und Halten (Endstand {bh_curve.iloc[-1]:.0f} USD)")
ax1.set_yscale("log")
ax1.set_ylabel("Depot in USD (Log-Skala)")
ax1.set_title(f"Depotverlauf bei {INITIAL_CASH:.0f} USD Startkapital, {eval_start.date()} bis {eval_end.date()}",
fontsize=12, loc="left")
ymin = min(strat_curve.min(), bh_curve.min()) * 0.8
ymax = max(strat_curve.max(), bh_curve.max()) * 1.15
ax1.set_ylim(ymin, ymax)
ax1.yaxis.set_major_locator(mticker.FixedLocator([200, 500, 1000, 2000, 5000, 10000]))
ax1.yaxis.set_major_formatter(mticker.FuncFormatter(lambda x, _: f"{int(x):,}".replace(",", ".")))
ax1.yaxis.set_minor_locator(mticker.NullLocator())
ax1.legend(loc="upper left", fontsize=8.5)
ax1.grid(True, alpha=0.25)
ax2.fill_between(dd_s.index, dd_s * 100, 0, color="#0052FF", alpha=0.35,
label=f"DD Strategie (max {dd_s.min()*100:.1f} %)")
ax2.fill_between(dd_bh.index, dd_bh * 100, 0, color="#5B616E", alpha=0.35,
label=f"DD B&H (max {dd_bh.min()*100:.1f} %)")
ax2.set_ylabel("Drawdown in %")
ax2.legend(loc="lower right", fontsize=8.5)
ax2.grid(True, alpha=0.25)
fig.autofmt_xdate()
fig.savefig("sma200_vergleich.png", dpi=150, bbox_inches="tight")
plt.close(fig)
print("Chart gespeichert: sma200_vergleich.png")

Was zeigt der Backtest? Im Evaluierungsfenster vom 17. Oktober 2007 bis zum 2. Oktober 2026 wächst das Strategie-Depot von 500 USD netto auf 3.946 USD. Das sind rund 689 Prozent Gesamtrendite oder 11,5 Prozent pro Jahr bei einem maximalen Drawdown von 28,5 Prozent. Der Kaufen-und-Halten-Vergleich mit identischen Gebühren endet bei 7.050 USD, also 1.310 Prozent Gesamtrendite oder 15,0 Prozent pro Jahr bei einem maximalen Drawdown von 53,7 Prozent. Ohne Gebühr („gross“) sind es für die Strategie 710 Prozent, für die Vergleichslinie 1.311 Prozent. Die Gebührenannahme verschiebt die Zahlen, dreht das Vorzeichen aber nicht. Die Strategie schnitt in diesem Fenster also schlechter ab als die Vergleichslinie, hielt den maximalen Verlust aber etwa halb so klein. Insgesamt wurden 26 Entries, 25 Signal-Exits und eine Endpunkt-Liquidation ausgelöst, die Position war an 79,9 Prozent der Evaluierungstage investiert (vor der Endpunkt-Liquidation gezählt).
Mit diesem Beispiel wollte ich dir zeigen, dass sich ein einfaches Regelwerk vollständig nachvollziehen und messen lässt. Es belegt auch, warum eine Behauptung wie „schlägt den Index“ ohne Zahlen wenig wert ist. Vergangene Performance ist kein Indikator für zukünftige Ergebnisse. Warum dazu ein Out-of-Sample-Test gehört, zeigt das Backtesting-Beispiel mit 32 Jahren DAX.
Der Nasdaq 100 ist selbst nicht handelbar; ein Live-Pendant wäre ein ETF, ein Futures-Kontrakt oder ein CFD mit eigenen Kosten, Dividenden und Steuern. In Bullenmärkten, in denen der Aufwärtstrend stark ist, bleibt die Strategie meist voll investiert und zeigt kaum Vorteil gegenüber Kaufen-und-Halten. In Seitwärtsphasen oder Bärenmärkten kann der Filter einen Teil eines Rückgangs auslassen; dafür zahlst du mit verzögerten Einstiegen und Whipsaws, wenn der Markt knapp um den Durchschnitt pendelt.
Lesetipp: Mehr über Grid Trading erfahren
Trading Bot mit KI erstellen: ChatGPT und Claude als Coding-Hilfe
KI-Sprachmodelle haben die Einstiegshürde fürs Bot-Programmieren drastisch gesenkt. ChatGPT, Claude und ähnliche Tools schreiben dir ein komplettes Code-Gerüst, wenn du deine Strategie präzise beschreibst. Für unseren Artikel über KI Trading habe ich mit einem einzigen Prompt einen kompletten DAX-Backtest von Claude erstellen lassen.
Ein brauchbarer Prompt für den Einstieg sieht so aus. Je konkreter du Regeln, Markt und Zeitraum benennst, desto besser wird der Code:
Schreibe mir ein Python-Skript, das mit yfinance die Tageskurse des
Nasdaq 100 vom 1. Januar 2007 bis 2. Oktober 2026 lädt, den SMA200
berechnet und eine Long-Only-Strategie backtestet: Signal entsteht am
Close, Fill zum nächsten Open; Kauf nach 3 Schlusskursen strikt über
dem SMA200, Verkauf nach 3 Schlusskursen strikt darunter. Gleichheit
und fehlende SMA brechen die Serie. Zeige Depotverlauf und Drawdown
im Vergleich zu Kaufen-und-Halten mit matplotlib.
Verlass dich trotzdem nie blind auf den generierten Code. KI-Modelle verwenden gelegentlich veraltete Bibliotheks-Syntax oder bauen stille Logikfehler ein, etwa bei der Reihenfolge von Signal und Ausführung. Lies jeden Vorschlag gegen, lass dir unklare Zeilen erklären und prüfe das Ergebnis immer mit einem eigenen Backtest. API-Schlüssel oder Passwörter gehören nicht in einen Prompt; die KI beschleunigt das Tippen, das Denken bleibt bei dir.
Vom Backtest zum echten Bot: Paper Trading und Broker-API
Wichtig für die Einordnung: Der Beispielcode oben ist ein reiner Backtest. Er handelt nicht selbst, sondern rechnet die Strategie an historischen Daten durch. Ein echter Bot braucht zwei Dinge zusätzlich: eine Testphase ohne echtes Geld und eine Anbindung an einen Broker.
Ein Backtest prüft eine Handelsstrategie an historischen Kursdaten. Er zeigt, wie sich die Regeln in der Vergangenheit geschlagen hätten, garantiert aber keine künftigen Ergebnisse.
Der sinnvolle Weg in den Live-Betrieb führt über vier Stufen:
- Backtest verfeinern: Teste die Strategie über verschiedene Zeiträume und Märkte, nicht nur über den einen Chart, der gut aussieht.
- Broker-API und Demokonto einrichten: Öffne ein Demokonto bei einem Broker, der eine Programmierschnittstelle anbietet, und bringe deinen Bot dazu, dort Orders zu senden statt sie nur zu drucken.
- Paper Trading: Lass den Bot wochenlang auf dem Demokonto mit simulierten Ausführungen laufen. Fehler kosten nichts, bedeuten aber auch keine echten Fills: Latenz, Ablehnungen und Teilfills verhalten sich auf Demokonten anders als unter echten Marktbedingungen.
- Live mit kleiner Positionsgröße: Erst wenn der Bot stabil läuft, kommt echtes Geld ins Spiel, und zwar mit kleiner Positionsgröße.
Eine Broker-API ist eine Programmierschnittstelle, über die ein Programm Kurse abruft und Orders direkt an den Broker sendet. Automatisierter Paper-Handel setzt denselben Programmierzugang voraus wie der spätere Live-Handel; der Konto-Modus und das Risiko unterscheiden sich offensichtlich, zusätzlich bekommst du im Paper-Konto häufig nachgelagerte oder qualitativ andere Marktdaten. Die Ausführung wird simuliert; welche Teilfills, Ablehnungen und Liquiditätsgrenzen berücksichtigt werden, hängt vom Anbieter ab.
Für Aktien und Futures ist die API von Interactive Brokers eine mögliche Schnittstelle, inklusive Paper-Konto zum Testen (siehe die IBKR-Dokumentation zum Paper Trading). Im Krypto-Bereich verbindet die Open-Source-Bibliothek ccxt deinen Python-Code mit zahlreichen Kryptobörsen über eine einheitliche Schnittstelle; für Aktien und Futures ist sie nicht gedacht.
Was dein Bot zusätzlich braucht, bevor du ihn mit echtem Geld laufen lässt: Prüfung von Instrument und Ordergröße, Abgleich mit dem Konto-Status, Schutz vor doppelten Orders, Umgang mit abgelehnten oder nur teilweise ausgeführten Fills, saubere Wiederverbindung nach einem Netzausfall, Logs und harte Verlustgrenzen. API-Schlüssel gehören niemals in öffentlichen Code oder in einen KI-Prompt. Vergib dem Schlüssel nur die Rechte, die der Test wirklich braucht; das Abschalten von Auszahlungen verhindert keine Handelsverluste.
Ehrlicherweise gehört dazu: Ein Live-Bot ist kein Selbstläufer. Du musst den Code warten, die Positionen überwachen und bei API-Änderungen nachbessern. Wer keine Lust auf laufende Pflege hat, fährt mit regelbasiertem manuellem Trading oft besser.
Bot mit Claude Code und Alpaca-MCP bauen: worauf du achten musst
Ein viel gesehenes Beispiel für den Bau mit KI ist das englische YouTube-Video von Ray Fu vom 17. September 2026. Darin verbindet er Claude über den Alpaca-MCP-Server mit einem Paper-Konto und lässt sich von Claude Code ein Python-Skript für eine SMA-Kreuzung 20/50 schreiben, das werktags zur Börseneröffnung starten soll. Als Einrichtungs-Anleitung ist das brauchbar. Im ausgewerteten Transkript wird aber kein nachvollziehbarer Backtest mit Kennzahlen erläutert. Ein Nachweis für einen profitablen Bot liegt damit nicht vor.
Ein MCP-Server (Model Context Protocol) ist ein Zusatzprogramm, über das ein KI-Assistent auf fremde Dienste zugreift, zum Beispiel Kurse abfragt oder beim Broker Orders sendet.
Wichtig für die Einordnung: Die KI schreibt hier den Code. Der beschriebene Bot soll Kauf und Verkauf nach einer festen SMA-Regel ausführen. Ob der erzeugte Code diese Vorgabe korrekt umsetzt, wurde nicht geprüft. Drei Stellen laut Transkript (Startzeit der Untertitelzeile, Aussagen sinngemäß):
- 06:55 bis 07:02: Ray Fu lässt Claude über MCP per Chat-Befehl eine Order auf Micron senden.
- 10:32: Er nutzt Claude Code meist mit „bypass permissions“, weil das viel einfacher sei.
- 11:37: Der Dry Run lief gut, also funktioniere der Bot.
Unsere Einschätzung: Die folgenden Empfehlungen stammen von uns, nicht aus dem Video.
Falle 1: Welche Kerze nutzt der Lauf zur Eröffnung?
Um 9:30 Uhr New Yorker Zeit hat die heutige Tageskerze gerade erst begonnen. Lege fest, ob dein Skript den letzten abgeschlossenen Schlusskurs nutzt oder eine halbe Kerze von heute. Im Transkript ist von 9:30 Uhr EST die Rede; im Sommer gilt in New York aber EDT. Sicherer ist es, vor jedem Lauf die Börsenuhr und den Handelskalender von Alpaca abzufragen, damit der Bot an Feiertagen nicht handelt. Prüfe auch, was bei ausgeschaltetem Rechner passiert: Ausfall, Nachholen oder doppelter Lauf.
Falle 2: MCP mit Orderrechten plus „bypass permissions“
Der Alpaca-MCP-Server kann echte Orders senden und auf dein Depot zugreifen, so steht es im Projekt auf GitHub; voreingestellt ist Paper Trading. Mit freigegebenen Orderwerkzeugen und passenden Broker-Schlüsseln hat der angeschlossene KI-Assistent damit eine Kauf-Taste. „Bypass permissions“ überspringt zusätzlich die Berechtigungsabfragen in Claude Code. Eingeschaltete Abfragen allein schützen Schlüsseldateien aber nicht zuverlässig vor Lesezugriffen, siehe die Berechtigungsregeln von Claude Code. Anthropic beschreibt die Abfragen in der Sicherheitsdokumentation von Claude Code als Schutz, auch gegen eingeschleuste Anweisungen (Prompt Injection).
Unsere Empfehlung: Verwende nur Paper-Schlüssel. Alpaca vergibt dafür laut Paper-Trading-Dokumentation eigene Schlüssel und eine eigene Adresse. Lege den Schlüssel nur an einer Stelle ab, nicht wie im Transkript beschrieben zusätzlich in einer zweiten Datei, und lass die Abfragen eingeschaltet. Wenn der Chat nur Kurse abrufen soll, aktiviere ausschließlich die dafür benötigten Datenwerkzeuge. Laut Alpaca-Anleitung Working with Orders lassen sich Short-Orders auch ohne offene Long-Position platzieren. Prüfe vor jedem Verkauf den aktuellen Long-Bestand und offene Verkaufsorders. Begrenze die Verkaufsmenge auf den verfügbaren Bestand; andernfalls kann bei erlaubtem Leerverkauf unbeabsichtigt eine Short-Position entstehen.
Falle 3: „Dry Run läuft“ ist kein Backtest
Ein fehlerfreier Probelauf zeigt nur, dass das Programm startet. Ob die Regel Geld verdient, zeigt er nicht. Dafür brauchst du einen Backtest mit sauberer Reihenfolge von Signal und Ausführung, wie oben in Schritt 3, und danach die Prüfliste aus dem Abschnitt Vom Backtest zum echten Bot. Paper Trading bildet laut Alpaca zudem weder Markteinfluss noch Slippage durch Latenz oder regulatorische Gebühren ab.
Anzeige
Anzeige
Open-Source-Frameworks: Freqtrade, Jesse und NautilusTrader statt eigenem Gerüst
Der Bot oben ist bewusst von Hand gebaut, damit du jeden Schritt siehst. Für den Dauerbetrieb brauchst du mehr als Signale: Orderverwaltung, Wiederanlauf nach Verbindungsabbruch, Logging, sauberes Backtesting mit Gebühren und Slippage. Diese Projekte bieten quelloffene Software oder einen quelloffenen Kern. Cloud-Betrieb, Zusatzfunktionen, Marktdaten und Handel können trotzdem Geld kosten.
- Freqtrade: quelloffen, auf Kryptobörsen ausgerichtet. Enthält Backtesting, Hyperopt-Optimierung, Steuerung per Telegram oder WebUI und Beispielstrategien.
- Jesse: quelloffener Kern, Strategien als Python-Klassen; der Anbieter bietet zusätzlich bezahlte Live-Plattform-Dienste.
- NautilusTrader: Kern in Rust, Strategien in Python, ereignisgesteuert, mehrere Assetklassen inklusive Aktien und Futures.
- Hummingbot: quelloffen und auf Market Making und Arbitrage spezialisiert, an zentralen wie dezentralen Handelsplätzen.
- OctoBot: quelloffene Software mit grafischer Oberfläche; die verlinkte Cloud-Variante bietet zusätzlich kostenpflichtige Pläne und fertige Strategien.
Was dir kein Framework abnimmt: die Entscheidung für eine Strategie, die zu dir passt. Alle Projekte liefern die Technik drumherum, einige liefern zusätzlich Beispielstrategien oder fertige Bausteine. Deren bloße Verfügbarkeit ist kein Nachweis für einen profitablen Handel. Deine Regeln, deine Positionsgröße, dein Stop bleiben deine Aufgabe. Eigener Code lässt sich untersuchen und ändern; dafür musst du seine Logik und Abhängigkeiten auch tatsächlich prüfen. Bevor du ein Framework mit echtem Geld laufen lässt, sollte es wochenlang im Paper-Modus gelaufen sein und du solltest verstanden haben, was es bei einem Verbindungsabbruch tut.
Wer den Aufwand mit Server und Code scheut, greift zu einer fertigen Abo-Plattform. Die kostet dafür Geld, und zwar mehr als nur die Monatsgebühr. Was dabei zusammenkommt, rechnen wir am Beispiel der Abo-Plattform WunderTrading durch.
Kein eigener Code? Wenn du gar nicht selbst programmieren willst, führt der Weg zu den fertigen Plattformen. Was eine solche Abo-Lösung im Alltag leistet und wo ihre Grenzen liegen, zeigt unser Cryptohopper Test.
Ein Bot ist nur einer von mehreren Wegen zur Automatisierung. Welche Alternativen es zum eigenen Code gibt und was sie kosten, zeigt unser Überblick zum Auto Trading.
Grenzen und Risiken: Was der einfache Bot nicht kann
Der gezeigte Backtest rechnet mit groben Gebühren, aber ohne Steuern, ohne Spreads und ohne Slippage. Die reale Performance kann dadurch spürbar schlechter ausfallen als die Linien im Chart.
Slippage ist die Differenz zwischen dem erwarteten und dem tatsächlich ausgeführten Kurs einer Order. Sie entsteht vor allem in schnellen Märkten und bei geringer Liquidität.
Die zweite große Falle ist die Überanpassung. Wer die Parameter so lange dreht, bis der Backtest perfekt aussieht, optimiert die Strategie auf die Vergangenheit statt auf die Zukunft.
Overfitting bedeutet, dass eine Handelsstrategie zu stark an historische Kursdaten angepasst wurde. Im Live-Handel versagt sie dann häufig.
Dazu kommt das Marktrisiko: Die SMA200-Strategie lebt von stabilen Trends. In langen Seitwärtsphasen produziert sie Fehlsignale am laufenden Band. Ein Bot ersetzt deshalb kein Risikomanagement: Positionsgröße, maximaler Verlust pro Trade und ein Notfallplan für Technikausfälle gehören zu jedem Live-Betrieb.
Rechtlich gilt in Deutschland: Für private Anleger ist der Einsatz eines Bots auf dem eigenen Konto grundsätzlich möglich. Brokerbedingungen und Marktregeln gelten trotzdem. Wer Dienstleistungen für andere anbietet, muss das konkrete Geschäftsmodell prüfen: Persönliche Anlageberatung oder Vermögensverwaltung mit Entscheidungsspielraum können nach § 2 WpIG und § 15 WpIG erlaubnispflichtig sein. Öffentlich verbreitete Handelssignale sind nicht allein deshalb erlaubnispflichtige Anlageberatung, weil sie kostenpflichtig sind; weitere gesetzliche Pflichten können gelten. Dieser Absatz ist keine Rechtsberatung.
Fertige Systeme als Abkürzung: Eine Alternative sind kommerzielle Systeme wie die Handelssysteme von Algo-Camp. Allerdings gibst du damit die Kontrolle über die Strategielogik aus der Hand.
Vor dem Kauf fertiger Systeme lohnt ein Blick in unseren Praxischeck des kommerziellen Anbieters Mader & Rausch: Auch verifizierte Konten erzählen nicht immer die ganze Geschichte.
Fazit: Was dieser Bot zeigt und was nicht
Der SMA200-Beispielcode liefert in diesem Test eine klare, aber unspektakuläre Erkenntnis: Mit drei Bibliotheken und vier übersichtlichen Code-Blöcken lässt sich eine Trendfolgeregel vollständig testen, inklusive Buchführung und Transaktionslog. Die Zahlen aus unserem Fenster 2007 bis 2026 belegen auch, warum pauschale Behauptungen über eine „Outperformance“ ohne Rechnung wenig wert sind: Die Strategie blieb hinter Kaufen-und-Halten zurück, bot aber einen deutlich kleineren maximalen Drawdown. Was sich für dich lohnt, musst du anhand deiner eigenen Ziele entscheiden.
Algo-Trading entkoppelt Entscheidungen von Emotionen, ersetzt aber kein Trading-Handwerk. Fortschritt ist nicht garantiert und schon kleine Live-Positionen können echte Verluste bedeuten; sauberer Backtest, eine ausreichend lange Phase im Demokonto und eine kleine Startposition begrenzen den Schaden, wenn die Idee nicht funktioniert.
Ein praktischer Tipp: Wenn du beim Programmieren nicht weiterkommst, google die Fehlermeldung oder frag eine KI danach. Viele Trader standen vor denselben Problemen, die Lösungen stehen längst in Foren und Blogs.
Falls du tiefer einsteigen willst, schau dir unseren Überblick zum Algo-Trading an. Mehr Strategien findest du in unserer Rubrik Trading-Strategien. Und wenn du deine Grundlagen systematisch ausbauen möchtest, ist unsere Trading-Ausbildung der richtige Ort dafür.
FAQ zu Trading mit Python
Was brauche ich für einen Python Trading Bot?
Für den Einstieg reichen eine Python-Umgebung (dieser Artikel wurde mit Python 3.13 getestet; andere Versionen sind nicht verifiziert), eine stabile Internetverbindung und drei Bibliotheken: yfinance für die Kurse, pandas für die Datenverarbeitung und matplotlib für die Auswertung. Dazu kommen Grundwissen über Trading-Strategien und Risikomanagement. Für den Backtest genügt dieser Setup; sobald du den Bot automatisiert Orders schicken lassen willst (auch nur auf einem Demokonto), brauchst du zusätzlich einen Broker-API-Zugang.
Handelt der Beispielcode schon mit echtem Geld?
Nein. Der Beispielcode ist ein historischer Backtest: Er rechnet die Regeln an vergangenen Kursen durch und schreibt ein Transaktionslog, sendet aber keine Orders an einen Broker. Für echten Handel brauchst du zusätzlich eine Broker-API, ein Demokonto und eine Testphase, bevor echtes Kapital im Spiel ist.
Was ist ein Trading Bot?
Ein Trading Bot ist ein automatisiertes Programm, das auf Basis festgelegter Regeln Kauf- und Verkaufsentscheidungen trifft. Er analysiert Marktdaten, kann Orders ausführen und arbeitet ohne emotionale Entscheidungen. Die tatsächlichen Handelszeiten hängen vom Instrument und Handelsplatz ab.
Welche Fehler sollte ich vermeiden, wenn ich einen Trading-Bot programmiere?
Ein häufiger Fehler ist es, den Bot zu kompliziert zu gestalten. Halte die Strategie einfach, wie die SMA200-Trendfolge, und teste sie gründlich, bevor du echtes Kapital einsetzt. Zweiter Dauerfehler ist eine schlampige Buchführung: Signal und Ausführung gehören getrennt, Equality und fehlende Werte dürfen keine Signale erzeugen, und Gebühren und Slippage gehören in den Backtest. Märkte verändern sich; überprüfe regelmäßig, ob die Strategie noch funktioniert.
Sind Trading Bots in Deutschland legal?
Grundsätzlich ja, wenn du als privater Anleger auf deinem eigenen Konto handelst und die geltenden Regeln einhältst. Für Dienstleistungen an Dritte hängt eine mögliche Erlaubnispflicht vom konkreten Angebot ab; persönliche Anlageberatung oder Vermögensverwaltung mit Entscheidungsspielraum können nach §§ 2, 15 WpIG erlaubnispflichtig sein. Kostenpflichtige Handelssignale lassen sich nicht pauschal mit erlaubnispflichtiger Anlageberatung gleichsetzen. Beachte zusätzlich die Regeln deines Brokers: Manche Anbieter schränken automatisierten Handel in ihren AGB ein.
Welche Programmiersprache eignet sich am besten für Trading Bots?
Die passende Sprache hängt von Plattform, vorhandenen Bibliotheken und Anforderungen ab. Python eignet sich häufig für Datenanalyse und Prototypen, die Lernkurve ist flach. Wer schon in einer anderen Sprache zu Hause ist oder eine fertige Plattform nutzt, hat mit C++, Java oder Pine Script ebenfalls gute Wege.
Über den Autor: Bjarne Claussen
Bjarne Claussen ist seit 2018 im Trading aktiv und schreibt als Autor für Kagels Trading zu den Schwerpunkten Prop Trading, KI- und Algo-Trading, Kryptowährungen, Makroökonomie und Fundamentalanalyse.
Als Algo-Trader handelt er selbst primär Rohöl und den S&P 500. Sein Fokus auf systematische, datengetriebene Handelsansätze ergänzt die diskretionäre Trading-Perspektive bei Kagels Trading und bildet die Grundlage seiner kritischen Bewertungen von Trading-Software und KI-gestützten Tools.
In diesem Artikel erläutert er ein SMA200-Beispiel und die Anforderungen an einen anschließenden Demotest. Eine fertig getestete Live-Anbindung ist nicht Bestandteil der Anleitung.
Dieser Artikel wurde von Karsten Kagels final geprüft.










