Skip to content

Commit

Permalink
ADD: Add separate BboMsg to C++ client
Browse files Browse the repository at this point in the history
  • Loading branch information
threecgreen committed Jul 8, 2024
1 parent 7eb0c14 commit 601767d
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 12 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ for date fields were changed from strings or ints to `date::year_month_day`.
- Added `DbnEncoder` class for encoding DBN data
- Added blocking API similar to `LiveBlocking` to `DbnFileStore` with new `GetMetadata`
and `NextRecord` methods
- Added `BboMsg` record struct for future `bbo-1m` and `bbo-1s` schemas
- Added `PitSymbol` map constructor from `Metadata` and a `date::year_month_day`
- Added `Metadata::CreateSymbolMap` and `Metadata::CreateSymbolMapForDate` methods for
creating symbology maps from historical metadata
Expand All @@ -25,6 +26,7 @@ for date fields were changed from strings or ints to `date::year_month_day`.
- Added new dependency on [Howard Hinnant's date library](https://howardhinnant.github.io/date/date.html)
- Added `ILogReceiver*` parameter to all `DbnDecoder` constructors and one `DbnFileStore` constructor
- Removed type `StrMappingInterval`. `MappingInterval` is now also used in `SymbologyResolution`.
- Changed `Bbo1sMsg` and `Bbo1mMsg` to be aliases for `BboMsg`
- Changed type of `start_date` and `end_date` in `MappingInterval` to `date::year_month_day`
- Added `stype_in` and `stype_out` fields to `SymbologyResolution` to support creating
a `TsSymbolMap`
Expand Down
61 changes: 49 additions & 12 deletions include/databento/record.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,9 +177,7 @@ static_assert(alignof(TradeMsg) == 8, "Must have 8-byte alignment");
struct Mbp1Msg {
static bool HasRType(RType rtype) {
switch (rtype) {
case RType::Mbp1: // fallthrough
case RType::Bbo1M: // fallthrough
case RType::Bbo1S:
case RType::Mbp1:
return true;
default:
return false;
Expand All @@ -202,8 +200,9 @@ struct Mbp1Msg {
std::array<BidAskPair, 1> levels;
};
using TbboMsg = Mbp1Msg;
using Bbo1SMsg = Mbp1Msg;
using Bbo1MMsg = Mbp1Msg;
static_assert(alignof(Mbp1Msg) == 8, "Must have 8-byte alignment");
static_assert(sizeof(Mbp1Msg) == sizeof(TradeMsg) + sizeof(BidAskPair),
"Mbp1Msg size must match Rust");

struct Mbp10Msg {
static bool HasRType(RType rtype) { return rtype == rtype::Mbp10; }
Expand All @@ -223,14 +222,40 @@ struct Mbp10Msg {
std::uint32_t sequence;
std::array<BidAskPair, 10> levels;
};

static_assert(alignof(Mbp1Msg) == 8, "Must have 8-byte alignment");
static_assert(alignof(Mbp10Msg) == 8, "Must have 8-byte alignment");
static_assert(sizeof(Mbp1Msg) == sizeof(TradeMsg) + sizeof(BidAskPair),
"Mbp1Msg size must match Rust");
static_assert(sizeof(Mbp10Msg) == sizeof(TradeMsg) + sizeof(BidAskPair) * 10,
"Mbp10Msg size must match Rust");

struct BboMsg {
static bool HasRType(RType rtype) {
switch (rtype) {
case RType::Bbo1S: // fallthrough
case RType::Bbo1M:
return true;
default:
return false;
};
}

UnixNanos IndexTs() const { return ts_recv; }

RecordHeader hd;
std::int64_t price;
std::uint32_t size;
char reserved1;
Side side;
FlagSet flags;
char reserved2;
UnixNanos ts_recv;
std::array<char, 4> reserved3;
std::uint32_t sequence;
std::array<BidAskPair, 1> levels;
};
using Bbo1SMsg = BboMsg;
using Bbo1MMsg = BboMsg;
static_assert(alignof(BboMsg) == 8, "Must have 8-byte alignment");
static_assert(sizeof(BboMsg) == sizeof(Mbp1Msg), "BboMsg size must match Rust");

struct CbboMsg {
static bool HasRType(RType rtype) {
switch (rtype) {
Expand All @@ -252,7 +277,7 @@ struct CbboMsg {
Action action;
Side side;
FlagSet flags;
std::array<char, 1> reserved;
char reserved;
UnixNanos ts_recv;
TimeDeltaNanos ts_in_delta;
std::uint32_t sequence;
Expand Down Expand Up @@ -571,6 +596,16 @@ inline bool operator!=(const Mbp10Msg& lhs, const Mbp10Msg& rhs) {
return !(lhs == rhs);
}

inline bool operator==(const BboMsg& lhs, const BboMsg& rhs) {
return std::tie(lhs.hd, lhs.price, lhs.size, lhs.side, lhs.flags, lhs.ts_recv,
lhs.sequence, lhs.levels) ==
std::tie(rhs.hd, rhs.price, rhs.size, rhs.side, rhs.flags, rhs.ts_recv,
rhs.sequence, rhs.levels);
}
inline bool operator!=(const BboMsg& lhs, const BboMsg& rhs) {
return !(lhs == rhs);
}

inline bool operator==(const CbboMsg& lhs, const CbboMsg& rhs) {
return lhs.hd == rhs.hd && lhs.price == rhs.price && lhs.size == rhs.size &&
lhs.action == rhs.action && lhs.side == rhs.side &&
Expand Down Expand Up @@ -680,8 +715,10 @@ std::string ToString(const Mbp1Msg& mbp_msg);
std::ostream& operator<<(std::ostream& stream, const Mbp1Msg& mbp_msg);
std::string ToString(const Mbp10Msg& mbp_msg);
std::ostream& operator<<(std::ostream& stream, const Mbp10Msg& mbp_msg);
std::string ToString(const CbboMsg& mbp_msg);
std::ostream& operator<<(std::ostream& stream, const CbboMsg& mbp_msg);
std::string ToString(const BboMsg& bbo_msg);
std::ostream& operator<<(std::ostream& stream, const BboMsg& bbo_msg);
std::string ToString(const CbboMsg& cbbo_msg);
std::ostream& operator<<(std::ostream& stream, const CbboMsg& cbbo_msg);
std::string ToString(const TradeMsg& trade_msg);
std::ostream& operator<<(std::ostream& stream, const TradeMsg& trade_msg);
std::string ToString(const OhlcvMsg& ohlcv_msg);
Expand Down
16 changes: 16 additions & 0 deletions src/record.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,22 @@ std::ostream& operator<<(std::ostream& stream, const Mbp10Msg& mbp_msg) {
static_cast<std::ostringstream&>(levels_helper.Finish()))
.Finish();
}
std::string ToString(const BboMsg& bbo_msg) { return MakeString(bbo_msg); }
std::ostream& operator<<(std::ostream& stream, const BboMsg& bbo_msg) {
return StreamOpBuilder{stream}
.SetTypeName("BboMsg")
.SetSpacer("\n ")
.Build()
.AddField("hd", bbo_msg.hd)
.AddField("price", FixPx{bbo_msg.price})
.AddField("size", bbo_msg.size)
.AddField("side", bbo_msg.side)
.AddField("flags", bbo_msg.flags)
.AddField("ts_recv", bbo_msg.ts_recv)
.AddField("sequence", bbo_msg.sequence)
.AddField("levels", std::get<0>(bbo_msg.levels))
.Finish();
}
std::string ToString(const CbboMsg& cbbo_msg) { return MakeString(cbbo_msg); }
std::ostream& operator<<(std::ostream& stream, const CbboMsg& cbbo_msg) {
return StreamOpBuilder{stream}
Expand Down

0 comments on commit 601767d

Please sign in to comment.