3 votos

¿Simular los precios de las acciones con un movimiento browniano geométrico con mu y signa basado en una composición "normal" o continua?

He escrito un simple script para modelar los precios de las acciones utilizando el Movimiento Browniano Geométrico. Las series temporales que estoy descargando son precios de cierre ajustados diariamente. Mi objetivo es poder cambiar el periodo de predicción y el resto de variables.

Sin embargo, estoy tratando de entender las diferencias de predicción de precios entre el cálculo de la mu (rendimientos medios) y la sigma (varianza) utilizando un método lineal o estándar frente a la utilización de un Registro enfoque. El enfoque del registro genera sistemáticamente una predicción más alta del precio de las acciones. Mi código está abajo.

He rebuscado en internet y he leído todo lo que he podido encontrar. También hay varios artículos útiles en este foro, como aquí y aquí . Pero nada cubre realmente mi pregunta.

Mi pregunta es: ¿qué enfoque es el más adecuado?

(Estoy usando Python 3.)

from math import log, e
import matplotlib.pyplot as plt
from pandas_datareader import data
from datetime import date, timedelta
import datetime

stock = 'AAPL' # Enter the name of the stock
start = '2015/1/1'
apple = data.DataReader(stock, 'yahoo', start)

# This is the 'normal' way of calculating mu and sigma
close = apple[:]['Adj Close']
mu = (close[-1]/close[1])** (252.0/len(close)) - 1
sigma = (close/close.shift(1)-1)[1:].std()*np.sqrt(252)

# This is the 'log' way of calculating mu and sigma
apple['log_price'] = np.log(apple['Adj Close'])
apple['log_return'] = apple['log_price'].diff()
mu = apple.log_return.sum() -1
sigma = np.std(apple.log_price)

s0 = close[-1]
T = 18/12
delta_t = 0.001
num_reps = 1000
steps = T/delta_t
plt.figure(figsize=(15,10))
closing_prices = []
for j in range(num_reps):
    price_path = [s0]
    st = s0
    for i in range(int(steps)):
        drift = (mu - 0.5 * sigma**2) * delta_t
        diffusion = sigma * np.sqrt(delta_t) * np.random.normal(0, 1)
        st = st*e**(drift + diffusion)
        price_path.append(st)
        closing_prices.append(price_path[-1])
    plt.plot(price_path)
plt.ylabel('stock price',fontsize=15)
plt.xlabel('steps',fontsize=15)
plt.axhline(y = s0, color = 'r', linestyle = '-') # print latest price TW
plt.show()

mean_end_price = round(np.mean(closing_prices),2)
print("Expected price in 12 months: $", str(mean_end_price))

0 votos

"El enfoque logarítmico genera sistemáticamente una mayor predicción del precio de las acciones" porque su deriva logarítmica es mayor que su deriva normal debido a la forma en que calcula mu para el logaritmo frente a la normalidad que se señala en la respuesta siguiente.

5voto

Amod Gokhale Puntos 26

La deriva de su código es:

drift = (mu - 0.5 * sigma**2) * delta_t

Así que asumo que estás usando el Movimiento Browniano Geométrico para simular el precio de tus acciones, y no un simple movimiento browniano. Por lo tanto su modelo es Lognormal, no Normal. También, asumo que la serie de tiempo que estás descargando es diario precios de cierre.

La solución del modelo GBM es la siguiente (abajo) $\delta t:=(t_i)-(t_{i-1})$ & $Z\sim~N(0,1)$ ):

$$ ln(S_{t_i}) - ln(S_{t_{i-1}}) = (\mu - 0.5\sigma^2)\delta t+\sigma\sqrt{\delta t}Z $$

Obsérvese que los rendimientos logarítmicos anteriores se distribuyen normalmente:

$$ln(S_{t_i}) - ln(S_{t_{i-1}}) \sim N\left(\tilde{\mu} := (\mu - 0.5\sigma^2)\delta t;\tilde{\sigma}:=\sqrt{\delta t}\sigma\right)$$

Si utilizamos series temporales diarias, entonces $\delta t = \frac{1}{260}$ .

Si quiere calibrar el modelo anterior basándose en datos diarios históricos, su tarea consiste en calibrar $\tilde{\mu}$ y $\tilde{\sigma}$ :

$$(i): \tilde{\mu}=\frac{1}{n}\sum_{i=1}^{n} ln\left( \frac{S_{t_i}}{S_{t_{i-1}}}\right)$$

$$ (ii): \tilde{\sigma}^2 = \frac{1}{n-1} \sum_{i=1}^{n} \left( \left[ ln\left( \frac{S_{t_i}}{S_{t_{i-1}}}\right) - \tilde{\mu} \right]^2\right) $$

Obsérvese que en (i) se ha calculado $\tilde{\mu}$ y NO $\mu$ . En su simulación, necesita $\mu$ Así que primero haz lo siguiente:

$$ \sigma = \tilde{\sigma}*\frac{1}{\sqrt{\delta t}}=\tilde{\sigma}*\sqrt{260} $$

$$\mu = \frac{1}{\delta t}*\tilde{\mu}+0.5{\sigma}^2=260*\tilde{\mu}+0.5{\sigma}^2$$

Esta es la $\mu$ que debe utilizar en su simulación.

El siguiente punto es: ¿por qué tienes la siguiente línea en tu código?

mu = apple.log_return.sum() -1

¿Por qué restar el 1? Si sus retornos de registro son diarios, para obtener $\mu$ su código debería ser el siguiente:

mu = apple.log_return.sum()/apple.log_return.count()
mu = mu*260 + 0.5*apple.log_return.var()*sqrt(260)

Para obtener el $\mu$ de acuerdo con las fórmulas que he descrito anteriormente.

Si está utilizando el GBM para simular el precio de sus acciones, no debería utilizar los rendimientos normales para calibrar su modelo: por lo tanto, lo que usted llama forma "normal" es la forma incorrecta de calibrar su modelo.

Ps: si tiene series temporales diarias para empezar, puede elegir un día como unidad de tiempo si quiere simular con granularidad diaria. Esto le facilitará considerablemente la tarea, ya que podrá trabajar con $\tilde{\sigma}$ y $\tilde{\mu}$ directamente, en lugar de tener que anualizarlos: es decir, convertirlos en $\sigma$ y $\mu$ .

0 votos

Muchas gracias por este comentario tan elaborado. Sí, utilizo el Movimiento Browniano Geométrico y los precios de cierre diarios (he actualizado la pregunta, gracias). Si entiendo bien su respuesta: (1) delta_t = 0.001 se convierte en delta_t = 1/260 (2) utilizar su código para mu. ¿Es eso correcto? (P.D. Creo que sqrt en tu código debería ser np.sqrt).

0 votos

(1) Sí, (2) Sí (correcto, debería ser np.sqrt()). Ps: ¿por qué tienes T=18/12? ¿Su serie temporal tiene una duración de 18 meses?

0 votos

Gracias. T=18/12 porque quiero predecir el precio dentro de 1,5 años. ¿Utilizas 1/260 porque hay alrededor de 260 días de negociación en un año?

Finanhelp.com

FinanHelp es una comunidad para personas con conocimientos de economía y finanzas, o quiere aprender. Puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X