Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
Public Member Functions | Private Member Functions | Private Attributes | List of all members
ScriptedInstrumentPricingEngine Class Reference

#include <ored/scripting/engines/scriptedinstrumentpricingengine.hpp>

+ Inheritance diagram for ScriptedInstrumentPricingEngine:
+ Collaboration diagram for ScriptedInstrumentPricingEngine:

Public Member Functions

 ScriptedInstrumentPricingEngine (const std::string &npv, const std::vector< std::pair< std::string, std::string > > &additionalResults, const QuantLib::ext::shared_ptr< Model > &model, const ASTNodePtr ast, const QuantLib::ext::shared_ptr< Context > &context, const std::string &script="", const bool interactive=false, const bool amcEnabled=false, const std::set< std::string > &amcStickyCloseOutStates={}, const bool generateAdditionalResults=false, const bool includePastCashflows=false)
 
bool lastCalculationWasValid () const
 

Private Member Functions

void calculate () const override
 
Real addMcErrorEstimate (const std::string &label, const ValueType &v) const
 

Private Attributes

bool lastCalculationWasValid_ = false
 
const std::string npv_
 
const std::vector< std::pair< std::string, std::string > > additionalResults_
 
const QuantLib::ext::shared_ptr< Modelmodel_
 
const ASTNodePtr ast_
 
const QuantLib::ext::shared_ptr< Contextcontext_
 
const std::string script_
 
const bool interactive_
 
const bool amcEnabled_
 
const std::set< std::string > amcStickyCloseOutStates_
 
const bool generateAdditionalResults_
 
const bool includePastCashflows_
 

Detailed Description

Definition at line 35 of file scriptedinstrumentpricingengine.hpp.

Constructor & Destructor Documentation

◆ ScriptedInstrumentPricingEngine()

ScriptedInstrumentPricingEngine ( const std::string &  npv,
const std::vector< std::pair< std::string, std::string > > &  additionalResults,
const QuantLib::ext::shared_ptr< Model > &  model,
const ASTNodePtr  ast,
const QuantLib::ext::shared_ptr< Context > &  context,
const std::string &  script = "",
const bool  interactive = false,
const bool  amcEnabled = false,
const std::set< std::string > &  amcStickyCloseOutStates = {},
const bool  generateAdditionalResults = false,
const bool  includePastCashflows = false 
)

Definition at line 37 of file scriptedinstrumentpricingengine.hpp.

42 {},
43 const bool generateAdditionalResults = false,
44 const bool includePastCashflows = false)
45 : npv_(npv), additionalResults_(additionalResults), model_(model), ast_(ast), context_(context),
46 script_(script), interactive_(interactive), amcEnabled_(amcEnabled),
47 amcStickyCloseOutStates_(amcStickyCloseOutStates), generateAdditionalResults_(generateAdditionalResults),
48 includePastCashflows_(includePastCashflows) {
49 registerWith(model_);
50 }
std::string script
const QuantLib::ext::shared_ptr< Context > context_
const std::vector< std::pair< std::string, std::string > > additionalResults_
const QuantLib::ext::shared_ptr< Model > model_

Member Function Documentation

◆ lastCalculationWasValid()

bool lastCalculationWasValid ( ) const

◆ calculate()

void calculate ( ) const
overrideprivate

Definition at line 67 of file scriptedinstrumentpricingengine.cpp.

67 {
68
70
71 // make sure we release the memory allocated by the model after the pricing
72 struct MemoryReleaser {
73 ~MemoryReleaser() { model->releaseMemory(); }
74 QuantLib::ext::shared_ptr<Model> model;
75 };
76 MemoryReleaser memoryReleaser{model_};
77
78 // set up copy of initial context to run the script engine on
79
80 auto workingContext = QuantLib::ext::make_shared<Context>(*context_);
81
82 // set TODAY in the context
83
84 checkDuplicateName(workingContext, "TODAY");
85 Date referenceDate = model_->referenceDate();
86 workingContext->scalars["TODAY"] = EventVec{model_->size(), referenceDate};
87 workingContext->constants.insert("TODAY");
88
89 // clear NPVMem() regression coefficients
90
91 model_->resetNPVMem();
92
93 // if the model uses a separate training phase for NPV(), run this
94
95 if (model_->trainingSamples() != Null<Size>()) {
96 auto trainingContext = QuantLib::ext::make_shared<Context>(*workingContext);
97 trainingContext->resetSize(model_->trainingSamples());
98 struct TrainingPathToggle {
99 TrainingPathToggle(QuantLib::ext::shared_ptr<Model> model) : model(model) { model->toggleTrainingPaths(); }
100 ~TrainingPathToggle() { model->toggleTrainingPaths(); }
101 QuantLib::ext::shared_ptr<Model> model;
102 } toggle(model_);
103 ScriptEngine trainingEngine(ast_, trainingContext, model_);
104 trainingEngine.run(script_, interactive_);
105 }
106
107 // set up script engine and run it
108
109 ScriptEngine engine(ast_, workingContext, model_);
110
111 QuantLib::ext::shared_ptr<PayLog> paylog;
113 paylog = QuantLib::ext::make_shared<PayLog>();
114
115 engine.run(script_, interactive_, paylog, includePastCashflows_);
116
117 // extract npv result and set it
118
119 auto npv = workingContext->scalars.find(npv_);
120 QL_REQUIRE(npv != workingContext->scalars.end(),
121 "did not find npv result variable '" << npv_ << "' as scalar in context");
122 QL_REQUIRE(npv->second.which() == ValueTypeWhich::Number,
123 "result variable '" << npv_ << "' must be of type NUMBER, got " << npv->second.which());
124 results_.value = model_->extractT0Result(QuantLib::ext::get<RandomVariable>(npv->second));
125 DLOG("got NPV = " << results_.value << " " << model_->baseCcy());
126
127 // set additional results, if this feature is enabled
128
130 results_.errorEstimate = addMcErrorEstimate("NPV_MCErrEst", npv->second);
131 for (auto const& r : additionalResults_) {
132 auto s = workingContext->scalars.find(r.second);
133 bool resultSet = false;
134 if (s != workingContext->scalars.end()) {
135 boost::any t = valueToAny(model_, s->second);
136 results_.additionalResults[r.first] = t;
137 addMcErrorEstimate(r.first + "_MCErrEst", s->second);
138 DLOG("got additional result '" << r.first << "' referencing script variable '" << r.second << "'");
139 resultSet = true;
140 }
141 auto v = workingContext->arrays.find(r.second);
142 if (v != workingContext->arrays.end()) {
143 QL_REQUIRE(!resultSet, "result variable '"
144 << r.first << "' referencing script variable '" << r.second
145 << "' appears both as a scalar and an array, this is unexpected");
146 QL_REQUIRE(!v->second.empty(), "result variable '" << v->first << "' is an empty array.");
147 std::vector<double> tmpdouble;
148 std::vector<std::string> tmpstring;
149 std::vector<QuantLib::Date> tmpdate;
150 for (auto const& d : v->second) {
151 boost::any t = valueToAny(model_, d);
152 if (t.type() == typeid(double))
153 tmpdouble.push_back(boost::any_cast<double>(t));
154 else if (t.type() == typeid(std::string))
155 tmpstring.push_back(boost::any_cast<std::string>(t));
156 else if (t.type() == typeid(QuantLib::Date))
157 tmpdate.push_back(boost::any_cast<QuantLib::Date>(t));
158 else {
159 QL_FAIL("unexpected result type '" << t.type().name() << "' for result variable '" << r.first
160 << "' referencing script variable '" << r.second << "'");
161 }
162 }
163 QL_REQUIRE((int)!tmpdouble.empty() + (int)!tmpstring.empty() + (int)!tmpdate.empty() == 1,
164 "expected exactly one result type in result array '" << v->first << "'");
165 DLOG("got additional result '" << r.first << "' referencing script variable '" << r.second
166 << "' vector of size "
167 << tmpdouble.size() + tmpstring.size() + tmpdate.size());
168 if (!tmpdouble.empty())
169 results_.additionalResults[r.first] = tmpdouble;
170 else if (!tmpstring.empty())
171 results_.additionalResults[r.first] = tmpstring;
172 else if (!tmpdate.empty())
173 results_.additionalResults[r.first] = tmpdate;
174 else {
175 QL_FAIL("got empty result vector for result variable '"
176 << r.first << "' referencing script variable '" << r.second << "', this is unexpected");
177 }
178 std::vector<double> errEst;
179 for (auto const& d : v->second) {
180 errEst.push_back(addMcErrorEstimate(std::string(), d));
181 }
182 if (!errEst.empty() && errEst.front() != Null<Real>())
183 results_.additionalResults[r.first + "_MCErrEst"] = errEst;
184 resultSet = true;
185 }
186 QL_REQUIRE(resultSet, "could not set additional result '" << r.first << "' referencing script variable '"
187 << r.second << "'");
188 }
189
190 // set contents from paylog as additional results
191
192 paylog->consolidateAndSort();
193 std::vector<CashFlowResults> cashFlowResults(paylog->size());
194 std::map<Size, Size> cashflowNumber;
195 for (Size i = 0; i < paylog->size(); ++i) {
196 // cashflow is written as expectation of deflated base ccy amount at T0, converted to flow ccy
197 // with the T0 FX Spot and compounded back to the pay date on T0 curves
198 Real fx = 1.0;
199 Real discount = 1.0;
200 if (paylog->dates().at(i) > model_->referenceDate()) {
201 fx = model_->fxSpotT0(paylog->currencies().at(i), model_->baseCcy());
202 discount = model_->discount(referenceDate, paylog->dates().at(i), paylog->currencies().at(i)).at(0);
203 }
204 cashFlowResults[i].amount = model_->extractT0Result(paylog->amounts().at(i)) / fx / discount;
205 cashFlowResults[i].payDate = paylog->dates().at(i);
206 cashFlowResults[i].currency = paylog->currencies().at(i);
207 cashFlowResults[i].legNumber = paylog->legNos().at(i);
208 cashFlowResults[i].type = paylog->cashflowTypes().at(i);
209 DLOG("got cashflow " << QuantLib::io::iso_date(cashFlowResults[i].payDate) << " "
210 << cashFlowResults[i].currency << cashFlowResults[i].amount << " "
211 << cashFlowResults[i].currency << "-" << model_->baseCcy() << " " << fx << " discount("
212 << cashFlowResults[i].currency << ") " << discount);
213 if (paylog->dates().at(i) > model_->referenceDate()) {
214 addMcErrorEstimate("cashflow_" + std::to_string(paylog->legNos().at(i)) + "_" +
215 std::to_string(++cashflowNumber[paylog->legNos().at(i)]) + "_MCErrEst",
216 paylog->amounts().at(i) /
217 RandomVariable(paylog->amounts().at(i).size(), (fx * discount)));
218 }
219 }
220 results_.additionalResults["cashFlowResults"] = cashFlowResults;
221
222 // set additional results from the model
223
224 results_.additionalResults.insert(model_->additionalResults().begin(), model_->additionalResults().end());
225
226 } // if generate additional results
227
228 // if the engine is amc enabled, add an amc calculator to the additional results
229
230 if (amcEnabled_) {
231 DLOG("add amc calculator to results");
232 results_.additionalResults["amcCalculator"] =
233 QuantLib::ext::static_pointer_cast<AmcCalculator>(QuantLib::ext::make_shared<ScriptedInstrumentAmcCalculator>(
235 }
236
238}
const Instrument::results * results_
Real addMcErrorEstimate(const std::string &label, const ValueType &v) const
#define DLOG(text)
Logging Macro (Level = Debug)
Definition: log.hpp:554
Date referenceDate
Definition: utilities.cpp:442
void checkDuplicateName(const QuantLib::ext::shared_ptr< Context > context, const std::string &name)
Definition: utilities.cpp:156
+ Here is the call graph for this function:

◆ addMcErrorEstimate()

Real addMcErrorEstimate ( const std::string &  label,
const ValueType v 
) const
private

Definition at line 55 of file scriptedinstrumentpricingengine.cpp.

55 {
56 if (model_->type() != Model::Type::MC)
57 return Null<Real>();
58 if (v.which() != ValueTypeWhich::Number)
59 return Null<Real>();
60 Real var = variance(QuantLib::ext::get<RandomVariable>(v)).at(0);
61 Real errEst = std::sqrt(var / static_cast<double>(model_->size()));
62 if(!label.empty())
63 results_.additionalResults[label] = errEst;
64 return errEst;
65}
RandomVariable variance(const RandomVariable &r)
Real at(const Size i) const
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Member Data Documentation

◆ lastCalculationWasValid_

bool lastCalculationWasValid_ = false
mutableprivate

Definition at line 59 of file scriptedinstrumentpricingengine.hpp.

◆ npv_

const std::string npv_
private

Definition at line 61 of file scriptedinstrumentpricingengine.hpp.

◆ additionalResults_

const std::vector<std::pair<std::string, std::string> > additionalResults_
private

Definition at line 62 of file scriptedinstrumentpricingengine.hpp.

◆ model_

const QuantLib::ext::shared_ptr<Model> model_
private

Definition at line 63 of file scriptedinstrumentpricingengine.hpp.

◆ ast_

const ASTNodePtr ast_
private

Definition at line 64 of file scriptedinstrumentpricingengine.hpp.

◆ context_

const QuantLib::ext::shared_ptr<Context> context_
private

Definition at line 65 of file scriptedinstrumentpricingengine.hpp.

◆ script_

const std::string script_
private

Definition at line 66 of file scriptedinstrumentpricingengine.hpp.

◆ interactive_

const bool interactive_
private

Definition at line 67 of file scriptedinstrumentpricingengine.hpp.

◆ amcEnabled_

const bool amcEnabled_
private

Definition at line 68 of file scriptedinstrumentpricingengine.hpp.

◆ amcStickyCloseOutStates_

const std::set<std::string> amcStickyCloseOutStates_
private

Definition at line 69 of file scriptedinstrumentpricingengine.hpp.

◆ generateAdditionalResults_

const bool generateAdditionalResults_
private

Definition at line 70 of file scriptedinstrumentpricingengine.hpp.

◆ includePastCashflows_

const bool includePastCashflows_
private

Definition at line 71 of file scriptedinstrumentpricingengine.hpp.