You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于债券数据拟合Vasicek模型参数?现有代码结果异常求修正

Vasicek模型债券拟合问题排查与修复

核心错误点

  • 数据映射错误:你提供的期限数组years长度为6,价格数组pric长度为7,且首元素设为0不符合金融逻辑:零息债券0时刻到期价格应为面值1,且价格和期限需要一一对应。
  • 模型输入错误:Vasicek是短期利率模型,输入变量应为即期利率,你直接把债券价格当作利率r代入模型计算,完全不符合模型定义。
  • 离散化逻辑错误:Vasicek的SDE离散形式需要考虑时间间隔Δt,你忽略了非均匀期限的间隔差异,也没有使用正确的转移分布公式,仅用简单差分计算误差项。
  • 优化逻辑错误:你构造的对数似然函数需要最大化,但你使用了least_squares最小二乘优化器,且初始参数[10,10,10]远超出合理范围,导致优化结果偏离正确值。

正确实现方案

实现步骤

  1. 从债券价格计算对应期限的即期利率
  2. 计算相邻期限的时间间隔Δt
  3. 基于Vasicek精确离散形式的正态转移分布构造对数似然函数
  4. 带参数约束最小化负对数似然求解最优参数

完整代码

import numpy as np
import scipy.optimize as opt

# 数据预处理:修正价格与期限对应关系
years = np.array([1, 2, 3, 4, 7, 10])
# 去掉原价格数组的错误首元素0,对应6个期限的债券价格
bond_prices = np.array([.93, .85, .78, .65, .55, .42])
# 零息债券即期利率计算公式:r(T) = -ln(P(T))/T
r = -np.log(bond_prices) / years
# 计算相邻观测的时间间隔
dt = np.diff(years)
r_prev = r[:-1]
r_next = r[1:]

def neg_log_likelihood(params):
    a, b, sigma = params
    # 避免参数为负导致计算异常
    if a <= 1e-6 or sigma <= 1e-6:
        return 1e10
    # Vasicek精确转移分布的均值和方差
    exp_a_dt = np.exp(-a * dt)
    mean = r_prev * exp_a_dt + b * (1 - exp_a_dt)
    var = sigma**2 * (1 - np.exp(-2*a*dt)) / (2*a)
    # 计算对数似然,忽略不影响优化结果的常数项
    ll = -0.5 * np.sum(np.log(var) + (r_next - mean)**2 / var)
    # 返回负对数似然用于最小化
    return -ll

# 合理初始参数:a=0.1(均值回复速度), b=0.05(长期利率5%), sigma=0.01(波动率1%)
init_params = [0.1, 0.05, 0.01]
# 参数约束:a>0, b>0, sigma>0
bounds = [(1e-6, None), (1e-6, None), (1e-6, None)]
# 优化求解
result = opt.minimize(neg_log_likelihood, init_params, bounds=bounds)

# 输出拟合结果
a_opt, b_opt, sigma_opt = result.x
print(f"拟合得到Vasicek参数:")
print(f"均值回复速度a = {a_opt:.4f}")
print(f"长期平均利率b = {b_opt:.4f}")
print(f"波动率sigma = {sigma_opt:.4f}")

内容的提问来源于stack exchange,提问作者ElonMuskofBadIdeas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 15:54:00