Skip to content

Commit ed9864a

Browse files
ADD: Add new bbo/cbbo schemas to C++ client
1 parent ae7db1e commit ed9864a

File tree

10 files changed

+333
-85
lines changed

10 files changed

+333
-85
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
- Added logic to skip `find_package` call if `nlohmann_json` and `httplib` targets
1212
already exist (credit: @akovachev)
1313
- Added specific instructions for installing dependencies on Ubuntu and macOS (credit: @camrongodbout)
14+
- Added `CbboMsg` record and corresponding `ConsolidatedBidAskPair` structure
15+
- Added new enum values for `Schema` and `RType` corresponding to new schemas
16+
`cbbo`, `cbbo-1s`, `cbbo-1m`, `tcbbo`, `bbo-1s`, `bbo-1m`
1417

1518
### Bug fixes
1619
- Fixed out-of-order initialization in `DbnDecoder` (credit: @Hailios)

include/databento/enums.hpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@ enum class Schema : std::uint16_t {
3434
Statistics = 10,
3535
Status = 11,
3636
Imbalance = 12,
37+
Cbbo = 14,
38+
Cbbo1S = 15,
39+
Cbbo1M = 16,
40+
Tcbbo = 17,
41+
Bbo1S = 18,
42+
Bbo1M = 19,
3743
};
3844

3945
// Represents a data output encoding.
@@ -133,6 +139,12 @@ enum RType : std::uint8_t {
133139
System = 0x17,
134140
Statistics = 0x18,
135141
Mbo = 0xA0,
142+
Cbbo = 0xB1,
143+
Cbbo1S = 0xC0,
144+
Cbbo1M = 0xC1,
145+
Tcbbo = 0xC2,
146+
Bbo1S = 0xC3,
147+
Bbo1M = 0xC4,
136148
};
137149
} // namespace rtype
138150
using rtype::RType;

include/databento/record.hpp

Lines changed: 127 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -102,13 +102,51 @@ struct BidAskPair {
102102
static_assert(sizeof(BidAskPair) == 32, "BidAskPair size must match Rust");
103103
static_assert(alignof(BidAskPair) == 8, "Must have 8-byte alignment");
104104

105-
namespace detail {
106-
template <std::size_t N>
107-
struct MbpMsg {
108-
static_assert(N <= 15, "The maximum number of levels in an MbpMsg is 15");
105+
struct ConsolidatedBidAskPair {
106+
std::int64_t bid_px;
107+
std::int64_t ask_px;
108+
std::uint32_t bid_sz;
109+
std::uint32_t ask_sz;
110+
std::uint16_t bid_pb;
111+
std::array<char, 2> reserved1;
112+
std::uint16_t ask_pb;
113+
std::array<char, 2> reserved2;
114+
};
115+
static_assert(sizeof(ConsolidatedBidAskPair) == 32,
116+
"ConsolidatedBidAskPair size must match Rust");
117+
static_assert(alignof(ConsolidatedBidAskPair) == 8,
118+
"Must have 8-byte alignment");
109119

120+
struct TradeMsg {
121+
static bool HasRType(RType rtype) { return rtype == RType::Mbp0; }
122+
123+
UnixNanos IndexTs() const { return ts_recv; }
124+
125+
RecordHeader hd;
126+
std::int64_t price;
127+
std::uint32_t size;
128+
Action action;
129+
Side side;
130+
FlagSet flags;
131+
// Depth of the actual book change.
132+
std::uint8_t depth;
133+
UnixNanos ts_recv;
134+
TimeDeltaNanos ts_in_delta;
135+
std::uint32_t sequence;
136+
};
137+
static_assert(sizeof(TradeMsg) == 48, "TradeMsg size must match Rust");
138+
static_assert(alignof(TradeMsg) == 8, "Must have 8-byte alignment");
139+
140+
struct Mbp1Msg {
110141
static bool HasRType(RType rtype) {
111-
return static_cast<std::uint8_t>(rtype) == N;
142+
switch (rtype) {
143+
case RType::Mbp1: // fallthrough
144+
case RType::Bbo1M: // fallthrough
145+
case RType::Bbo1S:
146+
return true;
147+
default:
148+
return false;
149+
};
112150
}
113151

114152
UnixNanos IndexTs() const { return ts_recv; }
@@ -124,12 +162,14 @@ struct MbpMsg {
124162
UnixNanos ts_recv;
125163
TimeDeltaNanos ts_in_delta;
126164
std::uint32_t sequence;
127-
std::array<BidAskPair, N> levels;
165+
std::array<BidAskPair, 1> levels;
128166
};
129-
} // namespace detail
167+
using TbboMsg = Mbp1Msg;
168+
using Bbo1SMsg = Mbp1Msg;
169+
using Bbo1MMsg = Mbp1Msg;
130170

131-
struct TradeMsg {
132-
static bool HasRType(RType rtype) { return rtype == RType::Mbp0; }
171+
struct Mbp10Msg {
172+
static bool HasRType(RType rtype) { return rtype == rtype::Mbp10; }
133173

134174
UnixNanos IndexTs() const { return ts_recv; }
135175

@@ -144,13 +184,8 @@ struct TradeMsg {
144184
UnixNanos ts_recv;
145185
TimeDeltaNanos ts_in_delta;
146186
std::uint32_t sequence;
187+
std::array<BidAskPair, 10> levels;
147188
};
148-
static_assert(sizeof(TradeMsg) == 48, "TradeMsg size must match Rust");
149-
static_assert(alignof(TradeMsg) == 8, "Must have 8-byte alignment");
150-
151-
using Mbp1Msg = detail::MbpMsg<1>;
152-
using TbboMsg = Mbp1Msg;
153-
using Mbp10Msg = detail::MbpMsg<10>;
154189

155190
static_assert(alignof(Mbp1Msg) == 8, "Must have 8-byte alignment");
156191
static_assert(alignof(Mbp10Msg) == 8, "Must have 8-byte alignment");
@@ -159,6 +194,41 @@ static_assert(sizeof(Mbp1Msg) == sizeof(TradeMsg) + sizeof(BidAskPair),
159194
static_assert(sizeof(Mbp10Msg) == sizeof(TradeMsg) + sizeof(BidAskPair) * 10,
160195
"Mbp10Msg size must match Rust");
161196

197+
struct CbboMsg {
198+
static bool HasRType(RType rtype) {
199+
switch (rtype) {
200+
case RType::Cbbo: // fallthrough
201+
case RType::Cbbo1S: // fallthrough
202+
case RType::Cbbo1M: // fallthrough
203+
case RType::Tcbbo:
204+
return true;
205+
default:
206+
return false;
207+
};
208+
}
209+
210+
UnixNanos IndexTs() const { return ts_recv; }
211+
212+
RecordHeader hd;
213+
std::int64_t price;
214+
std::uint32_t size;
215+
Action action;
216+
Side side;
217+
FlagSet flags;
218+
std::array<char, 1> reserved;
219+
UnixNanos ts_recv;
220+
TimeDeltaNanos ts_in_delta;
221+
std::uint32_t sequence;
222+
std::array<ConsolidatedBidAskPair, 1> levels;
223+
};
224+
using Cbbo1SMsg = CbboMsg;
225+
using Cbbo1MMsg = CbboMsg;
226+
using TcbboMsg = CbboMsg;
227+
static_assert(alignof(CbboMsg) == 8, "Must have 8-byte alignment");
228+
static_assert(sizeof(CbboMsg) ==
229+
sizeof(TradeMsg) + sizeof(ConsolidatedBidAskPair),
230+
"CbboMsg size must match Rust");
231+
162232
// Aggregate of open, high, low, and close prices with volume.
163233
struct OhlcvMsg {
164234
static bool HasRType(RType rtype) {
@@ -431,34 +501,49 @@ inline bool operator!=(const BidAskPair& lhs, const BidAskPair& rhs) {
431501
return !(lhs == rhs);
432502
}
433503

434-
namespace detail {
435-
template <std::size_t N>
436-
bool operator==(const MbpMsg<N>& lhs, const MbpMsg<N>& rhs) {
504+
inline bool operator==(const ConsolidatedBidAskPair& lhs,
505+
const ConsolidatedBidAskPair& rhs) {
506+
return lhs.bid_px == rhs.bid_px && lhs.ask_px == rhs.ask_px &&
507+
lhs.bid_sz == rhs.bid_sz && lhs.ask_sz == rhs.ask_sz &&
508+
lhs.bid_pb == rhs.bid_pb && lhs.ask_pb == rhs.ask_pb;
509+
}
510+
inline bool operator!=(const ConsolidatedBidAskPair& lhs,
511+
const ConsolidatedBidAskPair& rhs) {
512+
return !(lhs == rhs);
513+
}
514+
515+
inline bool operator==(const Mbp1Msg& lhs, const Mbp1Msg& rhs) {
437516
return lhs.hd == rhs.hd && lhs.price == rhs.price && lhs.size == rhs.size &&
438517
lhs.action == rhs.action && lhs.side == rhs.side &&
439518
lhs.flags == rhs.flags && lhs.depth == rhs.depth &&
440519
lhs.ts_recv == rhs.ts_recv && lhs.ts_in_delta == rhs.ts_in_delta &&
441520
lhs.sequence == rhs.sequence && lhs.levels == rhs.levels;
442521
}
443-
template <std::size_t N>
444-
bool operator!=(const MbpMsg<N>& lhs, const MbpMsg<N>& rhs) {
522+
inline bool operator!=(const Mbp1Msg& lhs, const Mbp1Msg& rhs) {
445523
return !(lhs == rhs);
446524
}
447525

448-
template <std::size_t N>
449-
std::string ToString(const MbpMsg<N>& mbp_msg);
450-
template <>
451-
std::string ToString(const Mbp1Msg& mbp_msg);
452-
template <>
453-
std::string ToString(const Mbp10Msg& mbp_msg);
526+
inline bool operator==(const Mbp10Msg& lhs, const Mbp10Msg& rhs) {
527+
return lhs.hd == rhs.hd && lhs.price == rhs.price && lhs.size == rhs.size &&
528+
lhs.action == rhs.action && lhs.side == rhs.side &&
529+
lhs.flags == rhs.flags && lhs.depth == rhs.depth &&
530+
lhs.ts_recv == rhs.ts_recv && lhs.ts_in_delta == rhs.ts_in_delta &&
531+
lhs.sequence == rhs.sequence && lhs.levels == rhs.levels;
532+
}
533+
inline bool operator!=(const Mbp10Msg& lhs, const Mbp10Msg& rhs) {
534+
return !(lhs == rhs);
535+
}
454536

455-
template <std::size_t N>
456-
std::ostream& operator<<(std::ostream& stream, const MbpMsg<N>& mbp_msg);
457-
template <>
458-
std::ostream& operator<<(std::ostream& stream, const Mbp1Msg& mbp_msg);
459-
template <>
460-
std::ostream& operator<<(std::ostream& stream, const Mbp10Msg& mbp_msg);
461-
} // namespace detail
537+
inline bool operator==(const CbboMsg& lhs, const CbboMsg& rhs) {
538+
return lhs.hd == rhs.hd && lhs.price == rhs.price && lhs.size == rhs.size &&
539+
lhs.action == rhs.action && lhs.side == rhs.side &&
540+
lhs.flags == rhs.flags && lhs.ts_recv == rhs.ts_recv &&
541+
lhs.ts_in_delta == rhs.ts_in_delta && lhs.sequence == rhs.sequence &&
542+
lhs.levels == rhs.levels;
543+
}
544+
inline bool operator!=(const CbboMsg& lhs, const CbboMsg& rhs) {
545+
return !(lhs == rhs);
546+
}
462547

463548
inline bool operator==(const TradeMsg& lhs, const TradeMsg& rhs) {
464549
return lhs.hd == rhs.hd && lhs.price == rhs.price && lhs.size == rhs.size &&
@@ -549,6 +634,15 @@ std::string ToString(const MboMsg& mbo_msg);
549634
std::ostream& operator<<(std::ostream& stream, const MboMsg& mbo_msg);
550635
std::string ToString(const BidAskPair& ba_pair);
551636
std::ostream& operator<<(std::ostream& stream, const BidAskPair& ba_pair);
637+
std::string ToString(const ConsolidatedBidAskPair& ba_pair);
638+
std::ostream& operator<<(std::ostream& stream,
639+
const ConsolidatedBidAskPair& ba_pair);
640+
std::string ToString(const Mbp1Msg& mbp_msg);
641+
std::ostream& operator<<(std::ostream& stream, const Mbp1Msg& mbp_msg);
642+
std::string ToString(const Mbp10Msg& mbp_msg);
643+
std::ostream& operator<<(std::ostream& stream, const Mbp10Msg& mbp_msg);
644+
std::string ToString(const CbboMsg& mbp_msg);
645+
std::ostream& operator<<(std::ostream& stream, const CbboMsg& mbp_msg);
552646
std::string ToString(const TradeMsg& trade_msg);
553647
std::ostream& operator<<(std::ostream& stream, const TradeMsg& trade_msg);
554648
std::string ToString(const OhlcvMsg& ohlcv_msg);

src/enums.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,24 @@ const char* ToString(Schema schema) {
6262
case Schema::Status: {
6363
return "status";
6464
}
65+
case Schema::Cbbo: {
66+
return "cbbo";
67+
}
68+
case Schema::Cbbo1S: {
69+
return "cbbo-1s";
70+
}
71+
case Schema::Cbbo1M: {
72+
return "cbbo-1m";
73+
}
74+
case Schema::Tcbbo: {
75+
return "tcbbo";
76+
}
77+
case Schema::Bbo1S: {
78+
return "bbo-1s";
79+
}
80+
case Schema::Bbo1M: {
81+
return "bbo-1m";
82+
}
6583
default: {
6684
return "unknown";
6785
}
@@ -286,6 +304,24 @@ const char* ToString(RType rtype) {
286304
case RType::Mbo: {
287305
return "Mbo";
288306
}
307+
case RType::Cbbo: {
308+
return "Cbbo";
309+
}
310+
case RType::Cbbo1S: {
311+
return "Cbbo1S";
312+
}
313+
case RType::Cbbo1M: {
314+
return "Cbbo1M";
315+
}
316+
case RType::Tcbbo: {
317+
return "Tcbbo";
318+
}
319+
case RType::Bbo1S: {
320+
return "Bbo1S";
321+
}
322+
case RType::Bbo1M: {
323+
return "Bbo1M";
324+
}
289325
default: {
290326
return "Unknown";
291327
}

0 commit comments

Comments
 (0)