Skip to content

Commit b519265

Browse files
authored
VER: Release 0.14.1
2 parents e2ce872 + b767fad commit b519265

File tree

15 files changed

+202
-35
lines changed

15 files changed

+202
-35
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# Changelog
22

3+
## 0.14.1 - 2023-12-18
4+
5+
### Enhancements
6+
- Added `PitSymbolMap` helper for keeping track of symbology mappings in Live
7+
- Added new publisher value for OPRA MIAX Sapphire
8+
9+
### Bug fixes
10+
- Fixed misaligned read undefined behavior when decoding records
11+
312
## 0.14.0 - 2023-11-23
413

514
This release adds support for DBN v2.

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.14)
44
# Project details
55
#
66

7-
project("databento" VERSION 0.14.0 LANGUAGES CXX)
7+
project("databento" VERSION 0.14.1 LANGUAGES CXX)
88
string(TOUPPER ${PROJECT_NAME} PROJECT_NAME_UPPERCASE)
99

1010
#

README.md

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,28 +78,26 @@ Here is a simple program that fetches 10 seconds of trades for all ES mini futur
7878
```cpp
7979
#include <chrono>
8080
#include <databento/live.hpp>
81+
#include <databento/symbol_map.hpp>
8182
#include <iostream>
8283
#include <string>
8384
#include <thread>
84-
#include <unordered_map>
8585

8686
using namespace databento;
8787

8888
int main() {
89-
std::unordered_map<std::uint32_t, std::string> symbol_mappings;
89+
PitSymbolMap symbol_mappings;
9090

9191
auto client =
9292
LiveBuilder{}.SetKeyFromEnv().SetDataset("GLBX.MDP3").BuildThreaded();
9393

9494
auto handler = [&symbol_mappings](const Record& rec) {
95+
symbol_mappings.OnRecord(rec);
9596
if (rec.Holds<TradeMsg>()) {
9697
auto trade = rec.Get<TradeMsg>();
9798
std::cout << "Received trade for "
9899
<< symbol_mappings[trade.hd.instrument_id] << ':' << trade
99100
<< '\n';
100-
} else if (rec.Holds<SymbolMappingMsg>()) {
101-
auto mapping = rec.Get<SymbolMappingMsg>();
102-
symbol_mappings[mapping.hd.instrument_id] = mapping.STypeOutSymbol();
103101
}
104102
return KeepGoing::Continue;
105103
};

cmake/SourcesAndHeaders.cmake

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ set(headers
1919
include/databento/metadata.hpp
2020
include/databento/publishers.hpp
2121
include/databento/record.hpp
22+
include/databento/symbol_map.hpp
2223
include/databento/symbology.hpp
2324
include/databento/timeseries.hpp
2425
include/databento/with_ts_out.hpp
@@ -51,6 +52,7 @@ set(sources
5152
src/metadata.cpp
5253
src/publishers.cpp
5354
src/record.cpp
55+
src/symbol_map.cpp
5456
src/symbology.cpp
5557
src/detail/file_stream.cpp
5658
src/detail/http_client.cpp

example/live/readme.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,26 @@
33
// NOLINTBEGIN(google-build-using-namespace)
44
#include <chrono>
55
#include <databento/live.hpp>
6+
#include <databento/symbol_map.hpp>
67
#include <iostream>
78
#include <string>
89
#include <thread>
9-
#include <unordered_map>
1010

1111
using namespace databento;
1212

1313
int main() {
14-
std::unordered_map<std::uint32_t, std::string> symbol_mappings;
14+
PitSymbolMap symbol_mappings;
1515

1616
auto client =
1717
LiveBuilder{}.SetKeyFromEnv().SetDataset("GLBX.MDP3").BuildThreaded();
1818

1919
auto handler = [&symbol_mappings](const Record& rec) {
20+
symbol_mappings.OnRecord(rec);
2021
if (rec.Holds<TradeMsg>()) {
2122
auto trade = rec.Get<TradeMsg>();
2223
std::cout << "Received trade for "
2324
<< symbol_mappings[trade.hd.instrument_id] << ':' << trade
2425
<< '\n';
25-
} else if (rec.Holds<SymbolMappingMsg>()) {
26-
auto mapping = rec.Get<SymbolMappingMsg>();
27-
symbol_mappings[mapping.hd.instrument_id] = mapping.STypeOutSymbol();
2826
}
2927
return KeepGoing::Continue;
3028
};

example/live/simple.cpp

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,29 @@
11
#include <csignal> // sig_atomic_t
22
#include <cstdint>
3+
#include <databento/constants.hpp>
4+
#include <databento/dbn.hpp>
5+
#include <databento/enums.hpp>
6+
#include <databento/live.hpp>
7+
#include <databento/live_threaded.hpp>
8+
#include <databento/log.hpp>
9+
#include <databento/record.hpp>
10+
#include <databento/symbol_map.hpp>
11+
#include <databento/with_ts_out.hpp>
312
#include <iostream>
413
#include <memory>
5-
#include <unordered_map>
6-
7-
#include "databento/constants.hpp"
8-
#include "databento/dbn.hpp"
9-
#include "databento/enums.hpp"
10-
#include "databento/live.hpp"
11-
#include "databento/live_threaded.hpp"
12-
#include "databento/log.hpp"
13-
#include "databento/record.hpp"
14-
#include "databento/with_ts_out.hpp"
1514

1615
static std::sig_atomic_t volatile gSignal;
1716

1817
int main() {
19-
std::unordered_map<std::uint32_t, std::string> symbol_mappings;
18+
databento::PitSymbolMap symbol_mappings;
2019
std::unique_ptr<databento::ILogReceiver> log_receiver{
2120
new databento::ConsoleLogReceiver{databento::LogLevel::Debug}};
2221

2322
auto client = databento::LiveBuilder{}
2423
.SetLogReceiver(log_receiver.get())
2524
.SetKeyFromEnv()
2625
.SetDataset(databento::dataset::kGlbxMdp3)
26+
.SetUpgradePolicy(databento::VersionUpgradePolicy::Upgrade)
2727
.BuildThreaded();
2828

2929
// Set up signal handler for Ctrl+C
@@ -44,7 +44,7 @@ int main() {
4444
case RType::Mbo: {
4545
auto ohlcv = rec.Get<databento::WithTsOut<databento::MboMsg>>();
4646
std::cout << "Received tick for "
47-
<< symbol_mappings.at(ohlcv.rec.hd.instrument_id)
47+
<< symbol_mappings[ohlcv.rec.hd.instrument_id]
4848
<< " with ts_out " << ohlcv.ts_out.time_since_epoch().count()
4949
<< ": " << ohlcv.rec << '\n';
5050
break;
@@ -56,9 +56,7 @@ int main() {
5656
}
5757
case RType::SymbolMapping: {
5858
auto mapping = rec.Get<databento::SymbolMappingMsg>();
59-
std::cout << "Received symbol mapping: " << mapping << '\n';
60-
symbol_mappings.emplace(mapping.hd.instrument_id,
61-
mapping.STypeInSymbol());
59+
symbol_mappings.OnSymbolMapping(mapping);
6260
break;
6361
}
6462
case RType::System: {

include/databento/dbn_decoder.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#include "databento/detail/shared_channel.hpp"
1111
#include "databento/enums.hpp" // Upgrade Policy
1212
#include "databento/ireadable.hpp"
13-
#include "databento/record.hpp"
13+
#include "databento/record.hpp" // Record, RecordHeader
1414

1515
namespace databento {
1616
// DBN decoder. Set upgrade_policy to control how DBN version 1 data should be
@@ -68,7 +68,9 @@ class DbnDecoder {
6868
std::unique_ptr<IReadable> input_;
6969
std::vector<std::uint8_t> read_buffer_;
7070
std::size_t buffer_idx_{};
71-
std::array<std::uint8_t, kMaxRecordLen> compat_buffer_{};
71+
// Must be 8-byte aligned for records
72+
alignas(
73+
RecordHeader) std::array<std::uint8_t, kMaxRecordLen> compat_buffer_{};
7274
Record current_record_{nullptr};
7375
};
7476
} // namespace databento

include/databento/live_blocking.hpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#include "databento/dbn.hpp" // Metadata
1212
#include "databento/detail/tcp_client.hpp" // TcpClient
1313
#include "databento/enums.hpp" // Schema, SType, VersionUpgradePolicy
14-
#include "databento/record.hpp" // Record
14+
#include "databento/record.hpp" // Record, RecordHeader
1515

1616
namespace databento {
1717
class ILogReceiver;
@@ -93,10 +93,13 @@ class LiveBlocking {
9393
std::uint8_t version_{};
9494
VersionUpgradePolicy upgrade_policy_;
9595
detail::TcpClient client_;
96-
std::array<char, kMaxStrLen> read_buffer_{};
96+
// Must be 8-byte aligned for records
97+
alignas(RecordHeader) std::array<char, kMaxStrLen> read_buffer_{};
9798
std::size_t buffer_size_{};
9899
std::size_t buffer_idx_{};
99-
std::array<std::uint8_t, kMaxRecordLen> compat_buffer_{};
100+
// Must be 8-byte aligned for records
101+
alignas(
102+
RecordHeader) std::array<std::uint8_t, kMaxRecordLen> compat_buffer_{};
100103
std::uint64_t session_id_;
101104
Record current_record_{nullptr};
102105
};

include/databento/publishers.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ enum class Venue : std::uint16_t {
8787
Ndex = 39,
8888
// Databento Equities - Consolidated
8989
Dbeq = 40,
90+
// MIAX Sapphire
91+
Sphr = 41,
9092
};
9193

9294
// A source of data.
@@ -273,6 +275,8 @@ enum class Publisher : std::uint16_t {
273275
DbeqBasicDbeq = 59,
274276
// DBEQ Plus - Consolidated
275277
DbeqPlusDbeq = 60,
278+
// OPRA - MIAX Sapphire
279+
OpraPillarSphr = 61,
276280
};
277281

278282
// Get a Publisher's Venue.

include/databento/symbol_map.hpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#pragma once
2+
3+
#include <cstdint>
4+
#include <string>
5+
#include <unordered_map>
6+
7+
#include "databento/compat.hpp"
8+
#include "databento/record.hpp"
9+
10+
namespace databento {
11+
// A point-in-time symbol map. Useful for working with live symbology or
12+
// a historical request over a single day or other situations where the
13+
// symbol mappings are known not to change.
14+
class PitSymbolMap {
15+
public:
16+
using Store = std::unordered_map<std::uint32_t, std::string>;
17+
18+
PitSymbolMap() = default;
19+
20+
bool IsEmpty() const { return map_.empty(); }
21+
std::size_t Size() const { return map_.size(); }
22+
const Store& Map() const { return map_; }
23+
Store& Map() { return map_; }
24+
Store::const_iterator Find(std::uint32_t instrument_id) const {
25+
return map_.find(instrument_id);
26+
}
27+
std::string& operator[](std::uint32_t instrument_id) {
28+
return map_[instrument_id];
29+
}
30+
void OnRecord(const Record& rec);
31+
template <typename SymbolMappingRec>
32+
void OnSymbolMapping(const SymbolMappingRec& symbol_mapping);
33+
34+
private:
35+
Store map_;
36+
};
37+
38+
// Forward declare explicit instantiation
39+
extern template void PitSymbolMap::OnSymbolMapping(
40+
const SymbolMappingMsgV1& symbol_mapping);
41+
extern template void PitSymbolMap::OnSymbolMapping(
42+
const SymbolMappingMsgV2& symbol_mapping);
43+
} // namespace databento

0 commit comments

Comments
 (0)