金融工具定价的一个常见方法是通过模拟来进行。对于股票价格的模拟,最简单的假设是股票价格遵循几何布朗运动(GBM)。利用模拟出的股票价格,可以进一步定价其衍生品或其他结构性产品。
几何布朗运动(GBM)的定义可以在维基百科中找到。简而言之,它假设股票价格的回报率服从正态分布,并且可以通过漂移率μ和波动率σ来表示。用dS(t)/S(t)来表示股票价格S(t)在时间t和t+dt之间的微小变化,其中dS(t)是股票价格的微小变化量。
dS(t)/S(t) = μ * dt + σ * dW(t)
dW(t)是一个服从正态分布N(0,t)的随机变量,被称为维纳过程。上述随机微分方程(SDE)的直观含义是:股票回报将以μ的速率增加或减少,称为漂移,但同时伴随着正态分布的随机噪声,其均值为零,方差与σ和时间t成比例。因此,随着时间的推移,不确定性会增加。
解几何布朗运动(GBM)的SDE,股票价格服从对数正态分布。
S(t) = S(0) * exp( (μ – σ^2 / 2) * t + σ * W(t))
其期望值和方差定义如下:
E(S(t)) = S(0) * exp(μt)
Var(S(t)) = S(0)^2 * exp(2μt) * (exp(σ^2 * t) – 1)
上述公式的关键输入参数是μ和σ。传统上,人们使用样本均值和样本标准差作为近似值。然而,μ和σ并不一定是常数。从贝叶斯的角度来看,可以假设μ和σ服从某些概率分布。
贝叶斯理论允许使用概率编程来估计参数μ和σ的概率分布(即后验概率分布)。可以使用Julia语言的Turing.jl包,这是一个为概率编程设计的包,通过使用股票价格时间序列数据S(t)来估计μ和σ的后验概率分布。
以下是Julia代码段中定义的股票价格的概率模型,其中“s”和“y”是股票价格时间序列数据。(“s”和“y”是相同的数据,只是使用s1作为初始价格S(0),y[i]是时间“i”的价格)。
@model GBM(s,y,n) = begin
sig ~ Exponential(sample_std)
u ~ Uniform(sample_mean - 2*sample_std,sample_mean + 2*sample_std)
for i in 1:n
if i == 1
y[1] = s[1]
else
t = i-1
mu = s[1]*exp(u * t)
var = s[1]*s[1]*exp(2*u*t)*(exp(sig*sig*t)-1)
y[i] ~ LogNormal(mu,sqrt(var))
end
end
end;
发现模型的收敛性对先验概率的初始化非常敏感。作为合理的初始值,可以使用股票价格的样本均值(sample_mean)和样本标准差(sample_std)来初始化它们。
在GBM模型上进行了1000次采样(代码如下所示)。在每次调用模型GBM时,输入时间序列数据作为参数:即变量“train”,它存储了大小为n的股票价格数据。然后用mapreduce函数重复了5次1000次迭代的采样。最终结果将被连接到变量“chain”中。
chain = mapreduce(c -> sample(GBM(train,train,n),NUTS(200, 0.65), 1000, discard_adapt=true),
chainscat,
1:5)
上面的图表显示了模拟的收敛性。左列的两个图表显示了μ和σ的样本值在1000次迭代中是稳定的。5条不同颜色的线代表了5个数据链。它们紧密重叠,因此可以说结果是稳定的。
右列的两个图表是通过模拟推断出的μ和σ的后验分布。μ和σ的形状分别是正态分布和对数正态分布。尽管μ和σ是用指数分布和均匀分布初始化的先验概率,但在推断结束时,μ和σ的后验概率分别是正态分布和对数正态分布。这是因为,在推断过程中,μ和σ的分布将被股票数据(即证据)校正。
使用后验分布模拟股票价格的一个优势是,可以使用后验分布而不是常数值来模拟股票价格。链包含5000对μ和σ在后验分布下的值。因此,可以使用“chain”数组从后验概率分布中采样μ和σ。
在时间t的模拟股票价格是通过以下公式计算的:
S(t) = S(t-dt) * exp( (μ – σ^2 / 2) * dt + σ * W(dt))
指数中的第一项:(μ – σ^2 / 2) * dt是漂移,第二部分:σ * W(dt)是扩散,其中包含随机部分:W(dt) = epi[k,I] * sqrt(dt),其中epi ~ Normal(0,1)。
从0到T的时间的股票价格通过N个时间步长来模拟。将时间T分成N步,因此有:dt = T/N。在每个时间步长,前一时间步长的股票价格乘以漂移和扩散的和的指数。从chain[:u][:,]和chain[:sig][:,]中得到N个随机样本的μ和σ,它们应该在μ和σ的后验概率分布下。由于使用u[i]和sig[i]以及时间步长来计算漂移和扩散,因此通过变化μ和σ而不是常数μ和σ来计算沿时间的模拟股票价格。
以下是使用μ和σ的后验分布模拟股票价格的代码。
function simulate_price(chain,s0,T,N)
npath = 10
y = zeros(Float32, npath, N)
dt = convert(Float64,T) / convert(Float64,N)
epi = rand(Normal(0,1),(npath,N))
for k in 1:npath
sig = sample(chain[:sig][:,], N)
u = sample(chain[:u][:,] , N)
for i in 1:N
if i == 1
y[k,1] = s0
else
drift = (u[i]-0.5*sig[i]*sig[i])*dt
diffusion = sig[i]*epi[k,i]*sqrt(dt)
y[k,i] = y[k,i-1]*exp(drift + diffusion)
end
end
end
return y
end;
plot(paths[1,:])
plot!(paths[2,:])
plot!(paths[3,:])
plot!(paths[5,:])
plot!(paths[7,:])
plot!(paths[9,:])
C = E[ g(S'(T)) ] / (1+r)^T