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é.
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.15Le 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 holdsCe 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 valueN(x) = 0.5 * (1 + erf(x / sqrt(2))), etd1 = (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