Recientemente he empezado a aprender sobre la fijación de precios de las opciones y la fórmula de Black Scholes, en la que se supone que los precios de las acciones se distribuyen de forma lognormal y los rendimientos de forma normal. Mientras trataba de hacer algunas simulaciones para aprender más sobre los parámetros y su comportamiento me di cuenta de que parece que estoy aplicando mal el concepto de que los precios de las acciones son lognormales. Por favor, vea el código de abajo en python donde simulo una opción de compra a 30 días con cambios de precio diarios, donde si trato de usar precios lognormales converjo en alrededor de 0.4~ EV versus breakeven, lo cual es esperado, si sólo uso retornos normalmente distribuidos, lo cual permitiría precios de acciones negativos.
import scipy.stats as stats
import numpy as np
import matplotlib.pyplot as plt
def black_scholes(S, K, r, T, sigma, option="call"):
d1, d2 = d(S, K, r, T, sigma)
if option == "call":
return (S * stats.norm.cdf(d1, 0, 1) - K * np.exp(-r * T) * stats.norm.cdf(d2, 0, 1))
elif option == "put":
return (K * np.exp(-r * T) * stats.norm.cdf(-d2, 0, 1) - S * stats.norm.cdf(-d1, 0, 1))
def d(S, K, r, T, sigma):
d1 = (np.log(S / K) + (r + 0.5 * sigma ** 2) * T) / (sigma * np.sqrt(T))
d2 = d1 - sigma * np.sqrt(T)
return d1, d2
price = 100
strike = 105
r = 0
T = 30/365
sigma = 0.5
option = "call"
cost = black_scholes(price,strike,r,T,sigma,option) # = 3.69...
avg_gains = []
avg_gains_logn = []
for _ in range(1000):
runs = {n:None for n in range(1000)}
runs_logn = {n:None for n in range(1000)}
for run in runs:
p = price
p_logn = price
for _ in range(30):
c = np.random.normal(0,sigma/np.sqrt(365))
p *= 1+c
p_logn *= np.exp(c)
runs[run] = p
runs_logn[run] = p_logn
gains = []
gains_logn = []
for n, result in runs.items():
gains.append(max(0, result - strike) - cost)
gains_logn.append(max(0, runs_logn[n] - strike) - cost)
avg_gains.append(sum(gains)/1000)
avg_gains_logn.append(sum(gains_logn)/1000)
plt.plot(avg_gains)
plt.plot(avg_gains_logn)
plt.show()
print(sum(avg_gains)/1000, sum(avg_gains_logn)/1000)