Estoy tratando de generar los resultados multivariados de MC presentados en este documento Una simple generalización de la aproximación de Kirk para las opciones de diferencial multiactivo mediante el método de división del operador Lie-Trotter por Chi-Fai Lo https://file.scirp.org/pdf/JMF_2014050615380663.pdf .
He hecho diferentes intentos utilizando diferentes enfoques pero siempre termino produciendo el mismo resultado incorrecto. Por ejemplo, mi código para generar el primer elemento de la tabla 5.1 produce 13.7424 +/- 0.0045
en lugar de 13.5763 ± 0.0089
.
Aquí abajo está el código Python que hice
Si alguien tiene la amabilidad de decirme qué estoy haciendo mal ....
(para información puedo confirmar que los valores de EK en el papel son correctos porque pude encontrar los valores proporcionados por Kirk)
import numpy as np
import scipy.stats
nb_simuls = 10_000_000
# parameters from https://file.scirp.org/pdf/JMF_2014050615380663.pdf Table 1 / cell 1
S1, S2, S3 = 50, 60, 150
v1, v2, v3 = 0.3, 0.3, 0.3
rho_12, rho_23, rho_13 = 0.40, 0.20, 0.80
K = 30.0
T = 0.25
r = 0.05
# from spot to forward values
F1 = S1 * np.exp(r*T)
F2 = S2 * np.exp(r*T)
F3 = S3 * np.exp(r*T)
# derive volatilities from yearly volatility
vols = np. array([v1, v2, v3]) * np.sqrt(T)
# determine covariance matrix from correls and volatilities
correl = np.asarray([[1, rho_12, rho_13],
[rho_12, 1, rho_23],
[rho_13, rho_23, 1]])
cov = np.diag(vols).dot(correl).dot(np.diag(vols))
# simulate prices
returns = 1 + np.random.default_rng().multivariate_normal((0, 0, 0), cov, nb_simuls)
# determine exercise and value
values = []
for i in range(nb_simuls):
v = max(0, F3 * returns[i, 2] - F1 * returns[i, 0] - F2 * returns[i, 1] - K)
values.append(v)
v, se = np.mean(values) * np.exp(-r*T), scipy.stats.sem(values) * np.exp(-r*T)
print(f"The option value is: {v} +/- {se}")
# The option value is: 13.742449851577431 +/- 0.004475778801668813
0 votos
A primera vista, ¿puede aumentar el número de simulaciones? Ellos utilizan 900.000.000. Me parece raro que tu error estándar sea menor que el de ellos si tienes menos simulaciones.
0 votos
@phdstudent He probado hasta 15 M pero el resultado no ha cambiado... No puedo ir por encima de ese número de simulación debido a las restricciones del sistema ....
0 votos
No veo ningún problema particular en su enfoque. ¿Podría ser que no tengan en cuenta el factor de descuento, en la estimación de la media y el stdev? Para este ejemplo podría explicar la discrepancia, si tienes el mismo comportamiento para otras configuraciones, entonces probablemente sea eso
0 votos
@Quantuple sin tener en cuenta el df las discrepancias son aún mayores. Además, sé que su valor tiene que ser el correcto porque está mucho más cerca del valor dado por la fórmula de kirk (lo he comprobado)
2 votos
Ah sí, lo siento, he aplicado el df a su resultado. Necesito mi café. He echado un vistazo rápido al documento, parece que postulan Black Scholes, es decir $S_T = F(0,T) \exp(-1/2\sigma^2T + \sigma \sqrt{T} z)$ para un activo mientras que usted está haciendo $S_T = F(0,T) (1 + \sigma\sqrt{T}z)$
0 votos
@Quantuple gracias, este fue mi error, puse una versión modificada de mi código a continuación ... para mi información ¿sería posible lograr lo mismo aún utilizando la matriz de covaraince en lugar de la matriz de correlación?
1 votos
¿Se refiere a algo como $S_T = F(0,T) \times \exp( - 1/2 \text{diag}(\Sigma) + Z )$ donde $F(0,T)$ es el vector 3x1 de los delanteros, $\times$ denota la multiplicación del vector componente por componente, $\Sigma$ la matriz de covarianza 3x3 y $Z \sim N( {\bf{0}}, \Sigma )$ una muestra de la normal multivariante con media ${\bf{0}}=(0,0,0)$ y la matriz de covarianza $\Sigma$ ?
0 votos
@Quantuple sí esto es lo que quería decir, pero aquí diag() es un vector ... He intentado algo como lo siguiente, pero no funciona ... Fi_exp = Fi * np.exp(-0.5 * np.diag(correl)[i] + returns[n, i])
0 votos
Pues sí, tiene que ser un vector 3x1, como el vector de precios a futuro