Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
# Changelog

## 0.35.0 - 2025-05-13

### Enhancements
- Added a `v3::StatMsg` record with an expanded 64-bit `quantity` field
- Added `kDbnVersion` constants to each version namespace: `v1`, `v2`, and `v3`
- Added `kUndefStatQuantity` constants to each version namespace
- Added new off-market publishers for Eurex, and European Energy Exchange (EEX)
- Increased live subscription symbol chunking size

## 0.34.2 - 2025-05-06

#### Bug fixes
### Bug fixes
- Fixed potential for unaligned records in live and historical streaming requests

## 0.34.1 - 2025-04-29
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ cmake_minimum_required(VERSION 3.24..4.0)

project(
databento
VERSION 0.34.2
VERSION 0.35.0
LANGUAGES CXX
DESCRIPTION "Official Databento client library"
)
Expand Down
60 changes: 32 additions & 28 deletions include/databento/publishers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ enum class Venue : std::uint16_t {
Xase = 11,
// NYSE Arca
Arcx = 12,
// NYSE Chicago, Inc.
// NYSE Texas, Inc.
Xchi = 13,
// Investors Exchange
Iexg = 14,
Expand All @@ -47,39 +47,39 @@ enum class Venue : std::uint16_t {
Eprl = 19,
// NYSE American Options
Amxo = 20,
// BOX Options Exchange
// BOX Options
Xbox = 21,
// Cboe Options Exchange
// Cboe Options
Xcbo = 22,
// MIAX Emerald
Emld = 23,
// Cboe EDGX Options Exchange
// Cboe EDGX Options
Edgo = 24,
// ISE Gemini Exchange
// Nasdaq GEMX
Gmni = 25,
// International Securities Exchange, LLC
// Nasdaq ISE
Xisx = 26,
// ISE Mercury, LLC
// Nasdaq MRX
Mcry = 27,
// Miami International Securities Exchange
// MIAX Options
Xmio = 28,
// NYSE Arca Options
Arco = 29,
// Options Price Reporting Authority
Opra = 30,
// MIAX Pearl
Mprl = 31,
// Nasdaq Options Market
// Nasdaq Options
Xndq = 32,
// Nasdaq OMX BX Options
// Nasdaq BX Options
Xbxo = 33,
// Cboe C2 Options Exchange
// Cboe C2 Options
C2Ox = 34,
// Nasdaq OMX PHLX
// Nasdaq PHLX
Xphl = 35,
// Cboe BZX Options Exchange
// Cboe BZX Options
Bato = 36,
// MEMX LLC Options
// MEMX Options
Mxop = 37,
// ICE Futures Europe (Commodities)
Ifeu = 38,
Expand Down Expand Up @@ -135,7 +135,7 @@ enum class Dataset : std::uint16_t {
XcisPillar = 10,
// NYSE American Integrated
XasePillar = 11,
// NYSE Chicago Integrated
// NYSE Texas Integrated
XchiPillar = 12,
// NYSE National BBO
XcisBbo = 13,
Expand Down Expand Up @@ -217,7 +217,7 @@ enum class Publisher : std::uint16_t {
XcisPillarXcis = 10,
// NYSE American Integrated
XasePillarXase = 11,
// NYSE Chicago Integrated
// NYSE Texas Integrated
XchiPillarXchi = 12,
// NYSE National BBO
XcisBboXcis = 13,
Expand All @@ -233,45 +233,45 @@ enum class Publisher : std::uint16_t {
XnasNlsFinc = 18,
// FINRA/NYSE TRF
XnysTradesFiny = 19,
// OPRA - NYSE American
// OPRA - NYSE American Options
OpraPillarAmxo = 20,
// OPRA - Boston Options Exchange
// OPRA - BOX Options
OpraPillarXbox = 21,
// OPRA - Cboe Options Exchange
// OPRA - Cboe Options
OpraPillarXcbo = 22,
// OPRA - MIAX Emerald
OpraPillarEmld = 23,
// OPRA - Cboe EDGX Options Exchange
// OPRA - Cboe EDGX Options
OpraPillarEdgo = 24,
// OPRA - Nasdaq GEMX
OpraPillarGmni = 25,
// OPRA - Nasdaq ISE
OpraPillarXisx = 26,
// OPRA - Nasdaq MRX
OpraPillarMcry = 27,
// OPRA - Miami International Securities
// OPRA - MIAX Options
OpraPillarXmio = 28,
// OPRA - NYSE Arca
// OPRA - NYSE Arca Options
OpraPillarArco = 29,
// OPRA - Options Price Reporting Authority
OpraPillarOpra = 30,
// OPRA - MIAX Pearl
OpraPillarMprl = 31,
// OPRA - Nasdaq Options Market
// OPRA - Nasdaq Options
OpraPillarXndq = 32,
// OPRA - Nasdaq BX Options
OpraPillarXbxo = 33,
// OPRA - Cboe C2 Options Exchange
// OPRA - Cboe C2 Options
OpraPillarC2Ox = 34,
// OPRA - Nasdaq PHLX
OpraPillarXphl = 35,
// OPRA - Cboe BZX Options
OpraPillarBato = 36,
// OPRA - MEMX Options Exchange
// OPRA - MEMX Options
OpraPillarMxop = 37,
// IEX TOPS
IexgTopsIexg = 38,
// DBEQ Basic - NYSE Chicago
// DBEQ Basic - NYSE Texas
DbeqBasicXchi = 39,
// DBEQ Basic - NYSE National
DbeqBasicXcis = 40,
Expand All @@ -289,7 +289,7 @@ enum class Publisher : std::uint16_t {
XnasQbboXnas = 46,
// Nasdaq Trades
XnasNlsXnas = 47,
// Databento US Equities Plus - NYSE Chicago
// Databento US Equities Plus - NYSE Texas
EqusPlusXchi = 48,
// Databento US Equities Plus - NYSE National
EqusPlusXcis = 49,
Expand Down Expand Up @@ -317,7 +317,7 @@ enum class Publisher : std::uint16_t {
EqusPlusEqus = 60,
// OPRA - MIAX Sapphire
OpraPillarSphr = 61,
// Databento US Equities (All Feeds) - NYSE Chicago
// Databento US Equities (All Feeds) - NYSE Texas
EqusAllXchi = 62,
// Databento US Equities (All Feeds) - NYSE National
EqusAllXcis = 63,
Expand Down Expand Up @@ -399,6 +399,10 @@ enum class Publisher : std::uint16_t {
XeurEobiXeur = 101,
// European Energy Exchange EOBI
XeerEobiXeer = 102,
// Eurex EOBI - Off-Market Trades
XeurEobiXoff = 103,
// European Energy Exchange EOBI - Off-Market Trades
XeerEobiXoff = 104,
};

// Get a Publisher's Venue.
Expand Down
4 changes: 3 additions & 1 deletion include/databento/record.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ namespace databento {
// Forward declare
namespace v3 {
struct InstrumentDefMsg;
}
struct StatMsg;
} // namespace v3

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

v3::StatMsg ToV3() const;
UnixNanos IndexTs() const { return ts_recv; }

RecordHeader hd;
Expand Down
7 changes: 5 additions & 2 deletions include/databento/v1.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#pragma once

#include "databento/constants.hpp" // kSymbolCstrLen
#include "databento/datetime.hpp" // UnixNanos
#include "databento/constants.hpp" // kAssetCstrLen, kSymbolCstrLen, kUndefStatQuantity
#include "databento/datetime.hpp" // UnixNanos
#include "databento/enums.hpp"
#include "databento/record.hpp"
#include "databento/v2.hpp"
Expand All @@ -13,8 +13,11 @@ struct InstrumentDefMsg;
}

namespace v1 {
static constexpr std::uint8_t kDbnVersion = 1;
static constexpr std::size_t kSymbolCstrLen = 22;
static constexpr std::size_t kAssetCstrLen = databento::kAssetCstrLen;
static constexpr std::int32_t kUndefStatQuantity =
databento::kUndefStatQuantity;

using MboMsg = databento::MboMsg;
using TradeMsg = databento::TradeMsg;
Expand Down
5 changes: 4 additions & 1 deletion include/databento/v2.hpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
#pragma once

#include "databento/constants.hpp" // kSymbolCstrLen
#include "databento/constants.hpp" // kAssetCstrLen, kSymbolCstrLen, kUndefStatQuantity
#include "databento/record.hpp"

namespace databento::v2 {
static constexpr std::uint8_t kDbnVersion = 2;
static constexpr std::size_t kSymbolCstrLen = databento::kSymbolCstrLen;
static constexpr std::size_t kAssetCstrLen = databento::kAssetCstrLen;
static constexpr std::int32_t kUndefStatQuantity =
databento::kUndefStatQuantity;

using MboMsg = databento::MboMsg;
using TradeMsg = databento::TradeMsg;
Expand Down
42 changes: 41 additions & 1 deletion include/databento/v3.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,19 @@

#include <cstddef>
#include <cstdint>
#include <limits>

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

namespace databento::v3 {
static constexpr std::uint8_t kDbnVersion = 3;
static constexpr std::size_t kSymbolCstrLen = databento::kSymbolCstrLen;
static constexpr std::size_t kAssetCstrLen = 11;
static constexpr std::int64_t kUndefStatQuantity =
std::numeric_limits<int64_t>::max();

using MboMsg = databento::MboMsg;
using TradeMsg = databento::TradeMsg;
Expand All @@ -28,7 +32,6 @@ using Cbbo1MMsg = databento::Cbbo1MMsg;
using OhlcvMsg = databento::OhlcvMsg;
using StatusMsg = databento::StatusMsg;
using ImbalanceMsg = databento::ImbalanceMsg;
using StatMsg = databento::StatMsg;
using ErrorMsg = databento::ErrorMsg;
using SymbolMappingMsg = databento::SymbolMappingMsg;
using SystemMsg = databento::SystemMsg;
Expand Down Expand Up @@ -133,13 +136,50 @@ static_assert(alignof(InstrumentDefMsg) == 8, "Must have 8-byte alignment");
static_assert(kMaxRecordLen == sizeof(InstrumentDefMsg) + sizeof(UnixNanos),
"v3 definition with ts_out should be the largest record");

/// A statistics message. A catchall for various data disseminated by
/// publishers. The `stat_type` indicates the statistic contained in the
/// message.
struct StatMsg {
static bool HasRType(RType rtype) { return rtype == RType::Statistics; }

UnixNanos IndexTs() const { return ts_recv; }

RecordHeader hd;
UnixNanos ts_recv;
UnixNanos ts_ref;
std::int64_t price;
std::int64_t quantity;
std::uint32_t sequence;
TimeDeltaNanos ts_in_delta;
StatType stat_type;
std::uint16_t channel_id;
StatUpdateAction update_action;
std::uint8_t stat_flags;
std::array<char, 18> reserved;
};
static_assert(sizeof(StatMsg) == 80, "StatMsg size must match Rust");
static_assert(alignof(StatMsg) == 8, "Must have 8-byte alignment");

bool operator==(const InstrumentDefMsg& lhs, const InstrumentDefMsg& rhs);
inline bool operator!=(const InstrumentDefMsg& lhs,
const InstrumentDefMsg& rhs) {
return !(lhs == rhs);
}
inline bool operator==(const StatMsg& lhs, const StatMsg& rhs) {
return std::tie(lhs.hd, lhs.ts_recv, lhs.ts_ref, lhs.price, lhs.quantity,
lhs.sequence, lhs.ts_in_delta, lhs.stat_type, lhs.channel_id,
lhs.update_action, lhs.stat_flags) ==
std::tie(rhs.hd, rhs.ts_recv, rhs.ts_ref, rhs.price, rhs.quantity,
rhs.sequence, rhs.ts_in_delta, rhs.stat_type, rhs.channel_id,
rhs.update_action, rhs.stat_flags);
}
inline bool operator!=(const StatMsg& lhs, const StatMsg& rhs) {
return !(lhs == rhs);
}

std::string ToString(const InstrumentDefMsg& instr_def_msg);
std::ostream& operator<<(std::ostream& stream,
const InstrumentDefMsg& instr_def_msg);
std::string ToString(const StatMsg& stat_msg);
std::ostream& operator<<(std::ostream& stream, const StatMsg& stat_msg);
} // namespace databento::v3
2 changes: 1 addition & 1 deletion pkg/PKGBUILD
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Maintainer: Databento <support@databento.com>
_pkgname=databento-cpp
pkgname=databento-cpp-git
pkgver=0.34.2
pkgver=0.35.0
pkgrel=1
pkgdesc="Official C++ client for Databento"
arch=('any')
Expand Down
4 changes: 3 additions & 1 deletion scripts/get_version.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@

SCRIPTS_DIR="$(cd "$(dirname "$0")" || exit; pwd -P)"
PROJECT_ROOT_DIR="$(dirname "${SCRIPTS_DIR}")"
grep '^project("databento" VERSION' "${PROJECT_ROOT_DIR}/CMakeLists.txt" | cut -d' ' -f3
grep --after-context=2 '^project($' "${PROJECT_ROOT_DIR}/CMakeLists.txt" \
| grep --perl-regexp --only-matching 'VERSION \d+\.\d+\.\d+' \
| cut --delimiter=' ' --fields=2
6 changes: 3 additions & 3 deletions src/live_blocking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,16 +113,16 @@ void LiveBlocking::Subscribe(std::string_view sub_msg,
const std::vector<std::string>& symbols,
bool use_snapshot) {
static constexpr auto kMethodName = "Live::Subscribe";
constexpr std::ptrdiff_t kSymbolMaxChunkSize = 128;
constexpr std::ptrdiff_t kSymbolMaxChunkSize = 500;

if (symbols.empty()) {
throw InvalidArgumentError{kMethodName, "symbols",
"must contain at least one symbol"};
}
auto symbols_it = symbols.begin();
while (symbols_it != symbols.end()) {
const auto chunk_size =
std::min(kSymbolMaxChunkSize, std::distance(symbols_it, symbols.end()));
const auto distance_from_end = std::distance(symbols_it, symbols.end());
const auto chunk_size = std::min(kSymbolMaxChunkSize, distance_from_end);

std::ostringstream chunked_sub_msg;
chunked_sub_msg << sub_msg << "|symbols="
Expand Down
Loading
Loading