Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
cubecsvreader.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2017 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>
20#include <fstream>
25#include <ql/errors.hpp>
26#include <stdio.h>
27
28using QuantLib::Date;
29using std::string;
30using std::vector;
31using namespace ore::analytics;
32
33namespace ore {
34namespace analytics {
35
36CubeCsvReader::CubeCsvReader(const std::string& filename) : filename_(filename) {}
37
38void CubeCsvReader::read(QuantLib::ext::shared_ptr<NPVCube>& cube, std::map<std::string, std::string>& nettingSetMap) {
39
40 std::set<string> tradeIds;
41 std::vector<Date> dateVec;
42 std::set<Size> sampleIdxSet, depthIdxSet;
43 Date asof;
44
45 std::ifstream file;
46 file.open(filename_.c_str());
47 QL_REQUIRE(file.is_open(), "error opening file " << filename_);
48 bool headerAlreadyLoaded1 = false;
49 while (!file.eof()) {
50 string line;
51 getline(file, line);
52 // skip blank and comment lines
53 if (line.size() > 0 && line[0] != '#') {
54 if (!headerAlreadyLoaded1) {
55 headerAlreadyLoaded1 = true;
56 continue;
57 }
58 vector<string> tokens;
59 boost::trim(line);
60 boost::split(tokens, line, boost::is_any_of(",;\t"), boost::token_compress_on);
61 QL_REQUIRE(tokens.size() == 7, "Invalid CubeCsvReader line, 7 tokens expected " << line);
62 string tradeId = tokens[0];
63 string nettingId = tokens[1];
64 Size dateIdx = ore::data::parseInteger(tokens[2]);
65 Date gridDate = ore::data::parseDate(tokens[3]);
66 Size sampleIdx = ore::data::parseInteger(tokens[4]);
67 Size depthIdx = ore::data::parseInteger(tokens[5]);
68
69 if (dateIdx == 0) {
70 asof = gridDate;
71 } else if (std::find(dateVec.begin(), dateVec.end(), gridDate) == dateVec.end()) {
72 dateVec.push_back(gridDate);
73 }
74 tradeIds.insert(tradeId);
75 if (nettingSetMap.find(tradeId) == nettingSetMap.end())
76 nettingSetMap[tradeId] = nettingId;
77 sampleIdxSet.insert(sampleIdx);
78 depthIdxSet.insert(depthIdx);
79 }
80 }
81 file.close();
82
83 QL_REQUIRE(dateVec.size() > 0, "CubeCsvReader - no simulation dates found");
84 QL_REQUIRE(tradeIds.size() > 0, "CubeCsvReader - no trades found");
85 Size numSamples = sampleIdxSet.size() - 1; // zero represents t0 data
86 Size cubeDepth = depthIdxSet.size();
87 QL_REQUIRE(numSamples > 0, "CubeCsvReader - no simulation paths found");
88 QL_REQUIRE(cubeDepth > 0, "CubeCsvReader - no cube depth");
89 QL_REQUIRE(nettingSetMap.size() == tradeIds.size(),
90 "CubeCsvReader - vector size mismatch - trade Ids vs netting map");
91 for (Size i = 0; i < dateVec.size(); ++i) {
92 QL_REQUIRE(dateVec[i] > asof, "CubeCsvReader - grid date " << QuantLib::io::iso_date(dateVec[i])
93 << "must be greater than asof "
94 << QuantLib::io::iso_date(asof));
95 if (i > 0) {
96 QL_REQUIRE(dateVec[i] > dateVec[i - 1], "CubeCsvReader - date grid must be monotonic increasing");
97 }
98 }
99 if (cubeDepth == 1)
100 cube = QuantLib::ext::make_shared<SinglePrecisionInMemoryCube>(asof, tradeIds, dateVec, numSamples);
101 else if (cubeDepth > 1)
102 cube = QuantLib::ext::make_shared<SinglePrecisionInMemoryCubeN>(asof, tradeIds, dateVec, numSamples, cubeDepth);
103
104 // Now re-open the file and loop through its contents AGAIN
105 std::ifstream file2;
106 file2.open(filename_.c_str());
107 QL_REQUIRE(file2.is_open(), "error opening file " << filename_);
108 bool headerAlreadyLoaded = false;
109 while (!file2.eof()) {
110 string line;
111 getline(file2, line);
112 // skip blank and comment lines
113 if (line.size() > 0 && line[0] != '#') {
114 if (!headerAlreadyLoaded) {
115 headerAlreadyLoaded = true;
116 continue;
117 }
118 vector<string> tokens;
119 boost::trim(line);
120 boost::split(tokens, line, boost::is_any_of(",;\t"), boost::token_compress_on);
121 QL_REQUIRE(tokens.size() == 7, "Invalid CubeCsvReader line, 7 tokens expected " << line);
122 string tradeId = tokens[0];
123 string nettingId = tokens[1];
124 Size dateIdx = ore::data::parseInteger(tokens[2]);
125 // Date gridDate = ore::data::parseDate(tokens[3]); Not needed
126 Size sampleIdx = ore::data::parseInteger(tokens[4]);
127 Size depthIdx = ore::data::parseInteger(tokens[5]);
128 Real value = ore::data::parseReal(tokens[6]);
129
130 auto pos_trade = cube->getTradeIndex(tradeId);
131
132 if (dateIdx == 0) {
133 cube->setT0(value, pos_trade, depthIdx);
134 } else {
135 QL_REQUIRE(sampleIdx > 0, "CubeCsvReader - input sampleIdx should be > 0");
136 cube->set(value, pos_trade, dateIdx - 1, sampleIdx - 1, depthIdx);
137 }
138 }
139 }
140 file2.close();
141}
142} // namespace analytics
143} // namespace ore
CubeCsvReader(const std::string &filename)
ctor
void read(QuantLib::ext::shared_ptr< ore::analytics::NPVCube > &cube, std::map< std::string, std::string > &nettingSetMap)
Read a cube from a csv file.
SafeStack< ValueType > value
A Class to read a cube file from csv input.
Date parseDate(const string &s)
Real parseReal(const string &s)
Integer parseInteger(const string &s)
A cube implementation that stores the cube in memory.
Date asof(14, Jun, 2018)