几何布朗运动的定义与表达式
用几何布朗运动模拟未来股价
下面我们以华泰证券[601688]股票为例,根据其2016年-2019年的日收盘价数据得到收益率和波动率,模拟未来三年(2020年-2022年)的价格走势,模拟路径为100条,S0设定为2020年1月2日的收盘价,具体操作如下:
第一步,导出该股票前4年的收盘价数据,生成对数收益率数据,计算年收益率和收益率序列的年波动率:
import numpy as np
import pandas as pd
import pandas_datareader.data as web
from datetime import date
df=web.DataReader('601688.SS','yahoo',date(2016,1,1),date(2019,12,31))['Adj Close']
df.tail()
Out[1]:
Date
2019-12-25 19.209999
2019-12-26 19.530001
2019-12-27 19.440001
2019-12-30 20.600000
2019-12-31 20.309999
Name: Adj Close, dtype: float64
R=np.log(df/df.shift(1))
R=R.dropna()
miu=R.mean()*252
sigma=R.std()*np.sqrt(252)
print('华泰证券股票预期年收益率为{:.4f},收益率的年化波动率为{:.4f}'.format(miu,sigma))
华泰证券股票预期年收益率为0.0569,收益率的年化波动率为0.3637
第二步,生成需要模拟的参数,需要导入pandas模块中的时间索引函数DatetimeIndex,其中freq='B’表示工作日,freq='D’表示日历日。用此函数生成2020年1月2日到2022年12月31日且是工作日的时间数据组:
import numpy.random as npr
date=pd.DatetimeIndex(start='2020-1-2',end='2022-12-31',freq='B')
n=len(date);I=100#生成需要预测的维度,n天100次
dt=1/252#St和St-1之间的时间间隔
result=np.zeros((n,I))
result[0]=20.35#datareader可找到2020年1月2日的股价,作为S0
result
Out[3]:
array([[20.35, 20.35, 20.35, ..., 20.35, 20.35, 20.35],
[ 0. , 0. , 0. , ..., 0. , 0. , 0. ],
[ 0. , 0. , 0. , ..., 0. , 0. , 0. ],
...,
[ 0. , 0. , 0. , ..., 0. , 0. , 0. ],
[ 0. , 0. , 0. , ..., 0. , 0. , 0. ],
[ 0. , 0. , 0. , ..., 0. , 0. , 0. ]])
第三步,代入几何布朗运动公式(3),生成未来股价的时间序列并可视化:
for t in range(1,n):
e=npr.standard_normal(I)#生成100个服从正态分布的ε
result[t]=result[t-1]*np.exp((miu-0.5*sigma**2)*dt+sigma*e*np.sqrt(dt))
result=pd.DataFrame(result,index=date)
result.tail()
Out[18]:
0 1 2 ... 97 98 99
2022-12-26 7.228284 50.589052 13.894615 ... 15.088003 26.878331 17.809976
2022-12-27 7.326814 50.246075 14.295553 ... 15.092543 26.331081 18.008560
2022-12-28 7.199398 49.766670 14.603153 ... 15.350998 27.281464 17.841967
2022-12-29 7.145956 49.649970 14.622990 ... 15.583868 28.576045 17.981660
2022-12-30 7.243188 50.790810 14.672076 ... 15.626152 27.511881 18.083931
[5 rows x 100 columns]
import matplotlib.pyplot as plt
from pylab import mpl
mpl.rcParams['font.sans-serif']=['SimHei']
mpl.rcParams['axes.unicode_minus']=False
plt.plot(result)
plt.xlabel('日期')
plt.ylabel('股价')
plt.xticks(rotation=30)#调整横坐标刻度值的角度
plt.title('2020年1月2日-2022年12月31日华泰证券股价模拟路径')
plt.grid()