Estoy tratando de utilizar el movimiento browniano para predecir los precios de las opciones y comparar los resultados con los de Black y Scholes. Para ello, quiero calcular los rendimientos medios (mu) y la volatilidad (sigma) del activo subyacente sobre la base de la composición continua - de ahí que utilice funciones logarítmicas.
Sin embargo, creo que puede haber varios errores en mi planteamiento que no puedo confirmar. Lamentablemente, no encuentro respuestas claras a mis preguntas en la red, en sitios como quantconnect, así como en este foro. Estas son mis dudas:
- ¿Pueden utilizarse ambos modelos con mu y sigma basados en cálculos logarítmicos?
- ¿Puede introducirse el tiempo de maduración T en la misma unidad para ambos modelos?
- Al utilizar el movimiento browniano geométrico para simular los precios de las acciones, hacemos un bucle, digamos, 10.000 veces y tomamos el resultado medio. La mayoría de los modelos GBM para los precios de las opciones que encuentro en la web no parecen hacer un bucle. ¿Por qué?
Mi código de Python está abajo. ¿Alguna sugerencia?
from math import log, e
from pandas_datareader import data
from datetime import date, timedelta
#import datetime
import yfinance as yf
import scipy.stats as si
# Get stock price data
apple = data.DataReader('AAPL', 'yahoo', '2018/1/1')
spot = apple["Adj Close"][-1]
# Calculate log annual returns (mu) and log volatility (sigma)
apple['log_price'] = np.log(apple['Adj Close'])
apple['log_return'] = apple['log_price'].diff()
mu = apple.log_return.sum()/apple.log_return.count()
mu = mu*365 + 0.5*apple.log_return.var()*np.sqrt(365)
sigma = np.std(apple.log_price) #sigma: volatility of underlying
spot = 463.94 #spot: spot price
K = 460 # strike price
T = 1 # time to maturity
r = 0.135 # risk-free interest rate
# Black and Scholes calculation
s0 = spot
def euro_vanilla_call(S, K, T, r, sigma):
d1 = (np.log(S / K) + (r + 0.5 * sigma ** 2) * T) / (sigma * np.sqrt(T))
d2 = (np.log(S / K) + (r - 0.5 * sigma ** 2) * T) / (sigma * np.sqrt(T))
call = (S * si.norm.cdf(d1, 0.0, 1.0) - K * np.exp(-r * T) * si.norm.cdf(d2, 0.0, 1.0))
return call
BSM1 = euro_vanilla_call(spot, K, T, r, sigma)
print(BSM1)
# Monte Carlo simulation
def mc_euro_options(option_type,s0,strike,maturity,r,sigma,num_reps):
payoff_sum = 0
for j in range(num_reps):
st = s0
st = st*e**((r-0.5*sigma**2)*maturity + sigma*np.sqrt(maturity)*np.random.normal(0, 1))
if option_type == 'c':
payoff = max(0,st-strike)
elif option_type == 'p':
payoff = max(0,strike-st)
payoff_sum += payoff
premium = (payoff_sum/float(num_reps))*e**(-r*maturity)
return premium
MCP1 = mc_euro_options('c', spot, K, T, r, sigma, 100)
print(MCP1)```