Более быстрое выполнение ванильных свопов в Python в Quantlib - PullRequest
0 голосов
/ 02 октября 2019

Я пытаюсь оценить Vanilla Swap в Quantlib для нескольких ccys и дат расчета по тысячам кривых для тысячи различных инструментов. Я пытаюсь найти способ, как существенно масштабировать мой код.

Я использую библиотеку 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)
...