Python实现Heston模型积分报错:仅大小为1数组可转为Python标量
Heston模型多行DataFrame积分报错解决方案
问题现象
实现Heston期权定价模型时,传入单行DataFrame能正常计算,但传入多行DataFrame时,在积分计算P1的代码行触发报错:
TypeError: only size-1 arrays can be converted to Python scalars
核心原因
- 变量维度不匹配:
heston_integrand函数中直接引用整个DataFrame的列(如df['[STRIKE]']),这些变量是数组而非标量。当lambda函数内部执行np.log(K)等运算时会生成数组,但scipy.integrate.quad要求被积函数接收标量输入并返回标量,数组运算直接触发类型错误。 - 冗余无效传参:循环生成被积函数时传入的
phi_values在heston_integrand中未被使用,属于无效参数。 - 期权价格计算逻辑错误:最终计算
C时使用的是最后一次循环的P1和P2,而非每行对应的结果,导致结果完全错误。
修复后的完整代码
import numpy as np from scipy.integrate import quad # 假设你已经实现了heston_char函数 def heston_char(St, v0, t, r, kappa_theta, eta, kappa, rho, sigma, phi): # 替换为你的特征函数实际实现 return np.exp(1j * phi * np.log(St)) def heston_price(df, v_0, theta, sigma, rho, kappa): results = [] for index, row in df.iterrows(): # 提取当前行的标量参数 St = row['[UNDERLYING_LAST]'] K = row['[STRIKE]'] r = row['[DTB3]'] t = row['[DTE]'] / 252 # 转换为年化时间 # 获取当前行对应的被积函数 integrand1, integrand2 = heston_integrand(St, K, r, t, v_0, theta, sigma, rho, kappa) # 计算积分得到P1和P2 P1 = 0.5 + (1/np.pi) * quad(integrand1, 0, 100)[0] P2 = 0.5 + (1/np.pi) * quad(integrand2, 0, 100)[0] # 计算当前行的期权价格 C = St * P1 - K * np.exp(-r * t) * P2 results.append(C) # 返回与原DataFrame行数匹配的结果列表 return results def heston_integrand(St, K, r, t, v_0, theta, sigma, rho, kappa): # 被积函数接收标量phi,所有参数均为标量 integrand1 = lambda phi: np.real(np.exp(-1j * phi * np.log(K)) * heston_char(St, v_0, t, r, kappa * theta, 0.5, kappa - rho * sigma, rho, sigma, phi) / (1j * phi)) integrand2 = lambda phi: np.real(np.exp(-1j * phi * np.log(K)) * heston_char(St, v_0, t, r, kappa * theta, -0.5, kappa, rho, sigma, phi) / (1j * phi)) return integrand1, integrand2
关键修改点
- 参数传递调整:将
heston_integrand的输入从整个DataFrame改为当前行的标量值,确保所有运算都是标量级别的,符合quad的要求。 - 移除无效代码:删除了未使用的
phi_values变量,避免混淆。 - 结果收集逻辑修正:每行计算完成后立即生成对应期权价格并存入结果列表,最终返回完整的结果集合,与原DataFrame的每行一一对应。
内容的提问来源于stack exchange,提问作者Kazuhira Miller
相关产品推荐
相关产品推荐

