Skip to content

Commit c39eefb

Browse files
Martin Sjogrenjenkins
authored andcommitted
Merge remote-tracking branch 'origin/master' into martin_docs1
2 parents 7c7ecb5 + 4693587 commit c39eefb

31 files changed

Lines changed: 562 additions & 440 deletions

File tree

Docs/UserGuide/tradedata/indexcdsoption.tex

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,6 @@ \subsubsection{Index Credit Default Swap Option}
33
An index CDS option, trade type \lstinline!IndexCreditDefaultSwapOption!, is an option to enter into an index CDS at a specified strike spread or strike price. The Index CDS Option is set up using an \lstinline!IndexCreditDefaultSwapOptionData! node as shown in Listing \ref{lst:indexcdsoptiondata}. Its child nodes have the following meanings:
44

55
\begin{itemize}
6-
\item
7-
\lstinline!KnockOut!: A boolean node that determines whether front end protection is included or not. When this node evaluates to \lstinline!false!, front end protection is included. When this node evaluates to \lstinline!true!, front end protection is not included.
8-
9-
Allowable values: Boolean node, allowing \emph{Y, N, 1, 0, true, false} etc. The full set of allowable values is given in Table \ref{tab:boolean_allowable}.
106

117
\item
128
\lstinline!IndexTerm! [Optional]: An optional node giving the term of the underlying index CDS e.g.\ 3Y, 5Y, 7Y, 10Y etc. The main function of this node is to allow for different index CDS option volatility structures for different terms of the same index series e.g.\ a CDX HY Series 34 5Y volatility structure and a CDX HY Series 34 10Y volatility structure. If this node is omitted, the market is searched for a CDS volatility surface with ID equal to the value of the \lstinline!CreditCurveId! node under \lstinline!IndexCreditDefaultSwapData!. There will generally be one \lstinline!CreditCurveId! for each index CDS series e.g.\ \lstinline!CDXHYS34V1! for CDX HY Series 34 Version 1. Consequently, there can only be one CDS volatility surface for this index CDS series. When \lstinline!IndexTerm! is populated with the underlying index term, the market is searched for a CDS volatility surface with ID equal to the value of the \lstinline!CreditCurveId! node with suffix \lstinline!-[IndexTerm]!. For example, if the \lstinline!CreditCurveId! node on an index CDS option trade is \lstinline!CDXHYS34V1! and the \lstinline!IndexTerm! node is populated with \lstinline!5Y!, the market will be searched for a CDS volatility surface with ID \lstinline!CDXHYS34V1-5Y! and this will be used in the trade valuation. In this way, different volatility surfaces can be used to value different terms of the same CDS index series.
@@ -83,7 +79,6 @@ \subsubsection{Index Credit Default Swap Option}
8379
\begin{listing}[H]
8480
\begin{minted}[fontsize=\footnotesize]{xml}
8581
<IndexCreditDefaultSwapOptionData>
86-
<KnockOut>N</KnockOut>
8782
<IndexTerm>5Y</IndexTerm>
8883
<OptionData>
8984
<LongShort>Long</LongShort>

Examples/Example_40/Input/portfolio.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,6 @@
267267
</Envelope>
268268
<IndexCreditDefaultSwapOptionData>
269269
<Strike>0.0060</Strike>
270-
<KnockOut>N</KnockOut>
271270
<OptionData>
272271
<LongShort>Long</LongShort>
273272
<OptionType>Call</OptionType>
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
#TradeId,TradeType,Maturity,MaturityTime,NPV,NpvCurrency,NPV(Base),BaseCurrency,Notional,NotionalCurrency,Notional(Base),NettingSet,CounterParty
22
BermSwp,ScriptedTrade,2036-03-03,20.073770,51640.311738,EUR,51640.311738,EUR,#N/A,#N/A,#N/A,CPTY_A,CPTY_A
3-
LPISwp,ScriptedTrade,2035-02-01,18.989303,62979.404029,GBP,78301.934721,EUR,#N/A,#N/A,#N/A,CPTY_B,CPTY_B
3+
LPISwp,ScriptedTrade,2035-02-01,18.989303,53833.516084,GBP,66930.904274,EUR,#N/A,#N/A,#N/A,CPTY_B,CPTY_B

Examples/Example_54/Input/pricingengine.xml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,17 @@
88
<Parameter name="EnforceBaseCcy">false</Parameter>
99
<Parameter name="GridCoarsening">3M(1W),1Y(1M),5Y(3M),10Y(1Y),50Y(5Y)</Parameter>
1010
<Parameter name="IrReversion_EUR">0.01</Parameter>
11-
<Parameter name="IrReversion_GBP">0.01</Parameter>
11+
<Parameter name="IrReversion_GBP">0.015</Parameter>
1212
<Parameter name="FullDynamicFx">true</Parameter>
1313
<Parameter name="FullDynamicIr">true</Parameter>
1414
<!-- DK or JY -->
1515
<Parameter name="InfModelType">JY</Parameter>
16+
<!-- explicit overwrite of cam correlations -->
17+
<Parameter name="Correlation_IR:GBP_INF:UKRPI:0">0.8</Parameter>
18+
<Parameter name="Correlation_IR:GBP_INF:UKRPI:1">0.6</Parameter>
19+
<Parameter name="Correlation_INF:UKRPI:0_INF:UKRPI:1">0.3</Parameter>
20+
<!-- real to nominal rate vol ratio in jy model -->
21+
<Parameter name="InfJyRealToNominalVolRatio">0.6</Parameter>
1622
</ModelParameters>
1723
<Engine>Generic</Engine>
1824
<EngineParameters>

Examples/Example_54/run.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,9 @@
55
sys.path.append('../')
66
from ore_examples_helper import OreExample
77

8-
samples1=os.environ["OVERWRITE_SCENARIOGENERATOR_SAMPLES"]
9-
print("samples1 =", samples1)
10-
os.environ["OVERWRITE_SCENARIOGENERATOR_SAMPLES"]=""
11-
samples2=os.environ["OVERWRITE_SCENARIOGENERATOR_SAMPLES"]
12-
print("samples2 =", samples2)
8+
if "OVERWRITE_SCENARIOGENERATOR_SAMPLES" in os.environ:
9+
backupSamples = os.environ["OVERWRITE_SCENARIOGENERATOR_SAMPLES"]
10+
os.environ["OVERWRITE_SCENARIOGENERATOR_SAMPLES"] = ""
1311

1412
oreex = OreExample(sys.argv[1] if len(sys.argv)>1 else False)
1513

@@ -41,4 +39,5 @@
4139
oreex.decorate_plot(title="Example Scripting / AMC - DIM Evolution for LPI Swap (sticky date mpor mode)")
4240
oreex.save_plot_to_file()
4341

44-
os.environ["OVERWRITE_SCENARIOGENERATOR_SAMPLES"]=samples1
42+
if "OVERWRITE_SCENARIOGENERATOR_SAMPLES" in os.environ:
43+
os.environ["OVERWRITE_SCENARIOGENERATOR_SAMPLES"] = backupSamples

OREData/ored/model/crossassetmodelbuilder.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,35 @@ void CrossAssetModelBuilder::resetModelParams(const CrossAssetModel::AssetType t
162162
}
163163
}
164164

165+
void CrossAssetModelBuilder::copyModelParams(const CrossAssetModel::AssetType t0, const Size param0, const Size index0,
166+
const Size i0, const CrossAssetModel::AssetType t1, const Size param1,
167+
const Size index1, const Size i1, const Real mult) const {
168+
auto mp0 = model_->MoveParameter(t0, param0, index0, i0);
169+
auto mp1 = model_->MoveParameter(t1, param1, index1, i1);
170+
auto s0 = 0, s1 = 0;
171+
for (Size i = 0; i < mp0.size(); ++i)
172+
if (mp0[i])
173+
s0++;
174+
for (Size i = 0; i < mp1.size(); ++i)
175+
if (mp1[i])
176+
s1++;
177+
QL_REQUIRE(s0 == s1, "CrossAssetModelBuilder::copyModelParams(): source range size ("
178+
<< s0 << ") does not match target range size (" << s1 << ") when copying (" << t0 << ", "
179+
<< param0 << "," << index0 << "," << i0 << ") -> (" << t0 << ", " << param0 << ","
180+
<< index0 << "," << i0 << ")");
181+
std::vector<Real> sourceValues(s0);
182+
for (Size idx0 = 0, count = 0; idx0 < mp0.size(); ++idx0) {
183+
if (!mp0[idx0]) {
184+
sourceValues[count++] = params_[idx0];
185+
}
186+
}
187+
for (Size idx1 = 0, count = 0; idx1 < mp1.size(); ++idx1) {
188+
if (!mp1[idx1]) {
189+
model_->setParam(idx1, sourceValues[count++] * mult);
190+
}
191+
}
192+
}
193+
165194
void CrossAssetModelBuilder::buildModel() const {
166195

167196
LOG("Start building CrossAssetModel");
@@ -842,6 +871,15 @@ void CrossAssetModelBuilder::calibrateInflation(const InfJyData& data, Size mode
842871
// Calibration configuration.
843872
const auto& cc = data.calibrationConfiguration();
844873

874+
// if we link the real rate params to the nominal rate params, we copy them over now (ir calibration is done at this point)
875+
if(data.linkRealRateParamsToNominalRateParams()) {
876+
Size irIdx = model_->ccyIndex(model_->infjy(modelIdx)->currency());
877+
copyModelParams(CrossAssetModel::AssetType::IR, 0, irIdx, Null<Size>(), CrossAssetModel::AssetType::INF, 0,
878+
modelIdx, Null<Size>(), data.linkedRealRateVolatilityScaling());
879+
copyModelParams(CrossAssetModel::AssetType::IR, 1, irIdx, Null<Size>(), CrossAssetModel::AssetType::INF, 1,
880+
modelIdx, Null<Size>(), 1.0);
881+
}
882+
845883
if (data.calibrationType() == CalibrationType::BestFit) {
846884

847885
// If calibration type is BestFit, do a global optimisation on the parameters that need to be calibrated.
@@ -937,6 +975,13 @@ void CrossAssetModelBuilder::calibrateInflation(const InfJyData& data, Size mode
937975
}
938976

939977
// Log the calibration details.
978+
TLOG("INF (JY) " << data.index() << " model parameters after calibration:");
979+
TLOG("Real rate vol times : " << inflationParam->parameterTimes(0));
980+
TLOG("Real rate vol values : " << inflationParam->parameterValues(0));
981+
TLOG("Real rate rev times : " << inflationParam->parameterTimes(1));
982+
TLOG("Real rate rev values : " << inflationParam->parameterValues(1));
983+
TLOG("R/N conversion times : " << inflationParam->parameterTimes(2));
984+
TLOG("R/N conversion values : " << inflationParam->parameterValues(2));
940985
DLOG("INF (JY) " << data.index() << " calibration errors:");
941986
inflationCalibrationErrors_[modelIdx] = getCalibrationError(allHelpers);
942987
if (data.calibrationType() == CalibrationType::Bootstrap) {

OREData/ored/model/crossassetmodelbuilder.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,9 @@ class CrossAssetModelBuilder : public QuantExt::ModelBuilder {
111111
void performCalculations() const override;
112112
void buildModel() const;
113113
void resetModelParams(const CrossAssetModel::AssetType t, const Size param, const Size index, const Size i) const;
114+
void copyModelParams(const CrossAssetModel::AssetType t0, const Size param0, const Size index0, const Size i0,
115+
const CrossAssetModel::AssetType t1, const Size param1, const Size index1, const Size i1,
116+
const Real mult) const;
114117

115118
mutable std::vector<std::vector<boost::shared_ptr<BlackCalibrationHelper>>> swaptionBaskets_;
116119
mutable std::vector<std::vector<boost::shared_ptr<BlackCalibrationHelper>>> fxOptionBaskets_;

OREData/ored/model/inflation/infjydata.cpp

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -29,22 +29,18 @@ namespace data {
2929

3030
InfJyData::InfJyData() {}
3131

32-
InfJyData::InfJyData(CalibrationType calibrationType,
33-
const vector<CalibrationBasket>& calibrationBaskets,
34-
const std::string& currency,
35-
const std::string& index,
36-
const ReversionParameter& realRateReversion,
37-
const VolatilityParameter& realRateVolatility,
38-
const VolatilityParameter& indexVolatility,
39-
const LgmReversionTransformation& reversionTransformation,
40-
const CalibrationConfiguration& calibrationConfiguration,
41-
const bool ignoreDuplicateCalibrationExpiryTimes)
32+
InfJyData::InfJyData(CalibrationType calibrationType, const vector<CalibrationBasket>& calibrationBaskets,
33+
const std::string& currency, const std::string& index, const ReversionParameter& realRateReversion,
34+
const VolatilityParameter& realRateVolatility, const VolatilityParameter& indexVolatility,
35+
const LgmReversionTransformation& reversionTransformation,
36+
const CalibrationConfiguration& calibrationConfiguration,
37+
const bool ignoreDuplicateCalibrationExpiryTimes, const bool linkRealToNominalRateParams,
38+
const Real linkedRealRateVolatilityScaling)
4239
: InflationModelData(calibrationType, calibrationBaskets, currency, index, ignoreDuplicateCalibrationExpiryTimes),
43-
realRateReversion_(realRateReversion),
44-
realRateVolatility_(realRateVolatility),
45-
indexVolatility_(indexVolatility),
46-
reversionTransformation_(reversionTransformation),
47-
calibrationConfiguration_(calibrationConfiguration) {}
40+
realRateReversion_(realRateReversion), realRateVolatility_(realRateVolatility), indexVolatility_(indexVolatility),
41+
reversionTransformation_(reversionTransformation), calibrationConfiguration_(calibrationConfiguration),
42+
linkRealToNominalRateParams_(linkRealToNominalRateParams),
43+
linkedRealRateVolatilityScaling_(linkedRealRateVolatilityScaling) {}
4844

4945
const ReversionParameter& InfJyData::realRateReversion() const {
5046
return realRateReversion_;
@@ -66,6 +62,10 @@ const CalibrationConfiguration& InfJyData::calibrationConfiguration() const {
6662
return calibrationConfiguration_;
6763
}
6864

65+
bool InfJyData::linkRealRateParamsToNominalRateParams() const { return linkRealToNominalRateParams_; }
66+
67+
Real InfJyData::linkedRealRateVolatilityScaling() const { return linkedRealRateVolatilityScaling_; }
68+
6969
void InfJyData::fromXML(XMLNode* node) {
7070

7171
// Check the node is not null and that name is LGM or DodgsonKainth. LGM is for backward compatibility.
@@ -88,9 +88,16 @@ void InfJyData::fromXML(XMLNode* node) {
8888
indexVolatility_.fromXML(XMLUtils::getChildNode(idxNode, "Volatility"));
8989

9090
// Get the calibration configuration
91-
XMLNode* ccNode = XMLUtils::getChildNode(node, "CalibrationConfiguration");
92-
if (ccNode)
91+
if (XMLNode* ccNode = XMLUtils::getChildNode(node, "CalibrationConfiguration"))
9392
calibrationConfiguration_.fromXML(ccNode);
93+
94+
// Get the link to nominal param fields
95+
linkRealToNominalRateParams_ =
96+
parseBool(XMLUtils::getChildValue(node, "LinkRealToNominalRateParams", false, "false"));
97+
if (linkRealToNominalRateParams_) {
98+
linkedRealRateVolatilityScaling_ =
99+
parseReal(XMLUtils::getChildValue(node, "LinkedRealRateVolatilityScaling", false, "1.0"));
100+
}
94101
}
95102

96103
XMLNode* InfJyData::toXML(XMLDocument& doc) const {
@@ -110,6 +117,11 @@ XMLNode* InfJyData::toXML(XMLDocument& doc) const {
110117

111118
XMLUtils::appendNode(node, calibrationConfiguration_.toXML(doc));
112119

120+
if (linkRealToNominalRateParams_) {
121+
XMLUtils::addChild(doc, node, "LinkRealToNominalRateParams", linkRealToNominalRateParams_);
122+
XMLUtils::addChild(doc, node, "LinkedRealRateVolatilityScaling", linkedRealRateVolatilityScaling_);
123+
}
124+
113125
return node;
114126
}
115127

OREData/ored/model/inflation/infjydata.hpp

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,16 +48,18 @@ class InfJyData : public InflationModelData {
4848
InfJyData();
4949

5050
//! Detailed constructor
51-
InfJyData(CalibrationType calibrationType,
52-
const std::vector<CalibrationBasket>& calibrationBaskets,
53-
const std::string& currency,
54-
const std::string& index,
55-
const ReversionParameter& realRateReversion,
56-
const VolatilityParameter& realRateVolatility,
57-
const VolatilityParameter& indexVolatility,
58-
const LgmReversionTransformation& reversionTransformation = LgmReversionTransformation(),
59-
const CalibrationConfiguration& calibrationConfiguration = CalibrationConfiguration(),
60-
const bool ignoreDuplicateCalibrationExpiryTimes = false);
51+
/* Note: If linkRealRateToNominalRateParams == true, the realRateVolatility and realRateReversion should be set to
52+
the nominal rate parameters and the calibrate flag in these new parameters should be set to false. Also, the
53+
scaling linkRealRateVolatilityScaling should have been applied to the new parameters. All this is not automatic
54+
neither cheked in this class (lack of info on the nominal parameters, but required to ensure a calibration of the
55+
jy model as part of the cam to work consistently. */
56+
InfJyData(CalibrationType calibrationType, const std::vector<CalibrationBasket>& calibrationBaskets,
57+
const std::string& currency, const std::string& index, const ReversionParameter& realRateReversion,
58+
const VolatilityParameter& realRateVolatility, const VolatilityParameter& indexVolatility,
59+
const LgmReversionTransformation& reversionTransformation = LgmReversionTransformation(),
60+
const CalibrationConfiguration& calibrationConfiguration = CalibrationConfiguration(),
61+
const bool ignoreDuplicateCalibrationExpiryTimes = false, const bool linkRealToNominalRateParams = false,
62+
const Real linkedRealRateVolatilityScaling = 1.0);
6163

6264
//! \name Inspectors
6365
//@{
@@ -66,6 +68,8 @@ class InfJyData : public InflationModelData {
6668
const VolatilityParameter& indexVolatility() const;
6769
const LgmReversionTransformation& reversionTransformation() const;
6870
const CalibrationConfiguration& calibrationConfiguration() const;
71+
bool linkRealRateParamsToNominalRateParams() const;
72+
Real linkedRealRateVolatilityScaling() const;
6973
//@}
7074

7175
//! \name Serialisation
@@ -80,6 +84,8 @@ class InfJyData : public InflationModelData {
8084
VolatilityParameter indexVolatility_;
8185
LgmReversionTransformation reversionTransformation_;
8286
CalibrationConfiguration calibrationConfiguration_;
87+
bool linkRealToNominalRateParams_;
88+
Real linkedRealRateVolatilityScaling_;
8389
};
8490

8591
}

OREData/ored/model/lgmdata.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
*/
1818

1919
#include <ored/model/lgmdata.hpp>
20+
#include <ored/model/modelparameter.hpp>
2021
#include <ored/utilities/correlationmatrix.hpp>
2122
#include <ored/utilities/log.hpp>
2223
#include <ored/utilities/parsers.hpp>
@@ -212,19 +213,22 @@ XMLNode* LgmData::toXML(XMLDocument& doc) const {
212213
return lgmNode;
213214
}
214215

215-
LgmReversionTransformation::LgmReversionTransformation()
216-
: horizon_(0.0), scaling_(1.0) {}
216+
ReversionParameter LgmData::reversionParameter() const {
217+
return ReversionParameter(revType_, calibrateH_, hType_, hTimes_, hValues_);
218+
}
219+
220+
VolatilityParameter LgmData::volatilityParameter() const {
221+
return VolatilityParameter(volType_, calibrateA_, aType_, aTimes_, aValues_);
222+
}
223+
224+
LgmReversionTransformation::LgmReversionTransformation() : horizon_(0.0), scaling_(1.0) {}
217225

218226
LgmReversionTransformation::LgmReversionTransformation(Time horizon, Real scaling)
219227
: horizon_(horizon), scaling_(scaling) {}
220228

221-
Time LgmReversionTransformation::horizon() const {
222-
return horizon_;
223-
}
229+
Time LgmReversionTransformation::horizon() const { return horizon_; }
224230

225-
Real LgmReversionTransformation::scaling() const {
226-
return scaling_;
227-
}
231+
Real LgmReversionTransformation::scaling() const { return scaling_; }
228232

229233
void LgmReversionTransformation::fromXML(XMLNode* node) {
230234
XMLUtils::checkNode(node, "ParameterTransformation");

0 commit comments

Comments
 (0)