|
| 1 | +/* |
| 2 | + Copyright (C) 2021 Quaternion Risk Management Ltd |
| 3 | + All rights reserved. |
| 4 | +
|
| 5 | + This file is part of ORE, a free-software/open-source library |
| 6 | + for transparent pricing and risk analysis - http://opensourcerisk.org |
| 7 | +
|
| 8 | + ORE is free software: you can redistribute it and/or modify it |
| 9 | + under the terms of the Modified BSD License. You should have received a |
| 10 | + copy of the license along with this program. |
| 11 | + The license is also available online at <http://opensourcerisk.org> |
| 12 | +
|
| 13 | + This program is distributed on the basis that it will form a useful |
| 14 | + contribution to risk analytics and model standardisation, but WITHOUT |
| 15 | + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| 16 | + FITNESS FOR A PARTICULAR PURPOSE. See the license for more details. |
| 17 | +*/ |
| 18 | + |
| 19 | +#include <ored/configuration/baseltrafficlightconfig.hpp> |
| 20 | +#include <ored/portfolio/structuredconfigurationwarning.hpp> |
| 21 | +#include <ored/utilities/log.hpp> |
| 22 | +#include <ored/utilities/parsers.hpp> |
| 23 | +#include <ored/utilities/to_string.hpp> |
| 24 | + |
| 25 | +#include <ql/time/date.hpp> |
| 26 | + |
| 27 | +namespace ore { |
| 28 | +namespace data { |
| 29 | + |
| 30 | +using namespace QuantLib; |
| 31 | + |
| 32 | +BaselTrafficLightData::BaselTrafficLightData() { clear(); } |
| 33 | +BaselTrafficLightData::BaselTrafficLightData(const std::map<int, ObservationData>& baselTrafficLight) : |
| 34 | + baselTrafficLight_(baselTrafficLight) {} |
| 35 | + |
| 36 | +void BaselTrafficLightData::clear() { |
| 37 | + baselTrafficLight_.clear(); |
| 38 | +} |
| 39 | +/* |
| 40 | +<BaselTrafficLightConfig> |
| 41 | + <Configuration> |
| 42 | + <mporDays>10</mporDays> |
| 43 | + <ObservationThresholds> |
| 44 | + <ObservationCount>1,2,3,...,6190</ObservationCount> |
| 45 | + <AmberLimit>0,0,0,...,89</AmberLimit> |
| 46 | + <RedLimit>0,1,2,3...133</RedLimit> |
| 47 | + </ObservationThresholds> |
| 48 | + </Configuration> |
| 49 | + <Configuration> |
| 50 | + <mporDays>1</mporDays> |
| 51 | + <ObservationThresholds> |
| 52 | + <ObservationCount>1,2,3,..,2200</ObservationCount> |
| 53 | + <AmberLimit>1,1,1...,30</AmberLimit> |
| 54 | + <RedLimit>1,1,...41</RedLimit> |
| 55 | + </ObservationThresholds> |
| 56 | + </Configuration> |
| 57 | +</BaselTrafficLightConfig> |
| 58 | +*/ |
| 59 | +void BaselTrafficLightData::fromXML(XMLNode* node) { |
| 60 | + XMLUtils::checkNode(node, "BaselTrafficLightConfig"); |
| 61 | + for (auto const c : XMLUtils::getChildrenNodes(node, "Configuration")) { |
| 62 | + int mporDays = XMLUtils::getChildValueAsInt(c, "mporDays", true); |
| 63 | + auto obsThreshold = XMLUtils::getChildNode(c, "ObservationThresholds"); |
| 64 | + auto observationCount = XMLUtils::getChildNode(obsThreshold, "ObservationCount"); |
| 65 | + auto amberLimit = XMLUtils::getChildNode(obsThreshold, "AmberLimit"); |
| 66 | + auto redLimit = XMLUtils::getChildNode(obsThreshold, "RedLimit"); |
| 67 | + std::vector<int> observationCt = parseListOfValuesAsInt(XMLUtils::getNodeValue(observationCount)); |
| 68 | + std::vector<int> amberLim = parseListOfValuesAsInt(XMLUtils::getNodeValue(amberLimit)); |
| 69 | + std::vector<int> redLim = parseListOfValuesAsInt(XMLUtils::getNodeValue(redLimit)); |
| 70 | + std::transform(amberLim.begin(), amberLim.end(), amberLim.begin(), [](int x) { return x - 1; }); |
| 71 | + std::transform(redLim.begin(), redLim.end(), redLim.begin(), [](int x) { return x - 1; }); |
| 72 | + QL_REQUIRE(observationCt.size() == amberLim.size() && amberLim.size() == redLim.size(), |
| 73 | + "We must have the same number number of observation and limits."); |
| 74 | + baselTrafficLight_[mporDays] = {observationCt, amberLim, redLim}; |
| 75 | + } |
| 76 | +} |
| 77 | + |
| 78 | +XMLNode* BaselTrafficLightData::toXML(XMLDocument& doc) const { |
| 79 | + XMLNode* node = doc.allocNode("BaselTrafficLightConfig"); |
| 80 | + for (const auto& pair : baselTrafficLight_) { |
| 81 | + int mporDays = pair.first; |
| 82 | + const ObservationData& data = pair.second; |
| 83 | + XMLNode* rdNode = XMLUtils::addChild(doc, node, "Configuration"); |
| 84 | + XMLUtils::addChild(doc, rdNode, "mporDays", std::to_string(mporDays)); |
| 85 | + XMLNode* oNode = XMLUtils::addChild(doc, rdNode, "ObservationThresholds"); |
| 86 | + XMLUtils::addGenericChildAsList(doc, oNode, "ObservationCount", data.observationCount); |
| 87 | + XMLUtils::addGenericChildAsList(doc, oNode, "AmberLimit", data.amberLimit); |
| 88 | + XMLUtils::addGenericChildAsList(doc, oNode, "RedLimit", data.redLimit); |
| 89 | + } |
| 90 | + |
| 91 | + return node; |
| 92 | +} |
| 93 | + |
| 94 | +} // namespace data |
| 95 | +} // namespace ore |
0 commit comments