σμimplied vol · KKmax(S−K,0)udβρᵢⱼfat tailsPnL · drawdownyield · TdSₜ = μSₜ dt + σSₜ dWₜC = S·N(d₁) − K·e⁻ʳᵀ·N(d₂)σₚ² = wᵀΣwd₁ = [ln(S/K) + (r + σ²⁄2)T] ⁄ σ√T∂V/∂t + ½σ²S²·∂²V/∂S² + rS·∂V/∂S − rV = 0Sharpe = (Rₚ − R_f) ⁄ σₚVaR₉₉ = μ − 2.33σρ = Cov(X,Y) ⁄ σₓσᵧE[Rₚ] = Σ wᵢ·E[Rᵢ]φ(x) = e^(−x²/2) ⁄ √2πE[Rᵢ] = R_f + βᵢ(E[Rₘ] − R_f)dXₜ = θ(μ − Xₜ)dt + σ dWₜσ²ₜ = ω + α·ε²ₜ₋₁ + β·σ²ₜ₋₁C − P = S − K·e⁻ʳᵀΔ = ∂V/∂S Γ = ∂²V/∂S²p = (e^(rΔt) − d) ⁄ (u − d)rₜ = ln(Pₜ ⁄ Pₜ₋₁)E[Xₜ₊₁ | ℱₜ] = Xₜf* = (bp − q) ⁄ bz = (x − μ) ⁄ σP(N=k) = λᵏe^(−λ) ⁄ k!Θ = −∂V/∂Tν = S·φ(d₁)·√Tmin wᵀΣw s.t. wᵀμ = μ*∫Σ∂∞λ
σμimplied vol · KKmax(S−K,0)udβρᵢⱼfat tailsPnL · drawdownyield · TdSₜ = μSₜ dt + σSₜ dWₜC = S·N(d₁) − K·e⁻ʳᵀ·N(d₂)σₚ² = wᵀΣwd₁ = [ln(S/K) + (r + σ²⁄2)T] ⁄ σ√T∂V/∂t + ½σ²S²·∂²V/∂S² + rS·∂V/∂S − rV = 0Sharpe = (Rₚ − R_f) ⁄ σₚVaR₉₉ = μ − 2.33σρ = Cov(X,Y) ⁄ σₓσᵧE[Rₚ] = Σ wᵢ·E[Rᵢ]φ(x) = e^(−x²/2) ⁄ √2πE[Rᵢ] = R_f + βᵢ(E[Rₘ] − R_f)dXₜ = θ(μ − Xₜ)dt + σ dWₜσ²ₜ = ω + α·ε²ₜ₋₁ + β·σ²ₜ₋₁C − P = S − K·e⁻ʳᵀΔ = ∂V/∂S Γ = ∂²V/∂S²p = (e^(rΔt) − d) ⁄ (u − d)rₜ = ln(Pₜ ⁄ Pₜ₋₁)E[Xₜ₊₁ | ℱₜ] = Xₜf* = (bp − q) ⁄ bz = (x − μ) ⁄ σP(N=k) = λᵏe^(−λ) ⁄ k!Θ = −∂V/∂Tν = S·φ(d₁)·√Tmin wᵀΣw s.t. wᵀμ = μ*∫Σ∂∞λ
uantCraft AcademySkills
Ctrl K
AO
+1,2 Tsd. Lernende
AnmeldenBeitreten ↗
Skills
AO
+1,2 Tsd. Lernende
Anmelden
  • English
  • Français
  • Español
  • العربية
  • Português
  • Deutsch
  • 日本語
  • 中文
Python-Skill›Modul 2 · NumPy & pandas für Marktdaten›Thema 2.14·~40 Min.Mittelstufe

Gleitende Fenster

Position in der SkillModul 2 von 11 · Thema 14 von 20
2.14 Gleitende Fenster
—Lab-Punkte— / 100XP gesamt—Serie—

Ein Fenster, das gleitet

Der heutige Preis sagt allein wenig; Trader vergleichen ihn mit der jüngeren Vergangenheit. Ein gleitendes Fenster behält die letzten n Beobachtungen und rückt Schritt für Schritt vor, sodass jedes Datum eine Statistik aus seiner eigenen jüngeren Geschichte erhält: einen gleitenden Durchschnitt, eine jüngste Volatilität, ein jüngstes Hoch. In pandas beschreibt series.rolling(n) das Fenster, und eine Statistik wie .mean() berechnet sie an jeder Position zugleich.

import pandas as pd

prices = pd.Series(
    [100.0, 102, 101, 105, 107, 106, 110],
    index=pd.bdate_range("2026-03-02", periods=7),
    name="close",
)

moving_average = prices.rolling(3).mean()
print(moving_average.round(2).tolist())
# [nan, nan, 101.0, 102.67, 104.33, 106.0, 107.67]

print(prices.rolling(3).max().tolist())   # [nan, nan, 102.0, 105.0, 107.0, 107.0, 110.0]   the 3-day high

Der Anfang der Reihe

Die ersten n - 1 Positionen haben noch kein volles Fenster, daher ist das Ergebnis dort NaN. Das ist ehrlich: Der Durchschnitt zweier Preise ist kein 3-Tage-Durchschnitt. Wollen Sie wirklich früher einen Wert, rechnet min_periods=1 mit dem Vorhandenen, und expanding() nutzt alles seit dem Anfang statt eines festen Fensters. Statistiken, die mehrere Punkte brauchen, etwa die Standardabweichung, bleiben NaN, bis genug Beobachtungen vorliegen. Eine Reihe, die schon mit NaN beginnt, etwa einfache Renditen, verschiebt das erste gültige Fenster um einen Schritt.

# min_periods=1: use whatever is available at the start
print(prices.rolling(3, min_periods=1).mean().round(2).tolist())   # [100.0, 101.0, 101.0, 102.67, 104.33, 106.0, 107.67]

# expanding(): everything since the first day, not a fixed window
print(prices.expanding().mean().round(2).tolist())   # [100.0, 101.0, 101.0, 102.0, 103.0, 103.5, 104.43]

# Rolling volatility of the returns: the first return is NaN, so three returns exist only from the 4th day
returns = prices.pct_change()
print(returns.rolling(3).std().round(4).tolist())   # [nan, nan, nan, 0.0249, 0.0248, 0.0246, 0.0237]

Von Fenstern zu Signalen

Gleitende Statistiken werden zu Handelssignalen, wenn man sie vergleicht. Ein z-Wert sagt, wie weit der heutige Preis von seinem eigenen jüngsten Mittel entfernt ist, gemessen in seiner jüngsten Standardabweichung: (price - rolling mean) / rolling std. Bauen Sie das Rolling-Objekt einmal (r = prices.rolling(3)) und nutzen Sie es zweimal. Ein Durchschnittskreuzung vergleicht einen schnellen mit einem langsamen Durchschnitt: Liegt der schnelle darüber, ist der jüngste Trend aufwärts. Ein Vergleich liefert Booleans, und astype("int64") macht daraus ein 0/1-Signal. Vergleiche mit NaN sind False, das Signal ist also 0, bis beide Durchschnitte existieren.

# z-score of each price against its own 3-day window
rolling = prices.rolling(3)
zscore = (prices - rolling.mean()) / rolling.std()
print(zscore.round(2).tolist())   # [nan, nan, 0.0, 1.12, 0.87, 0.0, 1.12]
# Moving-average crossover: 1 while the 2-day average is above the 4-day average
fast = prices.rolling(2).mean()
slow = prices.rolling(4).mean()
signal = (fast > slow).astype("int64")
print(signal.tolist())   # [0, 0, 0, 1, 1, 1, 1]

# Trade on the next day: the signal of today's close cannot be traded before tomorrow
print(signal.shift(1).fillna(0).astype("int64").tolist())   # [0, 0, 0, 0, 1, 1, 1]
Schauen Sie nicht in die ZukunftEin gleitendes Fenster endet in der aktuellen Zeile und nutzt daher nur die Vergangenheit. center=True setzt die aktuelle Zeile in die Fensterhälfte und verwendet damit zukünftige Preise: Im Chart sieht das großartig aus, handelbar ist es nicht. Ein Signal aus dem heutigen Schlusskurs sollte erst morgen angewendet werden, daher shift(1).
  • series.rolling(n).mean() (oder std(), max()...) berechnet an jeder Position eine Statistik über die letzten n Beobachtungen.
  • Die ersten n - 1 Einträge sind NaN; min_periods und expanding() ändern das bewusst.
  • z-Werte und Durchschnittskreuzungen machen aus Fenstern Signale; verschieben Sie ein Signal vor dem Handel und meiden Sie center=True.

Als Nächstes: der Umgang mit fehlenden Daten, was man mit den NaN-Werten tut, die echte Preistabellen immer enthalten.

Lab: Was bewertet wird

  • Mit moving_average die Preise glätten25 Pkt.
  • Mit rolling_volatility das jüngste Risiko messen25 Pkt.
  • Mit rolling_zscore jeden Preis an seinem Fenster standardisieren25 Pkt.
  • Mit ma_crossover zwei Durchschnitte in ein Signal verwandeln25 Pkt.
Explorer · lab-47-1
▾ lab-47-1
…
bash · im Browser
learner@quantcraft:~/lab-47-1$
Python noch nicht geladenPythonLn 1, Col 1Spaces: 4UTF-8

Dieses Thema zurücksetzen?

Alles in lab-47-1 wird auf die Startdateien zurückgesetzt und das Terminal geleert. Ihre aktuelle Lösung geht verloren – das lässt sich nicht rückgängig machen.

Wird zurückgesetzt
  • main.py → Startcode
  • Terminal-Verlauf und Testausgabe
  • Nicht eingereichte Änderungen
Bleibt erhalten
  • Beste Lab-Punktzahl
  • Ihre XP und Ihre Serie
  • Vorlesungsfortschritt und Notizen

Melde dich an, um deinen Code auszuführen.

Alle Lektionen kannst du kostenlos lesen. Erstelle ein Konto oder melde dich an, um Code auszuführen, Tests zu starten und dieses Lab abzugeben.

  • IDE im Browser mit Bash-Terminal — nichts zu installieren
  • Sofortige Bewertung, XP und dein Platz auf der Skill
Konto erstellenAnmelden
ODER
Weiter mit GitHub