|
From: Jake H. <jak...@gm...> - 2023-04-13 15:32:34
|
Hello Luigi,
Thanks for the fast feedback - Yes, before discounting I am checking if the
discount handle is empty. But the point is that the exception is returned
immediately when I call the new constructor.
It is not even arriving at the calculations, it is happening immediately.
It is not even entering in the code of the constructor.
The exception is just triggered immediately.
Conversely I tested the constructor with a non-empty discounting curve and
it is working fine.
I paste here the complete code of the test, the FRA3 constructor is the new
one that is failing.
Maybe I am doing some mistakes:
#include <ql/instruments/forwardrateagreement.hpp>
#include <ql/indexes/ibor/euribor.hpp>
#include <ql/termstructures/yield/flatforward.hpp>
#include <ql/time/calendars/target.hpp>
#include <ql/time/daycounters/actual360.hpp>
#include <iostream>
using namespace QuantLib;
void printFRA(const ForwardRateAgreement& FRA) {
std::cout << "FRA payoff amount on value date: " << FRA.amount() <<
'\n';
std::cout << "FRA Business day convention: " <<
FRA.businessDayConvention() << '\n';
std::cout << "FRA calendar: " << FRA.calendar() << '\n';
std::cout << "FRA day counter: " << FRA.dayCounter() << '\n';
std::cout << "FRA fixing date: " << FRA.fixingDate() << '\n';
std::cout << "FRA forward rate: " << FRA.forwardRate() << '\n';
std::cout << "FRA rate: " << FRA.forwardRate().rate() << '\n';
std::cout << "FRA is expired: " << FRA.isExpired() << '\n';
std::cout << "FRA NPV: " << FRA.NPV() << '\n' << '\n';
}
int main() {
Rate euriborRate = 0.04;
Rate strikeForwardRate = 0.05;
Date today = Date(31, January, 2023);
Settings::instance().evaluationDate() = today;
Calendar calendar = TARGET();
BusinessDayConvention businessDayConvention = ModifiedFollowing;
bool endOfMonth = true;
bool noIndexCoupon = false;
Period tenor = Period(3, Months);
DayCounter dayCounter = Actual360();
Date valueDate = calendar.advance(today, Period(1, Months),
businessDayConvention, endOfMonth);
Date maturityDate = calendar.advance(valueDate, tenor,
businessDayConvention, endOfMonth);
Position::Type fraFwdType = Position::Long;
Real fraNotional = 100.0;
Natural fixingDays = 2;
Natural settlementDays = 0;
// simple Flat forward term structure for Euribor
Handle<YieldTermStructure> euriborTermStructure(
ext::make_shared<FlatForward>(today, euriborRate, dayCounter,
Simple, Once));
// creation of the Euribor pointer
ext::shared_ptr<IborIndex> euribor3m(new
Euribor3M(euriborTermStructure));
// empty Yield Term structure
Handle<YieldTermStructure> emptyTermStructure;
// flat forward term structure
Handle<YieldTermStructure> flatForwardTS(
ext::make_shared<FlatForward>(settlementDays, calendar,
euriborRate, dayCounter, Simple, Once));
// FRA 1x4 creation
ForwardRateAgreement FRA(valueDate,
fraFwdType,
strikeForwardRate,
fraNotional,
euribor3m);
std::cout << "FRA test the constructor taking the index and using
indexed coupon = true\n";
printFRA(FRA);
ForwardRateAgreement FRA2(valueDate,
fraFwdType,
strikeForwardRate,
fraNotional,
euribor3m,
emptyTermStructure,
noIndexCoupon);
std::cout << "FRA test the constructor taking the index and using
indexed coupon = false\n";
printFRA(FRA2);
// this is the new constructor failing, returning the exception
ForwardRateAgreement FRA3(valueDate,
maturityDate,
fraFwdType,
strikeForwardRate,
fraNotional,
flatForwardTS,
fixingDays,
businessDayConvention);
std::cout << "FRA test the new constructor taking the term structure\n";
printFRA(FRA3);
return EXIT_SUCCESS;
}
If you prefer I can just push the code of the PR and then we can look also
at the big picture.
Thanks in advance for your time and your help.
Il giorno gio 13 apr 2023 alle ore 15:55 Luigi Ballabio <
lui...@gm...> ha scritto:
> Hello Jake,
> the bit of code that does the discounting should check if the discount
> handle is empty. If it's not empty, it should use it; otherwise, it should
> fall back to using the forecasting handle instead.
>
> Luigi
>
>
> On Thu, Apr 13, 2023 at 3:11 PM Jake Heke <jak...@gm...> wrote:
>
>> Hi all,
>> I am currently working on a pull request for class ForwardRateAgreement.
>> I coded a new version of the constructor:
>>
>> ForwardRateAgreement(
>> const Date& valueDate,
>> const Date& maturityDate,
>> Position::Type type,
>> Rate strikeForwardRate,
>> Real notionalAmount,
>> Handle<YieldTermStructure> forecastCurve,
>> Natural fixingDays,
>> BusinessDayConvention businessDayConvention,
>> Handle<YieldTermStructure> discountCurve =
>> Handle<YieldTermStructure>());
>>
>> The last discountCurve it is used only if provided, otherwise the
>> forecastCurve is used also for discounting.
>> That's why I provided a default for it as discountCurve =
>> Handle<YieldTermStructure>().
>>
>> Now, before submitting the PR I am trying to test some cases of the new
>> constructor.
>> Guess what? Unsurprisingly it is not working :-)
>> If I try to create the FRA as:
>>
>> ForwardRateAgreement FRA3(valueDate,
>> maturityDate,
>> fraFwdType,
>> strikeForwardRate,
>> fraNotional,
>> flatForwardTS,
>> fixingDays,
>> businessDayConvention);
>>
>> I am getting an exception in handle.hpp which is saying "empty Handle
>> cannot be dereferenced". Here is the piece of code issuing the exception:
>> template <class T>
>> inline const ext::shared_ptr<T>& Handle<T>::operator->() const {
>> QL_REQUIRE(!empty(), "empty Handle cannot be dereferenced");
>> return link_->currentLink();
>>
>> I am getting the same exception even if I call the new constructor by
>> passing explicitly the empty discount curve:
>>
>> ForwardRateAgreement FRA3(valueDate,
>> maturityDate,
>> fraFwdType,
>> strikeForwardRate,
>> fraNotional,
>> flatForwardTS,
>> fixingDays,
>> businessDayConvention,
>> Handle<YieldTermStructure>());
>>
>> What am I missing? Thanks in advance for your help.
>> _______________________________________________
>> QuantLib-users mailing list
>> Qua...@li...
>> https://lists.sourceforge.net/lists/listinfo/quantlib-users
>>
>
|