自定义利率模拟函数的输出结果不符合预期
下面是我自定义的一个名为vasicek_sim的函数用来模拟一段时间内利率的变化路径。
def vasicek_sim(initial, final_time, sim_path_len, num_paths=None, *,
a, b, sigma, allow_neg=True):
"""
Parameters
----------
inital : float
the initial value of interest rate, i.e. r(0).
final_time : int
the time when the simulation stops.
sim_path_len : int
the number of points generated after the initial data.
num_paths : int, optional
the number of paths simulated. The default is None.
a : float
the parameter used in corresponding interest rate model.
b : float
the parameter used in corresponding interest rate model.
sigma : float
the parameter used in corresponding interest rate model.
allow_neg : bool, optional
when it equals to True, a negative interest rate is allowable
in the simulation. The default is True.
Returns
-------
None.
"""
import math, random
""""Create a list to store a path of interest rate(IR)"""
if type(initial) == list:
path_initial = initial
else:
path_initial = [initial]
delta = final_time / sim_path_len
"""" Generate a original path_box which has num_paths identical initial."""
if num_paths == None:
num_paths = 1
path_box = [path_initial for i in range(num_paths)]
y = [] # Used to store the paths of IR that have negative IR.
exp = math.exp(-a*delta)
"""" When num_paths is default value, there is only one path."""
for i in path_box:
for j in range(sim_path_len):
#print(i[-1])
r_old = i[-1]
W_1 = random.gauss(0, 1)
W_2 = random.gauss(0, 1)
#print(f'{W_1 = }\n{W_2 = }')
r_new = (exp*r_old
+ b*(1-exp)
+ sigma*((1-exp**2)/(2*a))**0.5*(W_2-W_1))
if allow_neg == False and r_new < 0:
print(r_new)
break
#print(r_new)
#print(i)
i.append(r_new)
# The paths removed before are appended to path_box again.
if y != []:
path_box.append(y)
return path_box
下图是我的测试代码
if __name__ == '__main__':
z = vasicek_sim([0.25, 0.3, 0.4], 2, 3, 2, a=0.5, b=0.6, sigma=0.2)
print(f'The path of interest rate is\n {z}')
最后是我的运行结果
The path of interest rate is
[[0.25, 0.3, 0.4, 0.3479323841038564, 0.2375140125192349, 0.40864261608808583, 0.5588591529202444, 0.3464802076221359, 0.2132402884958335], [0.25, 0.3, 0.4, 0.3479323841038564, 0.2375140125192349, 0.40864261608808583, 0.5588591529202444, 0.3464802076221359, 0.2132402884958335]]
预期结果是,返回的path_box中的两个子列表各包含6个元素,其中前三个相同,后三个不同,但运行后发现每个子列表各有9个元素,并且两个子列表完全一样。通过检查发现,第一个子列表的最后三个元素本应该储存在第二个子列表的[3:5]部分,同时,debug的过程中每次最里面的回圈结束一圈后,path_box的两个子列表会同时被改变而非只改变当前这一个。
请问是哪部分代码导致了这个问题?
推荐文章: