使用Python最小化对数似然估计Heston-Nandi模型参数遇问题求助
Heston-Nandi模型MLE参数估计的数值问题解决建议
问题背景
我尝试用最大似然估计(MLE)求解Heston-Nandi模型参数,已编写目标函数及相关代码,股票对数收益率数组returnarr前30个值如下:
returnarr = filterdata['logreturn'].to_numpy(dtype=np.longdouble) returnarr[0:30]
输出结果:
array([ 0.00075018, -0.00696353, -0.00080357, 0.00287779, -0.00384807, -0.00496853, 0.00608317, -0.00252242, -0.00731938, 0.01879965, -0.00673696, -0.00757294, -0.02209292, 0.01152935, 0.00609485, 0.004072 , -0.01832714, -0.01604845, 0.0059958 , 0.00251289, 0.00740885, -0.01594026, 0.0076436 , -0.00298763, 0.00460656, -0.00237508, 0.0078305 , 0.003722 , 0.00649657])
定义的对数似然函数及相关代码:
import numpy as np from scipy.optimize import minimize # Define the log-likelihood function def log_likelihood(parameters,returnarr): size=len(returnarr) phi = parameters[0] w = parameters[1] B = parameters[2] alpha = parameters[3] lambda1=parameters[4] epsilon = np.zeros(size, dtype='longdouble') variance = np.zeros(size + 1, dtype='longdouble') variance[0]=0.001 for x,val in enumerate(returnarr): epsilon[x] = (val - (rate + (lambda1 * variance[x]))) / np.sqrt(variance[x]) variance[x+1] = w + (B * variance[x]) + (alpha * np.square(epsilon[x]-(phi*np.sqrt(variance[x])))) variance=variance[:-1]#remove last term log_likelihood_on_return = -0.5 * np.sum(np.log(variance) +np.square(epsilon)) return log_likelihood_on_return # Minimize the negative log-likelihood
尝试的参数求解代码:
initial_parameters=[0.01,0.01,0.01,0.01,0.01] bounds = [(0, 1), (0, 1), (0, 1), (0, 1), (0, 1)] result = minimize(log_likelihood, initial_parameters, args=(returnarr,),bounds=bounds)
运行后出现以下警告:
RuntimeWarning: overflow encountered in square variance[x+1] = w + (B * variance[x]) + (alpha * np.square(epsilon[x]-(phi*np.sqrt(variance[x])))) RuntimeWarning: invalid value encountered in double_scalars epsilon[x] = (val - (rate + (lambda1 * variance[x]))) / np.sqrt(variance[x])
解决建议
- 修复未定义变量
rate:代码中rate变量未声明,这是引发数值异常的核心原因之一。需替换为实际的日度无风险利率(年化利率除以交易日数),若模型无需该项则直接删除。 - 调整参数初始值与边界:
- Heston-Nandi参数有明确经济含义,不能统一设为(0,1):
B(持续性参数)应接近1,初始值设为0.95,边界设为(0.8, 0.999);alpha(方差冲击系数)量级极小,初始值设为1e-6,边界设为(1e-8, 1e-3);w(长期方差项)对应合理的长期方差水平,初始值设为1e-5,边界设为(1e-6, 1e-2);phi和lambda1初始值调整为0.1,边界可设为(0, 2)。
- Heston-Nandi参数有明确经济含义,不能统一设为(0,1):
- 添加数值稳定性保护:
- 计算平方根前确保方差大于极小值,避免除以0或无效开方:
sqrt_var = np.sqrt(max(variance[x], 1e-10)) epsilon[x] = (val - (rate + lambda1 * variance[x])) / sqrt_var - 限制方差最大值,防止溢出:
variance[x+1] = w + B * variance[x] + alpha * np.square(epsilon[x] - phi * sqrt_var) variance[x+1] = min(variance[x+1], 1e3) # 截断过大的方差值
- 计算平方根前确保方差大于极小值,避免除以0或无效开方:
- 优化求解器配置:
- 显式指定支持边界的
L-BFGS-B求解器,调整迭代次数与收敛阈值:result = minimize(log_likelihood, initial_parameters, args=(returnarr,), bounds=bounds, method='L-BFGS-B', options={'maxiter': 1000, 'ftol': 1e-8})
- 显式指定支持边界的
- 过滤无效参数组合:在似然函数末尾添加判断,若计算结果为NaN/inf则返回极大值,跳过无效参数:
if np.isnan(log_likelihood_on_return) or np.isinf(log_likelihood_on_return): return 1e10 return log_likelihood_on_return
内容的提问来源于stack exchange,提问作者Ranit Bagchi
相关产品推荐
相关产品推荐

