σμ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 4 · Valorisation des produits de taux et d'options›Sujet 4.8·~55 minIntermédiaire

La formule de Black–Scholes

Position dans le parcoursModule 4 sur 11 · Sujet 8 sur 16
4.8 La formule de Black–Scholes
—Score du lab— / 100XP total—Série—

Une formule pour une option

En 1973, Black et Scholes ont montré que, si une action suit le modèle log-normal à volatilité constante, une option peut être répliquée en négociant l'action et une obligation, de sorte que son prix ne dépend pas de la probabilité d'une hausse selon les investisseurs. Le prix d'un call européen est S * N(d1) - K * exp(-rT) * N(d2) : l'action que vous recevez si l'option finit dans la monnaie, pondérée par un nombre de type probabilité, moins le prix d'exercice actualisé que vous payez, pondéré par la probabilité risque-neutre N(d2) d'exercice. Le put découle de la parité.

d1 = (ln(S/K) + (r + sigma^2/2) T) / (sigma sqrt(T)) d2 = d1 - sigma sqrt(T) C = S N(d1) - K e^(-rT) N(d2)
import math

def norm_cdf(x):
    return 0.5 * (1 + math.erf(x / math.sqrt(2)))      # N(x): the probability that a standard normal is below x

print(round(norm_cdf(0.0), 4), round(norm_cdf(1.96), 4))      # 0.5 0.975

def d1_d2(spot, strike, rate, sigma, t):
    d1 = (math.log(spot / strike) + (rate + 0.5 * sigma ** 2) * t) / (sigma * math.sqrt(t))
    return d1, d1 - sigma * math.sqrt(t)

d1, d2 = d1_d2(100, 100, 0.05, 0.2, 1)
print(round(d1, 4), round(d2, 4))                               # 0.35 0.15

Le call et le put

N est la fonction de répartition de la loi normale centrée réduite, que math.erf de Python donne par 0.5 * (1 + erf(x / sqrt(2))). d1 et d2 combinent la position ln(S/K), la dérive et la volatilité sur la vie de l'option. Avec eux : call = S * N(d1) - K * exp(-rT) * N(d2) et put = K * exp(-rT) * N(-d2) - S * N(-d1). Pour un spot de 100, un prix d'exercice de 100, un taux de 5 %, une volatilité de 20 % et un an, le call coûte 10,45 et le put 5,57, et la différence 4,88 est exactement la valeur de parité S - K * exp(-rT).

def bs_call(spot, strike, rate, sigma, t):
    d1, d2 = d1_d2(spot, strike, rate, sigma, t)
    return spot * norm_cdf(d1) - strike * math.exp(-rate * t) * norm_cdf(d2)

def bs_put(spot, strike, rate, sigma, t):
    d1, d2 = d1_d2(spot, strike, rate, sigma, t)
    return strike * math.exp(-rate * t) * norm_cdf(-d2) - spot * norm_cdf(-d1)

call, put = bs_call(100, 100, 0.05, 0.2, 1), bs_put(100, 100, 0.05, 0.2, 1)
print(round(call, 4), round(put, 4))                            # 10.4506 5.5735
print(round(call - put, 4), round(100 - 100 * math.exp(-0.05), 4))   # 4.8771 4.8771   put-call parity holds

Ce qui fait bouger le prix

Cinq paramètres déterminent le prix. Un prix d'exercice plus élevé rend le call moins cher (80 : 24,59 ; 100 : 10,45 ; 120 : 3,25). Une volatilité plus élevée rend les deux options plus chères, car davantage d'incertitude n'ajoute que du potentiel de hausse pour le détenteur (10 % : 6,81 ; 20 % : 10,45 ; 40 % : 18,02). Un délai plus long avant l'échéance augmente aussi le prix (3 mois : 4,62 ; 1 an : 10,45 ; 4 ans : 25,21). Remarquez que le rendement espéré de l'action n'apparaît pas du tout dans la formule : seule la volatilité est à estimer, c'est pourquoi les prix d'options cotés sont souvent exprimés en volatilité.

for strike in (80, 100, 120):
    print("strike", strike, round(bs_call(100, strike, 0.05, 0.2, 1), 4))      # 24.5888, 10.4506, 3.2475
for sigma in (0.1, 0.2, 0.4):
    print("sigma", sigma, round(bs_call(100, 100, 0.05, sigma, 1), 4))         # 6.805, 10.4506, 18.023
for t in (0.25, 1, 4):
    print("t", t, round(bs_call(100, 100, 0.05, 0.2, t), 4))                   # 4.615, 10.4506, 25.2133
# Time value: the call is worth more than its intrinsic value (what it would pay if it expired today)
intrinsic = max(100 - 100 * math.exp(-0.05), 0)
print(round(intrinsic, 4), round(bs_call(100, 100, 0.05, 0.2, 1) - intrinsic, 4))     # 4.8771 5.5735   intrinsic value and time value
Un modèle, avec des hypothèsesBlack–Scholes suppose une volatilité constante, des prix log-normaux sans sauts, pas de dividendes, un exercice européen et des échanges sans frictions. Les vrais marchés montrent une volatilité qui change avec le prix d'exercice et la date (le sourire de volatilité), des sauts et des queues épaisses. La formule reste le langage commun du marché, c'est pourquoi les prix sont cotés en volatilité implicite, sujet d'un prochain cours.
  • N(x) = 0.5 * (1 + erf(x / sqrt(2))), et d1 = (ln(S/K) + (r + sigma²/2) T) / (sigma sqrt(T)), d2 = d1 - sigma sqrt(T).
  • Call = S N(d1) - K e^(-rT) N(d2) ; put = K e^(-rT) N(-d2) - S N(-d1) ; leur différence est la valeur de parité S - K e^(-rT).
  • Les prix augmentent avec la volatilité et la durée et baissent avec le prix d'exercice du call ; le rendement espéré de l'action est absent, seule la volatilité est requise.

À suivre : le delta, de combien le prix de l'option bouge quand l'action bouge d'un dollar.

Lab : ce qui est noté

  • Construire la probabilité cumulée de la cloche avec norm_cdf25 pts
  • Calculer les deux grandeurs de Black–Scholes avec d1_d225 pts
  • Valoriser un call avec bs_call25 pts
  • Valoriser un put avec bs_put25 pts
Explorateur · lab-73-1
▾ lab-73-1
…
bash · dans le navigateur
learner@quantcraft:~/lab-73-1$
Python pas encore chargéPythonLn 1, Col 1Spaces: 4UTF-8

Réinitialiser ce sujet ?

Tout le contenu de lab-73-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