σμ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 5 · Portfoliooptimierung›Thema 5.1·~45 Min.Mittelstufe

Kovarianz- und Korrelationsmatrizen

Position in der SkillModul 5 von 11 · Thema 1 von 5
5.1 Kovarianz- und Korrelationsmatrizen
—Lab-Punkte— / 100XP gesamt—Serie—

Von einem Asset zu vielen

Bisher ging es um eine einzige Renditereihe. Ein Portfolio enthält viele Assets, und sein Risiko hängt nicht nur davon ab, wie riskant jedes einzelne ist, sondern davon, wie sie sich *gemeinsam* bewegen. Die Kovarianz zweier Assets ist das mittlere Produkt ihrer Abweichungen vom Mittelwert: positiv, wenn sie tendenziell zusammen steigen und fallen, negativ, wenn eines steigt, während das andere fällt. Bei n Assets gibt es n * n Kovarianzen, angeordnet als Kovarianzmatrix, die symmetrisch ist und die Varianzen auf der Diagonale hat.

import numpy as np

# Five days of returns for two assets: shape (days, assets)
returns = np.array([[0.01, 0.02], [-0.02, -0.01], [0.03, 0.01], [0.00, -0.02], [0.01, 0.03]])

centered = returns - returns.mean(axis=0)            # subtract each column's mean
cov = centered.T @ centered / (len(returns) - 1)     # (assets x days) @ (days x assets) -> (assets x assets)
print(np.round(cov, 6))
print(np.allclose(cov, np.cov(returns, rowvar=False)))     # True

Die empirische Kovarianzmatrix

Mit einer Renditetabelle der Form (days, assets) ist die ganze Matrix eine Zeile lineare Algebra. Man zieht von jeder Spalte den Mittelwert ab (axis=0, Mittel über die Tage) und multipliziert die Transponierte der zentrierten Tabelle mit ihr selbst: Eintrag (i, j) von centered.T @ centered ist die Summe über die Tage von x_i * x_j. Dann teilt man durch days - 1, wie bei einer Stichprobenvarianz. Das berechnen np.cov(returns, rowvar=False) und DataFrame.cov(); beachten Sie rowvar=False, denn np.cov erwartet die Assets in den Zeilen.

Korrelation: Kovarianz ohne Einheiten

Eine Kovarianz von 0.0004 sagt wenig: Sie hängt davon ab, wie volatil die beiden Assets sind. Teilt man durch das Produkt der beiden Standardabweichungen, verschwindet die Skala, und man erhält die Korrelation, immer zwischen -1 und 1: corr[i, j] = cov[i, j] / (std[i] * std[j]), mit std als Wurzel der Diagonale. Im Code baut np.outer(std, std) die Tabelle der Produkte, und eine Division skaliert die ganze Matrix, mit Einsen auf der Diagonale. Die Korrelation zeigt, wie eng zwei Assets zusammenlaufen; die Kovarianz, die die Skala behält, brauchen die Risikoformeln.

# From covariance to correlation and annualised volatilities
import numpy as np

returns = np.array([[0.01, 0.02], [-0.02, -0.01], [0.03, 0.01], [0.00, -0.02], [0.01, 0.03]])
cov = np.cov(returns, rowvar=False)

std = np.sqrt(np.diag(cov))
corr = cov / np.outer(std, std)
print(np.round(corr, 4))
print(np.round(np.sqrt(np.diag(cov) * 252), 4))      # daily variances scaled to a year: volatility grows with sqrt(252)

Kann diese Matrix echt sein?

Eine beliebige Zahlentabelle ist keine Kovarianzmatrix. Sie muss symmetrisch und positiv semidefinit sein: Für beliebige Gewichte w ist w' C w die Varianz eines Portfolios und kann nicht negativ sein. Gleichwertig: Kein Eigenwert liegt unter null. Geschätzte Matrizen bestehen, von Hand bearbeitete oder ein Flickwerk aus Korrelationen verschiedener Quellen (etwa A~B = 0.9, B~C = 0.9, A~C = -0.9) nicht. Man prüft mit np.linalg.eigvalsh für symmetrische Matrizen, das reelle Eigenwerte liefert, mit kleiner Toleranz für Rundung.

# A validity check: symmetry and no negative eigenvalue
import numpy as np

def is_valid_cov(matrix, tol=1e-10):
    symmetric = bool(np.all(np.abs(matrix - matrix.T) <= tol))
    return symmetric and bool(np.linalg.eigvalsh(matrix).min() >= -tol)

good = np.array([[1.0, 0.5, 0.2], [0.5, 1.0, 0.3], [0.2, 0.3, 1.0]])
bad = np.array([[1.0, 0.9, -0.9], [0.9, 1.0, 0.9], [-0.9, 0.9, 1.0]])
print(is_valid_cov(good), np.round(np.linalg.eigvalsh(good), 3))
print(is_valid_cov(bad), np.round(np.linalg.eigvalsh(bad), 3))
# Few days, many assets: the sample covariance matrix is singular
import numpy as np

rng = np.random.default_rng(0)
returns = rng.normal(0, 0.01, size=(5, 8))              # 5 days, 8 assets
cov = np.cov(returns, rowvar=False)
print(np.linalg.matrix_rank(cov), "of", cov.shape[0])  # 4 of 8: some portfolios seem to have zero variance
Wenige Beobachtungen, viele AssetsEine Matrix für 500 Aktien hat 125.250 verschiedene Einträge, geschätzt aus vielleicht 250 Tagen. Bei weniger Tagen als Assets ist die empirische Matrix singulär: Irgendein Portfolio scheint die Varianz null zu haben, was kein Optimierer glauben sollte. Praktiker schrumpfen die Matrix auf ein einfaches Ziel oder nutzen ein Faktormodell. Die Schätzung ist außerdem ein Durchschnitt der Vergangenheit: Ruhige und Krisenzeiten haben sehr unterschiedliche Kovarianzen.
  • Die Kovarianzmatrix einer (days, assets)-Tabelle ist centered.T @ centered / (days - 1): symmetrisch, Varianzen auf der Diagonale.
  • Die Korrelation ist cov / np.outer(std, std): einheitenlos, zwischen -1 und 1, Einsen auf der Diagonale; Varianzen annualisiert man mit periods, Volatilitäten mit dessen Wurzel.
  • Eine gültige Kovarianzmatrix ist symmetrisch ohne negativen Eigenwert (np.linalg.eigvalsh); Schätzungen aus zu wenigen Tagen oder von Hand angepasste können das verletzen.

Als Nächstes: Portfoliorendite und -varianz, aus Gewichten und dieser Matrix das Risiko eines Portfolios machen.

Lab: Was bewertet wird

  • Mit cov_matrix die Kovarianztabelle aufbauen25 Pkt.
  • Mit corr_from_cov auf Korrelationen skalieren25 Pkt.
  • Mit annualised_vols die Volatilität jedes Assets ablesen25 Pkt.
  • Mit is_valid_cov prüfen, ob sie echt sein kann25 Pkt.
Explorer · lab-82-1
▾ lab-82-1
…
bash · im Browser
learner@quantcraft:~/lab-82-1$
Python noch nicht geladenPythonLn 1, Col 1Spaces: 4UTF-8

Dieses Thema zurücksetzen?

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