σμ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 AcademyParcours
Ctrl K
AO
+1,2 k apprenants
ConnexionRejoindre ↗
Parcours
AO
+1,2 k apprenants
Connexion
  • English
  • Français
  • Español
  • العربية
  • Português
  • Deutsch
  • 日本語
  • 中文
Parcours Python›Module 8 · Modèles stochastiques et apprentissage automatique›Sujet 8.7·~50 minAvancé

Variables de contrôle

Position dans le parcoursModule 8 sur 11 · Sujet 7 sur 10
8.7 Variables de contrôle
—Score du lab— / 100XP total—Série—

Utiliser ce que l'on sait déjà

En simulant un call, vous simulez aussi le prix de l'action à l'échéance S_T, dont la vraie moyenne S0 * exp(r * T) est exactement connue. Dans votre échantillon, la moyenne de S_T est sortie un peu fausse, disons trop haute. Comme le gain du call et S_T évoluent ensemble, la moyenne empirique du call est probablement trop haute aussi. Une variable de contrôle exploite cela : elle retranche à l'estimation de la quantité voulue un multiple de l'erreur observée sur la quantité connue.

import numpy as np

rng = np.random.default_rng(1)
z = rng.standard_normal(2000)
s_t = 100.0 * np.exp((0.05 - 0.5 * 0.2 ** 2) + 0.2 * z)             # terminal prices
call = np.maximum(s_t - 100.0, 0.0)                                  # the payoff we want

known = 100.0 * np.exp(0.05)                                         # E[S_T], exactly
print(round(float(s_t.mean()), 3), round(known, 3))                  # the sample mean of S_T vs its true mean
print(round(float(s_t.mean() - known), 3))                           # the observed error of the control

Le meilleur multiple

Quelle part de l'erreur du contrôle faut-il retrancher ? Le multiple b qui minimise la variance de payoff - b * control vaut b = cov(payoff, control) / var(control), exactement la pente de la régression du gain sur le contrôle (les mêmes sommes que le bêta du sujet MEDAF). L'estimation contrôlée est mean(payoff) - b * (mean(control) - known_mean). Elle est sans biais, car le terme retranché est d'espérance nulle.

import numpy as np

def control_coefficient(payoff, control):
    dev = control - control.mean()
    return float(np.sum(dev * (payoff - payoff.mean())) / np.sum(dev ** 2))

rng = np.random.default_rng(1)
z = rng.standard_normal(2000)
s_t = 100.0 * np.exp((0.05 - 0.5 * 0.2 ** 2) + 0.2 * z)
call = np.maximum(s_t - 100.0, 0.0)
known = 100.0 * np.exp(0.05)

b = control_coefficient(call, s_t)
controlled = call.mean() - b * (s_t.mean() - known)
print(round(b, 4), round(float(call.mean()), 4), round(float(controlled), 4))       # the plain mean and the corrected one
# A payoff that is exactly proportional to the control is estimated without any error
import numpy as np

x = np.random.default_rng(2).standard_normal(50) + 5.0          # the control, known mean 5.0
y = 2.0 * x                                                      # the payoff
dev = x - x.mean()
b = np.sum(dev * (y - y.mean())) / np.sum(dev ** 2)
print(round(float(b), 6), round(float(y.mean() - b * (x.mean() - 5.0)), 6))      # 2.0 and exactly 10.0

Combien d'erreur est économisée

Les échantillons ajustés payoff - b * control portent le bruit, donc l'erreur standard de l'estimation contrôlée est leur écart-type (ddof=1) divisé par sqrt(n). Avec une corrélation rho entre gain et contrôle, la variance diminue d'un facteur 1 - rho^2 : une corrélation de 0,9 en supprime 81 %, et 0,99 en supprime 98 %. Le contrôle ne coûte aucune simulation supplémentaire, seulement quelques lignes de plus.

import numpy as np

def control_variate_error(payoff, control):
    dev = control - control.mean()
    b = np.sum(dev * (payoff - payoff.mean())) / np.sum(dev ** 2)
    return float((payoff - b * control).std(ddof=1) / np.sqrt(len(payoff)))

rng = np.random.default_rng(1)
z = rng.standard_normal(20000)
s_t = 100.0 * np.exp((0.05 - 0.5 * 0.2 ** 2) + 0.2 * z)
for strike in (80.0, 100.0, 120.0):
    call = np.maximum(s_t - strike, 0.0)
    plain = float(call.std(ddof=1) / np.sqrt(len(call)))
    print(strike, round(plain, 4), round(control_variate_error(call, s_t), 4), round(plain / control_variate_error(call, s_t), 2))
Un bon contrôle est corrélé et connuLes deux conditions comptent. Le contrôle doit évoluer avec le gain (sinon b est proche de 0 et rien n'est gagné) et sa moyenne exacte doit être connue (sinon la correction n'est qu'une hypothèse). Pour la moyenne arithmétique d'une option asiatique, de bons contrôles sont la moyenne géométrique, dont le prix a une formule, ou le prix terminal lui-même. On peut utiliser plusieurs contrôles à la fois, les coefficients provenant alors d'une régression multiple.
  • Une variable de contrôle est une quantité simulée de moyenne connue ; on retranche à l'estimation un multiple de son erreur observée : mean(Y) - b * (mean(X) - E[X]).
  • Le meilleur multiple est la pente de régression b = cov(Y, X) / var(X) ; l'erreur est l'écart-type de Y - b * X divisé par sqrt(n).
  • La variance diminue de 1 - rho^2 ; un bon contrôle est très corrélé au gain et de moyenne exactement connue, et ne coûte aucune simulation supplémentaire.

À suivre : les pipelines scikit-learn pour les rendements, ajuster et évaluer des modèles prédictifs sur des rendements.

Lab : ce qui est noté

  • Choisir le bon multiple avec control_coefficient25 pts
  • Corriger l'estimation avec control_variate_estimate25 pts
  • Réduire la barre d'erreur avec control_variate_error25 pts
  • Compter le gain avec error_reduction25 pts
Explorateur · lab-108-1
▾ lab-108-1
…
bash · dans le navigateur
learner@quantcraft:~/lab-108-1$
Python pas encore chargéPythonLn 1, Col 1Spaces: 4UTF-8

Réinitialiser ce sujet ?

Tout le contenu de lab-108-1 revient aux fichiers de départ et le terminal est vidé. Votre solution actuelle sera perdue : cette action est irréversible.

Sera réinitialisé
  • main.py → code de départ
  • Historique du terminal et sortie des tests
  • Modifications non soumises
Sera conservé
  • Meilleur score du lab
  • Votre XP et votre série
  • Progression du cours et notes

Connectez-vous pour exécuter votre code.

Tous les cours sont gratuits à lire. Créez un compte ou connectez-vous pour exécuter du code, lancer les tests et soumettre ce lab.

  • IDE dans le navigateur avec terminal bash — rien à installer
  • Correction instantanée, XP et votre place dans le parcours
Créer un compteSe connecter
OU
Continuer avec GitHub