Indikatoren im Code: vektorisierte SMA, EMA, RSI, ATR und Bollinger-Bänder, abgeglichen mit einer Charting-Plattform
Schreiben Sie vektorisierte pandas-Funktionen für die fünf meistgenutzten Indikatoren und erfahren Sie, warum ihre Werte von einer Charting-Plattform abweichen können und wie Sie sie in Einklang bringen.
Was Sie lernen werden
- Wie
rollingundewmSMA, EMA, Wilder-Glättung, ATR und Bollinger-Bänder in jeweils wenigen Zeilen umsetzen. - Welche Parameter (
adjust,alpha,ddof) die Zahlen unbemerkt verändern. - Warum Ihr RSI oder EMA in den ersten Balken von der Charting-Plattform abweicht und wie Sie beide korrekt vergleichen.
- Wie Sie Indikatoren als reine Funktionen in
src/indicators.pyorganisieren, um sie wiederzuverwenden und zu testen.
Erklärung
Im Kurs „Technische Analyse im Detail“ wurde erklärt, was diese Indikatoren bedeuten; hier ist das Ziel korrekter, schneller, testbarer Code. Jede Funktion nimmt eine Series entgegen und gibt eine Series mit demselben Index zurück.
SMA (simple moving average, einfacher gleitender Durchschnitt): def sma(s, n): return s.rolling(n).mean().
EMA (exponential moving average, exponentieller gleitender Durchschnitt): def ema(s, n): return s.ewm(span=n, adjust=False).mean(). Mit span=n beträgt die Glättungskonstante α = 2 ÷ (n + 1); für n = 20 ist α = 0.0952. adjust=False ergibt die rekursive Formel EMAt = α × Pt + (1 − α) × EMAt−1, die Plattformen verwenden; die Standardeinstellung adjust=True gewichtet in den ersten paar Dutzend Balken anders. pandas startet mit dem ersten Kurs; die meisten Plattformen starten mit dem SMA der ersten n Balken. Beide Startwerte verblassen; nach etwa 3n Balken stimmen die Reihen weitgehend überein.
RSI (relative strength index, Relative-Stärke-Index), Wilders Version:
delta = s.diff()
gain = delta.clip(lower=0); loss = -delta.clip(upper=0)
avg_gain = gain.ewm(alpha=1/n, adjust=False).mean()
avg_loss = loss.ewm(alpha=1/n, adjust=False).mean()
rsi = 100 - 100 / (1 + avg_gain / avg_loss)
Wilders Glättung ist ein EMA mit α = 1 ÷ n, nicht 2 ÷ (n + 1); span=14 an dieser Stelle zu verwenden ist der häufigste RSI-Fehler. Ist avg_loss null, wird der RSI korrekterweise 100.
ATR (average true range, durchschnittliche wahre Handelsspanne): Die True Range ist der größte der Werte Hoch − Tief, |Hoch − vorheriger Schluss| und |Tief − vorheriger Schluss|:
pc = close.shift(1)
tr = pd.concat([high - low, (high - pc).abs(), (low - pc).abs()], axis=1).max(axis=1)
atr = tr.ewm(alpha=1/n, adjust=False).mean()
Manche Plattformen zeigen stattdessen eine SMA-basierte ATR; prüfen Sie das vor dem Vergleich. Lektion 8 nutzt die ATR für Stops und Positionsgrößen.
Bollinger-Bänder: Mitte = SMA(n), oberes und unteres Band = Mitte ± k × Standardabweichung über dieselben n Balken, typischerweise n = 20, k = 2. Die Falle ist ddof: pandas rolling(n).std() teilt durch n − 1 (Stichprobe), während Plattformen üblicherweise durch n teilen (Grundgesamtheit). Schreiben Sie std(ddof=0), um übereinzustimmen. Der Stichprobenwert ist größer, und zwar genug, um aus einer „Berührung“ des Bandes eine „Nicht-Berührung“ zu machen.
Abgleich mit einer Plattform. Verwenden Sie dieselbe adjustierte Reihe wie die Plattform, berechnen Sie Ihren Indikator und vergleichen Sie die letzten 100 Werte, weil Unterschiede durch den Startwert abklingen. Verwenden Sie np.allclose mit einer kleinen Toleranz. Dauerhafte Abweichungen haben fünf übliche Ursachen: adjustierte gegenüber unadjustierten Daten, der Startwert, span statt alpha, ddof oder ein anderer Eingangskurs. Beheben oder dokumentieren Sie die Abweichung; „tunen“ Sie niemals einen Parameter, bis die Zahlen übereinstimmen.
Durchgerechnetes Beispiel
Hypothetisches Beispiel: zehn tägliche Schlusskurse in Euro: 20.00, 20.50, 21.00, 20.80, 21.40, 21.00, 21.60, 22.00, 21.80, 22.40.
SMA(5) auf dem letzten Balken: (21.00 + 21.60 + 22.00 + 21.80 + 22.40) ÷ 5 = 108.80 ÷ 5 = €21.76.
Bollinger(5, 2) auf dem letzten Balken. Abweichungen von 21.76: −0.76, −0.16, 0.24, 0.04, 0.64; Quadratsumme 1.0720. Varianz der Grundgesamtheit = 1.0720 ÷ 5 = 0.2144, Standardabweichung 0.4630, oberes Band = 21.76 + 2 × 0.4630 = €22.69, unteres €20.83. Stichprobenformel: 1.0720 ÷ 4 = 0.2680, Standardabweichung 0.5177, oberes Band €22.80, unteres €20.72.
EMA(5) mit α = 2 ÷ 6 = 0.3333 und adjust=False: EMA1 = 20.00 (Startwert), EMA2 = 0.3333 × 20.50 + 0.6667 × 20.00 = 20.1667, EMA3 = 0.3333 × 21.00 + 0.6667 × 20.1667 = 20.4444 und so weiter bis 21.8310 auf dem letzten Balken.
True Range für einen Balken mit Hoch €21.20, Tief €20.60 und vorherigem Schlusskurs €20.80: max(0.60, |21.20 − 20.80| = 0.40, |20.60 − 20.80| = 0.20) = €0.60.
Häufiger Fehler
ewm(span=14) verwendet α = 2 ÷ 15 = 0.133, während Wilders RSI und ATR ewm(alpha=1/14) benötigen, α = 0.0714. Die span-Version reagiert fast doppelt so schnell und stimmt mit keiner Standardplattform überein. Schreiben Sie das beabsichtigte α explizit hin und halten Sie es im Docstring der Funktion fest.Übungsaufgabe
Auf Papier, mit einem Wilder-RSI über 3 Perioden nur zur Veranschaulichung (in der Praxis 14): Schlusskurse 50.00, 50.50, 51.00, 50.80. (a) Listen Sie die Gewinne und Verluste pro Balken auf. (b) pandas ewm(alpha=1/3, adjust=False) startet mit der ersten Beobachtung; berechnen Sie avg_gain und avg_loss auf dem letzten Balken sowie den RSI. (c) Erklären Sie in einem Satz, warum eine Plattform, die mit dem einfachen Durchschnitt der ersten drei Veränderungen startet, hier einen anderen Wert zeigen würde, und was Sie tun würden, bevor Sie schließen, dass Ihr Code falsch ist.
Lösung anzeigen
(a) Veränderungen: +0.50, +0.50, −0.20. Gewinne: 0.50, 0.50, 0.00. Verluste: 0.00, 0.00, 0.20.
(b) α = 1/3. avg_gain: 0.50 (Startwert) → (1/3)(0.50) + (2/3)(0.50) = 0.50 → (1/3)(0) + (2/3)(0.50) = 0.3333. avg_loss: 0 → 0 → (1/3)(0.20) + (2/3)(0) = 0.0667. RS = 0.3333 ÷ 0.0667 = 5.0; RSI = 100 − 100 ÷ (1 + 5) = 83.33.
(c) Hier ergibt der Startwert aus dem einfachen Durchschnitt (Gewinne 0.3333, Verluste 0.0667) zufällig ebenfalls 83.33, aber im Allgemeinen unterscheiden sich die beiden Startwerte in den ersten paar Dutzend Balken; vergleichen Sie daher die letzten 100 Werte einer langen Reihe, bevor Sie den Code anfassen.
Einschränkungen: Ein RSI über 3 Perioden ist ein Lehrmittel; vier Balken können das Konvergenzverhalten, auf das es in der Praxis ankommt, nicht zeigen.
Kernaussagen
- SMA ist
rolling(n).mean(); EMA istewm(span=n, adjust=False); die Wilder-Glättung für RSI und ATR istewm(alpha=1/n, adjust=False). - Bollinger-Bänder verwenden auf den meisten Plattformen die Standardabweichung der Grundgesamtheit: Übergeben Sie
ddof=0. - Unterschiede durch den Startwert verblassen; vergleichen Sie die letzten 100 Balken mit einer Toleranz und suchen Sie nach den fünf üblichen Ursachen für Abweichungen, bevor Sie Code ändern.
- Halten Sie Indikatoren als dokumentierte reine Funktionen, damit sie mit Unit-Tests geprüft und in jedem Backtest wiederverwendet werden können.
Nächster Schritt
Lektion 7 setzt die Teile zu einem vektorisierten Backtest zusammen: Signale, Positionen, die Verschiebung, die Look-Ahead-Bias verhindert, Transaktionskosten und die Equity-Kurve.
Selbsttest
Beantworten Sie die Fragen und prüfen Sie dann Ihre Antworten. Sie können es so oft wiederholen, wie Sie möchten.
Automatischer Selbsttest zur eigenen Wiederholung. Ihre Antworten werden in Ihrem Browser geprüft und von uns weder eingesehen noch bewertet. Es ist keine Prüfung und kein Abschluss.
Ihr Fortschritt
„Erledigt“ bedeutet nur, dass Sie die Lektion als abgeschlossen markiert haben. Es ist kein Test Ihres Verständnisses. Fortschritt und Notizen werden nur in diesem Browser auf diesem Gerät gespeichert — nicht in einem Konto.