Skip to content

Commit f9de3b2

Browse files
committed
ADD: Add StatMsg v3
1 parent cbc998f commit f9de3b2

File tree

7 files changed

+102
-6
lines changed

7 files changed

+102
-6
lines changed

CHANGELOG.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
11
# Changelog
22

3+
## 0.35.0 - TBD
4+
5+
### Enhancements
6+
- Added a `v3::StatMsg` record with an expanded 64-bit `quantity` field
7+
- Added `kDbnVersion` constants to each version namespace: `v1`, `v2`, and `v3`
8+
- Added `kUndefStatQuantity` constants to each version namespace
9+
310
## 0.34.2 - 2025-05-06
411

5-
#### Bug fixes
12+
### Bug fixes
613
- Fixed potential for unaligned records in live and historical streaming requests
714

815
## 0.34.1 - 2025-04-29

include/databento/record.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ namespace databento {
2020
// Forward declare
2121
namespace v3 {
2222
struct InstrumentDefMsg;
23-
}
23+
struct StatMsg;
24+
} // namespace v3
2425

2526
// Common data for all Databento Records.
2627
struct RecordHeader {
@@ -501,6 +502,7 @@ static_assert(alignof(ImbalanceMsg) == 8, "Must have 8-byte alignment");
501502
struct StatMsg {
502503
static bool HasRType(RType rtype) { return rtype == RType::Statistics; }
503504

505+
v3::StatMsg ToV3() const;
504506
UnixNanos IndexTs() const { return ts_recv; }
505507

506508
RecordHeader hd;

include/databento/v1.hpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#pragma once
22

3-
#include "databento/constants.hpp" // kSymbolCstrLen
4-
#include "databento/datetime.hpp" // UnixNanos
3+
#include "databento/constants.hpp" // kAssetCstrLen, kSymbolCstrLen, kUndefStatQuantity
4+
#include "databento/datetime.hpp" // UnixNanos
55
#include "databento/enums.hpp"
66
#include "databento/record.hpp"
77
#include "databento/v2.hpp"
@@ -13,8 +13,11 @@ struct InstrumentDefMsg;
1313
}
1414

1515
namespace v1 {
16+
static constexpr std::uint8_t kDbnVersion = 1;
1617
static constexpr std::size_t kSymbolCstrLen = 22;
1718
static constexpr std::size_t kAssetCstrLen = databento::kAssetCstrLen;
19+
static constexpr std::int32_t kUndefStatQuantity =
20+
databento::kUndefStatQuantity;
1821

1922
using MboMsg = databento::MboMsg;
2023
using TradeMsg = databento::TradeMsg;

include/databento/v2.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
#pragma once
22

3-
#include "databento/constants.hpp" // kSymbolCstrLen
3+
#include "databento/constants.hpp" // kAssetCstrLen, kSymbolCstrLen, kUndefStatQuantity
44
#include "databento/record.hpp"
55

66
namespace databento::v2 {
7+
static constexpr std::uint8_t kDbnVersion = 2;
78
static constexpr std::size_t kSymbolCstrLen = databento::kSymbolCstrLen;
89
static constexpr std::size_t kAssetCstrLen = databento::kAssetCstrLen;
10+
static constexpr std::int32_t kUndefStatQuantity =
11+
databento::kUndefStatQuantity;
912

1013
using MboMsg = databento::MboMsg;
1114
using TradeMsg = databento::TradeMsg;

include/databento/v3.hpp

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,19 @@
22

33
#include <cstddef>
44
#include <cstdint>
5+
#include <limits>
56

67
#include "databento/constants.hpp" // kSymbolCstrLen
78
#include "databento/datetime.hpp" // UnixNanos
89
#include "databento/enums.hpp" // InstrumentClass, MatchingAlgorithm, RType, SecurityUpdateAction, Side, UserDefinedInstrument
910
#include "databento/record.hpp" // RecordHeader
1011

1112
namespace databento::v3 {
13+
static constexpr std::uint8_t kDbnVersion = 3;
1214
static constexpr std::size_t kSymbolCstrLen = databento::kSymbolCstrLen;
1315
static constexpr std::size_t kAssetCstrLen = 11;
16+
static constexpr std::int64_t kUndefStatQuantity =
17+
std::numeric_limits<int64_t>::max();
1418

1519
using MboMsg = databento::MboMsg;
1620
using TradeMsg = databento::TradeMsg;
@@ -28,7 +32,6 @@ using Cbbo1MMsg = databento::Cbbo1MMsg;
2832
using OhlcvMsg = databento::OhlcvMsg;
2933
using StatusMsg = databento::StatusMsg;
3034
using ImbalanceMsg = databento::ImbalanceMsg;
31-
using StatMsg = databento::StatMsg;
3235
using ErrorMsg = databento::ErrorMsg;
3336
using SymbolMappingMsg = databento::SymbolMappingMsg;
3437
using SystemMsg = databento::SystemMsg;
@@ -133,13 +136,50 @@ static_assert(alignof(InstrumentDefMsg) == 8, "Must have 8-byte alignment");
133136
static_assert(kMaxRecordLen == sizeof(InstrumentDefMsg) + sizeof(UnixNanos),
134137
"v3 definition with ts_out should be the largest record");
135138

139+
/// A statistics message. A catchall for various data disseminated by
140+
/// publishers. The `stat_type` indicates the statistic contained in the
141+
/// message.
142+
struct StatMsg {
143+
static bool HasRType(RType rtype) { return rtype == RType::Statistics; }
144+
145+
UnixNanos IndexTs() const { return ts_recv; }
146+
147+
RecordHeader hd;
148+
UnixNanos ts_recv;
149+
UnixNanos ts_ref;
150+
std::int64_t price;
151+
std::int64_t quantity;
152+
std::uint32_t sequence;
153+
TimeDeltaNanos ts_in_delta;
154+
StatType stat_type;
155+
std::uint16_t channel_id;
156+
StatUpdateAction update_action;
157+
std::uint8_t stat_flags;
158+
std::array<char, 18> reserved;
159+
};
160+
static_assert(sizeof(StatMsg) == 80, "StatMsg size must match Rust");
161+
static_assert(alignof(StatMsg) == 8, "Must have 8-byte alignment");
162+
136163
bool operator==(const InstrumentDefMsg& lhs, const InstrumentDefMsg& rhs);
137164
inline bool operator!=(const InstrumentDefMsg& lhs,
138165
const InstrumentDefMsg& rhs) {
139166
return !(lhs == rhs);
140167
}
168+
inline bool operator==(const StatMsg& lhs, const StatMsg& rhs) {
169+
return std::tie(lhs.hd, lhs.ts_recv, lhs.ts_ref, lhs.price, lhs.quantity,
170+
lhs.sequence, lhs.ts_in_delta, lhs.stat_type, lhs.channel_id,
171+
lhs.update_action, lhs.stat_flags) ==
172+
std::tie(rhs.hd, rhs.ts_recv, rhs.ts_ref, rhs.price, rhs.quantity,
173+
rhs.sequence, rhs.ts_in_delta, rhs.stat_type, rhs.channel_id,
174+
rhs.update_action, rhs.stat_flags);
175+
}
176+
inline bool operator!=(const StatMsg& lhs, const StatMsg& rhs) {
177+
return !(lhs == rhs);
178+
}
141179

142180
std::string ToString(const InstrumentDefMsg& instr_def_msg);
143181
std::ostream& operator<<(std::ostream& stream,
144182
const InstrumentDefMsg& instr_def_msg);
183+
std::string ToString(const StatMsg& stat_msg);
184+
std::ostream& operator<<(std::ostream& stream, const StatMsg& stat_msg);
145185
} // namespace databento::v3

src/record.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include <string>
44

5+
#include "databento/constants.hpp"
56
#include "databento/enums.hpp"
67
#include "databento/exceptions.hpp" // InvalidArgumentError
78
#include "databento/fixed_price.hpp"
@@ -200,6 +201,26 @@ databento::v3::InstrumentDefMsg InstrumentDefMsg::ToV3() const {
200201
return ret;
201202
}
202203

204+
using databento::StatMsg;
205+
206+
databento::v3::StatMsg StatMsg::ToV3() const {
207+
return databento::v3::StatMsg{
208+
RecordHeader{sizeof(v3::StatMsg) / RecordHeader::kLengthMultiplier,
209+
RType::Statistics, hd.publisher_id, hd.instrument_id,
210+
hd.ts_event},
211+
ts_recv,
212+
ts_ref,
213+
price,
214+
quantity == kUndefStatQuantity ? v3::kUndefStatQuantity : quantity,
215+
sequence,
216+
ts_in_delta,
217+
stat_type,
218+
channel_id,
219+
update_action,
220+
stat_flags,
221+
{}};
222+
}
223+
203224
bool databento::operator==(const InstrumentDefMsg& lhs,
204225
const InstrumentDefMsg& rhs) {
205226
return lhs.hd == rhs.hd && lhs.ts_recv == rhs.ts_recv &&

src/v3.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,4 +157,24 @@ std::ostream& operator<<(std::ostream& stream,
157157
.AddField("leg_side", instr_def_msg.leg_side)
158158
.Finish();
159159
}
160+
161+
std::string ToString(const StatMsg& stat_msg) { return MakeString(stat_msg); }
162+
std::ostream& operator<<(std::ostream& stream, const StatMsg& stat_msg) {
163+
return StreamOpBuilder{stream}
164+
.SetSpacer("\n ")
165+
.SetTypeName("StatMsg")
166+
.Build()
167+
.AddField("hd", stat_msg.hd)
168+
.AddField("ts_recv", stat_msg.ts_recv)
169+
.AddField("ts_ref", stat_msg.ts_ref)
170+
.AddField("price", FixPx{stat_msg.price})
171+
.AddField("quantity", stat_msg.quantity)
172+
.AddField("sequence", stat_msg.sequence)
173+
.AddField("ts_in_delta", stat_msg.ts_in_delta)
174+
.AddField("stat_type", stat_msg.stat_type)
175+
.AddField("channel_id", stat_msg.channel_id)
176+
.AddField("update_action", stat_msg.update_action)
177+
.AddField("stat_flags", stat_msg.stat_flags)
178+
.Finish();
179+
}
160180
} // namespace databento::v3

0 commit comments

Comments
 (0)