首页 > 解决方案 > 在 Quantlib 中用 Python 更快地执行 Vanilla Swaps

问题描述

我试图在 Quantlib 中为一千种不同工具的数千条曲线上的多个 ccys 和结算日期定价 Vanilla Swap。我试图找到一种方法来从本质上扩展我的代码。

我正在使用 Python 库,并且使用多处理组件确实对性能有所帮助。由于许多曲线和交易将一次又一次地重复使用,我试图找出是否有办法禁用一些有助于提高性能的默认设置。除了单独定价掉期掉期,有没有办法聚合它们并计算 NPV,就像将它们添加到投资组合中一样?此外,我阅读了一些关于禁用观察者通知的帖子,但我看不到如何更新此设置。不确定这是否会有所帮助或导致更多问题。

我还在下面发布了一个代码片段,以防有明显的东西我可以更改以使代码运行得更快。(为简洁起见,我只保留了 2 个数据点并从下面的代码中删除了多处理组件)

import QuantLib as ql

execution_date = ql.Date(10, 9, 2019)
ql.Settings.instance().evaluationDate = execution_date
periods = ['1D', '50Y', ]
market_rates = [-0.0043, 0.002140, ]
calendar = ql.UnitedStates()
trade_count = 100
scenarios = 100
num = 0.000001

curves = []
for _ in range(scenarios):
    swap_rate_helpers = []
    for i in range(len(market_rates)):
        market_rate = market_rates[i] + num
        quote = ql.SimpleQuote(market_rate)
        helper = ql.SwapRateHelper(ql.QuoteHandle(quote),
                                   ql.Period(periods[i]),
                                   calendar,
                                   ql.Annual,
                                   ql.Unadjusted,
                                   ql.Actual360(),
                                   ql.Euribor6M()
                                   )
        swap_rate_helpers.append(helper)

    curve = ql.PiecewiseLogLinearDiscount(execution_date, swap_rate_helpers, ql.Actual360())
    curves.append(curve)
    num += 0.000001

start_date = calendar.advance(execution_date, 2, ql.Days)
end_date = calendar.advance(start_date, 30, ql.Years)

fixed_schedule = ql.Schedule(start_date, end_date, ql.Period(12, ql.Months), calendar, ql.ModifiedFollowing, ql.ModifiedFollowing, ql.DateGeneration.Forward, False)
float_schedule = ql.Schedule(start_date, end_date, ql.Period(6, ql.Months), calendar, ql.ModifiedFollowing, ql.ModifiedFollowing, ql.DateGeneration.Forward, False)

term_structure = ql.RelinkableYieldTermStructureHandle(curves[0])
float_index = ql.Euribor6M(term_structure)
swaps = []
swap_engine = ql.DiscountingSwapEngine(term_structure)
for _ in range(trade_count):
    ir_swap = ql.VanillaSwap(ql.VanillaSwap.Payer, 100000000, fixed_schedule, 0.008, ql.Actual360(), float_schedule, float_index, 0, ql.Actual360())
    ir_swap.setPricingEngine(swap_engine)
    swaps.append(ir_swap)

for curve in curves:
    term_structure.linkTo(curve)
    for swap in swaps:
        swap.NPV()

print 'Trade Count: {0}'.format(trade_count)
print 'Swaps Priced: {0}'.format(scenarios)

标签: pythonquantlib

解决方案


ObservableSettings特别是关于启用和禁用通知, C++ 类中有一些可用的方法:

QuantLib::ObservableSettings::instance().disableUpdates(true);

    // do the setup

QuantLib::ObservableSettings::instance().enableUpdates();

希望这些已经导出到 python 绑定。但是,我不完全确定这会对您的表现产生重大影响。有关这方面的功能,请参阅原始帖子 [1]。

[1] https://sourceforge.net/p/quantlib/mailman/message/31650848/


推荐阅读