Python
在 Quantlib Python 中使用 RateHelper(引導)和加速
我想知道是否有可能使用 ratehelpers/bootstrapping 以某種方式加速我的腳本。我每天都在創建一個新的 ratehelper。有沒有辦法只建立一次ratehelper然後每天引導?如果是的話,一個例子會是什麼樣子?
更新:
我的數據:
fact_date product_type fra_start_period maturity tenor quote currency 2015-02-09 Deposit 0D 1D 0.081 JPY 2015-02-09 OIS 1W 0.0713 JPY 2015-02-09 OIS 3W 0.0663 JPY 2015-02-09 OIS 1M 0.0656 JPY 2015-02-09 OIS 2M 0.0613 JPY 2015-02-09 OIS 3M 0.06 JPY 2015-02-09 OIS 10M 0.05 JPY 2015-02-09 OIS 12M 0.0494 JPY 2015-02-09 OIS 5Y 0.1563 JPY 2015-02-09 OIS 6Y 0.2025 JPY 2015-02-09 OIS 7Y 0.2481 JPY 2015-02-09 OIS 10Y 0.3806 JPY 2015-02-09 OIS 15Y 0.6888 JPY 2015-02-09 OIS 20Y 0.965 JPY 2015-02-09 OIS 25Y 1.1081 JPY 2015-02-09 OIS 30Y 1.1831 JPY 2015-02-10 Deposit 0D 1D 0.074 JPY 2015-02-10 OIS 1W 0.0725 JPY 2015-02-10 OIS 3W 0.0688 JPY 2015-02-10 OIS 1M 0.0681 JPY 2015-02-10 OIS 2M 0.0625 JPY 2015-02-10 OIS 3M 0.0606 JPY 2015-02-10 OIS 10M 0.0531 JPY 2015-02-10 OIS 12M 0.0525 JPY 2015-02-10 OIS 5Y 0.1719 JPY 2015-02-10 OIS 6Y 0.2244 JPY 2015-02-10 OIS 7Y 0.2744 JPY 2015-02-10 OIS 10Y 0.4169 JPY 2015-02-10 OIS 15Y 0.7269 JPY 2015-02-10 OIS 20Y 1.0044 JPY 2015-02-10 OIS 25Y 1.1475 JPY 2015-02-10 OIS 30Y 1.2225 JPY
我的程式碼:
import QuantLib as ql import pandas as pd import datetime as dt def Convert(Period): unit =[] if Period[-1:] == 'D': unit = ql.Days elif Period[-1:] == 'M': unit = ql.Months elif Period[-1:] == 'W': unit = ql.Weeks elif Period[-1:] == 'Y': unit = ql.Years period_object = ql.Period(int(Period[:-1]), unit) return period_object def qlStr2periodNumber(Period): if Period[-1:] == "D": period_unit = int(Period[:1]) elif Period[-1:] == 'M': period_unit = int(Period[:1]) elif Period[-1:] == 'W': period_unit = int(Period[:1]) elif Period[-1:] == 'Y': period_unit = int(Period[:1]) elif Period == '': period_unit = int(0) else: raise Exception('(qlStr2periodNumber) Period'+ Period + 'not recognized!') return period_unit def Datetime2ql(date): dates = ql.DateParser.parseFormatted(date,'%Y-%m-%d') return dates def ql2Datetime(date): dates = dt.datetime(date.year(), date.month(), date.dayOfMonth()) return dates Index_OIS = ql.OvernightIndex("Tonar", 2, ql.JPYCurrency(), ql.Japan(), ql.Actual365Fixed()) data = pd.read_csv('C:/Book1.csv').fillna('') quote_map = {} helpers = [] for product_type, fra_start_period, maturity, quote in zip(data.product_type, data.fra_start_period, data.maturity, data.quote): quotes = ql.SimpleQuote(quote/100) if product_type == 'Deposit': helper = ql.DepositRateHelper(ql.QuoteHandle(quotes), ql.Period(2,ql.Days), qlStr2periodNumber(fra_start_period), ql.Japan(), ql.ModifiedFollowing, False, ql.Actual365Fixed() ) elif product_type == 'OIS': helper = ql.OISRateHelper(2, Convert(maturity), ql.QuoteHandle(quotes), Index_OIS) helpers.append(helper) quote_map[(product_type,fra_start_period,maturity)] = quotes curve = ql.PiecewiseCubicZero(0, ql.Japan(), helpers, ql.Actual365Fixed()) for current_date in zip(data.fact_date): time = current_date[0] ql.Settings.instance().evaluationDate = Datetime2ql(str(time)) for row in data: quote_map[(product_type, fra_start_period, maturity, quote)].setValue(quote)
是的,可以減少要創建的對像數量;這是否會加快您的計算取決於創建它們所花費的時間以及實際引導所花費的時間。任何狀況之下:
- 創建費率助手時,請確保您傳遞的是報價對象而不是簡單的數字;也就是說,類似
q1 = SimpleQuote(0.0125) h1 = DepositRateHelper(QuoteHandle(q1), index)
並不是
h1 = DepositRateHelper(0.0125, index)
- 創建曲線時,不要明確指定其參考日期;相反,將其指定為從全域評估日期算起的天數(可能為 0);也就是說,類似
curve = PiecewiseFlatForward(0, UnitedStates(), helpers, day_counter)
如果您希望參考日期等於評估日期,或者
curve = PiecewiseFlatForward(2, UnitedStates(), helpers, day_counter)
如果你想讓它開始點。這樣,當評估日期發生變化時,曲線的參考日期將移動。 3. 現在你已經設置好了。當你想改變一個新的日期時,你會寫
Settings.instance().evaluationDate = new_today
對於每一個報價,
q1.setValue(new_value)
曲線將檢測變化並相應地重新計算。
在虛擬碼中,我們的想法是進行如下設置:
quote_map = {} helpers = [] for type, fra_start_date, maturity in ... # extract unique helper data quote = SimpleQuote(...) if type == 'Deposit': helper = ... else: ... helpers.append(helper) quote_map[(type,fra_start_date,maturity)] = quote curve = PiecewiseCubicZero(2, Japan(), helpers, day_counter)
然後在日期上循環:
for current_date in ... # Don't build stuff, just change date and quotes Settings.instance().evaluationDate = current_date for row in ... quote_map[(type,fra_start_date,maturity)].setValue(value) # now the curve is updated and you can use it