Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
Classes | Public Types | Public Member Functions | Protected Types | Protected Member Functions | Protected Attributes | Private Member Functions | List of all members
MarketRiskBacktest Class Referenceabstract

#include <orea/engine/marketriskbacktest.hpp>

+ Inheritance diagram for MarketRiskBacktest:
+ Collaboration diagram for MarketRiskBacktest:

Classes

struct  BacktestArgs
 
class  BacktestReports
 
struct  Data
 Used to pass information. More...
 
struct  SummaryResults
 Used to store results for writing rows in the summary report. More...
 
struct  VarBenchmark
 

Public Types

enum class  VarType { HistSim , HistSimTaylor , Parametric , Lch }
 VAR types used as a benchmark against which SIMM can be compared. More...
 

Public Member Functions

 MarketRiskBacktest (const std::string &calculationCurrency, const QuantLib::ext::shared_ptr< ore::data::Portfolio > &portfolio, const std::string &portfolioFilter, std::unique_ptr< BacktestArgs > btArgs, std::unique_ptr< SensiRunArgs > sensiArgs=nullptr, std::unique_ptr< FullRevalArgs > revalArgs=nullptr, std::unique_ptr< MultiThreadArgs > mtArgs=nullptr, const QuantLib::ext::shared_ptr< ore::analytics::HistoricalScenarioGenerator > &hisScenGen=nullptr, const bool breakdown=false, const bool requireTradePnl=false)
 
virtual ~MarketRiskBacktest ()
 
bool disablesAll (const QuantLib::ext::shared_ptr< ore::analytics::ScenarioFilter > &filter) const override
 
virtual void addPnlRow (const QuantLib::ext::shared_ptr< BacktestReports > &reports, QuantLib::Size scenarioIdx, bool isCall, const ore::analytics::RiskFactorKey &key_1, QuantLib::Real shift_1, QuantLib::Real delta, QuantLib::Real gamma, QuantLib::Real deltaPnl, QuantLib::Real gammaPnl, const ore::analytics::RiskFactorKey &key_2=ore::analytics::RiskFactorKey(), QuantLib::Real shift_2=0.0, const std::string &tradeId="", const std::string &currency="", QuantLib::Real fxSpot=1.0)
 Add a row to the P&L contribution report. More...
 
- Public Member Functions inherited from MarketRiskReport
 MarketRiskReport (const std::string &calculationCurrency, const QuantLib::ext::shared_ptr< Portfolio > &portfolio, const std::string &portfolioFilter, boost::optional< ore::data::TimePeriod > period, const QuantLib::ext::shared_ptr< HistoricalScenarioGenerator > &hisScenGen=nullptr, std::unique_ptr< SensiRunArgs > sensiArgs=nullptr, std::unique_ptr< FullRevalArgs > fullRevalArgs=nullptr, std::unique_ptr< MultiThreadArgs > multiThreadArgs=nullptr, const bool breakdown=false, const bool requireTradePnl=false)
 
virtual ~MarketRiskReport ()
 
virtual void initialise ()
 
void initSimMarket ()
 Method to init simMarket_ for multi-threaded ctors. More...
 
virtual void calculate (const QuantLib::ext::shared_ptr< Reports > &report)
 
void enableCubeWrite (const std::string &cubeDir, const std::string &cubeFilename)
 
- Public Member Functions inherited from ProgressReporter
 ProgressReporter ()
 
void registerProgressIndicator (const QuantLib::ext::shared_ptr< ProgressIndicator > &indicator)
 
void unregisterProgressIndicator (const QuantLib::ext::shared_ptr< ProgressIndicator > &indicator)
 
void unregisterAllProgressIndicators ()
 
void updateProgress (const unsigned long progress, const unsigned long total, const std::string &detail="")
 
void resetProgress ()
 
const std::set< QuantLib::ext::shared_ptr< ProgressIndicator > > & progressIndicators () const
 

Protected Types

typedef std::map< VarType, std::pair< QuantLib::ext::shared_ptr< ore::analytics::VarCalculator >, QuantLib::Real > > VarBenchmarks
 pointers to the VAR benchmarks More...
 

Protected Member Functions

void initialise () override
 
virtual const std::vector< std::tuple< std::string, ore::data::Report::ReportType, QuantLib::Size > > summaryColumns ()=0
 
virtual const std::vector< std::tuple< std::string, ore::data::Report::ReportType, QuantLib::Size, bool > > detailColumns ()=0
 
virtual const std::vector< std::tuple< std::string, ore::data::Report::ReportType, QuantLib::Size > > pnlColumns ()=0
 
virtual QuantLib::Real callValue (const Data &data)=0
 
virtual QuantLib::Real postValue (const Data &data)=0
 
virtual std::string counterparty (const std::string &tradeId) const =0
 
virtual void setUpBenchmarks ()=0
 
virtual void reset (const QuantLib::ext::shared_ptr< ore::analytics::MarketRiskGroupBase > &riskGroup) override
 
void createReports (const QuantLib::ext::shared_ptr< MarketRiskReport::Reports > &reports) override
 
virtual bool runTradeDetail (const QuantLib::ext::shared_ptr< MarketRiskReport::Reports > &reports) override
 
ore::data::TimePeriod covariancePeriod () const override
 
void addPnlCalculators (const QuantLib::ext::shared_ptr< MarketRiskReport::Reports > &reports) override
 
void handleSensiResults (const QuantLib::ext::shared_ptr< MarketRiskReport::Reports > &reports, const QuantLib::ext::shared_ptr< ore::analytics::MarketRiskGroupBase > &riskGroup, const QuantLib::ext::shared_ptr< ore::analytics::TradeGroupBase > &tradeGroup) override
 
void handleFullRevalResults (const QuantLib::ext::shared_ptr< MarketRiskReport::Reports > &reports, const QuantLib::ext::shared_ptr< ore::analytics::MarketRiskGroupBase > &riskGroup, const QuantLib::ext::shared_ptr< ore::analytics::TradeGroupBase > &tradeGroup) override
 
virtual void adjustFullRevalPnls (std::vector< QuantLib::Real > &pnls, std::vector< QuantLib::Real > &bmPnls, ore::analytics::TradePnLStore &tradePnls, const std::vector< QuantLib::Real > &foSensiPnls, const std::vector< QuantLib::Real > &bmFoSensiPnls, const ore::analytics::TradePnLStore &foTradePnls, const QuantLib::ext::shared_ptr< ore::analytics::MarketRiskGroupBase > &riskGroup)
 
virtual void addDetailRow (const QuantLib::ext::shared_ptr< BacktestReports > &reports, const Data &data, bool isCall, QuantLib::Real im, const QuantLib::Date &start, const QuantLib::Date &end, bool isFull, QuantLib::Real pnl, const std::string &result, const std::string &tradeId="") const =0
 Add a row to the detail report. More...
 
virtual void addSummaryRow (const QuantLib::ext::shared_ptr< BacktestReports > &reports, const Data &data, bool isCall, QuantLib::Real im, QuantLib::Size observations, bool isFull, QuantLib::Size exceptions, const std::vector< QuantLib::Size > &ragBounds, const VarBenchmarks &sensiBenchmarks, const VarBenchmarks &fullBenchmarks) const =0
 Add a row to the summary report. More...
 
virtual void calculateBenchmarks (VarBenchmarks &benchmarks, QuantLib::Real confidence, const bool isCall, const QuantLib::ext::shared_ptr< ore::analytics::MarketRiskGroupBase > &riskGroup, std::set< std::pair< std::string, QuantLib::Size > > &tradeIdIdxPairs)
 Calculate and update the benchmarks. More...
 
void writeReports (const QuantLib::ext::shared_ptr< MarketRiskReport::Reports > &reports, const QuantLib::ext::shared_ptr< ore::analytics::MarketRiskGroupBase > &riskGroup, const QuantLib::ext::shared_ptr< ore::analytics::TradeGroupBase > &tradeGroup) override
 
std::vector< ore::data::TimePeriodtimePeriods () override
 
- Protected Member Functions inherited from MarketRiskReport
virtual void initialiseRiskGroups ()
 Method for shared initialisation. More...
 
virtual void registerProgressIndicators ()
 
virtual void createReports (const QuantLib::ext::shared_ptr< MarketRiskReport::Reports > &reports)=0
 
virtual bool runTradeDetail (const QuantLib::ext::shared_ptr< MarketRiskReport::Reports > &reports)
 
virtual QuantLib::ext::shared_ptr< ScenarioFiltercreateScenarioFilter (const QuantLib::ext::shared_ptr< MarketRiskGroupBase > &riskGroup)
 
virtual void reset (const QuantLib::ext::shared_ptr< MarketRiskGroupBase > &riskGroup)
 
virtual bool runTradeRiskGroup (const QuantLib::ext::shared_ptr< TradeGroupBase > &tradeGroup, const QuantLib::ext::shared_ptr< MarketRiskGroupBase > &riskGroup) const
 
virtual bool disablesAll (const QuantLib::ext::shared_ptr< ScenarioFilter > &filter) const
 
virtual void updateFilter (const QuantLib::ext::shared_ptr< MarketRiskGroupBase > &riskGroup, const QuantLib::ext::shared_ptr< ScenarioFilter > &filter)
 update any filters required More...
 
virtual std::string portfolioId (const QuantLib::ext::shared_ptr< TradeGroupBase > &tradeGroup) const
 
virtual std::string tradeGroupKey (const QuantLib::ext::shared_ptr< TradeGroupBase > &tradeGroup) const
 
virtual ore::data::TimePeriod covariancePeriod () const
 
virtual void addPnlCalculators (const QuantLib::ext::shared_ptr< MarketRiskReport::Reports > &reports)
 
virtual void handleSensiResults (const QuantLib::ext::shared_ptr< MarketRiskReport::Reports > &report, const QuantLib::ext::shared_ptr< MarketRiskGroupBase > &riskGroup, const QuantLib::ext::shared_ptr< TradeGroupBase > &tradeGroup)
 
virtual void handleFullRevalResults (const QuantLib::ext::shared_ptr< MarketRiskReport::Reports > &reports, const QuantLib::ext::shared_ptr< MarketRiskGroupBase > &riskGroup, const QuantLib::ext::shared_ptr< TradeGroupBase > &tradeGroup)
 
virtual bool includeDeltaMargin (const QuantLib::ext::shared_ptr< MarketRiskGroupBase > &riskGroup) const
 
virtual bool includeGammaMargin (const QuantLib::ext::shared_ptr< MarketRiskGroupBase > &riskGroup) const
 
virtual bool runFullReval (const QuantLib::ext::shared_ptr< MarketRiskGroupBase > &riskGroup) const
 
virtual bool generateCube (const QuantLib::ext::shared_ptr< MarketRiskGroupBase > &riskGroup) const
 
virtual std::string cubeFilePath (const QuantLib::ext::shared_ptr< MarketRiskGroupBase > &riskGroup) const
 
virtual std::vector< ore::data::TimePeriodtimePeriods ()
 
virtual void writeReports (const QuantLib::ext::shared_ptr< MarketRiskReport::Reports > &reports, const QuantLib::ext::shared_ptr< MarketRiskGroupBase > &riskGroup, const QuantLib::ext::shared_ptr< TradeGroupBase > &tradeGroup)
 
virtual void closeReports (const QuantLib::ext::shared_ptr< MarketRiskReport::Reports > &reports)
 

Protected Attributes

std::unique_ptr< BacktestArgsbtArgs_
 
VarBenchmarks sensiCallBenchmarks_
 
VarBenchmarks sensiPostBenchmarks_
 
VarBenchmarks fullRevalCallBenchmarks_
 
VarBenchmarks fullRevalPostBenchmarks_
 
std::vector< QuantLib::Real > bmSensiPnls_
 variables for benchmark calculations More...
 
std::vector< QuantLib::Real > bmFoSensiPnls_
 
std::vector< QuantLib::Real > pnls_
 
std::vector< QuantLib::Real > bmPnls_
 
std::vector< QuantLib::Real > sensiPnls_
 
std::vector< QuantLib::Real > foSensiPnls_
 
ore::analytics::TradePnLStore foTradePnls_
 
ore::analytics::TradePnLStore tradePnls_
 
ore::analytics::TradePnLStore sensiTradePnls_
 
std::set< std::string > callTradeIds_
 
std::set< std::string > postTradeIds_
 
- Protected Attributes inherited from MarketRiskReport
bool sensiBased_ = false
 
bool fullReval_ = false
 
std::string calculationCurrency_
 
QuantLib::ext::shared_ptr< Portfolioportfolio_
 
std::string portfolioFilter_
 
boost::optional< ore::data::TimePeriodperiod_
 
QuantLib::ext::shared_ptr< HistoricalScenarioGeneratorhisScenGen_
 
std::unique_ptr< SensiRunArgssensiArgs_
 
std::unique_ptr< FullRevalArgsfullRevalArgs_
 
std::unique_ptr< MultiThreadArgsmultiThreadArgs_
 
bool breakdown_ = false
 
bool requireTradePnl_ = false
 
QuantLib::ext::shared_ptr< MarketRiskGroupBaseContainerriskGroups_
 
QuantLib::ext::shared_ptr< TradeGroupBaseContainertradeGroups_
 
std::map< std::string, std::set< std::pair< std::string, QuantLib::Size > > > tradeIdGroups_
 
std::set< std::pair< std::string, QuantLib::Size > > tradeIdIdxPairs_
 
std::vector< std::string > tradeIds_
 
std::map< RiskFactorKey, QuantLib::Real > deltas_
 
std::map< std::pair< RiskFactorKey, RiskFactorKey >, QuantLib::Real > gammas_
 
QuantLib::Matrix covarianceMatrix_
 
bool writePnl_ = false
 
std::vector< QuantLib::ext::shared_ptr< PNLCalculator > > pnlCalculators_
 
QuantLib::ext::shared_ptr< QuantExt::CovarianceSalvagesalvage_
 
bool includeDeltaMargin_ = true
 
bool includeGammaMargin_ = true
 
QuantLib::ext::shared_ptr< ore::data::EngineFactoryfactory_
 
QuantLib::ext::shared_ptr< ore::analytics::HistoricalPnlGeneratorhistPnlGen_
 
QuantLib::ext::shared_ptr< HistoricalSensiPnlCalculatorsensiPnlCalculator_
 

Private Member Functions

SummaryResults calculateSummary (const QuantLib::ext::shared_ptr< BacktestReports > &reports, const Data &data, bool isFull, const std::vector< QuantLib::Real > &pnls, const std::vector< std::string > &tradeIds, const TradePnLStore &tradePnls)
 

Detailed Description

Definition at line 41 of file marketriskbacktest.hpp.

Member Typedef Documentation

◆ VarBenchmarks

typedef std::map<VarType, std::pair<QuantLib::ext::shared_ptr<ore::analytics::VarCalculator>, QuantLib::Real> > VarBenchmarks
protected

pointers to the VAR benchmarks

Definition at line 159 of file marketriskbacktest.hpp.

Member Enumeration Documentation

◆ VarType

enum class VarType
strong

VAR types used as a benchmark against which SIMM can be compared.

Enumerator
HistSim 
HistSimTaylor 
Parametric 
Lch 

Definition at line 44 of file marketriskbacktest.hpp.

Constructor & Destructor Documentation

◆ MarketRiskBacktest()

MarketRiskBacktest ( const std::string &  calculationCurrency,
const QuantLib::ext::shared_ptr< ore::data::Portfolio > &  portfolio,
const std::string &  portfolioFilter,
std::unique_ptr< BacktestArgs btArgs,
std::unique_ptr< SensiRunArgs sensiArgs = nullptr,
std::unique_ptr< FullRevalArgs revalArgs = nullptr,
std::unique_ptr< MultiThreadArgs mtArgs = nullptr,
const QuantLib::ext::shared_ptr< ore::analytics::HistoricalScenarioGenerator > &  hisScenGen = nullptr,
const bool  breakdown = false,
const bool  requireTradePnl = false 
)

Definition at line 48 of file marketriskbacktest.cpp.

59 : MarketRiskReport(calculationCurrency, portfolio, portfolioFilter, btArgs->backtestPeriod_, hisScenGen, std::move(sensiArgs), std::move(revalArgs),
60 std::move(mtArgs), breakdown, requireTradePnl),
61 btArgs_(std::move(btArgs)) {
62}
std::unique_ptr< BacktestArgs > btArgs_

◆ ~MarketRiskBacktest()

virtual ~MarketRiskBacktest ( )
virtual

Definition at line 137 of file marketriskbacktest.hpp.

137{}

Member Function Documentation

◆ disablesAll()

bool disablesAll ( const QuantLib::ext::shared_ptr< ore::analytics::ScenarioFilter > &  filter) const
override

Check if the given scenario filter turns off all risk factors in the historical scenario generator

Definition at line 173 of file marketriskbacktest.cpp.

173 {
174 // Return false if we hit any risk factor that is "allowed" i.e. enabled
175 for (const auto& key : hisScenGen_->baseScenario()->keys()) {
176 if (filter->allow(key)) {
177 return false;
178 }
179 }
180 // If we get to here, all risk factors are "not allowed" i.e. disabled
181 return true;
182}
QuantLib::ext::shared_ptr< HistoricalScenarioGenerator > hisScenGen_
SafeStack< Filter > filter

◆ addPnlRow()

void addPnlRow ( const QuantLib::ext::shared_ptr< BacktestReports > &  reports,
QuantLib::Size  scenarioIdx,
bool  isCall,
const ore::analytics::RiskFactorKey key_1,
QuantLib::Real  shift_1,
QuantLib::Real  delta,
QuantLib::Real  gamma,
QuantLib::Real  deltaPnl,
QuantLib::Real  gammaPnl,
const ore::analytics::RiskFactorKey key_2 = ore::analytics::RiskFactorKey(),
QuantLib::Real  shift_2 = 0.0,
const std::string &  tradeId = "",
const std::string &  currency = "",
QuantLib::Real  fxSpot = 1.0 
)
virtual

Add a row to the P&L contribution report.

Definition at line 372 of file marketriskbacktest.cpp.

374 {
375
376 // Do we have a report to write to?
377 // Is this too slow to do on every call to addPnlRow? Need to find the report each time in any case.
378 QuantLib::ext::shared_ptr<ore::data::Report> rpt;
379 if (tradeId.empty()) {
382 } else {
385 }
386
387 // If we have no report or below threshold, do nothing.
388 if (!rpt ||
389 (std::abs(deltaPnl) < sensiArgs_->pnlWriteThreshold_ && std::abs(gammaPnl) < sensiArgs_->pnlWriteThreshold_))
390 return;
391
392 // Add the trade ID if we are writing trade level entries.
393 auto& report = tradeId.empty() ? rpt->next() : rpt->next().add(tradeId);
394
395 // Add the fields common to the trade level and aggregate reports.
396 report.add(hisScenGen_->startDates()[scenarioIdx])
397 .add(hisScenGen_->endDates()[scenarioIdx])
398 .add(isCall ? "call" : "post")
399 .add(to_string(key_1))
400 .add(to_string(key_2))
401 .add(delta)
402 .add(gamma)
403 .add(shift_1)
404 .add(shift_2)
405 .add(currency.empty() || currency == calculationCurrency_ ? deltaPnl : deltaPnl / fxSpot)
406 .add(currency.empty() || currency == calculationCurrency_ ? gammaPnl : gammaPnl / fxSpot)
407 .add(currency.empty() ? calculationCurrency_ : currency);
408}
std::unique_ptr< SensiRunArgs > sensiArgs_
std::string to_string(const LocationInfo &l)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ initialise()

void initialise ( )
overrideprotectedvirtual

Reimplemented from MarketRiskReport.

Definition at line 64 of file marketriskbacktest.cpp.

64 {
65 callTradeIds_ = btArgs_->callTradeIds_;
66 postTradeIds_ = btArgs_->postTradeIds_;
67
68 // If there is a mismatch between call and post, then we will have to exclude trade-level PnLs from the total (scenario) PnL
70
72}
+ Here is the call graph for this function:

◆ summaryColumns()

virtual const std::vector< std::tuple< std::string, ore::data::Report::ReportType, QuantLib::Size > > summaryColumns ( )
protectedpure virtual
+ Here is the caller graph for this function:

◆ detailColumns()

virtual const std::vector< std::tuple< std::string, ore::data::Report::ReportType, QuantLib::Size, bool > > detailColumns ( )
protectedpure virtual
+ Here is the caller graph for this function:

◆ pnlColumns()

virtual const std::vector< std::tuple< std::string, ore::data::Report::ReportType, QuantLib::Size > > pnlColumns ( )
protectedpure virtual
+ Here is the caller graph for this function:

◆ callValue()

virtual QuantLib::Real callValue ( const Data data)
protectedpure virtual
+ Here is the caller graph for this function:

◆ postValue()

virtual QuantLib::Real postValue ( const Data data)
protectedpure virtual
+ Here is the caller graph for this function:

◆ counterparty()

virtual std::string counterparty ( const std::string &  tradeId) const
protectedpure virtual
+ Here is the caller graph for this function:

◆ setUpBenchmarks()

virtual void setUpBenchmarks ( )
protectedpure virtual

◆ reset()

void reset ( const QuantLib::ext::shared_ptr< ore::analytics::MarketRiskGroupBase > &  riskGroup)
overrideprotectedvirtual

Definition at line 351 of file marketriskbacktest.cpp.

351 {
352 MarketRiskReport::reset(riskGroup);
353 bmSensiPnls_.clear();
354 pnls_.clear();
355 bmPnls_.clear();
356 foSensiPnls_.clear();
357 bmFoSensiPnls_.clear();
358 sensiPnls_.clear();
359 tradePnls_.clear();
360 sensiTradePnls_.clear();
361 foTradePnls_.clear();
362 for (auto& [type, value] : sensiCallBenchmarks_)
363 value.second = 0.0;
364 for (auto& [type, value] : sensiPostBenchmarks_)
365 value.second = 0.0;
366 for (auto& [type, value] : fullRevalCallBenchmarks_)
367 value.second = 0.0;
368 for (auto& [type, value] : fullRevalPostBenchmarks_)
369 value.second = 0.0;
370}
ore::analytics::TradePnLStore tradePnls_
std::vector< QuantLib::Real > pnls_
ore::analytics::TradePnLStore sensiTradePnls_
std::vector< QuantLib::Real > sensiPnls_
ore::analytics::TradePnLStore foTradePnls_
std::vector< QuantLib::Real > bmPnls_
std::vector< QuantLib::Real > foSensiPnls_
std::vector< QuantLib::Real > bmFoSensiPnls_
std::vector< QuantLib::Real > bmSensiPnls_
variables for benchmark calculations
virtual void reset(const QuantLib::ext::shared_ptr< MarketRiskGroupBase > &riskGroup)
SafeStack< ValueType > value
+ Here is the call graph for this function:

◆ createReports()

void createReports ( const QuantLib::ext::shared_ptr< MarketRiskReport::Reports > &  reports)
overrideprotectedvirtual

Implements MarketRiskReport.

Definition at line 290 of file marketriskbacktest.cpp.

290 {
291
292 auto rpts = ext::dynamic_pointer_cast<BacktestReports>(reports);
293 QL_REQUIRE(rpts, "Reports must be of type BacktestReports");
294
296 auto summary = rpts->get(BacktestReports::ReportType::Summary);
297 if (summary) {
298 for (const auto& t : summaryColumns())
299 summary->addColumn(std::get<0>(t), std::get<1>(t), std::get<2>(t));
300 }
301 }
302
304 auto detail = rpts->get(BacktestReports::ReportType::Detail);
305 if (detail) {
306 for (const auto& t : detailColumns())
307 detail->addColumn(std::get<0>(t), std::get<1>(t), std::get<2>(t));
308 }
309 }
310
312 auto detailTrade = rpts->get(BacktestReports::ReportType::DetailTrade);
313 if (detailTrade) {
314 detailTrade->addColumn("TradeId", string());
315 for (const auto& t : detailColumns()) {
316 if (btArgs_->tradeDetailIncludeAllColumns_ || std::get<3>(t))
317 detailTrade->addColumn(std::get<0>(t), std::get<1>(t), std::get<2>(t));
318 }
319 }
320 }
321
324 if (pnl) {
325 for (const auto& t : pnlColumns())
326 pnl->addColumn(std::get<0>(t), std::get<1>(t), std::get<2>(t));
327 }
328 }
329
331 auto pnlTrade = rpts->get(BacktestReports::ReportType::PnlContributionTrade);
332 if (pnlTrade) {
333 pnlTrade->addColumn("TradeId", string());
334 for (const auto& t : pnlColumns())
335 pnlTrade->addColumn(std::get<0>(t), std::get<1>(t), std::get<2>(t));
336 }
337 }
338}
virtual const std::vector< std::tuple< std::string, ore::data::Report::ReportType, QuantLib::Size, bool > > detailColumns()=0
virtual const std::vector< std::tuple< std::string, ore::data::Report::ReportType, QuantLib::Size > > pnlColumns()=0
virtual const std::vector< std::tuple< std::string, ore::data::Report::ReportType, QuantLib::Size > > summaryColumns()=0
+ Here is the call graph for this function:

◆ runTradeDetail()

bool runTradeDetail ( const QuantLib::ext::shared_ptr< MarketRiskReport::Reports > &  reports)
overrideprotectedvirtual

Reimplemented from MarketRiskReport.

Definition at line 80 of file marketriskbacktest.cpp.

80 {
81 auto rpts = ext::dynamic_pointer_cast<BacktestReports>(reports);
82 bool trdDetail = false;
84 auto detailTrade = rpts->get(BacktestReports::ReportType::DetailTrade);
85 trdDetail = detailTrade != nullptr;
86 }
87 return requireTradePnl_ || trdDetail;
88}
+ Here is the caller graph for this function:

◆ covariancePeriod()

ore::data::TimePeriod covariancePeriod ( ) const
overrideprotectedvirtual

Reimplemented from MarketRiskReport.

Definition at line 179 of file marketriskbacktest.hpp.

179{ return btArgs_->benchmarkPeriod_; }

◆ addPnlCalculators()

void addPnlCalculators ( const QuantLib::ext::shared_ptr< MarketRiskReport::Reports > &  reports)
overrideprotectedvirtual

Reimplemented from MarketRiskReport.

Definition at line 90 of file marketriskbacktest.cpp.

90 {
91 pnlCalculators_.push_back(
92 QuantLib::ext::make_shared<PNLCalculator>(btArgs_->benchmarkPeriod_));
93 auto btRpts = ext::dynamic_pointer_cast<BacktestReports>(reports);
94 pnlCalculators_.push_back(
95 QuantLib::ext::make_shared<BacktestPNLCalculator>(btArgs_->backtestPeriod_, writePnl_, this, btRpts));
96}
std::vector< QuantLib::ext::shared_ptr< PNLCalculator > > pnlCalculators_

◆ handleSensiResults()

void handleSensiResults ( const QuantLib::ext::shared_ptr< MarketRiskReport::Reports > &  reports,
const QuantLib::ext::shared_ptr< ore::analytics::MarketRiskGroupBase > &  riskGroup,
const QuantLib::ext::shared_ptr< ore::analytics::TradeGroupBase > &  tradeGroup 
)
overrideprotected

Definition at line 99 of file marketriskbacktest.cpp.

101 {
102 QL_REQUIRE(pnlCalculators_.size() == 2, "Expecting 2 PNL Calculators for Backtest");
103 bmSensiPnls_ = pnlCalculators_[0]->pnls();
104 bmFoSensiPnls_ = pnlCalculators_[0]->foPnls();
105 sensiPnls_ = pnlCalculators_[1]->pnls();
106 foSensiPnls_ = pnlCalculators_[1]->foPnls();
107
108 auto backtestPnlCalc = ext::dynamic_pointer_cast < BacktestPNLCalculator>(pnlCalculators_[1]);
109 QL_REQUIRE(backtestPnlCalc, "We must have a BacktestPnLCalculator");
110 if (runTradeDetail(reports)) {
111 foTradePnls_ = backtestPnlCalc->foTradePnls();
112 sensiTradePnls_ = backtestPnlCalc->tradePnls();
113 }
114
115 // Calculate benchmarks
116 calculateBenchmarks(sensiCallBenchmarks_, btArgs_->confidence_, true, riskGroup, tradeIdIdxPairs_);
117 calculateBenchmarks(sensiPostBenchmarks_, btArgs_->confidence_, false, riskGroup, tradeIdIdxPairs_);
118}
virtual bool runTradeDetail(const QuantLib::ext::shared_ptr< MarketRiskReport::Reports > &reports) override
virtual void calculateBenchmarks(VarBenchmarks &benchmarks, QuantLib::Real confidence, const bool isCall, const QuantLib::ext::shared_ptr< ore::analytics::MarketRiskGroupBase > &riskGroup, std::set< std::pair< std::string, QuantLib::Size > > &tradeIdIdxPairs)
Calculate and update the benchmarks.
std::set< std::pair< std::string, QuantLib::Size > > tradeIdIdxPairs_
+ Here is the call graph for this function:

◆ handleFullRevalResults()

void handleFullRevalResults ( const QuantLib::ext::shared_ptr< MarketRiskReport::Reports > &  reports,
const QuantLib::ext::shared_ptr< ore::analytics::MarketRiskGroupBase > &  riskGroup,
const QuantLib::ext::shared_ptr< ore::analytics::TradeGroupBase > &  tradeGroup 
)
overrideprotected

Definition at line 120 of file marketriskbacktest.cpp.

122 {
123
124 QL_REQUIRE(histPnlGen_, "Must have a Historical PNL Generator");
125 pnls_ = histPnlGen_->pnl(btArgs_->backtestPeriod_, tradeIdIdxPairs_);
126 bmPnls_ = histPnlGen_->pnl(btArgs_->benchmarkPeriod_, tradeIdIdxPairs_);
127
128 if (runTradeDetail(reports))
129 tradePnls_ = histPnlGen_->tradeLevelPnl(btArgs_->backtestPeriod_, tradeIdIdxPairs_);
130
132
135}
virtual void adjustFullRevalPnls(std::vector< QuantLib::Real > &pnls, std::vector< QuantLib::Real > &bmPnls, ore::analytics::TradePnLStore &tradePnls, const std::vector< QuantLib::Real > &foSensiPnls, const std::vector< QuantLib::Real > &bmFoSensiPnls, const ore::analytics::TradePnLStore &foTradePnls, const QuantLib::ext::shared_ptr< ore::analytics::MarketRiskGroupBase > &riskGroup)
QuantLib::ext::shared_ptr< ore::analytics::HistoricalPnlGenerator > histPnlGen_
+ Here is the call graph for this function:

◆ adjustFullRevalPnls()

virtual void adjustFullRevalPnls ( std::vector< QuantLib::Real > &  pnls,
std::vector< QuantLib::Real > &  bmPnls,
ore::analytics::TradePnLStore tradePnls,
const std::vector< QuantLib::Real > &  foSensiPnls,
const std::vector< QuantLib::Real > &  bmFoSensiPnls,
const ore::analytics::TradePnLStore foTradePnls,
const QuantLib::ext::shared_ptr< ore::analytics::MarketRiskGroupBase > &  riskGroup 
)
protectedvirtual

Definition at line 190 of file marketriskbacktest.hpp.

195 {};
+ Here is the caller graph for this function:

◆ addDetailRow()

virtual void addDetailRow ( const QuantLib::ext::shared_ptr< BacktestReports > &  reports,
const Data data,
bool  isCall,
QuantLib::Real  im,
const QuantLib::Date &  start,
const QuantLib::Date &  end,
bool  isFull,
QuantLib::Real  pnl,
const std::string &  result,
const std::string &  tradeId = "" 
) const
protectedpure virtual

Add a row to the detail report.

+ Here is the caller graph for this function:

◆ addSummaryRow()

virtual void addSummaryRow ( const QuantLib::ext::shared_ptr< BacktestReports > &  reports,
const Data data,
bool  isCall,
QuantLib::Real  im,
QuantLib::Size  observations,
bool  isFull,
QuantLib::Size  exceptions,
const std::vector< QuantLib::Size > &  ragBounds,
const VarBenchmarks sensiBenchmarks,
const VarBenchmarks fullBenchmarks 
) const
protectedpure virtual

Add a row to the summary report.

+ Here is the caller graph for this function:

◆ calculateBenchmarks()

void calculateBenchmarks ( VarBenchmarks benchmarks,
QuantLib::Real  confidence,
const bool  isCall,
const QuantLib::ext::shared_ptr< ore::analytics::MarketRiskGroupBase > &  riskGroup,
std::set< std::pair< std::string, QuantLib::Size > > &  tradeIdIdxPairs 
)
protectedvirtual

Calculate and update the benchmarks.

Definition at line 340 of file marketriskbacktest.cpp.

344 {
345 for (auto& [type, value] : benchmarks) {
346 if (value.first)
347 value.second = value.first->var(confidence, isCall, tradeIdIdxPairs);
348 }
349}
+ Here is the caller graph for this function:

◆ writeReports()

void writeReports ( const QuantLib::ext::shared_ptr< MarketRiskReport::Reports > &  reports,
const QuantLib::ext::shared_ptr< ore::analytics::MarketRiskGroupBase > &  riskGroup,
const QuantLib::ext::shared_ptr< ore::analytics::TradeGroupBase > &  tradeGroup 
)
overrideprotected

Definition at line 137 of file marketriskbacktest.cpp.

139 {
140
141 // Data for the current backtest
142 std::string cpty = tradeIdIdxPairs_.empty() ? "INVALID" : counterparty(tradeIdIdxPairs_.begin()->first);
143 Data data = {cpty, tradeGroup, riskGroup};
144
145 auto backtestRpts = ext::dynamic_pointer_cast<BacktestReports>(reports);
146 QL_REQUIRE(backtestRpts, "We must have backtest reports");
147
148 SummaryResults srSensi;
149 bool runSensi = sensiPnls_.size() > 0;
150 if (runSensi)
151 // Give back summary results for sensitivity backtest
152 srSensi = calculateSummary(backtestRpts, data, false, sensiPnls_, tradeIds_, sensiTradePnls_);
153
154 if (runFullReval(riskGroup)) {
155 // Give back summary results for full revaluation backtest
156 SummaryResults srFull = calculateSummary(backtestRpts, data, true, pnls_, tradeIds_, tradePnls_);
157
158 // Write the rows in the summary report
159 addSummaryRow(backtestRpts, data, true, srFull.callValue, srFull.observations, true, srFull.callExceptions,
161 addSummaryRow(backtestRpts, data, false, srFull.postValue, srFull.observations, true, srFull.postExceptions,
163 }
164
165 if (runSensi) {
166 addSummaryRow(backtestRpts, data, true, srSensi.callValue, srSensi.observations, false, srSensi.callExceptions,
168 addSummaryRow(backtestRpts, data, false, srSensi.postValue, srSensi.observations, false, srSensi.postExceptions,
170 }
171}
virtual void addSummaryRow(const QuantLib::ext::shared_ptr< BacktestReports > &reports, const Data &data, bool isCall, QuantLib::Real im, QuantLib::Size observations, bool isFull, QuantLib::Size exceptions, const std::vector< QuantLib::Size > &ragBounds, const VarBenchmarks &sensiBenchmarks, const VarBenchmarks &fullBenchmarks) const =0
Add a row to the summary report.
SummaryResults calculateSummary(const QuantLib::ext::shared_ptr< BacktestReports > &reports, const Data &data, bool isFull, const std::vector< QuantLib::Real > &pnls, const std::vector< std::string > &tradeIds, const TradePnLStore &tradePnls)
virtual std::string counterparty(const std::string &tradeId) const =0
std::vector< std::string > tradeIds_
virtual bool runFullReval(const QuantLib::ext::shared_ptr< MarketRiskGroupBase > &riskGroup) const
data
+ Here is the call graph for this function:

◆ timePeriods()

std::vector< ore::data::TimePeriod > timePeriods ( )
overrideprotectedvirtual

Reimplemented from MarketRiskReport.

Definition at line 75 of file marketriskbacktest.cpp.

75 {
76 std::vector<TimePeriod> tps{btArgs_->benchmarkPeriod_, btArgs_->backtestPeriod_};
77 return tps;
78}

◆ calculateSummary()

MarketRiskBacktest::SummaryResults calculateSummary ( const QuantLib::ext::shared_ptr< BacktestReports > &  reports,
const Data data,
bool  isFull,
const std::vector< QuantLib::Real > &  pnls,
const std::vector< std::string > &  tradeIds,
const TradePnLStore tradePnls 
)
private

Calculate the number of exceptions given the current data and the associated P&L vector pnls for both call and post sides. The parameter isFull is true if pnls come from a full revaluation and false if they are sensitivity based.

The parameters tradeIds and tradePnls are used if we are writing a trade level backtest detail report.

Definition at line 184 of file marketriskbacktest.cpp.

186 {
187
188 SummaryResults sr = {pnls.size(), 0.0, 0, 0.0, 0, {}};
189
190 sr.callValue = callValue(data);
191 sr.postValue = postValue(data);
192
193 auto pnlScenDates = hisScenGen_->filteredScenarioDates(btArgs_->backtestPeriod_);
194 QL_REQUIRE(pnlScenDates.size() == pnls.size(), "Backtest::calculateSummary(): internal error, pnlScenDates ("
195 << pnlScenDates.size() << ") do not match pnls (" << pnls.size()
196 << ")");
197
198 // If a trade level backtest detail report has been requested.
199 bool detailTrd = runTradeDetail(reports);
200 if (detailTrd)
201 QL_REQUIRE(pnls.size() == tradePnls.size(), "For trade level backtest detail report,"
202 << " expect the number of aggregate P&Ls (" << pnls.size()
203 << ") to equal the number"
204 << " of trade P&Ls (" << tradePnls.size() << ").");
205
206 // List of trades to exclude in the PnL calcs.
207 // This would happen when a trade is under a winning reg in the call side but not on the post side, or vice versa.
208 vector<Size> callTradesToSkip;
209 vector<Size> postTradesToSkip;
210 if (requireTradePnl_) {
211 for (Size t = 0; t < tradeIds.size(); t++) {
212 const string& tid = tradeIds[t];
213 if (callTradeIds_.find(tid) == callTradeIds_.end())
214 callTradesToSkip.push_back(t);
215 if (postTradeIds_.find(tid) == postTradeIds_.end())
216 postTradesToSkip.push_back(t);
217 }
218 }
219
220 Real callScenPnl;
221 Real postScenPnl;
222 vector<Real> scenTradePnls;
223 string cPassFail;
224 string pPassFail;
225 for (Size i = 0; i < pnls.size(); i++) {
226 const auto& start = pnlScenDates[i].first;
227 const auto& end = pnlScenDates[i].second;
228
229 // Deal with call and write report row
230 callScenPnl = pnls[i];
231 if (!callTradesToSkip.empty()) {
232 scenTradePnls = tradePnls[i];
233 for (const Size& t : callTradesToSkip) {
234 callScenPnl -= scenTradePnls[t];
235 }
236 }
237 if (callScenPnl > std::max(sr.callValue, btArgs_->exceptionThreshold_))
238 sr.callExceptions++;
239
240 cPassFail = callScenPnl > std::max(sr.callValue, btArgs_->exceptionThreshold_) ? "fail" : "pass";
241 addDetailRow(reports, data, true, sr.callValue, start, end, isFull, callScenPnl, cPassFail);
242
243 // Deal with post and write report row
244 postScenPnl = pnls[i];
245 if (!postTradesToSkip.empty()) {
246 scenTradePnls = tradePnls[i];
247 for (const Size& t : postTradesToSkip) {
248 postScenPnl -= scenTradePnls[t];
249 }
250 }
251 if (-postScenPnl > std::max(sr.postValue, btArgs_->exceptionThreshold_))
252 sr.postExceptions++;
253 pPassFail = -postScenPnl > std::max(sr.postValue, btArgs_->exceptionThreshold_) ? "fail" : "pass";
254 addDetailRow(reports, data, false, sr.postValue, start, end, isFull, -postScenPnl, pPassFail);
255
256 // Add the trade level breakdown if requested. Note that we are clearly not recomputing the IM for the
257 // trade - all we are doing is adding the P&L for each trade and the trade ID.
258 if (detailTrd && !data.tradeGroup->allLevel()) {
259 const auto& scenTradePnls = tradePnls[i];
260 QL_REQUIRE(tradeIds.size() == scenTradePnls.size(), "For trade level backtest detail report,"
261 << " the number of trades (" << tradeIds.size()
262 << ") does not equal the size of the trade level P&L"
263 << " container (" << scenTradePnls.size()
264 << ") on scenario date " << io::iso_date(start)
265 << ".");
266 for (Size j = 0; j < scenTradePnls.size(); ++j) {
267 if (std::find(callTradesToSkip.begin(), callTradesToSkip.end(), j) == callTradesToSkip.end())
268 addDetailRow(reports, data, true, sr.callValue, start, end, isFull, scenTradePnls[j], cPassFail, tradeIds[j]);
269 if (std::find(postTradesToSkip.begin(), postTradesToSkip.end(), j) == postTradesToSkip.end())
270 addDetailRow(reports, data, false, sr.postValue, start, end, isFull, -scenTradePnls[j], pPassFail, tradeIds[j]);
271 }
272 }
273 }
274
275 LOG("Got " << sr.callExceptions << " Call exceptions from " << sr.observations << " observations.");
276 LOG("Got " << sr.postExceptions << " Post exceptions from " << sr.observations << " observations.");
277
278 // Now calculate the [red, amber] and [amber, green] bounds
279 if (hisScenGen_->mporDays() != 10) {
280 ALOG("SimmBacktest: MPOR days is " << hisScenGen_->mporDays());
281 } else {
282 sr.bounds = hisScenGen_->overlapping() ? QuantExt::stopLightBoundsTabulated(btArgs_->ragLevels_, sr.observations,
283 hisScenGen_->mporDays(), btArgs_->confidence_)
284 : QuantExt::stopLightBounds(btArgs_->ragLevels_, sr.observations, btArgs_->confidence_);
285 }
286
287 return sr;
288}
virtual QuantLib::Real postValue(const Data &data)=0
virtual QuantLib::Real callValue(const Data &data)=0
virtual void addDetailRow(const QuantLib::ext::shared_ptr< BacktestReports > &reports, const Data &data, bool isCall, QuantLib::Real im, const QuantLib::Date &start, const QuantLib::Date &end, bool isFull, QuantLib::Real pnl, const std::string &result, const std::string &tradeId="") const =0
Add a row to the detail report.
#define LOG(text)
#define ALOG(text)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Member Data Documentation

◆ btArgs_

std::unique_ptr<BacktestArgs> btArgs_
protected

Definition at line 153 of file marketriskbacktest.hpp.

◆ sensiCallBenchmarks_

VarBenchmarks sensiCallBenchmarks_
protected

Definition at line 160 of file marketriskbacktest.hpp.

◆ sensiPostBenchmarks_

VarBenchmarks sensiPostBenchmarks_
protected

Definition at line 160 of file marketriskbacktest.hpp.

◆ fullRevalCallBenchmarks_

VarBenchmarks fullRevalCallBenchmarks_
protected

Definition at line 160 of file marketriskbacktest.hpp.

◆ fullRevalPostBenchmarks_

VarBenchmarks fullRevalPostBenchmarks_
protected

Definition at line 160 of file marketriskbacktest.hpp.

◆ bmSensiPnls_

std::vector<QuantLib::Real> bmSensiPnls_
protected

variables for benchmark calculations

Definition at line 163 of file marketriskbacktest.hpp.

◆ bmFoSensiPnls_

std::vector<QuantLib::Real> bmFoSensiPnls_
protected

Definition at line 163 of file marketriskbacktest.hpp.

◆ pnls_

std::vector<QuantLib::Real> pnls_
protected

Definition at line 163 of file marketriskbacktest.hpp.

◆ bmPnls_

std::vector<QuantLib::Real> bmPnls_
protected

Definition at line 163 of file marketriskbacktest.hpp.

◆ sensiPnls_

std::vector<QuantLib::Real> sensiPnls_
protected

Definition at line 163 of file marketriskbacktest.hpp.

◆ foSensiPnls_

std::vector<QuantLib::Real> foSensiPnls_
protected

Definition at line 163 of file marketriskbacktest.hpp.

◆ foTradePnls_

ore::analytics::TradePnLStore foTradePnls_
protected

Definition at line 164 of file marketriskbacktest.hpp.

◆ tradePnls_

ore::analytics::TradePnLStore tradePnls_
protected

Definition at line 164 of file marketriskbacktest.hpp.

◆ sensiTradePnls_

ore::analytics::TradePnLStore sensiTradePnls_
protected

Definition at line 164 of file marketriskbacktest.hpp.

◆ callTradeIds_

std::set<std::string> callTradeIds_
protected

Definition at line 165 of file marketriskbacktest.hpp.

◆ postTradeIds_

std::set<std::string> postTradeIds_
protected

Definition at line 166 of file marketriskbacktest.hpp.