σμ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 7 · Alpha-Forschung und Risiko›Thema 7.3·~55 Min.Fortgeschritten

Der Informationskoeffizient

Position in der SkillModul 7 von 11 · Thema 3 von 9
7.3 Der Informationskoeffizient
—Lab-Punkte— / 100XP gesamt—Serie—

Sagt das Signal etwas voraus?

Bevor man eine Strategie auf ein Signal baut, fragt man, ob es in die richtige Richtung zeigt. Jeden Tag gibt ein Signal jeder Aktie einen Score, und einen Tag später hat jede Aktie eine Rendite. Der Informationskoeffizient (IC) ist die Korrelation über die Aktien zwischen Score und späterer Rendite. Er reicht von -1 bis 1; null heißt keine Vorhersagekraft. Echte Signale sind schwach: Ein IC von 0,02 bis 0,05 ist schon nützlich, weil er sich über viele Aktien und viele Tage wiederholt.

import numpy as np

signal = np.array([0.3, -1.2, 0.8, 0.1, 1.5])                  # today's score for five stocks
returns = np.array([0.01, -0.02, 0.005, -0.004, 0.03])         # their returns over the next day

s = signal - signal.mean()
r = returns - returns.mean()
ic = np.sum(s * r) / np.sqrt(np.sum(s ** 2) * np.sum(r ** 2))   # the Pearson correlation
print(round(float(ic), 4))
print(round(float(np.corrcoef(signal, returns)[0, 1]), 4))     # the same number

Rang-IC: robust gegen Ausreißer

Eine Pearson-Korrelation wird von Extremwerten dominiert: Eine Aktie mit riesigem Score oder einem Tagessprung von 40 % kann sie kippen. Der Rang-IC ersetzt jedes Array durch den Rang seiner Werte (1 für den kleinsten) und korreliert die Ränge. Er fragt nur, ob die vom Signal höher eingestuften Aktien höher landen, egal wie groß die Zahlen sind, und bleibt daher bei jeder wachsenden Transformation des Signals unverändert. Die meisten Quant-Teams nennen diese Variante; es ist die Spearman-Korrelation.

# The rank of each value: argsort gives the order, assigning 1..n through it gives the ranks
import numpy as np

values = np.array([30.0, 10.0, 20.0, 5.0])
order = np.argsort(values)                       # positions from smallest to largest: [3 1 2 0]
ranks = np.empty(len(values))
ranks[order] = np.arange(1, len(values) + 1)
print(order, ranks)                              # [3 1 2 0] [4. 2. 3. 1.]
# Ranks via argsort, and a rank IC that shrugs off an extreme value
import numpy as np

def ranks(values):
    order = np.argsort(values)
    out = np.empty(len(values))
    out[order] = np.arange(1, len(values) + 1)
    return out

def ic(a, b):
    a, b = a - a.mean(), b - b.mean()
    return float(np.sum(a * b) / np.sqrt(np.sum(a ** 2) * np.sum(b ** 2)))

signal = np.array([0.3, -1.2, 0.8, 0.1, 1.5])
returns = np.array([0.01, -0.02, 0.005, -0.004, 0.03])
print(ranks(signal))                                           # [3. 1. 4. 2. 5.]
print(round(ic(signal, returns), 4), round(ic(ranks(signal), ranks(returns)), 4))

signal_with_outlier = signal.copy()
signal_with_outlier[4] = 1000.0                                # one absurd score
print(round(ic(signal_with_outlier, returns), 4), round(ic(ranks(signal_with_outlier), ranks(returns)), 4))

Beständigkeit über die Zeit: die Information Ratio des IC

Der IC eines Tages ist verrauscht. Berechnen Sie ihn täglich, um eine Reihe zu erhalten, und betrachten Sie Mittelwert und Stetigkeit. Die ICIR, der mittlere IC geteilt durch seine Standardabweichung, belohnt Signale, die jeden Tag ein wenig richtig liegen, gegenüber solchen, die an wenigen Tagen sehr richtig liegen. Sie ist eine Sharpe-ähnliche Kennzahl für das Signal selbst. Eine Tagesreihe von IC-Werten mit Mittel 0,03 und Standardabweichung 0,06 hat eine ICIR von 0,5.

# A daily rank-IC series for a weak signal, and its ICIR
import numpy as np

def ranks(values):
    out = np.empty(len(values))
    out[np.argsort(values)] = np.arange(1, len(values) + 1)
    return out

def ic(a, b):
    a, b = a - a.mean(), b - b.mean()
    return float(np.sum(a * b) / np.sqrt(np.sum(a ** 2) * np.sum(b ** 2)))

rng = np.random.default_rng(8)
daily_ics = []
for day in range(250):
    signal = rng.normal(size=300)                              # 300 stocks
    returns = 0.01 * (0.05 * signal + rng.normal(size=300))    # the signal explains a sliver of the return
    daily_ics.append(ic(ranks(signal), ranks(returns)))
daily_ics = np.array(daily_ics)
print(round(float(daily_ics.mean()), 4), round(float(daily_ics.std(ddof=1)), 4))
print(round(float(daily_ics.mean() / daily_ics.std(ddof=1)), 3))
Ein guter IC ist klein, und ein großer ist eine WarnungMärkte sind nahezu effizient, ein IC über 0,1 ist daher eher ein Bug als eine Entdeckung: Suchen Sie nach Look-ahead-Bias, einem aus den vorhergesagten Renditen gebauten Signal oder einem Datenfehler. Ein echter IC nimmt zudem mit dem Horizont ab, und sein Wert nach Kosten zählt mehr als vor Kosten. Berechnen Sie ihn immer auf Daten, an die das Signal nicht angepasst wurde.
  • Der IC ist die Korrelation zwischen dem heutigen Signal über die Aktien und deren späteren Renditen; 0,02 bis 0,05 ist nützlich, über 0,1 verdächtig.
  • Der Rang-IC korreliert Ränge (zweimal argsort): robust gegen Ausreißer und unverändert bei jeder wachsenden Transformation des Signals.
  • ICIR = mittlerer IC / Standardabweichung des IC über viele Tage: belohnt stetiges Können; immer außerhalb der Stichprobe bewerten.

Als Nächstes: historischer VaR, der Verlust, den ein Portfolio außer an den schlimmsten Tagen nicht überschreiten soll.

Lab: Was bewertet wird

  • Mit ranks die Werte in eine Reihenfolge bringen25 Pkt.
  • Mit ic Signal und Ergebnis korrelieren25 Pkt.
  • Mit rank_ic Ausreißer ignorieren25 Pkt.
  • Mit icir die Beständigkeit beurteilen25 Pkt.
Explorer · lab-95-1
▾ lab-95-1
…
bash · im Browser
learner@quantcraft:~/lab-95-1$
Python noch nicht geladenPythonLn 1, Col 1Spaces: 4UTF-8

Dieses Thema zurücksetzen?

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