Skip to content

Commit 3c00f7d

Browse files
committed
QPR-13802 emit warning if trade date is not given and there are defaults
1 parent 41747b9 commit 3c00f7d

3 files changed

Lines changed: 25 additions & 1 deletion

File tree

Docs/UserGuide/tradedata/indexcdsoption.tex

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,11 @@ \subsubsection{Index Credit Default Swap Option}
100100
\item
101101
\lstinline!TradeDate! [Optional]: The trade date. If not given defaults to the valuation date. In case of an underlying
102102
default the trade date is used to determine whether the underlying notional before default should be considered part of
103-
the outstanding notional (TradeDate $<$ AuctionDate) or not (TradeDate $\geq$ AuctionDate).
103+
the outstanding notional (TradeDate $<$ AuctionDate) or not (TradeDate $\geq$ AuctionDate). Since the trade date is also
104+
used as the start date of the front end protection (if the field FrontEndProtectionStartDate is not populated), it
105+
impacts the realized front end protection value. It is therefore essential to populate the TradeDate with the correct
106+
value if defaults occured in the underlying index. If the trade date is not given and there were defaults a warning is
107+
emitted stating that the valuation might not be accruate.
104108

105109
Allowable values: See \lstinline!Date! in Table \ref{tab:allow_stand_data}. Can not be later than the valuation date.
106110

OREData/ored/portfolio/indexcreditdefaultswapoption.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,10 @@ void IndexCreditDefaultSwapOption::build(const QuantLib::ext::shared_ptr<EngineF
8282
asof = Settings::instance().evaluationDate();
8383
}
8484

85+
bool defaultTradeDateIsUsed = false;
8586
if (tradeDate_ == Date()) {
8687
tradeDate_ = asof;
88+
defaultTradeDateIsUsed = true;
8789
} else {
8890
QL_REQUIRE(tradeDate_ <= asof, "Trade date (" << io::iso_date(tradeDate_) << ") should be on or "
8991
<< "before the valuation date (" << io::iso_date(asof) << ")");
@@ -182,12 +184,25 @@ void IndexCreditDefaultSwapOption::build(const QuantLib::ext::shared_ptr<EngineF
182184

183185
// Populate the constituents and determine the various notional amounts.
184186
constituents_.clear();
187+
defaultHasOccured_ = false;
185188
if (swap_.basket().constituents().size() > 1) {
186189
fromBasket(asof, constituents_);
187190
} else {
188191
fromReferenceData(asof, constituents_, engineFactory->referenceData());
189192
}
190193

194+
// Check if a default trade date might lead to an inaccurate valuation
195+
if (defaultTradeDateIsUsed && defaultHasOccured_) {
196+
StructuredTradeWarningMessage(id(), tradeType(), "Results might be inaccurate, because no trade date is given.",
197+
"No trade date is given and there were defaults in the underlying index. This "
198+
"might lead to wrong notional and realized fep amounts. The trade date is "
199+
"assumed to be the valuation date (" +
200+
ore::data::to_string(tradeDate_) +
201+
"). If this is not correct, consider "
202+
"populating the trade date.")
203+
.log();
204+
}
205+
191206
// Transfer to vectors for ctors below
192207
vector<string> constituentIds;
193208
constituentIds.reserve(constituents_.size());
@@ -510,6 +525,8 @@ void IndexCreditDefaultSwapOption::fromBasket(const Date& asof, map<string, Real
510525
notionals_.realisedFep += fepAmount;
511526
}
512527

528+
defaultHasOccured_ = true;
529+
513530
} else if (ntl > 0.0) {
514531

515532
// Entity is still in the index.
@@ -620,6 +637,8 @@ void IndexCreditDefaultSwapOption::fromReferenceData(const Date& asof, map<strin
620637
notionals_.realisedFep += fepAmount;
621638
}
622639

640+
defaultHasOccured_ = true;
641+
623642
} else if (weight > 0.0) {
624643

625644
// Entity is still in the index.

OREData/ored/portfolio/indexcreditdefaultswapoption.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ class IndexCreditDefaultSwapOption : public Trade {
9999

100100
//! Populated during trade building
101101
Notionals notionals_;
102+
bool defaultHasOccured_ = false;
102103

103104
//! map of all the constituents to notionals
104105
map<string, Real> constituents_;

0 commit comments

Comments
 (0)