Skip to content

Commit 1e6d309

Browse files
pcaspersjenkins
authored andcommitted
QPR-12417 include cashflows only if specified in pe config
1 parent 5984d4d commit 1e6d309

12 files changed

Lines changed: 50 additions & 33 deletions

Docs/ScriptedTrade/docs/language.tex

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,7 @@
467467
numeraire
468468
\item $d\leq p$ must hold
469469
\item if $p$ lies on or before the evaluation date, the result is zero; $X$ is not evaluated in this case.
470-
Note that $X$ is evaluated in the LOGPAY function though, see \ref{function_logpay}.
470+
Note that $X$ is evaluated in the LOGPAY function if past cashflows are included, see \ref{function_logpay}.
471471
\item avoids reading non-relevant past fixings from the index history
472472
\item if $d$ lies before (but $p$ after) the evaluation date, it is set to the evaluation date, i.e. the result is
473473
computed as of the evaluation date
@@ -515,9 +515,8 @@
515515
under leg number $2$ and flow Type ``Interest''. The same holds for Payoff3, but if any amounts were booked using the
516516
slot parameter $3$ previously they will be overwritten with the current amount.
517517

518-
Note: Even if $p$ lies on or before the evaluation date, a cashflow entry will be generated. If one wants to explicitly
519-
avoid that, e.g. because past fixings are not available to evaluate the past paid amounts, it can be done with an IF
520-
construct comparing the pay date with TODAY.
518+
Note: If IncludePastCashflows in the pricing engine config is set to true then even if $p$ lies on or before the
519+
evaluation date, a cashflow entry will be generated.
521520

522521
% ====================================================
523522
\stsubsection{Function {\tt NPV, NPVMEM}}\label{function_npv}

Docs/ScriptedTrade/docs/models.tex

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ \subsection{Pricing Engine Configuration}\label{pricingengine_config}
4949
<Parameter name="TimeStepsPerYear">24</Parameter>
5050
<Parameter name="Interactive">false</Parameter>
5151
<Parameter name="BootstrapTolerance">0.1</Parameter>
52+
<Parameter name="IncludePastCashflows">true</Parameter>
5253
<!-- product specific parameters -->
5354
<Parameter name="RegressionOrder_SingleAssetOption(EQ)">6</Parameter>
5455
<Parameter name="RegressionOrder_SingleAssetOption(FX)">6</Parameter>
@@ -136,6 +137,8 @@ \subsection{Pricing Engine Configuration}\label{pricingengine_config}
136137
only. The moneyness is defined as a ``standardised moneyness'' $\ln(K/F) / \sigma\sqrt{t}$ with $K$ strike, $F$ ATMF
137138
forward, $\sigma$ ATMF market vol, $t$ option time to expiry
138139
\item BootstrapTolerance: tolerance for calibration bootstrap, only applies to model = GaussianCam
140+
\item IncludePastCashflows: if true, LOGPAY() will generate cashflow information for pay dates on or before the
141+
reference date. Optional, defaults to false.
139142
\item Interactive: If true an interactive session is started on script execution for debugging purposes; should be false
140143
except for debugging purposes
141144
\item UseAD: If true and RunType in the global pricing engine parameters is SensitivityDelta, a first order pnl

OREData/ored/portfolio/builders/scriptedtrade.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ ScriptedTradeEngineBuilder::engine(const std::string& id, const ScriptedTrade& s
320320
engine = boost::make_shared<ScriptedInstrumentPricingEngine>(
321321
script.npv(), script.results(), model_, ast_, context, script.code(), interactive_, amcCam_ != nullptr,
322322
std::set<std::string>(script.stickyCloseOutStates().begin(), script.stickyCloseOutStates().end()),
323-
generateAdditionalResults);
323+
generateAdditionalResults, includePastCashflows_);
324324
} else if (modelCG_) {
325325
auto rt = globalParameters_.find("RunType");
326326
bool useCachedSensis = useAd_ && (rt != globalParameters_.end() && rt->second == "SensitivityDelta");
@@ -485,6 +485,7 @@ void ScriptedTradeEngineBuilder::populateModelParameters() {
485485
useExternalComputeDevice_ =
486486
parseBool(engineParameter("UseExternalComputeDevice", {resolvedProductTag_}, false, "false"));
487487
externalComputeDevice_ = engineParameter("ExternalComputeDevice", {}, false, "");
488+
includePastCashflows_ = parseBool(engineParameter("IncludePastCashflows", {resolvedProductTag_}, false, "false"));
488489

489490
// usage of ad or an external device implies usage of cg
490491
if (useAd_ || useExternalComputeDevice_)

OREData/ored/portfolio/builders/scriptedtrade.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ class ScriptedTradeEngineBuilder : public EngineBuilder {
161161
bool useAd_;
162162
bool useExternalComputeDevice_;
163163
std::string externalComputeDevice_;
164+
bool includePastCashflows_;
164165
};
165166

166167
} // namespace data

OREData/ored/scripting/computationgraphbuilder.cpp

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -119,12 +119,12 @@ class ASTRunner : public AcyclicVisitor,
119119
public Visitor<LoopNode> {
120120
public:
121121
ASTRunner(ComputationGraph& g, const std::vector<std::string>& opLabels, const boost::shared_ptr<ModelCG> model,
122-
const bool generatePayLog, const std::string& script, bool& interactive, Context& context,
123-
ASTNode*& lastVisitedNode, std::set<std::size_t>& keepNodes,
122+
const bool generatePayLog, const bool includePastCashflows, const std::string& script, bool& interactive,
123+
Context& context, ASTNode*& lastVisitedNode, std::set<std::size_t>& keepNodes,
124124
std::vector<ComputationGraphBuilder::PayLogEntry>& payLogEntries)
125125
: g_(g), opLabels_(opLabels), model_(model), size_(model ? model->size() : 1), generatePayLog_(generatePayLog),
126-
script_(script), interactive_(interactive), keepNodes_(keepNodes), payLogEntries_(payLogEntries),
127-
context_(context), lastVisitedNode_(lastVisitedNode) {
126+
includePastCashflows_(includePastCashflows), script_(script), interactive_(interactive),
127+
keepNodes_(keepNodes), payLogEntries_(payLogEntries), context_(context), lastVisitedNode_(lastVisitedNode) {
128128
filter.emplace(size_, true);
129129
value.push(RandomVariable());
130130
filter_node.push(ComputationGraph::nan);
@@ -1029,7 +1029,7 @@ class ASTRunner : public AcyclicVisitor,
10291029
QL_REQUIRE(model_, "model is null");
10301030
// handle case of past payments: do not evaluate the other parameters, since not needed (e.g. past fixings)
10311031
Date pay = boost::get<EventVec>(paydate).value;
1032-
if (pay <= model_->referenceDate() && !log) {
1032+
if (pay <= model_->referenceDate() && (!log || !includePastCashflows_)) {
10331033
value.push(RandomVariable(size_, 0.0));
10341034
std::size_t node = cg_const(g_, 0.0);
10351035
value_node.push(node);
@@ -1465,6 +1465,7 @@ class ASTRunner : public AcyclicVisitor,
14651465
const boost::shared_ptr<ModelCG> model_;
14661466
const Size size_;
14671467
const bool generatePayLog_;
1468+
const bool includePastCashflows_;
14681469
const std::string script_;
14691470
bool& interactive_;
14701471
std::set<std::size_t>& keepNodes_;
@@ -1481,14 +1482,15 @@ class ASTRunner : public AcyclicVisitor,
14811482

14821483
} // namespace
14831484

1484-
void ComputationGraphBuilder::run(const bool generatePayLog, const std::string& script, bool interactive) {
1485+
void ComputationGraphBuilder::run(const bool generatePayLog, const bool includePastCashflows, const std::string& script,
1486+
bool interactive) {
14851487

14861488
keepNodes_.clear();
14871489
payLogEntries_.clear();
14881490

14891491
ASTNode* loc;
1490-
ASTRunner runner(g_, opLabels_, model_, generatePayLog, script, interactive, *context_, loc, keepNodes_,
1491-
payLogEntries_);
1492+
ASTRunner runner(g_, opLabels_, model_, generatePayLog, generatePayLog && includePastCashflows, script, interactive,
1493+
*context_, loc, keepNodes_, payLogEntries_);
14921494

14931495
randomvariable_output_pattern pattern;
14941496
if (model_ == nullptr || model_->type() == ModelCG::Type::MC) {

OREData/ored/scripting/computationgraphbuilder.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ class ComputationGraphBuilder {
4949
ComputationGraphBuilder(ComputationGraph& g, const std::vector<std::string>& opLabels, const ASTNodePtr root,
5050
const boost::shared_ptr<Context> context, const boost::shared_ptr<ModelCG> model = nullptr)
5151
: g_(g), opLabels_(opLabels), root_(root), context_(context), model_(model) {}
52-
void run(const bool generatePayLog, const std::string& script = "", bool interactive = false);
52+
void run(const bool generatePayLog, const bool includePastCashflows = false, const std::string& script = "",
53+
bool interactive = false);
5354
const std::set<std::size_t>& keepNodes() const { return keepNodes_; }
5455
const std::vector<PayLogEntry>& payLogEntries() const { return payLogEntries_; }
5556

OREData/ored/scripting/engines/scriptedinstrumentpricingengine.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ void ScriptedInstrumentPricingEngine::calculate() const {
112112
if (generateAdditionalResults_)
113113
paylog = boost::make_shared<PayLog>();
114114

115-
engine.run(script_, interactive_, paylog);
115+
engine.run(script_, interactive_, paylog, includePastCashflows_);
116116

117117
// extract npv result and set it
118118

OREData/ored/scripting/engines/scriptedinstrumentpricingengine.hpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,18 @@ namespace data {
3434

3535
class ScriptedInstrumentPricingEngine : public QuantExt::ScriptedInstrument::engine {
3636
public:
37-
ScriptedInstrumentPricingEngine(
38-
const std::string& npv, const std::vector<std::pair<std::string, std::string>>& additionalResults,
39-
const boost::shared_ptr<Model>& model, const ASTNodePtr ast, const boost::shared_ptr<Context>& context,
40-
const std::string& script = "", const bool interactive = false,
41-
const bool amcEnabled = false,
42-
const std::set<std::string>& amcStickyCloseOutStates = {}, const bool generateAdditionalResults = false)
37+
ScriptedInstrumentPricingEngine(const std::string& npv,
38+
const std::vector<std::pair<std::string, std::string>>& additionalResults,
39+
const boost::shared_ptr<Model>& model, const ASTNodePtr ast,
40+
const boost::shared_ptr<Context>& context, const std::string& script = "",
41+
const bool interactive = false, const bool amcEnabled = false,
42+
const std::set<std::string>& amcStickyCloseOutStates = {},
43+
const bool generateAdditionalResults = false,
44+
const bool includePastCashflows = false)
4345
: npv_(npv), additionalResults_(additionalResults), model_(model), ast_(ast), context_(context),
4446
script_(script), interactive_(interactive), amcEnabled_(amcEnabled),
45-
amcStickyCloseOutStates_(amcStickyCloseOutStates), generateAdditionalResults_(generateAdditionalResults) {
47+
amcStickyCloseOutStates_(amcStickyCloseOutStates), generateAdditionalResults_(generateAdditionalResults),
48+
includePastCashflows_(includePastCashflows) {
4649
registerWith(model_);
4750
}
4851

@@ -65,6 +68,7 @@ class ScriptedInstrumentPricingEngine : public QuantExt::ScriptedInstrument::eng
6568
const bool amcEnabled_;
6669
const std::set<std::string> amcStickyCloseOutStates_;
6770
const bool generateAdditionalResults_;
71+
const bool includePastCashflows_;
6872
};
6973

7074
} // namespace data

OREData/ored/scripting/engines/scriptedinstrumentpricingenginecg.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,12 @@ ScriptedInstrumentPricingEngineCG::ScriptedInstrumentPricingEngineCG(
6868
const std::string& npv, const std::vector<std::pair<std::string, std::string>>& additionalResults,
6969
const boost::shared_ptr<ModelCG>& model, const ASTNodePtr ast, const boost::shared_ptr<Context>& context,
7070
const Model::McParams& mcParams, const std::string& script, const bool interactive,
71-
const bool generateAdditionalResults, const bool useCachedSensis, const bool useExternalComputeFramework)
71+
const bool generateAdditionalResults, const bool includePastCashflows, const bool useCachedSensis,
72+
const bool useExternalComputeFramework)
7273
: npv_(npv), additionalResults_(additionalResults), model_(model), ast_(ast), context_(context),
7374
mcParams_(mcParams), script_(script), interactive_(interactive),
74-
generateAdditionalResults_(generateAdditionalResults), useCachedSensis_(useCachedSensis),
75-
useExternalComputeFramework_(useExternalComputeFramework) {
75+
generateAdditionalResults_(generateAdditionalResults), includePastCashflows_(includePastCashflows),
76+
useCachedSensis_(useCachedSensis), useExternalComputeFramework_(useExternalComputeFramework) {
7677

7778
// register with model
7879

@@ -138,7 +139,7 @@ void ScriptedInstrumentPricingEngineCG::buildComputationGraph() const {
138139
// build graph
139140

140141
ComputationGraphBuilder cgBuilder(*g, getRandomVariableOpLabels(), ast_, workingContext_, model_);
141-
cgBuilder.run(generateAdditionalResults_, script_, interactive_);
142+
cgBuilder.run(generateAdditionalResults_, includePastCashflows_, script_, interactive_);
142143
cgVersion_ = model_->cgVersion();
143144
DLOG("Built computation graph version " << cgVersion_ << " size is " << g->size());
144145
TLOGGERSTREAM(ssaForm(*g, getRandomVariableOpLabels()));

OREData/ored/scripting/engines/scriptedinstrumentpricingenginecg.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ class ScriptedInstrumentPricingEngineCG : public QuantExt::ScriptedInstrument::e
4444
const boost::shared_ptr<ModelCG>& model, const ASTNodePtr ast,
4545
const boost::shared_ptr<Context>& context, const Model::McParams& mcParams,
4646
const std::string& script = "", const bool interactive = false,
47-
const bool generateAdditionalResults = false, const bool useCachedSensis = false,
47+
const bool generateAdditionalResults = false,
48+
const bool includePastCashflows = false, const bool useCachedSensis = false,
4849
const bool useExternalComputeFramework = false);
4950

5051
bool lastCalculationWasValid() const { return lastCalculationWasValid_; }
@@ -106,6 +107,7 @@ class ScriptedInstrumentPricingEngineCG : public QuantExt::ScriptedInstrument::e
106107
const std::string script_;
107108
const bool interactive_;
108109
const bool generateAdditionalResults_;
110+
const bool includePastCashflows_;
109111
const bool useCachedSensis_;
110112
const bool useExternalComputeFramework_;
111113
};

0 commit comments

Comments
 (0)