Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion LICENSE.TXT
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,8 @@ Copyright (C) 2015, 2016 Andres Hernandez
Copyright (C) 2016 Nicholas Bertocchi
Copyright (C) 2016 Stefano Fondi
Copyright (C) 2016, 2017 Fabrice Lecuyer
Copyright (C) 2016, 2018, 2022 Quaternion Risk Management Ltd
Copyright (C) 2016, 2019, 2020 Eisuke Tani
Copyright (C) 2016, 2022 Quaternion Risk Management Ltd

Copyright (C) 2017 BN Algorithms Ltd
Copyright (C) 2017 Joseph Jeisman
Expand Down
8 changes: 8 additions & 0 deletions QuantLib.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -912,6 +912,9 @@
<ClInclude Include="ql\instruments\cpicapfloor.hpp" />
<ClInclude Include="ql\instruments\cpiswap.hpp" />
<ClInclude Include="ql\instruments\creditdefaultswap.hpp" />
<ClInclude Include="ql\instruments\crossccybasisswap.hpp" />
<ClInclude Include="ql\instruments\crossccyfixfloatswap.hpp" />
<ClInclude Include="ql\instruments\crossccyswap.hpp" />
<ClInclude Include="ql\instruments\dividendbarrieroption.hpp" />
<ClInclude Include="ql\instruments\dividendschedule.hpp" />
<ClInclude Include="ql\instruments\dividendvanillaoption.hpp" />
Expand Down Expand Up @@ -1580,6 +1583,7 @@
<ClInclude Include="ql\pricingengines\quanto\all.hpp" />
<ClInclude Include="ql\pricingengines\quanto\quantoengine.hpp" />
<ClInclude Include="ql\pricingengines\swap\all.hpp" />
<ClInclude Include="ql\pricingengines\swap\crossccyswapengine.hpp" />
<ClInclude Include="ql\pricingengines\swap\cvaswapengine.hpp" />
<ClInclude Include="ql\pricingengines\swap\discountingswapengine.hpp" />
<ClInclude Include="ql\pricingengines\swap\discretizedswap.hpp" />
Expand Down Expand Up @@ -2187,6 +2191,9 @@
<ClCompile Include="ql\instruments\cpicapfloor.cpp" />
<ClCompile Include="ql\instruments\cpiswap.cpp" />
<ClCompile Include="ql\instruments\creditdefaultswap.cpp" />
<ClCompile Include="ql\instruments\crossccybasisswap.cpp" />
<ClCompile Include="ql\instruments\crossccyfixfloatswap.cpp" />
<ClCompile Include="ql\instruments\crossccyswap.cpp" />
<ClCompile Include="ql\instruments\doublebarrieroption.cpp" />
<ClCompile Include="ql\instruments\doublebarriertype.cpp" />
<ClCompile Include="ql\instruments\equitytotalreturnswap.cpp" />
Expand Down Expand Up @@ -2635,6 +2642,7 @@
<ClCompile Include="ql\pricingengines\lookback\analyticcontinuouspartialfixedlookback.cpp" />
<ClCompile Include="ql\pricingengines\lookback\analyticcontinuouspartialfloatinglookback.cpp" />
<ClCompile Include="ql\pricingengines\lookback\mclookbackengine.cpp" />
<ClCompile Include="ql\pricingengines\swap\crossccyswapengine.cpp" />
<ClCompile Include="ql\pricingengines\swap\cvaswapengine.cpp" />
<ClCompile Include="ql\pricingengines\swap\discountingswapengine.cpp" />
<ClCompile Include="ql\pricingengines\swap\discretizedswap.cpp" />
Expand Down
24 changes: 24 additions & 0 deletions QuantLib.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -822,6 +822,15 @@
<ClInclude Include="ql\instruments\creditdefaultswap.hpp">
<Filter>instruments</Filter>
</ClInclude>
<ClInclude Include="ql\instruments\crossccybasisswap.hpp">
<Filter>instruments</Filter>
</ClInclude>
<ClInclude Include="ql\instruments\crossccyfixfloatswap.hpp">
<Filter>instruments</Filter>
</ClInclude>
<ClInclude Include="ql\instruments\crossccyswap.hpp">
<Filter>instruments</Filter>
</ClInclude>
<ClInclude Include="ql\instruments\dividendschedule.hpp">
<Filter>instruments</Filter>
</ClInclude>
Expand Down Expand Up @@ -2700,6 +2709,9 @@
<ClInclude Include="ql\pricingengines\swap\all.hpp">
<Filter>pricingengines\swap</Filter>
</ClInclude>
<ClInclude Include="ql\pricingengines\swap\crossccyswapengine.hpp">
<Filter>pricingengines\swap</Filter>
</ClInclude>
<ClInclude Include="ql\pricingengines\swap\cvaswapengine.hpp">
<Filter>pricingengines\swap</Filter>
</ClInclude>
Expand Down Expand Up @@ -4745,6 +4757,15 @@
<ClCompile Include="ql\instruments\creditdefaultswap.cpp">
<Filter>instruments</Filter>
</ClCompile>
<ClCompile Include="ql\instruments\crossccybasisswap.cpp">
<Filter>instruments</Filter>
</ClCompile>
<ClCompile Include="ql\instruments\crossccyfixfloatswap.cpp">
<Filter>instruments</Filter>
</ClCompile>
<ClCompile Include="ql\instruments\crossccyswap.cpp">
<Filter>instruments</Filter>
</ClCompile>
<ClCompile Include="ql\instruments\europeanoption.cpp">
<Filter>instruments</Filter>
</ClCompile>
Expand Down Expand Up @@ -5975,6 +5996,9 @@
<ClCompile Include="ql\pricingengines\bond\discretizedconvertible.cpp">
<Filter>pricingengines\bond</Filter>
</ClCompile>
<ClCompile Include="ql\pricingengines\swap\crossccyswapengine.cpp">
<Filter>pricingengines\swap</Filter>
</ClCompile>
<ClCompile Include="ql\pricingengines\swap\cvaswapengine.cpp">
<Filter>pricingengines\swap</Filter>
</ClCompile>
Expand Down
8 changes: 8 additions & 0 deletions ql/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,9 @@ set(QL_SOURCES
instruments/cpicapfloor.cpp
instruments/cpiswap.cpp
instruments/creditdefaultswap.cpp
instruments/crossccybasisswap.cpp
instruments/crossccyfixfloatswap.cpp
instruments/crossccyswap.cpp
instruments/doublebarrieroption.cpp
instruments/doublebarriertype.cpp
instruments/equitytotalreturnswap.cpp
Expand Down Expand Up @@ -723,6 +726,7 @@ set(QL_SOURCES
pricingengines/lookback/analyticcontinuouspartialfixedlookback.cpp
pricingengines/lookback/analyticcontinuouspartialfloatinglookback.cpp
pricingengines/lookback/mclookbackengine.cpp
pricingengines/swap/crossccyswapengine.cpp
pricingengines/swap/cvaswapengine.cpp
pricingengines/swap/discountingswapengine.cpp
pricingengines/swap/discretizedswap.cpp
Expand Down Expand Up @@ -1336,6 +1340,9 @@ set(QL_HEADERS
instruments/cpicapfloor.hpp
instruments/cpiswap.hpp
instruments/creditdefaultswap.hpp
instruments/crossccybasisswap.hpp
instruments/crossccyfixfloatswap.hpp
instruments/crossccyswap.hpp
instruments/dividendbarrieroption.hpp
instruments/dividendschedule.hpp
instruments/dividendvanillaoption.hpp
Expand Down Expand Up @@ -1955,6 +1962,7 @@ set(QL_HEADERS
pricingengines/mclongstaffschwartzengine.hpp
pricingengines/mcsimulation.hpp
pricingengines/quanto/quantoengine.hpp
pricingengines/swap/crossccyswapengine.hpp
pricingengines/swap/cvaswapengine.hpp
pricingengines/swap/discountingswapengine.hpp
pricingengines/swap/discretizedswap.hpp
Expand Down
6 changes: 6 additions & 0 deletions ql/instruments/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ this_include_HEADERS = \
cpicapfloor.hpp \
cpiswap.hpp \
creditdefaultswap.hpp \
crossccybasisswap.hpp \
crossccyfixfloatswap.hpp \
crossccyswap.hpp \
dividendbarrieroption.hpp \
dividendschedule.hpp \
dividendvanillaoption.hpp \
Expand Down Expand Up @@ -100,6 +103,9 @@ cpp_files = \
cpicapfloor.cpp \
cpiswap.cpp \
creditdefaultswap.cpp \
crossccybasisswap.cpp \
crossccyfixfloatswap.cpp \
crossccyswap.cpp \
doublebarrieroption.cpp \
doublebarriertype.cpp \
equitytotalreturnswap.cpp \
Expand Down
3 changes: 3 additions & 0 deletions ql/instruments/all.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
#include <ql/instruments/cpicapfloor.hpp>
#include <ql/instruments/cpiswap.hpp>
#include <ql/instruments/creditdefaultswap.hpp>
#include <ql/instruments/crossccybasisswap.hpp>
#include <ql/instruments/crossccyfixfloatswap.hpp>
#include <ql/instruments/crossccyswap.hpp>
#include <ql/instruments/dividendschedule.hpp>
#include <ql/instruments/doublebarrieroption.hpp>
#include <ql/instruments/doublebarriertype.hpp>
Expand Down
176 changes: 176 additions & 0 deletions ql/instruments/crossccybasisswap.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */

/*
Copyright (C) 2016 Quaternion Risk Management Ltd
All rights reserved.

This file is part of QuantLib, a free-software/open-source library
for financial quantitative analysts and developers - http://quantlib.org/

QuantLib is free software: you can redistribute it and/or modify it
under the terms of the QuantLib license. You should have received a
copy of the license along with this program; if not, please email
<[email protected]>. The license is also available online at
<http://quantlib.org/license.shtml>.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the license for more details.
*/

#include <ql/cashflows/iborcoupon.hpp>
#include <ql/cashflows/simplecashflow.hpp>
#include <ql/cashflows/overnightindexedcoupon.hpp>
#include <ql/instruments/crossccybasisswap.hpp>

namespace QuantLib {

CrossCcyBasisSwap::CrossCcyBasisSwap(Real payNominal, const Currency& payCurrency, const Schedule& paySchedule,
const ext::shared_ptr<IborIndex>& payIndex, Spread paySpread, Real payGearing,
Real recNominal, const Currency& recCurrency, const Schedule& recSchedule,
const ext::shared_ptr<IborIndex>& recIndex, Spread recSpread, Real recGearing,
Size payPaymentLag, Size recPaymentLag, ext::optional<bool> payIncludeSpread,
ext::optional<Natural> payLookbackDays, ext::optional<bool> recIncludeSpread,
ext::optional<Natural> recLookbackDays, const bool telescopicValueDates)
: CrossCcySwap(2), payNominal_(payNominal), payCurrency_(payCurrency), paySchedule_(paySchedule),
payIndex_(payIndex), paySpread_(paySpread), payGearing_(payGearing), recNominal_(recNominal),
recCurrency_(recCurrency), recSchedule_(recSchedule), recIndex_(recIndex), recSpread_(recSpread),
recGearing_(recGearing), payPaymentLag_(payPaymentLag), recPaymentLag_(recPaymentLag),
payIncludeSpread_(payIncludeSpread), payLookbackDays_(payLookbackDays), recIncludeSpread_(recIncludeSpread),
recLookbackDays_(recLookbackDays), telescopicValueDates_(telescopicValueDates) {
registerWith(payIndex_);
registerWith(recIndex_);
initialize();
}

void CrossCcyBasisSwap::initialize() {
// Pay leg
if (auto on = ext::dynamic_pointer_cast<OvernightIndex>(payIndex_)) {
// ON leg
legs_[0] = OvernightLeg(paySchedule_, on)
.withNotionals(payNominal_)
.withSpreads(paySpread_)
.withGearings(payGearing_)
.withPaymentLag(payPaymentLag_)
.withSpreads(payIncludeSpread_ ? *payIncludeSpread_ : false)
.withLookbackDays(payLookbackDays_ ? *payLookbackDays_ : 0)
.withTelescopicValueDates(telescopicValueDates_);
} else {
// Ibor leg
legs_[0] = IborLeg(paySchedule_, payIndex_)
.withNotionals(payNominal_)
.withSpreads(paySpread_)
.withGearings(payGearing_)
.withPaymentLag(payPaymentLag_);
}
payer_[0] = -1.0;
currencies_[0] = payCurrency_;
// 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);
Comment on lines +68 to +75
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?


// Receive leg
if (auto on = ext::dynamic_pointer_cast<OvernightIndex>(recIndex_)) {
// ON leg
legs_[1] = OvernightLeg(recSchedule_, on)
.withNotionals(recNominal_)
.withSpreads(recSpread_)
.withGearings(recGearing_)
.withPaymentLag(recPaymentLag_)
.withSpreads(recIncludeSpread_ ? *recIncludeSpread_ : false)
.withLookbackDays(recLookbackDays_ ? *recLookbackDays_ : 0)
.withTelescopicValueDates(telescopicValueDates_);
} else {
// Ibor leg
legs_[1] = IborLeg(recSchedule_, recIndex_)
.withNotionals(recNominal_)
.withSpreads(recSpread_)
.withGearings(recGearing_)
.withPaymentLag(recPaymentLag_);
}
payer_[1] = +1.0;
currencies_[1] = recCurrency_;
// Receive leg notional exchange at start.
Date initialRecDate = recSchedule_.dates().front();
ext::shared_ptr<CashFlow> initialRecCF(new SimpleCashFlow(-recNominal_, initialRecDate));
legs_[1].insert(legs_[1].begin(), initialRecCF);
// Receive leg notional exchange at end.
Date finalRecDate = recSchedule_.dates().back();
ext::shared_ptr<CashFlow> finalRecCF(new SimpleCashFlow(recNominal_, finalRecDate));
legs_[1].push_back(finalRecCF);

// Register the instrument with all cashflows on each leg.
for (Size legNo = 0; legNo < 2; legNo++) {
Leg::iterator it;
for (it = legs_[legNo].begin(); it != legs_[legNo].end(); ++it) {
registerWith(*it);
}
}
}

void CrossCcyBasisSwap::setupArguments(PricingEngine::arguments* args) const {

CrossCcySwap::setupArguments(args);

CrossCcyBasisSwap::arguments* arguments = dynamic_cast<CrossCcyBasisSwap::arguments*>(args);

/* Returns here if e.g. args is CrossCcySwap::arguments which
is the case if PricingEngine is a CrossCcySwap::engine. */
if (!arguments)
return;

arguments->paySpread = paySpread_;
arguments->recSpread = recSpread_;
}

void CrossCcyBasisSwap::fetchResults(const PricingEngine::results* r) const {

CrossCcySwap::fetchResults(r);

const CrossCcyBasisSwap::results* results = dynamic_cast<const CrossCcyBasisSwap::results*>(r);
if (results) {
/* If PricingEngine::results are of type
CrossCcyBasisSwap::results */
fairPaySpread_ = results->fairPaySpread;
fairRecSpread_ = results->fairRecSpread;
} else {
/* If not, e.g. if the engine is a CrossCcySwap::engine */
fairPaySpread_ = Null<Spread>();
fairRecSpread_ = Null<Spread>();
}

/* Calculate the fair pay and receive spreads if they are null */
static Spread basisPoint = 1.0e-4;
if (fairPaySpread_ == Null<Spread>()) {
if (legBPS_[0] != Null<Real>())
fairPaySpread_ = paySpread_ - NPV_ / (legBPS_[0] / basisPoint);
}
if (fairRecSpread_ == Null<Spread>()) {
if (legBPS_[1] != Null<Real>())
fairRecSpread_ = recSpread_ - NPV_ / (legBPS_[1] / basisPoint);
}
}

void CrossCcyBasisSwap::setupExpired() const {
CrossCcySwap::setupExpired();
fairPaySpread_ = Null<Spread>();
fairRecSpread_ = Null<Spread>();
}

void CrossCcyBasisSwap::arguments::validate() const {
CrossCcySwap::arguments::validate();
QL_REQUIRE(paySpread != Null<Spread>(), "Pay spread cannot be null");
QL_REQUIRE(recSpread != Null<Spread>(), "Rec spread cannot be null");
}

void CrossCcyBasisSwap::results::reset() {
CrossCcySwap::results::reset();
fairPaySpread = Null<Spread>();
fairRecSpread = Null<Spread>();
}
} // namespace QuantLib
Loading