σμ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 8 · Stochastische Modelle und Machine Learning›Thema 8.9·~1 Std.Fortgeschritten

Feature Engineering für Finanzdaten

Position in der SkillModul 8 von 11 · Thema 9 von 10
8.9 Feature Engineering für Finanzdaten
—Lab-Punkte— / 100XP gesamt—Serie—

Dem Modell vergleichbare Eingaben geben

Ein Preis von 250 bedeutet einem Modell nichts: Er hängt von der Aktie ab und steigt mit der Zeit, sodass die Werte von 2020 denen von 2010 nie ähneln. Feature Engineering macht Rohdaten zu Eingaben, die über Zeit und Assets vergleichbar sind: Renditen statt Preise, Volatilität statt Spannen, standardisierte Scores statt Niveaus. Gute Merkmale tragen mehr zum Ergebnis bei als die Modellwahl, und jedes darf nur beschreiben, was an dem Tag bekannt war.

import numpy as np

prices = np.array([100.0, 101.0, 99.0, 102.0, 104.0, 103.0, 106.0])

window = 3
momentum = np.full(len(prices), np.nan)
momentum[window:] = prices[window:] / prices[:-window] - 1          # the return over the last 3 days
print(np.round(momentum, 4))                                        # nan for the first 3 days: no price 3 days back

Fenster, die zurückblicken

Die meisten Merkmale sind Statistiken eines zurückblickenden Fensters: der letzten n Werte bis einschließlich heute. Momentum vergleicht heute mit vor n Tagen; die rollierende Volatilität ist die Standardabweichung der letzten n Renditen; der rollierende Z-Score sagt, wie viele Fenster-Standardabweichungen heute vom Fenstermittel entfernt liegt. Mit sliding_window_view erhält man alle Fenster als Zeilen einer Matrix und berechnet die Statistik entlang einer Achse, ohne Schleife. Die ersten n - 1 Tage haben kein vollständiges Fenster und bleiben nan.

import numpy as np

prices = np.array([100.0, 101.0, 99.0, 102.0, 104.0, 103.0, 106.0])
returns = np.diff(prices) / prices[:-1]
window = 3

windows = np.lib.stride_tricks.sliding_window_view(returns, window)        # every 3-day window as a row
vol = np.full(len(returns), np.nan)
vol[window - 1:] = windows.std(axis=1, ddof=1)
print(np.round(vol, 4))                                                    # nan nan then one value per complete window

p_windows = np.lib.stride_tricks.sliding_window_view(prices, window)
z = np.full(len(prices), np.nan)
z[window - 1:] = (prices[window - 1:] - p_windows.mean(axis=1)) / p_windows.std(axis=1, ddof=1)
print(np.round(z, 3))                                                      # how unusual each price is for its last 3 days
# Features put prices of different stocks on the same footing
import numpy as np

cheap = np.array([5.0, 5.2, 5.1, 5.4, 5.5])
dear = np.array([500.0, 520.0, 510.0, 540.0, 550.0])           # ten times the price, the same movements
print(cheap[-1] / cheap[-3] - 1, dear[-1] / dear[-3] - 1)        # identical momentum, about 0.0784 for both
print(dear[-1] - dear[-3], cheap[-1] - cheap[-3])                # price changes (40.0 and 0.4) would not be comparable

Das Ziel blickt voraus

Was das Modell vorhersagt, ist das Ziel, meist die Rendite der nächsten h Tage: prices[t + h] / prices[t] - 1. Es ist die einzige Spalte, die nach vorn schauen darf, und für die letzten h Tage nan, weil die Zukunft noch nicht eingetreten ist; diese Zeilen entfernt man vor dem Training. Ein häufiger Fehler ist ein Merkmal, das das Ziel versehentlich enthält, etwa ein zentriertes Fenster, eine über alle Daten berechnete Statistik oder eine als Eingabe wiederverwendete künftige Rendite. Der Test ist einfach: Ein Merkmal an Tag t darf sich nicht ändern, wenn spätere Tage hinzukommen.

import numpy as np

def forward_return(prices, horizon):
    out = np.full(len(prices), np.nan)
    out[:-horizon] = prices[horizon:] / prices[:-horizon] - 1
    return out

def momentum(prices, window):
    out = np.full(len(prices), np.nan)
    out[window:] = prices[window:] / prices[:-window] - 1
    return out

prices = np.array([100.0, 101.0, 99.0, 102.0, 104.0, 103.0, 106.0])
print(np.round(momentum(prices, 2), 4))                 # looks back: known on each day
print(np.round(forward_return(prices, 2), 4))           # looks forward: the target, nan for the last 2 days

# The prefix test: a feature computed on the first 5 days equals the first 5 values of the full computation
print(np.allclose(momentum(prices[:5], 2), momentum(prices, 2)[:5], equal_nan=True))      # True
Vorsicht vor Merkmalen, die heimlich das Ziel sindEin Merkmal, das zu gut vorhersagt, ist ein Warnsignal. Ein Momentum mit zentriertem Fenster, eine Volatilität inklusive der morgigen Rendite, ein auf der ganzen Stichprobe standardisierter Z-Score: Jedes lässt Backtests glänzen und scheitert live. Bauen Sie jedes Merkmal so, dass es in der Produktion am Morgen von Tag t berechnet werden kann, und prüfen Sie es mit dem Präfixtest oben.
  • Machen Sie aus Preisen vergleichbare Merkmale: Momentum prices[t] / prices[t - n] - 1, rollierende Volatilität, rollierender Z-Score, jeweils über ein zurückblickendes Fenster inklusive heute.
  • sliding_window_view liefert jedes Fenster als Zeile, Statistiken brauchen also keine Schleife; die ersten n - 1 Tage bleiben nan.
  • Die künftige Rendite prices[t + h] / prices[t] - 1 ist das Ziel, nie ein Merkmal; prüfen Sie jedes Merkmal mit dem Präfixtest.

Als Nächstes: Walk-forward-Validierung, ein Modell in der Reihenfolge testen, in der die Zeit tatsächlich fließt.

Lab: Was bewertet wird

  • Mit momentum den Trend messen25 Pkt.
  • Mit rolling_vol das jüngste Risiko verfolgen25 Pkt.
  • Mit rolling_zscore zeigen, wie ungewöhnlich heute ist25 Pkt.
  • Mit forward_return das Ziel definieren25 Pkt.
Explorer · lab-110-1
▾ lab-110-1
…
bash · im Browser
learner@quantcraft:~/lab-110-1$
Python noch nicht geladenPythonLn 1, Col 1Spaces: 4UTF-8

Dieses Thema zurücksetzen?

Alles in lab-110-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