Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
inmemoryloader.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2018 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 <boost/algorithm/string.hpp>
24
25using namespace std;
26using namespace QuantLib;
27
28namespace ore {
29namespace data {
30
31namespace {
32QuantLib::ext::shared_ptr<MarketDatum> makeDummyMarketDatum(const Date& d, const std::string& name) {
33 return QuantLib::ext::make_shared<MarketDatum>(0.0, d, name, MarketDatum::QuoteType::NONE,
35}
36} // namespace
37
38std::vector<QuantLib::ext::shared_ptr<MarketDatum>> InMemoryLoader::loadQuotes(const QuantLib::Date& d) const {
39 auto it = data_.find(d);
40 if(it == data_.end())
41 return {};
42 return std::vector<QuantLib::ext::shared_ptr<MarketDatum>>(it->second.begin(), it->second.end());
43}
44
45QuantLib::ext::shared_ptr<MarketDatum> InMemoryLoader::get(const string& name, const QuantLib::Date& d) const {
46 auto it = data_.find(d);
47 QL_REQUIRE(it != data_.end(), "No datum for " << name << " on date " << d);
48 auto it2 = it->second.find(makeDummyMarketDatum(d, name));
49 QL_REQUIRE(it2 != it->second.end(), "No datum for " << name << " on date " << d);
50 return *it2;
51}
52
53std::set<QuantLib::ext::shared_ptr<MarketDatum>> InMemoryLoader::get(const std::set<std::string>& names,
54 const QuantLib::Date& asof) const {
55 auto it = data_.find(asof);
56 if(it == data_.end())
57 return {};
58 std::set<QuantLib::ext::shared_ptr<MarketDatum>> result;
59 for (auto const& n : names) {
60 auto it2 = it->second.find(makeDummyMarketDatum(asof, n));
61 if (it2 != it->second.end())
62 result.insert(*it2);
63 }
64 return result;
65}
66
67std::set<QuantLib::ext::shared_ptr<MarketDatum>> InMemoryLoader::get(const Wildcard& wildcard,
68 const QuantLib::Date& asof) const {
69 if (!wildcard.hasWildcard()) {
70 // no wildcard => use get by name function
71 try {
72 return {get(wildcard.pattern(), asof)};
73 } catch (...) {
74 }
75 return {};
76 }
77 auto it = data_.find(asof);
78 if (it == data_.end())
79 return {};
80 std::set<QuantLib::ext::shared_ptr<MarketDatum>> result;
81 std::set<QuantLib::ext::shared_ptr<MarketDatum>>::iterator it1, it2;
82 if (wildcard.wildcardPos() == 0) {
83 // wildcard at first position => we have to search all of the data
84 it1 = it->second.begin();
85 it2 = it->second.end();
86 } else {
87 // search the range matching the substring of the pattern until the wildcard
88 std::string prefix = wildcard.pattern().substr(0, wildcard.wildcardPos());
89 it1 = it->second.lower_bound(makeDummyMarketDatum(asof, prefix));
90 it2 = it->second.upper_bound(makeDummyMarketDatum(asof, prefix + "\xFF"));
91 }
92 for (auto it = it1; it != it2; ++it) {
93 if (wildcard.isPrefix() || wildcard.matches((*it)->name()))
94 result.insert(*it);
95 }
96 return result;
97}
98
99bool InMemoryLoader::hasQuotes(const QuantLib::Date& d) const {
100 auto it = data_.find(d);
101 return it != data_.end();
102}
103
104void InMemoryLoader::add(QuantLib::Date date, const string& name, QuantLib::Real value) {
105 QuantLib::ext::shared_ptr<MarketDatum> md;
106 try {
107 md = parseMarketDatum(date, name, value);
108 } catch (std::exception& e) {
109 WLOG("Failed to parse MarketDatum " << name << ": " << e.what());
110 }
111 if (md != nullptr) {
112 std::pair<bool, string> addFX = {true, ""};
113 if (md->instrumentType() == MarketDatum::InstrumentType::FX_SPOT &&
114 md->quoteType() == MarketDatum::QuoteType::RATE) {
115 addFX = checkFxDuplicate(md, date);
116 if (!addFX.second.empty()) {
117 auto it = data_[date].find(makeDummyMarketDatum(date, addFX.second));
118 TLOG("Replacing MarketDatum " << addFX.second << " with " << name << " due to FX Dominance.");
119 if (it != data_[date].end())
120 data_[date].erase(it);
121 }
122 }
123 if (addFX.first && data_[date].insert(md).second) {
124 TLOG("Added MarketDatum " << name);
125 } else if (!addFX.first) {
126 WLOG("Skipped MarketDatum " << name << " - dominant FX already present.")
127 } else {
128 WLOG("Skipped MarketDatum " << name << " - this is already present.");
129 }
130 }
131}
132
133void InMemoryLoader::addFixing(QuantLib::Date date, const string& name, QuantLib::Real value) {
134 if (!fixings_.insert(Fixing(date, name, value)).second) {
135 WLOG("Skipped Fixing " << name << "@" << QuantLib::io::iso_date(date) << " - this is already present.");
136 }
137}
138
140 if (!dividends_.insert(dividend).second) {
141 WLOG("Skipped Dividend " << dividend.name << "@" << QuantLib::io::iso_date(dividend.exDate) << " - this is already present.");
142 }
143}
144
146 data_.clear();
147 fixings_.clear();
148 dividends_.clear();
149 actualDate_ = Date();
150}
151
152void load(InMemoryLoader& loader, const vector<string>& data, bool isMarket, bool implyTodaysFixings) {
153 LOG("MemoryLoader started");
154
155 Date today = QuantLib::Settings::instance().evaluationDate();
156
157 for (Size i = 0; i < data.size(); ++i) {
158 string line = data[i];
159 // skip blank and comment lines
160 if (line.size() > 0 && line[0] != '#') {
161 vector<string> tokens;
162 boost::trim(line);
163 boost::split(tokens, line, boost::is_any_of(",;\t "), boost::token_compress_on);
164
165 // TODO: should we try, catch and log any invalid lines?
166 QL_REQUIRE(tokens.size() == 3, "Invalid MemoryLoader line, 3 tokens expected " << line);
167 Date date = parseDate(tokens[0]);
168 const string& key = tokens[1];
169 Real value = parseReal(tokens[2]);
170
171 if (isMarket) {
172 // process market
173 // build market datum and add to map
174 try {
175 loader.add(date, key, value);
176 TLOG("Added MarketDatum " << key);
177 } catch (std::exception& e) {
178 WLOG("Failed to parse MarketDatum " << key << ": " << e.what());
179 }
180 } else {
181 // process fixings
182 if (date < today || (date == today && !implyTodaysFixings))
183 loader.addFixing(date, key, value);
184 }
185 }
186 }
187 LOG("MemoryLoader completed");
188}
189
190void loadDataFromBuffers(InMemoryLoader& loader, const std::vector<std::string>& marketData,
191 const std::vector<std::string>& fixingData, bool implyTodaysFixings) {
192 load(loader, marketData, true, implyTodaysFixings);
193 load(loader, fixingData, false, implyTodaysFixings);
194}
195
196} // namespace data
197} // namespace ore
bool hasQuotes(const QuantLib::Date &d) const override
check if there are quotes for a date
std::set< QuantExt::Dividend > dividends_
std::set< Fixing > fixings_
virtual void addFixing(QuantLib::Date date, const string &name, QuantLib::Real value)
QuantLib::ext::shared_ptr< MarketDatum > get(const string &name, const QuantLib::Date &d) const override
get quote by its unique name, throws if not existent, override in derived classes for performance
std::vector< QuantLib::ext::shared_ptr< MarketDatum > > loadQuotes(const QuantLib::Date &d) const override
get all quotes, TODO change the return value to std::set
virtual void add(QuantLib::Date date, const string &name, QuantLib::Real value)
virtual void addDividend(const QuantExt::Dividend &dividend)
std::map< QuantLib::Date, std::set< QuantLib::ext::shared_ptr< MarketDatum >, SharedPtrMarketDatumComparator > > data_
std::pair< bool, string > checkFxDuplicate(const ext::shared_ptr< MarketDatum >, const QuantLib::Date &)
Definition: loader.cpp:85
bool isPrefix() const
Definition: wildcard.cpp:66
bool hasWildcard() const
Definition: wildcard.cpp:62
const std::string & pattern() const
Definition: wildcard.cpp:80
bool matches(const std::string &s) const
Definition: wildcard.cpp:68
std::size_t wildcardPos() const
Definition: wildcard.cpp:64
SafeStack< ValueType > value
QuantLib::ext::shared_ptr< MarketDatum > parseMarketDatum(const Date &asof, const string &datumName, const Real &value)
Function to parse a market datum.
Date parseDate(const string &s)
Convert std::string to QuantLib::Date.
Definition: parsers.cpp:51
Real parseReal(const string &s)
Convert text to Real.
Definition: parsers.cpp:112
Classes and functions for log message handling.
@ data
Definition: log.hpp:77
#define LOG(text)
Logging Macro (Level = Notice)
Definition: log.hpp:552
#define WLOG(text)
Logging Macro (Level = Warning)
Definition: log.hpp:550
#define TLOG(text)
Logging Macro (Level = Data)
Definition: log.hpp:556
Market Datum parser.
void loadDataFromBuffers(InMemoryLoader &loader, const std::vector< std::string > &marketData, const std::vector< std::string > &fixingData, bool implyTodaysFixings)
Utility function for loading market quotes and fixings from an in memory csv buffer.
void load(InMemoryLoader &loader, const vector< string > &data, bool isMarket, bool implyTodaysFixings)
QuantLib::ext::shared_ptr< MarketDatum > makeDummyMarketDatum(const Date &d, const std::string &name)
Definition: csvloader.cpp:95
Serializable Credit Default Swap.
Definition: namespaces.docs:23
Map text representations to QuantLib/QuantExt types.
std::string name
QuantLib::Date exDate
Fixing data structure.
Definition: fixings.hpp:44
string name