|
From: Peter C. <pca...@gm...> - 2019-12-30 20:54:43
|
Hi Goutham,
the issue in your example is that you use an Euribor 6M index in conjunction with the India() calendar to build the swap helpers: 26th December 2019 is a fixing (Target) holiday for Euribor but it is a business day w.r.t. the India() calendar. In the current code the spot date of the swap rate helper is computed using the India() calendar which then leads to a first fixing date 23th December 2019 for the helper.
I assume you use Euribor as a proxy since the proper Ibor index is not available in QuantLib. You could “extend" this workaround and use a combined Target / India calendar to set up the helper, which should avoid the past fixing date and hence the exception you see. Of course it would be much better to add the INR index to QuantLib and use that from the start.
Regards,
Peter
> On 30 Dec 2019, at 12:47, Goutham Mahesh <gou...@gm...> wrote:
>
> Hi All,
>
> The problem is arising for me only for the specific date of 24th December 2019. I wanted to figure out the error so that I can correct it later on. On the contrary, when i bootstrap the curve to receive the EUR discount factors using the calendar TARGET there is no problem. For INR, it says that EURIBOR fixing is not there on 23rd December but 23rd is a normal working day in India, whereas for the USD, the error is euribor fixing not present for 24th December 2019. I have attached the errors above in my initial email.
>
> I have attached the code here for your reference:
> from QuantLib import *
> import datetime
> import numpy as np
> from QuantLib import *
> import datetime
> import numpy as np
>
>
>
> # global data
> # Here enter the Yield Curve reference Data
> #calendar = TARGET()
> calendar = India()
> #calendar = UnitedStates()
> fixedLegDayCounter = Actual360()
> libor_type = Euribor6M()
> fixedLegFrequency = Quarterly
> fixedLegTenor = Period(6,Months)
> floatingLegAdjustment = Quarterly
> floatingLegTenor = Period(6,Months)
> dayCounter = Actual360()
> todaysDate = Date(24,December,2019);
> #Settings.instance().evaluationDate = todaysDate
> Settings.instance().evaluationDate = todaysDate
> settlementDate = Date(27,December,2019);
>
> # market quotes
> # Update deposit Rates ( usual source will be LIBOR Fixings on the Curve Date
> deposits = {
> (1,Months): 0.018,
> (2,Months): 0.0183,
> (3,Months): 0.0189,
> (4,Months): 0.0189,
> (5,Months): 0.0189,
> (6,Months): 0.019,
> (7,Months): 0.019,
> (8,Months): 0.0191,
> (9,Months): 0.0192,
> (10,Months): 0.0192,
> (11,Months): 0.0192,
> (12,Months): 0.0193
> }
>
>
> swaps = { (24,Months): 0.0167,
> (36,Months): 0.0164,
> (48,Months): 0.0164,
> (60,Months): 0.0166,
> (72,Months): 0.0168,
> (84,Months): 0.017,
> (96,Months): 0.0173,
> (108,Months): 0.0176,
> (120,Months): 0.0179}
>
> # convert them to Quote objects
> for n,unit in deposits.keys():
> deposits[(n,unit)] = SimpleQuote(deposits[(n,unit)])
>
> for n,unit in swaps.keys():
> swaps[(n,unit)] = SimpleQuote(swaps[(n,unit)])
>
> # build rate helpers
>
> dayCounter = Actual360()
> settlementDays = 2
> depositHelpers = [ DepositRateHelper(QuoteHandle(deposits[(n,unit)]),
> Period(n,unit), settlementDays,
> calendar, ModifiedFollowing,
> False, dayCounter)
> for n, unit in deposits.keys()]
>
> dayCounter = Actual360()
> months = 3
>
>
> settlementDays = 2
> fixedLegFrequency = Semiannual
> fixedLegTenor = Period(6,Months)
> fixedLegAdjustment = Unadjusted
> #fixedLegDayCounter = Thirty360()
> floatingLegFrequency = Quarterly
> floatingLegTenor = Period(3,Months)
> floatingLegAdjustment = ModifiedFollowing
> swapHelpers = [ SwapRateHelper(QuoteHandle(swaps[(n,unit)]),
> Period(n,unit), calendar,
> fixedLegFrequency, fixedLegAdjustment,
> fixedLegDayCounter, Euribor6M())
> for n, unit in swaps.keys() ]
>
> # term structure handles
>
> discountTermStructure = RelinkableYieldTermStructureHandle()
> forecastTermStructure = RelinkableYieldTermStructureHandle()
>
> # term-structure construction
>
> helpers = depositHelpers + swapHelpers
> depoFuturesSwapCurve = PiecewiseFlatForward(settlementDate, helpers,
> Actual360())
> print("",depoFuturesSwapCurve.dates())
> for c in depoFuturesSwapCurve.dates():
> print("", depoFuturesSwapCurve.discount(c))
>
>
>
> This is not the code that is running on the main system but a simple hardcoded version in which i have assigned some arbitrary inputs for the rates.
>
> Thank You,
> Best,
> Goutham
>
> On Sat, Dec 28, 2019 at 1:43 AM Peter Caspers <pca...@gm... <mailto:pca...@gm...>> wrote:
> Hi Mike,
>
> thanks. So yes, I suppose in this case we would set up a swap helper like this
>
>
> #include <ql/cashflows/iborcoupon.hpp>
> #include <ql/indexes/ibor/usdlibor.hpp>
> #include <ql/termstructures/yield/ratehelpers.hpp>
> #include <ql/time/daycounters/thirty360.hpp>
>
> #include <iostream>
>
> using namespace QuantLib;
>
> int main() {
>
> auto usd3m = boost::make_shared<USDLibor>(3 * Months);
>
> SwapRateHelper h(Handle<Quote>(boost::make_shared<SimpleQuote>(0.01)), 10 * Years, usd3m->jointCalendar(),
> Semiannual, ModifiedFollowing, Thirty360(), usd3m);
>
> std::cout << "swap start date = " << h.swap()->startDate() << std::endl;
> std::cout << "first fixing date = "
> << boost::static_pointer_cast<IborCoupon>(h.swap()->floatingLeg().front())->fixingDate() << std::endl;
> }
>
>
> which yields
>
> swap start date = December 31st, 2019
> first fixing date = December 27th, 2019
>
> contrary to what you say below, i.e. in this case we should not adjust the reference date for the swap rate helper and change makevanillaswap.cpp as follows
>
> modified ql/instruments/makevanillaswap.cpp
> @@ -70,9 +70,7 @@ namespace QuantLib {
> else {
> Date refDate = Settings::instance().evaluationDate();
> - // if the evaluation date is not a business day
> - // then move to the next business day
> - refDate = floatCalendar_.adjust(refDate);
>
> which then gives the correct result:
>
> swap start date = December 30th, 2019
> first fixing date = December 24th, 2019
>
> Would you agree?
>
> I wonder if there is a use case for the reference date adjustment at all. For example, if we are on a TARGET holiday that is not (say) a US holiday I suppose there are still Euribor3M swaps traded on that day and the spot and fixing date calculation would be along the lines as in the example above?
>
> Thank you
> Peter
>
>> On 27 Dec 2019, at 18:20, Mike DelMedico <mik...@gm... <mailto:mik...@gm...>> wrote:
>>
>> Peter, 12/26/2019 might be a good test for the logic. In USD the market is open even though it’s a fixing holiday in the UK (Boxing Day). Spot date is 12/30/2019 for that trade date, and the fixing used for the first 3mL period is the one from 12/24/2019. Is that the kind of example you are looking for?
>>
>> -Mike
>>
>> On Fri, Dec 27, 2019 at 11:07 Peter Caspers <pca...@gm... <mailto:pca...@gm...>> wrote:
>> Hi Goutham,
>>
>> can I ask which version of QL you are using and of which kind of rate helper (Deposit, Swap, …) is failing for you? A while back a change was introduced that would adjust the reference date (i.e. the “trade date”) of the helpers to a business day w.r.t. the instrument’s index fixing calendar. The aim was to avoid situations like the below where a past fixing is required for curve bootstrapping, so it would be interesting to see whether you have a case where this does not work as expected.
>>
>> On another note, I’d be interested in reviewing this logic again, since I am not sure that this corresponds to actual market practice? What I heard from a trader is that at least for specific swaps a) you can trade them on fixing holidays and b) the start date is calculated from the trade date which results in a first float period with a fixing date before the horizon date (i.e. exactly what QL did before the “fix”). I’d need to confirm this more systematically, but maybe someone on the list knows about this in more detail?
>>
>> If you are using an older version of QL where the reference date adjustment was not yet applied the appropriate fix would be to just provide the missing historical fixing from the error message.
>>
>> Best Regards,
>> Peter
>>
>>> On 27 Dec 2019, at 11:41, David Duarte <nh...@gm... <mailto:nh...@gm...>> wrote:
>>>
>>> Goutham,
>>>
>>> Why are you using the Euribor6M Index for an instrument in INR?
>>>
>>> There are some indexes with predefined conventions but you can define your own. Here is an example to try to make this clear.
>>> I am checking the properties of some predefined indexes and in the last case I am creating my own (I don't know the conventions for indian rupee indexes).
>>>
>>> import QuantLib as ql
>>> import pandas as pd
>>> index_data = []
>>> indexes = [
>>> ql.Euribor6M(),
>>> ql.Euribor3M(),
>>> ql.USDLibor(ql.Period('6M')),
>>> ql.USDLiborON(),
>>> ql.Libor('MyIndex', ql.Period('6M'), 2, ql.INRCurrency(), ql.India(), ql.Actual360())
>>> ]
>>> properties = ['familyName', 'currency', 'dayCounter', 'tenor', 'endOfMonth', 'fixingCalendar', 'fixingDays']
>>> for index in indexes:
>>> index_data.append({prop: eval(f"index.{prop}()") for prop in properties})
>>> pd.DataFrame(index_data)
>>>
>>>
>>> In your particular case, if you are using Euribor6M as the index which has the TARGET fixing calendar, you can check for the holidays in December with this snippet:
>>>
>>> calendar = ql.TARGET()
>>> calendar.holidayList(ql.TARGET(), ql.Date(1,12,2019), ql.Date(31,12,2019))
>>>
>>>
>>> which would show >>>> (Date(25,12,2019), Date(26,12,2019))
>>>
>>> So if you have a swap starting 27.12.2019 with this calendar, it would expect a fixing on the 23.12.2019 for an index with 2 settlementdays .
>>>
>>>
>>>
>>>
>>>
>>> On Fri, 27 Dec 2019 at 05:40, Goutham Mahesh <gou...@gm... <mailto:gou...@gm...>> wrote:
>>> Dear David,
>>>
>>> So the thing is 23rd is not a holiday here in India and I am still receiving the error. When i use the United States calendar, the same error is coming except for one difference: Euribor 3M fixing is not there for 24th December. Don't know why this error is coming, as both of these dates in India and the US the markets were open. Would be good to hear back from you, if you want some more information i can attach parts of the code.
>>>
>>> Thank You,
>>> Best,
>>> Goutham
>>>
>>> On Thu, Dec 26, 2019 at 8:28 PM David Duarte <nh...@gm... <mailto:nh...@gm...>> wrote:
>>> Hi,
>>>
>>> Seem like QuantLib is expecting one of your instruments (looks like 2y swap) to have a Euribor6M fixing on the 23rd of December.
>>> You should check your calendars because if start date is 27.12 and you have holidays on the 24th and 25th of Dec, then the fixing would be 23.
>>>
>>> If you manually add the fixing, the error would probably go away
>>>
>>> index.addFixing(ql.Date(23, 12, 2019), -0.00339)
>>>
>>> but I don't think that is what you want because since you are bootstrapping INR and USD you should use another index with the appropriate calendars.
>>>
>>> Hope that helps
>>>
>>> On Thu, 26 Dec 2019 at 12:23, Goutham Mahesh <gou...@gm... <mailto:gou...@gm...>> wrote:
>>> Hi,
>>>
>>> So I am calculating discount factors for INR and USD using bootstrapping. My code has been working fine so far and is giving me discount actors for all previous dates. But specifically for the date of 24th December 2019, I am receiving the following error:
>>>
>>> Traceback (most recent call last):
>>> File "discount_factor_hardcode_test.py", line 101, in <module>
>>> print("",depoFuturesSwapCurve.dates())
>>> File "/usr/local/lib/python3.5/dist-packages/QuantLib_Python-1.15-py3.5-linux-x86_64.egg/QuantLib/QuantLib.py", line 20084, in dates
>>> return _QuantLib.PiecewiseFlatForward_dates(self)
>>> RuntimeError: 1st iteration: failed at 3rd alive instrument, pillar December 27th, 2021, maturity December 27th, 2021, reference date December 27th, 2019: 2nd leg: Missing Euribor6M Actual/360 fixing for December 23rd, 2019
>>>
>>> Can someone help me with this as I am lost and have no clue how to fix it.
>>>
>>> Thank You,
>>> Best,
>>> Goutham
>>> _______________________________________________
>>> QuantLib-users mailing list
>>> Qua...@li... <mailto:Qua...@li...>
>>> https://lists.sourceforge.net/lists/listinfo/quantlib-users <https://lists.sourceforge.net/lists/listinfo/quantlib-users>
>>> _______________________________________________
>>> QuantLib-users mailing list
>>> Qua...@li... <mailto:Qua...@li...>
>>> https://lists.sourceforge.net/lists/listinfo/quantlib-users <https://lists.sourceforge.net/lists/listinfo/quantlib-users>
>>
>> _______________________________________________
>> QuantLib-users mailing list
>> Qua...@li... <mailto:Qua...@li...>
>> https://lists.sourceforge.net/lists/listinfo/quantlib-users <https://lists.sourceforge.net/lists/listinfo/quantlib-users>
>
|