-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
allow swaptions to take OvernightIndexedSwap #1593
Conversation
I have no objections doing this. Quite the contrary, it helps reducing the diff between our fork and the official repo! |
@@ -72,6 +72,7 @@ namespace QuantLib { | |||
} | |||
|
|||
void OvernightIndexedSwap::initialize(const Schedule& schedule) { | |||
schedule_ = schedule; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be assigned in the constructor?
Regardless of where it is assigned, it should be passed by value and moved into the member variable in order to avoid a copy.
ql/instruments/swaption.hpp
Outdated
@@ -97,10 +102,13 @@ namespace QuantLib { | |||
Settlement::Method settlementMethod() const { | |||
return settlementMethod_; | |||
} | |||
Swap::Type type() const { return swap_->type(); } | |||
Swap::Type type() const { return swap_ ? swap_->type() : swapOis_->type(); } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If swapOis_
is assumed to be non-null when swap_
is null then this should probably be asserted in the constructor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is implicitly enforced by the signature. One can never pass both a vanillaswap and a overnightindexedswap to the constructor.
ql/instruments/swaption.cpp
Outdated
VanillaSwap::arguments::validate(); | ||
QL_REQUIRE(swap, "vanilla swap not set"); | ||
} | ||
if (swapOis) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean else if
?
const Leg& fixedLeg = swap.fixedLeg(); | ||
auto swap = arguments_.swap; | ||
auto swapOis = arguments_.swapOis; | ||
QL_REQUIRE(swap || swapOis, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean QL_REQUIRE((swap || swapOis) && !(swap && swapOis)
?
Hi @thrasibule, IMHO this PR looks a little bit like this anti-pattern: We are now having both E.g. what about the other pricing engines in @pcaspers: I guess in ORE you don't care about the other engines aka don't use them? Wouldn't it be better to derive an Regards Ralf |
Yes, I was thinking about reworking this somehow. I'll give it a go. |
Yes - the goal in ORE was to get it working with as little effort as possible. |
I think I'd duplicate the class so that we have a Swaption and an OvernightIndexedSwaption. Same for the Black engine. We can find later ways to factor out common code (templates, maybe? Types are different). Also, I don't think any of the other engines (besides the Black engine in this PR) will work with an OI swaption — they all use |
Yes we have adapted those as well |
The danger here being that a partial migration and / or refactoring will cause conflicts in our codebase. Not sure if this is the right way forward? |
Hmm. Yes, we probably need to look at those as well. Do you have additional engines in QuantExt too? |
Another road here would be to revisit the idea of a base type for interest rate swaps (#662). I agree that it seems janky to have two fields for the different types of swaps as in the original implementation, but it seems just as janky to have two classes of swaption which ultimately differ only in the underlying index! |
yes - also updates for CMS pricers (not sure at the moment if they are affected too) |
@pcaspers: I'm not sure I understood all of your answers concerning what has been adopted in ORE correctly. E.g. which of the engines in You have the I would expect changes for them as well to handle e.g. a Bermudan swaption which is between two call dates. The current running OIS coupon cannot be priced correctly with their current implementation, can they?! Or have I overlooked something? |
Yes, I'm liking this solution better than any of the alternatives |
No you haven't overlooked anything. We don't use |
This PR was automatically marked as stale because it has been open 60 days with no activity. Remove stale label or comment, or this will be closed in two weeks. |
@pcaspers: I'm having another look at this. So if I get this correctly: Is that right? |
@lballabio yes that sounds right. |
@lballabio that would be nice. However since we have a release end of September I am going to look into this in October or possibly even later. I.e. I don't want to hold things up! |
Sure! |
So in ORE we are moving in a slightly different direction now: In general we need to support swaptions with European, Bermudan, American exercise right on overnight, Ibor, BMA/SIFMA, Subperiod coupons. For Bermudan / American swaptions we are using the MultiLegOption instrument https://github.com/OpenSourceRisk/Engine/blob/master/QuantExt/qle/instruments/multilegoption.hpp for a while now already, in conjunction with numerical integration / finite-difference and MC engines. Only the European case still used QuantLib::Swaption and NonStandardSwaption and the corresponding Black pricing engine. I am now working on adapting the Black engine to MultiLegOption and generalizing it to the remaining coupon types, so that all cases can be uniformly represented by MultiLegOption and our existing numerical engines can also be applied to the European case. SwaptionHelper is still on Swaption and the QL Black engine. We might move to the new Black engine there too. Long story short, this development here has no high priority for us at the moment. Of course I'd be happy to migrate our approach to QuantLib, but I appreciate that this would be too disruptive (correct me if I am wrong!), so that we'll probably just keep the variants in parallel. |
What do you think of the current PR? This is a natural extension of ##1789. I don't think it breaks anything, and it allows to price OIS european swaptions using the Black engine, which is better than the status quo. |
I still have to find some time to look at the new changes, but yes, I'd try to get it into next release. |
Real shift = 0.0); | ||
Real shift = 0.0, | ||
Natural settlementDays = Null<Size>(), | ||
RateAveraging::Type averagingMethod = RateAveraging::Compound); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure that we want to pass the averaging method yet—the engines we can use with the swaption helper (Jamshidian etc) don't manage OIS yet and are going to treat the swaps as vanilla during calibration. This might be ok if the averaging method is compounding, because of the telescopic property, but not for arithmetic averaging. I wouldn't add the parameter yet and would hard-code the method instead.
I'm not fully convinced by the approach yet.
I am still in favor of doing it the hard but consistent way to have a class like |
|
A separate |
I started separating |
This definitely less invasive. I've done the whole hierarchy here: thrasibule@038a30b (with almost the same makeSwap method). The only advantage is if we want to pass additional parameters to overnightindexed swaption like averaging method. |
closes #1588 I don't want to take any credit this for this code. This is cherry picked from https://github.com/OpenSourceRisk/QuantLib. @pcaspers mentionned before that he would be willing to contribute this to QuantLib, see #1379 (comment)