Quantlib跨函数调用RelinkableYieldTermStructureHandle遇NameError求助
问题原因与解决方案
错误根源
- 未提前初始化全局变量:你在
bootstrap()中用global yts声明了全局变量,但如果调用getrate()前没执行bootstrap(),yts从未被定义,直接访问就会触发NameError。 - 作用域声明缺失:即使执行了
bootstrap(),getrate()里没有声明global yts,函数会默认把yts当成局部变量,同样找不到定义。
修复方案(两种选择)
方案1:修正全局变量用法(适配现有代码)
在getrate()中也声明global yts,并且确保先调用bootstrap()初始化变量:
def bootstrap(): today = ql.Date.todaysDate() ql.Settings.instance().evaluationDate = today global yts yts = ql.RelinkableYieldTermStructureHandle() estr = ql.Estr() # 补充实际的helper rates数据 helpers = [] estr_curve_c = ql.PiecewiseLogCubicDiscount(0, ql.TARGET(), helpers, ql.Actual365Fixed()) estr_curve_c.enableExtrapolation() yts.linkTo(estr_curve_c) def getrate(tenor, fwd): global yts # 声明使用全局变量yts swapEngine = ql.DiscountingSwapEngine(yts) ir_swap = ql.MakeOIS(swapTenor=ql.Period(tenor, ql.Months), fwdStart=ql.Period(fwd, ql.Months), overnightIndex=ql.Estr(yts), pricingEngine=swapEngine, fixedRate=2.0) return ir_swap.fairRate() # 必须先初始化再调用 bootstrap() print(getrate(12, 3)) # 示例调用
方案2:使用返回值传递(推荐,符合Python编码规范)
避免全局变量,让bootstrap()返回生成的yts,getrate()接收该参数作为输入:
def bootstrap(): today = ql.Date.todaysDate() ql.Settings.instance().evaluationDate = today yts = ql.RelinkableYieldTermStructureHandle() estr = ql.Estr() # 补充实际的helper rates数据 helpers = [] estr_curve_c = ql.PiecewiseLogCubicDiscount(0, ql.TARGET(), helpers, ql.Actual365Fixed()) estr_curve_c.enableExtrapolation() yts.linkTo(estr_curve_c) return yts # 返回生成的收益率曲线句柄 def getrate(yts, tenor, fwd): # 新增yts参数 swapEngine = ql.DiscountingSwapEngine(yts) ir_swap = ql.MakeOIS(swapTenor=ql.Period(tenor, ql.Months), fwdStart=ql.Period(fwd, ql.Months), overnightIndex=ql.Estr(yts), pricingEngine=swapEngine, fixedRate=2.0) return ir_swap.fairRate() # 使用方式 yield_curve = bootstrap() print(getrate(yield_curve, 12, 3)) # 传入生成的曲线句柄
说明
方案2的优势在于:
- 避免全局变量带来的作用域污染和不可预测性
- 函数职责更清晰,
bootstrap()负责生成曲线,getrate()负责计算利率,依赖关系明确 - 支持同时生成多个不同的收益率曲线,分别传入
getrate()使用
内容的提问来源于stack exchange,提问作者gghickman
相关产品推荐
相关产品推荐

