Skip to content

Commit fad1770

Browse files
damienbarkerfarahkhashman
authored andcommitted
Merge branch 'feature/QPR-13533' into 'master'
QPR-13533 Closes QPR-13533 See merge request qs/oreplus!2998
1 parent 406faff commit fad1770

4 files changed

Lines changed: 51 additions & 18 deletions

File tree

OREData/ored/portfolio/trs.cpp

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include <ql/cashflows/cashflows.hpp>
3333
#include <ql/cashflows/fixedratecoupon.hpp>
3434

35+
#include <boost/optional/optional_io.hpp>
3536
#include <boost/assign/list_of.hpp>
3637
#include <boost/bimap.hpp>
3738
#include <boost/optional.hpp>
@@ -40,8 +41,8 @@
4041
namespace ore {
4142
namespace data {
4243

43-
void addTRSRequiredFixings(RequiredFixings& fixings, const std::vector<Leg>& returnLegs,
44-
const QuantLib::ext::shared_ptr<QuantExt::FxIndex>& ind = nullptr) {
44+
void addTRSRequiredFixings(RequiredFixings& fixings, const std::vector<Leg>& returnLegs,
45+
const QuantLib::ext::shared_ptr<QuantExt::FxIndex>& ind = nullptr) {
4546
QL_REQUIRE(returnLegs.size() > 0, "TrsUnderlyingBuilder: No returnLeg built");
4647
auto fdg = QuantLib::ext::make_shared<FixingDateGetter>(fixings);
4748
fdg->setAdditionalFxIndex(ind);
@@ -62,7 +63,9 @@ void TRS::ReturnData::fromXML(XMLNode* node) {
6263
paymentCalendar_ = XMLUtils::getChildValue(node, "PaymentCalendar", false);
6364
paymentDates_ = XMLUtils::getChildrenValues(node, "PaymentDates", "PaymentDate", false);
6465
initialPrice_ = Null<Real>();
65-
fxConversionAtPeriodEnd_ = XMLUtils::getChildValue(node, "FXConversion", false, "Start") == "End";
66+
if (XMLNode* fxcNode = XMLUtils::getChildNode(node, "FXConversion")) {
67+
fxConversion_ = parseFXConversion(XMLUtils::getNodeValue(fxcNode));
68+
}
6669
if (auto n = XMLUtils::getChildNode(node, "InitialPrice")) {
6770
initialPrice_ = parseReal(XMLUtils::getNodeValue(n));
6871
}
@@ -101,9 +104,19 @@ XMLNode* TRS::ReturnData::toXML(XMLDocument& doc) const {
101104
XMLUtils::addChild(doc, n, "PayUnderlyingCashFlowsImmediately", *payUnderlyingCashFlowsImmediately_);
102105
if (!fxTerms_.empty())
103106
XMLUtils::addChildren(doc, n, "FXTerms", "FXIndex", fxTerms_);
107+
if (fxConversion_) {
108+
XMLUtils::addChild(doc, n, "FXConversion", ore::data::to_string(fxConversion_));
109+
}
104110
return n;
105111
}
106112

113+
TRS::FXConversion TRS::ReturnData::parseFXConversion(string fxConv_) {
114+
return fxConv_ == "End" ? FXConversion::End : FXConversion::Start;
115+
}
116+
117+
118+
119+
107120
void TRS::FundingData::fromXML(XMLNode* node) {
108121
XMLUtils::checkNode(node, "FundingData");
109122
vector<XMLNode*> nodes = XMLUtils::getChildrenNodes(node, "LegData");
@@ -314,6 +327,10 @@ TRS::getFxIndex(const QuantLib::ext::shared_ptr<Market> market, const std::strin
314327
return fx;
315328
}
316329

330+
/*TRS::FXConversion TRS::ReturnData::parseFXConversion(string fxConv_) { return (fxConv_ == "Start" ? FXConversion::Start
331+
: FXConversion::End);
332+
}*/
333+
317334
void TRS::build(const QuantLib::ext::shared_ptr<EngineFactory>& engineFactory) {
318335

319336
DLOG("TRS::build() called for id = " << id());
@@ -861,6 +878,17 @@ std::ostream& operator<<(std::ostream& os, const TRS::FundingData::NotionalType
861878
return os;
862879
}
863880

881+
std::ostream& operator<<(std::ostream& out, const TRS::FXConversion type) {
882+
switch (type) {
883+
case TRS::FXConversion::Start:
884+
return out << "Start";
885+
case TRS::FXConversion::End:
886+
return out << "End";
887+
default:
888+
QL_FAIL("Unrecognized FXConversion type");
889+
}
890+
}
891+
864892
void TRS::populateFromReferenceData(const QuantLib::ext::shared_ptr<ReferenceDataManager>& referenceData) const{
865893

866894
if (!portfolioId_.empty() && referenceData != nullptr &&

OREData/ored/portfolio/trs.hpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,25 +36,24 @@ namespace data {
3636
/*! TRS trade class */
3737
class TRS : public Trade {
3838
public:
39+
enum class FXConversion { Start, End };
3940
class ReturnData : public XMLSerializable {
4041
public:
4142
ReturnData()
42-
: payer_(false), initialPrice_(Null<Real>()), payUnderlyingCashFlowsImmediately_(false),
43-
fxConversionAtPeriodEnd_(false) {}
43+
: payer_(false), initialPrice_(Null<Real>()), payUnderlyingCashFlowsImmediately_(false) {}
4444
ReturnData(const bool payer, const std::string& currency, const ScheduleData& scheduleData,
4545
const std::string& observationLag, const std::string& observationConvention,
4646
const std::string& observationCalendar, const std::string& paymentLag,
4747
const std::string& paymentConvention, const std::string& paymentCalendar,
4848
const std::vector<std::string>& paymentDates, const Real initialPrice,
4949
const std::string& initialPriceCurrency, const std::vector<std::string>& fxTerms,
5050
const boost::optional<bool> payUnderlyingCashFlowsImmediately,
51-
const boost::optional<bool> fxConversionAtPeriodEnd)
51+
const boost::optional<FXConversion> fxConversion)
5252
: payer_(payer), currency_(currency), scheduleData_(scheduleData), observationLag_(observationLag),
5353
observationCalendar_(observationCalendar), paymentLag_(paymentLag), paymentConvention_(paymentConvention),
5454
paymentCalendar_(paymentCalendar), paymentDates_(paymentDates), initialPrice_(initialPrice),
5555
initialPriceCurrency_(initialPriceCurrency), fxTerms_(fxTerms),
56-
payUnderlyingCashFlowsImmediately_(payUnderlyingCashFlowsImmediately),
57-
fxConversionAtPeriodEnd_(fxConversionAtPeriodEnd) {}
56+
payUnderlyingCashFlowsImmediately_(payUnderlyingCashFlowsImmediately), fxConversion_(fxConversion) {}
5857

5958
bool payer() const { return payer_; }
6059
const std::string& currency() const { return currency_; }
@@ -70,9 +69,10 @@ class TRS : public Trade {
7069
const std::string& initialPriceCurrency() const { return initialPriceCurrency_; }
7170
const std::vector<std::string>& fxTerms() const { return fxTerms_; }
7271
boost::optional<bool> payUnderlyingCashFlowsImmediately() const { return payUnderlyingCashFlowsImmediately_; }
73-
bool fxConversionAtPeriodEnd() const { return fxConversionAtPeriodEnd_; }
72+
boost::optional<FXConversion> fxConversionAtPeriodEnd() const { return fxConversion_; }
7473
void fromXML(XMLNode* node) override;
7574
XMLNode* toXML(XMLDocument& doc) const override;
75+
FXConversion parseFXConversion(string fxConv_);
7676

7777
private:
7878
bool payer_;
@@ -85,7 +85,7 @@ class TRS : public Trade {
8585
std::string initialPriceCurrency_;
8686
std::vector<std::string> fxTerms_; // FX index strings
8787
boost::optional<bool> payUnderlyingCashFlowsImmediately_;
88-
bool fxConversionAtPeriodEnd_;
88+
boost::optional<FXConversion> fxConversion_;
8989
};
9090

9191
class FundingData : public XMLSerializable {

OREData/ored/portfolio/trswrapper.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,10 @@ TRSWrapper::TRSWrapper(
4444
const Currency& fundingCurrency, const Size fundingResetGracePeriod, const bool paysAsset, const bool paysFunding,
4545
const Leg& additionalCashflowLeg, const bool additionalCashflowLegPayer, const Currency& additionalCashflowCurrency,
4646
const std::vector<QuantLib::ext::shared_ptr<FxIndex>>& fxIndexAsset, const QuantLib::ext::shared_ptr<FxIndex>& fxIndexReturn,
47-
const QuantLib::ext::shared_ptr<FxIndex>& fxIndexAdditionalCashflows,
47+
const QuantLib::ext::shared_ptr<FxIndex>& fxIndexAdditionalCashflows,
4848
const std::map<std::string, QuantLib::ext::shared_ptr<QuantExt::FxIndex>>& addFxIndices,
49-
const bool fxConversionAtPeriodEnd)
49+
const boost::optional<TRS::FXConversion>& fxConversion)
50+
5051
: underlying_(underlying), underlyingIndex_(underlyingIndex), underlyingMultiplier_(underlyingMultiplier),
5152
includeUnderlyingCashflowsInReturn_(includeUnderlyingCashflowsInReturn), initialPrice_(initialPrice),
5253
portfolioInitialPrice_(portfolioInitialPrice), portfolioId_(portfolioId),
@@ -57,7 +58,7 @@ TRSWrapper::TRSWrapper(
5758
additionalCashflowLeg_(additionalCashflowLeg), additionalCashflowLegPayer_(additionalCashflowLegPayer),
5859
additionalCashflowCurrency_(additionalCashflowCurrency), fxIndexAsset_(fxIndexAsset),
5960
fxIndexReturn_(fxIndexReturn), fxIndexAdditionalCashflows_(fxIndexAdditionalCashflows),
60-
addFxIndices_(addFxIndices), fxConversionAtPeriodEnd_(fxConversionAtPeriodEnd) {
61+
addFxIndices_(addFxIndices), fxConversion_(fxConversion) {
6162

6263
QL_REQUIRE(!paymentSchedule_.empty(), "TRSWrapper::TRSWrapper(): payment schedule must not be empty()");
6364

@@ -167,7 +168,7 @@ void TRSWrapper::setupArguments(PricingEngine::arguments* args) const {
167168
a->fxIndexReturn_ = fxIndexReturn_;
168169
a->fxIndexAdditionalCashflows_ = fxIndexAdditionalCashflows_;
169170
a->addFxIndices_ = addFxIndices_;
170-
a->fxConversionAtPeriodEnd_ = fxConversionAtPeriodEnd_;
171+
a->fxConversion_ = fxConversion_;
171172
}
172173

173174
void TRSWrapper::arguments::validate() const {
@@ -249,7 +250,9 @@ bool TRSWrapperAccrualEngine::computeStartValue(std::vector<Real>& underlyingSta
249250
} else {
250251
// The start valuation date is <= today, we determine the start value from the initial price or a
251252
// historical fixing
252-
Date fxDate = !arguments_.fxConversionAtPeriodEnd_ ? v0 : (endDate == Null<Date>() ? today : endDate);
253+
Date fxDate = arguments_.fxConversion_ != TRS::FXConversion::End
254+
? v0
255+
: (endDate == Null<Date>() ? today : endDate);
253256
Real s0 = 0.0, fx0 = 1.0;
254257
if (nth == 0 && arguments_.initialPrice_ != Null<Real>() &&
255258
v0 == arguments_.valuationSchedule_.front()) {

OREData/ored/portfolio/trswrapper.hpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,9 @@ class TRSWrapper : public QuantLib::Instrument {
7474
const std::vector<QuantLib::ext::shared_ptr<QuantExt::FxIndex>>& fxIndexAsset,
7575
const QuantLib::ext::shared_ptr<QuantExt::FxIndex>& fxIndexReturn,
7676
const QuantLib::ext::shared_ptr<QuantExt::FxIndex>& fxIndexAdditionalCashflows,
77-
const std::map<std::string, QuantLib::ext::shared_ptr<QuantExt::FxIndex>>& addFxindices, const bool useTodaysFixing);
77+
const std::map<std::string, QuantLib::ext::shared_ptr<QuantExt::FxIndex>>& addFxindices,
78+
const boost::optional<TRS::FXConversion>& fxConversion);
79+
7880

7981
//! \name Instrument interface
8082
//@{
@@ -106,7 +108,7 @@ class TRSWrapper : public QuantLib::Instrument {
106108
std::vector<QuantLib::ext::shared_ptr<QuantExt::FxIndex>> fxIndexAsset_;
107109
QuantLib::ext::shared_ptr<QuantExt::FxIndex> fxIndexReturn_, fxIndexAdditionalCashflows_;
108110
std::map<std::string, QuantLib::ext::shared_ptr<QuantExt::FxIndex>> addFxIndices_;
109-
bool fxConversionAtPeriodEnd_;
111+
boost::optional<TRS::FXConversion> fxConversion_;
110112

111113
Date lastDate_;
112114
};
@@ -136,7 +138,7 @@ class TRSWrapper::arguments : public virtual QuantLib::PricingEngine::arguments
136138
std::vector<QuantLib::ext::shared_ptr<QuantExt::FxIndex>> fxIndexAsset_;
137139
QuantLib::ext::shared_ptr<QuantExt::FxIndex> fxIndexReturn_, fxIndexAdditionalCashflows_;
138140
std::map<std::string, QuantLib::ext::shared_ptr<QuantExt::FxIndex>> addFxIndices_;
139-
bool fxConversionAtPeriodEnd_;
141+
boost::optional<TRS::FXConversion> fxConversion_;
140142
void validate() const override;
141143
};
142144

0 commit comments

Comments
 (0)