σμ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.4·~55 Min.Mittelstufe

Mittelwert-Varianz-Optimierung

Position in der SkillModul 5 von 11 · Thema 4 von 5
5.4 Mittelwert-Varianz-Optimierung
—Lab-Punkte— / 100XP gesamt—Serie—

Rendite und Risiko in einer Zahl

Minimale Varianz ignoriert Renditen. Die Mittelwert-Varianz-Optimierung (Markowitz) nutzt beides: Ein Anleger will eine hohe erwartete Rendite w @ mu und eine niedrige Varianz w @ cov @ w. Ein einfacher Kompromiss ist der Nutzen w @ mu - 0.5 * lambda * w @ cov @ w, wobei lambda die Risikoaversion ist: Je höher, desto mehr kostet eine Varianzeinheit. Zwei Anleger mit gleichen Erwartungen, aber verschiedenem lambda wählen verschiedene Portfolios, und das beste Portfolio jedes Anlegers ist das Maximum einer glatten, konkaven Funktion.

import numpy as np

mu = np.array([0.08, 0.05, 0.10])                         # expected annual returns
cov = np.array([[0.0400, 0.0060, 0.0100],
                [0.0060, 0.0100, 0.0020],
                [0.0100, 0.0020, 0.0225]])

def utility(weights, mu, cov, risk_aversion):
    return weights @ mu - 0.5 * risk_aversion * weights @ cov @ weights

equal = np.full(3, 1 / 3)
print(round(float(equal @ mu), 4), round(float(equal @ cov @ equal), 4))      # 0.0767 0.0121
print(round(float(utility(equal, mu, cov, 4.0)), 4))                          # 0.0526

Die beste Position bei gegebener Risikoaversion

Ohne Budgetrestriktion (das übrige Geld verdient den risikolosen Zins, hier als null in Überrenditen genommen) liegt die beste Position dort, wo der Gradient mu - lambda * cov @ w null ist: w = cov^-1 * mu / lambda. Im Code np.linalg.solve(cov, mu) / lambda. Es skaliert, wie der gesunde Menschenverstand sagt: doppelte Risikoaversion, halbe Position. Die Summe der Gewichte ist, was sie sein muss; der Rest, 1 - w.sum(), ist Bargeld.

# The best position for several risk aversions: more aversion, smaller bets
import numpy as np

mu = np.array([0.08, 0.05, 0.10])
cov = np.array([[0.0400, 0.0060, 0.0100],
                [0.0060, 0.0100, 0.0020],
                [0.0100, 0.0020, 0.0225]])

for aversion in (5.0, 10.0, 20.0):
    w = np.linalg.solve(cov, mu) / aversion
    print(aversion, np.round(w, 3), "invested", round(float(w.sum()), 3))

Das Tangentialportfolio

Mit einem risikolosen Asset halten alle Anleger dieselbe riskante Mischung, nur in unterschiedlicher Menge. Diese Mischung hat die höchste Sharpe-Ratio (w @ mu - rf) / sqrt(w @ cov @ w), das Tangentialportfolio: w proportional zu cov^-1 * (mu - rf), auf Summe 1 skaliert. Der vorsichtige Anleger legt nur einen Teil des Geldes darin an und den Rest in bar; der mutige leiht sich Geld, um mehr zu halten. Wie viel Risiko man eingeht und welche riskanten Assets man hält, sind zwei getrennte Probleme.

# The tangency portfolio: no other mix of the three assets has a higher Sharpe ratio
import numpy as np

mu = np.array([0.08, 0.05, 0.10])
cov = np.array([[0.0400, 0.0060, 0.0100],
                [0.0060, 0.0100, 0.0020],
                [0.0100, 0.0020, 0.0225]])
rf = 0.02

x = np.linalg.solve(cov, mu - rf)
best = x / x.sum()

def sharpe(w):
    return (w @ mu - rf) / np.sqrt(w @ cov @ w)

rng = np.random.default_rng(1)
trials = rng.normal(size=(2000, 3))
trials = trials / trials.sum(axis=1, keepdims=True)
print(np.round(best, 4), round(float(sharpe(best)), 4))
print(round(max(float(sharpe(w)) for w in trials), 4))      # the best of 2000 random mixes comes close, never above

Ein Renditeziel erreichen

Eine andere Fragestellung: Welches unter allen Portfolios mit Summe 1 und gegebener erwarteter Rendite hat die kleinste Varianz? Mit zwei Nebenbedingungen ist die Lösung eine Kombination der beiden gelösten Vektoren s1 = cov^-1 * 1 und sm = cov^-1 * mu, mit Koeffizienten aus vier Zahlen a, b, c, d, die den Markt zusammenfassen. Jede Zielrendite liefert ein Portfolio; das Risiko aller aufzutragen ergibt die Effizienzlinie des nächsten Themas.

# Minimum-variance portfolios for three target returns
import numpy as np

mu = np.array([0.08, 0.05, 0.10])
cov = np.array([[0.0400, 0.0060, 0.0100],
                [0.0060, 0.0100, 0.0020],
                [0.0100, 0.0020, 0.0225]])
ones = np.ones(3)
s1, sm = np.linalg.solve(cov, ones), np.linalg.solve(cov, mu)
a, b, c = ones @ s1, ones @ sm, mu @ sm
d = a * c - b ** 2

for target in (0.06, 0.08, 0.09):
    w = ((c - b * target) * s1 + (a * target - b) * sm) / d
    print(target, np.round(w, 3), round(float(w @ mu), 4), round(float(np.sqrt(w @ cov @ w)), 4))
Der Optimierer maximiert Ihre FehlerMittelwert-Varianz-Gewichte reagieren sehr empfindlich auf mu: Eine kleine Änderung einer erwarteten Rendite kann das Portfolio von einem Asset zu einem anderen schwenken. Der Optimierer vertraut den Eingaben vollständig, jede überschätzte Rendite wird also zu einer großen Position. In der Praxis werden Renditen geschrumpft, Gewichte begrenzt, und die Eingaben stammen aus Modellen oder Einschätzungen statt aus rohen Vergangenheitsmitteln. Mittelwert-Varianz ist ein gutes Denkwerkzeug und blind angewendet ein gefährliches.
  • Der Nutzen ist w @ mu - 0.5 * lambda * w @ cov @ w; die beste Position ohne Budget ist solve(cov, mu) / lambda, und doppeltes lambda halbiert sie.
  • Mit einem risikolosen Asset ist die beste riskante Mischung das Tangentialportfolio solve(cov, mu - rf), auf Summe 1 skaliert: die höchste Sharpe-Ratio.
  • Für eine Zielrendite sind die Minimum-Varianz-Gewichte eine Kombination aus solve(cov, ones) und solve(cov, mu); das Ergebnis ist nur so gut wie das geschätzte mu.

Als Nächstes: die Effizienzlinie, die Kurve des besten Risikos für jedes Renditeniveau.

Lab: Was bewertet wird

  • Ein Portfolio mit utility bewerten25 Pkt.
  • Mit utility_weights die beste Position finden25 Pkt.
  • Mit tangency_weights die Sharpe-Ratio maximieren25 Pkt.
  • Mit target_return_weights ein Renditeziel erreichen25 Pkt.
Explorer · lab-85-1
▾ lab-85-1
…
bash · im Browser
learner@quantcraft:~/lab-85-1$
Python noch nicht geladenPythonLn 1, Col 1Spaces: 4UTF-8

Dieses Thema zurücksetzen?

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