Skip to content

Commit 0e54392

Browse files
NathanielVolfangojenkins
authored andcommitted
QPR-12117 -- Adjust PnLs according to trades under the winning regulation for each side. Separate out tradePnls and foTradePnls for each PnL calculator.
1 parent 0aa2ebc commit 0e54392

2 files changed

Lines changed: 38 additions & 27 deletions

File tree

OREAnalytics/orea/engine/historicalsensipnlcalculator.cpp

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -222,19 +222,27 @@ void HistoricalSensiPnlCalculator::calculateSensiPnl(
222222
bool runTradeLevel = tradeLevel && sensitivityStream_;
223223

224224
// Local P&L vectors to hold _all_ historical P&Ls
225-
auto nScenarios = hisScenGen_->numScenarios();
225+
Size nScenarios = hisScenGen_->numScenarios();
226+
Size nCalculators = pnlCalculators.size();
226227
vector<Real> allPnls(hisScenGen_->numScenarios(), 0.0);
227228
vector<Real> allFoPnls(hisScenGen_->numScenarios(), 0.0);
228-
229+
230+
// calculators,scenarios, trades
229231
using TradePnLStore = std::vector<std::vector<QuantLib::Real>>;
230-
TradePnLStore tradePnls, foTradePnls;
232+
std::vector<TradePnLStore> tradePnls, foTradePnls;
231233

232234
// We may need to store trade level P&Ls.
233235
if (runTradeLevel) {
234236
tradePnls.clear();
235-
tradePnls.reserve(nScenarios);
237+
tradePnls.reserve(nCalculators);
236238
foTradePnls.clear();
237-
foTradePnls.reserve(nScenarios);
239+
foTradePnls.reserve(nCalculators);
240+
for (Size i = 0; i < nCalculators; i++) {
241+
tradePnls.push_back(std::vector<std::vector<QuantLib::Real>>());
242+
tradePnls.at(i).reserve(nScenarios);
243+
foTradePnls.push_back(std::vector<std::vector<QuantLib::Real>>());
244+
foTradePnls.at(i).reserve(nScenarios);
245+
}
238246
}
239247

240248
hisScenGen_->reset();
@@ -252,14 +260,13 @@ void HistoricalSensiPnlCalculator::calculateSensiPnl(
252260

253261
// Add trade level P&L vector if needed.
254262
if (runTradeLevel) {
255-
bool inPeriod = false;
256-
for (const auto& c : pnlCalculators) {
257-
if (c->isInTimePeriod(hisScenGen_->startDates()[i], hisScenGen_->endDates()[i]))
258-
inPeriod = true;
259-
}
260-
if (inPeriod) {
261-
tradePnls.push_back(vector<Real>(tradeIds.size(), 0.0));
262-
foTradePnls.push_back(vector<Real>(tradeIds.size(), 0.0));
263+
for (Size j = 0; j < pnlCalculators.size(); j++) {
264+
bool inPeriod =
265+
pnlCalculators.at(j)->isInTimePeriod(hisScenGen_->startDates()[i], hisScenGen_->endDates()[i]);
266+
if (inPeriod) {
267+
tradePnls.at(j).push_back(vector<Real>(tradeIds.size(), 0.0));
268+
foTradePnls.at(j).push_back(vector<Real>(tradeIds.size(), 0.0));
269+
}
263270
}
264271
}
265272

@@ -282,9 +289,11 @@ void HistoricalSensiPnlCalculator::calculateSensiPnl(
282289
if (includeGammaMargin)
283290
allPnls[i] += gammaPnl;
284291

285-
for (const auto& c : pnlCalculators) {
286-
if (c->isInTimePeriod(hisScenGen_->startDates()[i], hisScenGen_->endDates()[i])) {
287-
c->writePNL(i, true, sr.key_1, shift, sr.delta, sr.gamma, deltaPnl, gammaPnl);
292+
for (Size k = 0; k < pnlCalculators.size(); k++) {
293+
if (pnlCalculators.at(k)->isInTimePeriod(hisScenGen_->startDates()[i],
294+
hisScenGen_->endDates()[i])) {
295+
pnlCalculators.at(k)->writePNL(i, true, sr.key_1, shift, sr.delta, sr.gamma, deltaPnl,
296+
gammaPnl);
288297
if (!tradeSensiCache.empty()) {
289298
auto itSr = tradeSensiCache.find(j);
290299
if (itSr != tradeSensiCache.end()) {
@@ -295,15 +304,16 @@ void HistoricalSensiPnlCalculator::calculateSensiPnl(
295304
Real tradeGamma = kv.second.second;
296305
Real tradeGammaPnl = 0.5 * shift * shift * tradeGamma;
297306
// Attempt to write trade level P&L contribution row.
298-
c->writePNL(i, true, sr.key_1, shift, tradeDelta, tradeGamma, tradeDeltaPnl,
299-
tradeGammaPnl, RiskFactorKey(), 0.0, tradeId);
307+
pnlCalculators.at(k)->writePNL(i, true, sr.key_1, shift, tradeDelta, tradeGamma,
308+
tradeDeltaPnl, tradeGammaPnl, RiskFactorKey(), 0.0,
309+
tradeId);
300310
// Update the sensitivity based trade level P&Ls
301311
if (runTradeLevel) {
302-
foTradePnls.back()[kv.first] += tradeDeltaPnl;
312+
foTradePnls.at(k).back()[kv.first] += tradeDeltaPnl;
303313
if (includeDeltaMargin)
304-
tradePnls.back()[kv.first] += tradeDeltaPnl;
314+
tradePnls.at(k).back()[kv.first] += tradeDeltaPnl;
305315
if (includeGammaMargin)
306-
tradePnls.back()[kv.first] += tradeGammaPnl;
316+
tradePnls.at(k).back()[kv.first] += tradeGammaPnl;
307317
}
308318
}
309319
}
@@ -319,7 +329,8 @@ void HistoricalSensiPnlCalculator::calculateSensiPnl(
319329
if (includeGammaMargin)
320330
allPnls[i] += gammaPnl;
321331

322-
for (const auto& c : pnlCalculators) {
332+
for (Size j = 0; j < pnlCalculators.size(); j++) {
333+
const auto& c = pnlCalculators[j];
323334
if (c->isInTimePeriod(hisScenGen_->startDates()[i], hisScenGen_->endDates()[i])) {
324335
c->writePNL(i, true, sr.key_1, shift_1, sr.delta, sr.gamma, 0.0, gammaPnl, sr.key_2, shift_2);
325336
if (!tradeSensiCache.empty()) {
@@ -334,7 +345,7 @@ void HistoricalSensiPnlCalculator::calculateSensiPnl(
334345
sr.key_2, shift_2, tradeId);
335346
// Update the sensitivity based trade level P&Ls
336347
if (runTradeLevel && includeGammaMargin) {
337-
tradePnls.back()[kv.first] += tradeGammaPnl;
348+
tradePnls.at(j).back()[kv.first] += tradeGammaPnl;
338349
}
339350
}
340351
}
@@ -351,10 +362,10 @@ void HistoricalSensiPnlCalculator::calculateSensiPnl(
351362
covarianceCalculator->populateCovariance(keys);
352363

353364
LOG("Populate the sensitivity backtesting P&L vectors");
354-
for (const auto& c : pnlCalculators) {
355-
c->populatePNLs(allPnls, allFoPnls, hisScenGen_->startDates(), hisScenGen_->endDates());
365+
for (Size j = 0; j < pnlCalculators.size(); j++) {
366+
pnlCalculators.at(j)->populatePNLs(allPnls, allFoPnls, hisScenGen_->startDates(), hisScenGen_->endDates());
356367
if (runTradeLevel)
357-
c->populateTradePNLs(tradePnls, foTradePnls);
368+
pnlCalculators.at(j)->populateTradePNLs(tradePnls.at(j), foTradePnls.at(j));
358369
}
359370
}
360371

OREAnalytics/orea/simm/simmcalculator.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ class SimmCalculator {
8888
const std::map<ore::data::NettingSetDetails, std::pair<std::string, SimmResults>>& finalSimmResults(const SimmSide& side) const;
8989
const std::map<SimmSide, std::map<ore::data::NettingSetDetails, std::pair<std::string, SimmResults>>>& finalSimmResults() const;
9090

91-
const std::map<SimmSide, std::set<std::string>> finalTradeIds() const { return finalTradeIds_; }
91+
const std::map<SimmSide, std::set<std::string>>& finalTradeIds() const { return finalTradeIds_; }
9292

9393
//! Return the calculator's calculation currency
9494
const std::string& calculationCurrency() const { return calculationCcy_; }

0 commit comments

Comments
 (0)