-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathsymbol_map.cpp
139 lines (127 loc) · 4.49 KB
/
symbol_map.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#include "databento/symbol_map.hpp"
#include <date/date.h>
#include <memory>
#include <string>
#include "databento/datetime.hpp"
#include "databento/dbn.hpp"
#include "databento/enums.hpp"
#include "databento/exceptions.hpp"
using databento::TsSymbolMap;
namespace {
bool IsInverse(const databento::Metadata& metadata) {
if (!metadata.has_mixed_stype_in) {
if (metadata.stype_in == databento::SType::InstrumentId) {
return true;
}
if (metadata.stype_out == databento::SType::InstrumentId) {
return false;
}
}
throw databento::InvalidArgumentError{
"SymbolMap", "metadata",
"Can only create symbol maps from metadata where InstrumentId is one "
"of the stypes"};
}
} // namespace
TsSymbolMap::TsSymbolMap(const Metadata& metadata) {
if (::IsInverse(metadata)) {
for (const auto& mapping : metadata.mappings) {
const auto iid =
static_cast<std::uint32_t>(std::stoul(mapping.raw_symbol));
for (const auto& interval : mapping.intervals) {
// Handle old symbology format
if (interval.symbol.empty()) {
continue;
}
Insert(iid, interval.start_date, interval.end_date,
std::make_shared<std::string>(interval.symbol));
}
}
} else {
for (const auto& mapping : metadata.mappings) {
const auto symbol = std::make_shared<std::string>(mapping.raw_symbol);
for (const auto& interval : mapping.intervals) {
// Handle old symbology format
if (interval.symbol.empty()) {
continue;
}
const auto iid =
static_cast<std::uint32_t>(std::stoul(interval.symbol));
Insert(iid, interval.start_date, interval.end_date, symbol);
}
}
}
}
void TsSymbolMap::Insert(std::uint32_t instrument_id,
date::year_month_day start_date,
date::year_month_day end_date,
const std::shared_ptr<const std::string>& symbol) {
if (start_date > end_date) {
throw InvalidArgumentError{"TsSymbolMap::Insert", "end_date",
"can't be before start_date"};
}
if (start_date == end_date) {
// Ignore
return;
}
for (date::sys_days day = start_date; day < end_date; day += date::days{1}) {
map_.emplace(std::make_pair(date::year_month_day{day}, instrument_id),
symbol);
}
}
using databento::PitSymbolMap;
PitSymbolMap::PitSymbolMap(const Metadata& metadata,
date::year_month_day date) {
if (date::sys_days{date} < date::floor<date::days>(metadata.start) ||
// need to compare with `end` as datetime to handle midnight case
UnixNanos{date::sys_days{date}} >= metadata.end) {
throw InvalidArgumentError{"PitSymbolMap::PitSymbolMap", "date",
"Outside query range"};
}
const auto is_inverse = IsInverse(metadata);
for (const auto& mapping : metadata.mappings) {
const auto interval_it = std::find_if(
mapping.intervals.begin(), mapping.intervals.end(),
[date](const MappingInterval& interval) {
return date >= interval.start_date && date < interval.end_date;
});
// Empty symbols in old symbology format
if (interval_it == mapping.intervals.end() || interval_it->symbol.empty()) {
continue;
}
if (is_inverse) {
const auto iid =
static_cast<std::uint32_t>(std::stoul(mapping.raw_symbol));
map_.emplace(iid, interval_it->symbol);
} else {
const auto iid =
static_cast<std::uint32_t>(std::stoul(interval_it->symbol));
map_.emplace(iid, mapping.raw_symbol);
}
}
}
template <typename SymbolMappingRec>
void PitSymbolMap::OnSymbolMapping(const SymbolMappingRec& symbol_mapping) {
const auto it = map_.find(symbol_mapping.hd.instrument_id);
if (it == map_.end()) {
map_.emplace(symbol_mapping.hd.instrument_id,
symbol_mapping.STypeOutSymbol());
} else {
it->second = symbol_mapping.STypeOutSymbol();
}
}
void PitSymbolMap::OnRecord(const Record& record) {
if (record.RType() == RType::SymbolMapping) {
// Version compat
if (record.Header().Size() >= sizeof(SymbolMappingMsgV2)) {
OnSymbolMapping(record.Get<SymbolMappingMsgV2>());
} else {
OnSymbolMapping(record.Get<SymbolMappingMsgV1>());
}
}
}
// Explicit instantiation
template void PitSymbolMap::OnSymbolMapping(
const SymbolMappingMsgV1& symbol_mapping);
template void PitSymbolMap::OnSymbolMapping(
const SymbolMappingMsgV2& symbol_mapping);