金融资产/证券已使用多种技术进行建模。
该项目的主要目标是使用几何布朗运动模型和蒙特卡罗模拟来模拟股票价格。
该模型基于受乘性噪声影响的随机(与确定性相反)变量。
布朗运动是指悬浮在液体或气体中的微粒所做的永不停息的无规则运动。其因由英国植物学家布朗所发现而得名。作布朗运动的微粒的直径一般为e-5~e-3厘米,这些小的微粒处于液体或气体中时,由于液体分子的热运动,微粒受到来自各个方向液体分子的碰撞,当受到不平衡的冲撞时而运动,由于这种不平衡的冲撞,微粒的运动不断地改变方向而使微粒出现不规则的运动。布朗运动的剧烈程度随着流体的温度升高而增加。
布朗运动{B(t)} (brownian motion)也称为维纳过程,是一个随机过程,其满足以下性质:
01 独立的增量(independenceof increments)
对于任意的t>s, B(t)-B(s)独立于之前的过程B(u):0<=u<=s。
02正态的增量(normalincrements)
B(t)-B(s)满足均值为0方差为t-s的正态分布。即,B(t)-B(s)~ N(0,t-s)。
03连续的路径(continuityof paths)
B(t), t>=0是关于t的连续函数。固定一条路径, B(t)->B(s) 满足依概率收敛。
温度越高,液体分子的运动越剧烈,分子撞击颗粒时对颗粒的撞击力越大,因而同一瞬间来自各个不同方向的液体分子对颗粒撞击力越大,颗粒的运动状态改变越快,故温度越高,布朗运动越明显。
在金融领域,布朗运动可以用来描述股价走势的有效模型,计算出布朗运动在一段时间内能够到达的极值的概率分布,这对于投资中的风控至关重要。进一步的,几何布朗运动可以作为对股价建模的更精确的模型。从长期来看,几何布朗运动的走势由漂移项控制,这意味着对于慢牛的市场我们要做的是坚定价值投资、长期持股、忽视股价短期由随机游走带来的波动。
该项目分两部分完成:
- 第一部分涉及为几何布朗运动编写代码,并检查和验证它是否工作。这是使用 Python 中的几个函数完成的,并使用迭代设置将后续股票价格建模为马尔可夫链,给定初始起始价格 S0。验证过程包括运行多个模拟或随机游走样本,然后检查结果分布,以查看股票价格、收益和波动性是否满足某些属性和假设。
- 第二阶段涉及探索,将模型实际应用于实际股票价格,并使用耐克股票的真实股票数据进行回测。模拟是通过获取收益率 μ 和波动率 σ 的样本值并观察股票价格演变的模拟数据和真实数据之间的相关程度来完成的。
模拟需要大约 10-15 分钟才能完全运行。请注意,对模拟结果的所有解释都是通过解释价格水平和收益率的结果分布的均值和方差等参数来完成的。
假设
此项目中使用了以下变量和符号列表:
- S0 – 初始股票价格
- St – 时间的股票价格,t
- μ – 在特定时间段内平均的股票收益(漂移)率
- σ – 在特定时间段内平均的股票波动率(标准差)
- dt – 模拟的时间步长,对应于一天内股票价格采样的频率
- N – 模拟的总天数。
- r – 无风险利率,任何人都可以借/贷
还对股票市场/价格做出了以下假设。虽然这些假设确实有助于大大简化模型,但它们非常现实,有助于在理想情况下制定模型。
- 股票价格遵循马尔科夫过程,即是无记忆的,随后的股票价格仅取决于当前价值,而不取决于任何先前的价值。
- 与 N 相比,考虑的时间步长 dt 较短,即 Ndt>>1
- 市场完整高效,不存在套利机会。
- 没有股息、交易成本或税收考虑。
维纳过程和几何布朗运动
维纳过程(也称为布朗运动)是一个具有连续变量和连续时间的马尔可夫过程。对于随机变量 z,它有两个重要的性质:
- 所有的 Δz 都是统计独立的。
- dz = εdt
其中 ϵ 来自正态分布
通过将漂移项 a(x,t)dt 添加到随机过程 dz 上,可以将维纳过程进一步推广到 Ito 过程。
对于股票价格,上述方程是 Ito 过程,也称为几何布朗运动,描述了随时间的随机变化。请注意,μ 和 σ 分别是瞬时漂移和标准偏差率。S 遵循一个受乘性噪声影响的随机过程。这里还需要注意的是,几何布朗运动模型避免了负股票价格的问题。
为股票价格的解决方案建模
上述随机微分方程 (SDE) 具有以下形式的解析解:
请注意,在上述等式中,常数 μ 和 σ 分别对应于股票价格的百分比漂移(收益)和百分比波动(标准差)率。Wt 指的是由 dz=ϵdt 给出的维纳过程,如上所述。该解方程用于以下列方式迭代计算每个时间步的 St:
这里,t 是计算的时间步长,每个 St 仅取决于之前的起始价格 St−1,这是布朗运动模型所要求的,因为它是一个马尔可夫过程。请注意,通过选择一个小的时间步长,我们可以接近连续时间的极限。
随时关注您喜欢的主题
因此,给定某个时间步长,随后的每个股票价格 St 完全由三个参数描述:
- 初始“开始”价格,St−1
- 百分比收益(漂移)率,μ
- 波动率或标准偏差率,σ
下面的代码实现了上面描述的迭代过程。时间步长由 dt 给出,对应于对股票价格进行采样的频率,N 是模拟运行的总天数。
#几何布朗运动模型 #使用mu=收益率 #sigma=波动率 #dt=时间步长 #Si=每个时间段的初始(开始)价格值 #价格和收益的时间演变 #使用布朗运动模型来生成N天(时间段)的价格列表 def gices(mu, sigma, dt, Si, N): pirr = np.zeros(N) #初始化一个长度为N的向量来存储价格值 pr_r\[0\] = Si #存储第一个价格值 retrr = np.zeros(N) #初始化向量来存储返回值 #还可以计算连续N之间的价格回报率 for i in range (1,N): #注意price\[i-1\]是每次迭代的Si pr\_arr\[i\] = geoeti\_bown(mu, sigma, dt, price_arr\[i-1\])
运行单个模拟/步行
这部分代码只是调用上面编写的函数并绘制结果。
给出了收益率和波动率、起始价格和时间步长的样本值。以下数字按出现顺序显示:
- 股票价格的演变,St 作为 N 的函数
- 股票价格水平的分布,绘制为直方图。
- 收益和对数收益的分布,也绘制为直方图。
在随后的部分中进行了多次模拟,以实际验证模型的正确性。
#运行单个模拟以检查功能 #使用 mu、sigma 和 Si 的样本值进行测试 #调用函数 Slst, RitRlolist = gpes(mu, sigma, dt, Si, N) #绘制结果 plt.figure(figsize=(15,5))
#用于获取mu\_multiple和sigma\_multiple #将价格数组作为输入并返回 mu 和 sigma def v\_tun(price\_array): mu_single = 0 sgm_sigle = 0 #计算模拟的平均收益率,mu和平均波动率,sigma musigle = np.mean(mu_temp) sigmsile = np.std(mu_temp) #Monte Carlo 模拟几何布朗运动演化 #运行几个模拟来生成几个可能的价格演变数组 #用它来计算平均波动率和回报率 def gmlie(mu, sigma, dt, Si, N, sim_count): cacies = np.zeros(shape=(N,sim_count)) #创建一个数组来存储模拟值 #对于 alc_res 数组,我们只关心值 #创建数组来存储每个的mu和sigma的值 m\_mutple = np.zeros(sim\_count) sigmmiple = np.zeros(sim_count) vl = np.linspace(0,N-1,N) #运行模拟并绘制每个价格演变的结果 plt.figure(figsize=(20,20))
检查和测试多个模拟的代码
上面的代码包含一个函数,可以为几何布朗运动描述的随机游走运行多个模拟。还编写了另一个计算给定输入数组的平均收益和波动率水平的函数。这两个函数都用于生成几个模拟/随机游走,如上图所示。
上图显示了在相同起始价格、S0=100 和收益率和波动率、μ=0.2 和 σ=0.07 下运行的 500 次模拟图。使用的时间步长为 dt=0.01,表示每天对股票价格进行频繁抽样。每条线代表使用前面描述的几何布朗运动模型建模的样本随机游走。然后通过绘制股票价格、收益和标准差的分布来分析使用这些模拟生成的数据。然后分析这些价格水平、收益和波动率的分布,以检查其正确性和一致性。
从下面的第一张图中可以看出,价格水平遵循近似对数正态分布。这实际上是一个预期的结果。解,St 是一个对数正态分布的随机变量,其期望值和方差由下式给出:
从下面的第一幅图中可以看出,对于 sim_count = 500 次模拟,价格水平确实近似于对数正态分布,平均值约为 200。使用 tats.lmfit 函数测量的均值和方差也与以上定义的值在合理的误差范围内。对于使用上面给出的参数的模拟运行,它们被计算为:
下面的第二张图显示了上面运行的模拟的收益率分布。可以很容易地观察到,收益呈正态分布,平均值约为 0.15,这是模拟中 μ 的输入值。这种收益率的正态分布也是布朗运动模型的预期结果。下面的第三张图显示了标准偏差率的分布,也可以观察到其呈正态分布,平均值约为 0.07,这是模拟的 σ 输入值。
因此,上述讨论验证了几何布朗运动编码模型确实按预期工作,并生成与模型的属性和假设相对应的结果。自相似性也被证明适用于模型,其中不同的时间步长 dt 与调整后的 μ 和 σ 一起使用,以产生相似的价格水平和收益分布。这是模型的另一个预期结果,因为布朗运动在不同尺度上表现出分形行为。
#绘制价格水平和收益的分布以检查代码的有效性 #价格水平应根据几何布朗运动模型呈对数正态分布 #Retu ate 和 Vlatiiy 应该是正态分布的 #Plot 价格水平 plt.figure(figsize=(15,5)) #与下面给出的均值和标准差的对数正态分布进行比较 logorman = Si\*np.exp(mu\*N*dt) logmvar = (Si\*\*2)\*np.exp(2\*mu\*N\*dt)\*(np.exp((sigma\*\*2)\*N*dt)-1) plt.plot(bns,lonm_dst,"g",lw=5) #绘制预期的对数正态密度分布 #绘制收益和波动率分布 plt.figure(figsize=(15,5))
print(lono_ean) print(np.sqrt(loomvr))
探索:使用真实股票数据测试模型
一旦模型被检查为正常工作,它就会用真实的库存数据进行测试。耐克 (NKE) 2013-2015 年的股价被用来回测该模型。并且使用上述几何布朗运动模型运行 Monte Carlo 模拟。
以下值用于在两年期间使用 NKE 的真实数据测试代码。假设一年大约有 250 个工作日,N = 500 表示大约两年的时间框架。通过将数据导入单独的 .csv 文件并对股票价格的收益率和标准差进行所需的计算来计算收益率和波动率。
- 截至 2013 年 1 月 2 日,起始价格 S0 为 52.4。两年期末的预期价格 St 预计在 98.6 左右。
- 两年年化收益率为 μ=0.13,这是使用雅虎财经历史记录生成的价格列表计算得出的。
- 两年年化波动率也从价格中获得,σ=0.05。
以下代码调用函数以通过几何布朗运动模型生成随机游走。
#使用这些价格计算回报率和波动率。 pprint(k.geical('2013-01-01', '2015-01-01'))
#使用输入参数的样本值运行多个模拟 dt = 0.01 sim_count = 500 #调用函数并运行模拟 prie, mu_arr, sigrr = geiple(mu, sgma, dt, Si, N, icont) 在 \[29\] 中: lorm_ean = Si\*np.exp(mu\*N*dt)
解释模拟结果
从上图中生成的随机游走可以看出,我们在这里使用的模型乍一看似乎产生了正确方向和近似幅度的价格演变。由于它是一个随机游走模型,重要的是要注意,结果只能解释为价格水平或整体收益分布,而不是单个模拟。下面的代码和数字为价格水平和收益率和波动率生成所需的分布图。
首先需要注意的是,使用等式 E[St]=S0e(μNt) 的对数正态分布价格水平的计算平均值为 100.374。这位于真实值 98.6 的 5% 误差范围内,是使用 500 次模拟生成的。
其次,可以看出几何布朗运动的所有性质都得到满足——价格水平服从对数正态分布,收益率和波动率正态分布,均值对应于输入参数值。
请注意,模拟还针对其他时间范围和不同的股票价格运行,平均而言,该模型显示的值在圣路易斯真实价值的 10% 以内。
#绘制价格水平的分布并返回以检查真实数据的代码 #价格水平应根据几何布朗运动模型呈对数正态分布 #Return Rate 和 Volatility 应该是正态分布的 #Plot 价格水平 plt.hist(prestiple,bins=100,normed=1,label="R") #与下面给出的均值和标准差的对数正态分布进行比较 lognorm_mean = Si\*np.exp(mu\*N*dt) lognorm_var = (Si\*\*2)\*np.exp(2\*mu\*N\*dt)\*(np.exp((sigma\*\*2)\*N*dt)-1) #绘制预期的对数正态密度分布 #绘制收益和波动率分布 plt.hist(mu_arr,bins=100,normed=1,label="R")
评论和结论
从生成的模拟结果可以看出,几何布朗运动模型可以很好地使用上面讨论的随机过程来模拟股票价格。该模型首先被检查以满足几何布朗运动的特性,然后用真实的股票价格数据进行回测。NKE 2013-2015 年的股票价格用于计算 μ 和 σ 的值,然后用于运行该期间的模拟。股票价格的模拟结果和真实价值在 5% 的误差范围内相似。
可下载资源
关于作者
Kaizong Ye是拓端研究室(TRL)的研究员。在此对他对本文所作的贡献表示诚挚感谢,他在上海财经大学完成了统计学专业的硕士学位,专注人工智能领域。擅长Python.Matlab仿真、视觉处理、神经网络、数据分析。
本文借鉴了作者最近为《R语言数据分析挖掘必知必会 》课堂做的准备。
非常感谢您阅读本文,如需帮助请联系我们!