Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

paolodelia99
Copy link
Contributor

Partially solving #2201 by adding const notional xccy swaps classes from ORE and readapting them to the current QuantLib version. MTM xccy swap will be added in another PR.

Classes added:

  • CrossCcySwap: base class for a cross currency swap
  • CrossCcyFixFloatSwap: cross currency swap with a fixed leg and a floating leg
  • CrossCcyBasisSwap: cross currency swap with two floating legs
  • CrossCcySwapEngine: the cross currency swap engine

@coveralls
Copy link

Coverage Status

coverage: 73.854% (+0.04%) from 73.814%
when pulling 9c82a36 on paolodelia99:feature/const-notional-xccy
into 4460bb6 on lballabio:master.

@lballabio
Copy link
Owner

@pcaspers — I'm assuming you're still ok with moving things here from ORE, give me a shout if things changed. Thanks!

Comment on lines +68 to +75
// Pay leg notional exchange at start.
Date initialPayDate = paySchedule_.dates().front();
ext::shared_ptr<CashFlow> initialPayCF(new SimpleCashFlow(-payNominal_, initialPayDate));
legs_[0].insert(legs_[0].begin(), initialPayCF);
// Pay leg notional exchange at end.
Date finalPayDate = paySchedule_.dates().back();
ext::shared_ptr<CashFlow> finalPayCF(new SimpleCashFlow(payNominal_, finalPayDate));
legs_[0].push_back(finalPayCF);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This means that this models only the const-notional swap, right? If so, it should probably be in the name of the class. The same goes for the other classes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the mtm crossccy in ORE are named crossccy<type_of_crossccy>mtmresetswap, while the const-notionals are named crossccy<type_of_crossccy>swap. Would you prefer crossccy<type_of_crossccy>constnotionalswap as naming convention for const-notional xccy?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok for me.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pcaspers, would changing the class name be a problem?

\warning The notional amounts, payment schedules, and other details of each leg must be
set up in the provided Leg objects before constructing the swap.
*/
CrossCcySwap(const std::vector<Leg>& legs, const std::vector<bool>& payer, const std::vector<Currency>& currencies);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really want an arbitrary number of legs here and the complexity that follows? @pcaspers, did you ever have a use for this in the past?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not that I know of, but we might break our processing if we restrict the class to 2 legs now. What kind of increased complexity do you have in mind?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just that you have to loop over the legs, no big deal. Ok to have a vector.

Comment on lines 29 to 30
CrossCcySwapEngine::CrossCcySwapEngine(const Currency& ccy1, const Handle<YieldTermStructure>& currency1Discountcurve,
const Currency& ccy2, const Handle<YieldTermStructure>& currency2Discountcurve,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any better name for instead of currency1/currency2? Domestic/foreign? Base/other? Main/other? @pcaspers, was there any reason you picked 1 and 2?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Domestic / Foreign is in line with the expected fx spot quote and better than 1 and 2 in my opnion.

registerWith(spotFX_);
}

void CrossCcySwapEngine::calculate() const {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should work for both const-notional and mark-to-market, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, to be sure you can just check the following test

@pcaspers
Copy link
Contributor

@pcaspers — I'm assuming you're still ok with moving things here from ORE, give me a shout if things changed. Thanks!

We are ok with that. My only ask would be to keep ORE aligned, i.e. remove the classes from ORE and make sure ORE still works with the ql version.

@paolodelia99
Copy link
Contributor Author

@pcaspers - One thing, in the CrossCcyBasisSwap class I haven't included the case when one of the of the legs are averaged ON indexes (recIsAveraged and payIsAveraged have been deleted from the constructors arguments). Should I also include those cases in the CrossCcyBasisSwap class?

@pcaspers
Copy link
Contributor

@pcaspers - One thing, in the CrossCcyBasisSwap class I haven't included the case when one of the of the legs are averaged ON indexes (recIsAveraged and payIsAveraged have been deleted from the constructors arguments). Should I also include those cases in the CrossCcyBasisSwap class?

Yes please, CrossCcyBasisSwap is supposed to support overnight legs. I ddn't check this PR in detail, but as I said above, I would appreciate if all functionality is preserved and a corresponding PR is opened for ORE that allows to remove the migrated classes in ORE and rely on the then-ql classes.

@lballabio
Copy link
Owner

Yes please, CrossCcyBasisSwap is supposed to support overnight legs

Agreed — but should we use bools like recIsAveraged or autodetect overnight indexes based on the class? I think we started doing the latter of late and it might be more convenient.

@paolodelia99
Copy link
Contributor Author

Another thing @pcaspers, I see that in ORE you are using a different OvernightLeg than in QuantLib (with a bunch of other additional methods like withCaps, withFloors, withNakedOptions, ...), on top of that AverageONLeg is not present in QuantLib but you have two different pricers for AverageONIndex pricers in ORE and QuantLib, AverageONIndexedCouponPricer in ORE and ArithmeticAverageOvernightIndexCouponPricer in QuantLib. Don't know If they are meant to price the same type (they are both using the Takada approximation) of copouns since the one in QuantLib can also take into account covexity adjustements.

How should I tackle this problem?

@lballabio seeking you guidance as well

@lballabio
Copy link
Owner

Another thing @pcaspers, I see that in ORE you are using a different OvernightLeg than in QuantLib (with a bunch of other additional methods like withCaps, withFloors, withNakedOptions, ...), on top of that AverageONLeg is not present in QuantLib but you have two different pricers for AverageONIndex pricers in ORE and QuantLib, AverageONIndexedCouponPricer in ORE and ArithmeticAverageOvernightIndexCouponPricer in QuantLib. Don't know If they are meant to price the same type (they are both using the Takada approximation) of copouns since the one in QuantLib can also take into account covexity adjustements.

Hmm, if that's the case it's probably better to make another PR first that sorts out the overnight leg and pricers. @pcaspers, do you happen to have a summary of the differences?

@pcaspers
Copy link
Contributor

pcaspers commented Aug 2, 2025

Ah yes, ORE and QuantLib diverged for the on coupons a while ago. I'd think they have roughly the same functional scope. QuantLib is more elegant. ORE might have some extensions like a freely definable rate computation period.

Also, ORE adds cap / floors on overnight coupons.

It would be great if someone could work on aligning QuantLib and ORE in this regard. It's on our roadmap for a while, but we never came around to actually do this.

And yes, we probably better do this before migrating dependent classes like the xccy swap.

@paolodelia99
Copy link
Contributor Author

All right, make sense to work on the copouns differences before introducing these new classes.

I'll try to work on it, since I've already spotted some of the differences.

I'll ping you guys (@lballabio, @pcaspers) if I need any help with that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants