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
22 changes: 20 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
# Changelog

## 0.27.0 - 2025-01-07

### Breaking changes
- Converted the `UserDefinedInstrument` enum class to an enum to safely allow handling
invalid data and adding future variants
- Updated the value of the `kMaxRecordLen` constant for the changes to
`InstrumentDefMsg` in version 3

### Enhancements
- Added `v3` namespace in preparation for future DBN version 3 release. DBN version 2
remains the current and default version
- Added `v3::InstrumentDefMsg` record with new fields to support normalizing multi-leg
strategy definitions
- Removal of statistics-schema related fields `trading_reference_price`,
`trading_reference_date`, and `settl_price_type`
- Removal of the status-schema related field `md_security_trading_status`

## 0.26.0 - 2024-12-17

### Breaking changes
Expand Down Expand Up @@ -261,7 +278,8 @@ fields for `SymbolMappingMsg`, and extends the symbol field length for `SymbolMa
Users who wish to convert DBN v1 files to v2 can use the `dbn-cli` tool available in the [databento-dbn](https://github.com/databento/dbn/) crate.
On a future date, the Databento live and historical APIs will stop serving DBN v1.

This release is fully compatible with both DBN v1 and v2, and so should be seamless for most users.
This release is fully compatible with both DBN v1 and v2, and so the change should be
seamless for most users.

### Enhancements

Expand All @@ -288,7 +306,7 @@ This release is fully compatible with both DBN v1 and v2, and so should be seaml

- The old `InstrumentDefMsg` is now `InstrumentDefMsgV1` in `compat.hpp`
- The old `SymbolMappingMsg` is now `SymbolMappingMsgV1` in `compat.hpp`
- Converted the following enums to enum classes to allow safely adding new variants:
- Converted the following enum classes to enums to allow safely adding new variants:
`SecurityUpdateAction` and `SType`
- Renamed `dummy` to `reserved` in `InstrumentDefMsg`
- Removed `reserved2`, `reserved3`, `reserved4`, and `reserved5` from `InstrumentDefMsg`
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.14)
# Project details
#

project("databento" VERSION 0.26.0 LANGUAGES CXX)
project("databento" VERSION 0.27.0 LANGUAGES CXX)
string(TOUPPER ${PROJECT_NAME} PROJECT_NAME_UPPERCASE)

#
Expand Down
2 changes: 2 additions & 0 deletions cmake/SourcesAndHeaders.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ set(headers
include/databento/timeseries.hpp
include/databento/v1.hpp
include/databento/v2.hpp
include/databento/v3.hpp
include/databento/with_ts_out.hpp
src/stream_op_helper.hpp
)
Expand Down Expand Up @@ -67,4 +68,5 @@ set(sources
src/symbol_map.cpp
src/symbology.cpp
src/v1.cpp
src/v3.cpp
)
5 changes: 4 additions & 1 deletion include/databento/enums.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,10 +220,13 @@ enum SecurityUpdateAction : char {
}
using security_update_action::SecurityUpdateAction;

enum class UserDefinedInstrument : char {
namespace user_defined_instrument {
enum UserDefinedInstrument : char {
No = 'N',
Yes = 'Y',
};
}
using user_defined_instrument::UserDefinedInstrument;

namespace stat_type {
// The type of statistic contained in a StatMsg.
Expand Down
10 changes: 7 additions & 3 deletions include/databento/record.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,13 @@
#include "databento/exceptions.hpp" // InvalidArgumentError
#include "databento/flag_set.hpp" // FlagSet
#include "databento/publishers.hpp" // Publisher
#include "databento/with_ts_out.hpp"

namespace databento {
// Forward declare
namespace v3 {
struct InstrumentDefMsg;
}

// Common data for all Databento Records.
struct RecordHeader {
static constexpr std::size_t kLengthMultiplier =
Expand Down Expand Up @@ -371,6 +375,7 @@ static_assert(alignof(StatusMsg) == 8, "Must have 8-byte alignment");
struct InstrumentDefMsg {
static bool HasRType(RType rtype) { return rtype == RType::InstrumentDef; }

v3::InstrumentDefMsg ToV3() const;
UnixNanos IndexTs() const { return ts_recv; }
const char* Currency() const { return currency.data(); }
const char* SettlCurrency() const { return settl_currency.data(); }
Expand Down Expand Up @@ -780,6 +785,5 @@ std::ostream& operator<<(std::ostream& stream,
const SymbolMappingMsg& symbol_mapping_msg);

// The length in bytes of the largest record type.
static constexpr std::size_t kMaxRecordLen =
sizeof(WithTsOut<InstrumentDefMsg>);
static constexpr std::size_t kMaxRecordLen = 520 + 8;
} // namespace databento
6 changes: 6 additions & 0 deletions include/databento/v1.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
#include "databento/v2.hpp"

namespace databento {
// Forward declare
namespace v3 {
struct InstrumentDefMsg;
}

namespace v1 {
static constexpr std::size_t kSymbolCstrLen = 22;

Expand All @@ -31,6 +36,7 @@ struct InstrumentDefMsg {
static bool HasRType(RType rtype) { return rtype == RType::InstrumentDef; }

v2::InstrumentDefMsg ToV2() const;
v3::InstrumentDefMsg ToV3() const;
const char* Currency() const { return currency.data(); }
const char* SettlCurrency() const { return settl_currency.data(); }
const char* SecSubType() const { return secsubtype.data(); }
Expand Down
146 changes: 146 additions & 0 deletions include/databento/v3.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
#pragma once

#include <cstddef>
#include <cstdint>

#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 {
namespace v3 {
static constexpr std::size_t kSymbolCstrLen = databento::kSymbolCstrLen;

using MboMsg = databento::MboMsg;
using TradeMsg = databento::TradeMsg;
using Mbp1Msg = databento::Mbp1Msg;
using TbboMsg = databento::TbboMsg;
using Mbp10Msg = databento::Mbp10Msg;
using BboMsg = databento::BboMsg;
using Bbo1SMsg = databento::Bbo1SMsg;
using Bbo1MMsg = databento::Bbo1MMsg;
using Cmbp1Msg = databento::Cmbp1Msg;
using TcbboMsg = databento::TcbboMsg;
using CbboMsg = databento::CbboMsg;
using Cbbo1SMsg = databento::Cbbo1SMsg;
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;

// An instrument definition in DBN version 3.
struct InstrumentDefMsg {
static bool HasRType(RType rtype) { return rtype == RType::InstrumentDef; }

UnixNanos IndexTs() const { return ts_recv; }
const char* Currency() const { return currency.data(); }
const char* SettlCurrency() const { return settl_currency.data(); }
const char* SecSubType() const { return secsubtype.data(); }
const char* RawSymbol() const { return raw_symbol.data(); }
const char* Group() const { return group.data(); }
const char* Exchange() const { return exchange.data(); }
const char* Asset() const { return asset.data(); }
const char* Cfi() const { return cfi.data(); }
const char* SecurityType() const { return security_type.data(); }
const char* UnitOfMeasure() const { return unit_of_measure.data(); }
const char* Underlying() const { return underlying.data(); }
const char* StrikePriceCurrency() const {
return strike_price_currency.data();
}
const char* LegRawSymbol() const { return leg_raw_symbol.data(); }

RecordHeader hd;
UnixNanos ts_recv;
std::int64_t min_price_increment;
std::int64_t display_factor;
UnixNanos expiration;
UnixNanos activation;
std::int64_t high_limit_price;
std::int64_t low_limit_price;
std::int64_t max_price_variation;
std::int64_t unit_of_measure_qty;
std::int64_t min_price_increment_amount;
std::int64_t price_ratio;
std::int64_t strike_price;
std::uint64_t raw_instrument_id;
std::int64_t leg_price;
std::int64_t leg_delta;
std::int32_t inst_attrib_value;
std::uint32_t underlying_id;
std::int32_t market_depth_implied;
std::int32_t market_depth;
std::uint32_t market_segment_id;
std::uint32_t max_trade_vol;
std::int32_t min_lot_size;
std::int32_t min_lot_size_block;
std::int32_t min_lot_size_round_lot;
std::uint32_t min_trade_vol;
std::int32_t contract_multiplier;
std::int32_t decay_quantity;
std::int32_t original_contract_size;
std::uint32_t leg_instrument_id;
std::int32_t leg_ratio_price_numerator;
std::int32_t leg_ratio_price_denominator;
std::int32_t leg_ratio_qty_numerator;
std::int32_t leg_ratio_qty_denominator;
std::uint32_t leg_underlying_id;
std::int16_t appl_id;
std::uint16_t maturity_year;
std::uint16_t decay_start_date;
std::uint16_t channel_id;
std::uint16_t leg_count;
std::uint16_t leg_index;
std::array<char, 4> currency;
std::array<char, 4> settl_currency;
std::array<char, 6> secsubtype;
std::array<char, kSymbolCstrLen> raw_symbol;
std::array<char, 21> group;
std::array<char, 5> exchange;
std::array<char, 7> asset;
std::array<char, 7> cfi;
std::array<char, 7> security_type;
std::array<char, 31> unit_of_measure;
std::array<char, 21> underlying;
std::array<char, 4> strike_price_currency;
std::array<char, kSymbolCstrLen> leg_raw_symbol;
InstrumentClass instrument_class;
MatchAlgorithm match_algorithm;
std::uint8_t main_fraction;
std::uint8_t price_display_format;
std::uint8_t sub_fraction;
std::uint8_t underlying_product;
SecurityUpdateAction security_update_action;
std::uint8_t maturity_month;
std::uint8_t maturity_day;
std::uint8_t maturity_week;
UserDefinedInstrument user_defined_instrument;
std::int8_t contract_multiplier_unit;
std::int8_t flow_schedule_type;
std::uint8_t tick_rule;
InstrumentClass leg_instrument_class;
Side leg_side;
// padding for alignment
std::array<char, 21> reserved;
};
static_assert(sizeof(InstrumentDefMsg) == 520,
"InstrumentDefMsg size must match Rust");
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");

bool operator==(const InstrumentDefMsg& lhs, const InstrumentDefMsg& rhs);
inline bool operator!=(const InstrumentDefMsg& lhs,
const InstrumentDefMsg& rhs) {
return !(lhs == rhs);
}

std::string ToString(const InstrumentDefMsg& instr_def_msg);
std::ostream& operator<<(std::ostream& stream,
const InstrumentDefMsg& instr_def_msg);
} // namespace v3
} // namespace databento
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.26.0
pkgver=0.27.0
pkgrel=1
pkgdesc="Official C++ client for Databento"
arch=('any')
Expand Down
91 changes: 91 additions & 0 deletions src/record.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "databento/enums.hpp"
#include "databento/exceptions.hpp" // InvalidArgumentError
#include "databento/fixed_price.hpp"
#include "databento/v3.hpp"
#include "stream_op_helper.hpp"

using databento::Record;
Expand Down Expand Up @@ -106,6 +107,96 @@ databento::RType Record::RTypeFromSchema(const Schema schema) {

using databento::InstrumentDefMsg;

databento::v3::InstrumentDefMsg InstrumentDefMsg::ToV3() const {
v3::InstrumentDefMsg ret{
RecordHeader{
sizeof(v3::InstrumentDefMsg) / RecordHeader::kLengthMultiplier,
RType::InstrumentDef, hd.publisher_id, hd.instrument_id, hd.ts_event},
ts_recv,
min_price_increment,
display_factor,
expiration,
activation,
high_limit_price,
low_limit_price,
max_price_variation,
unit_of_measure_qty,
min_price_increment_amount,
price_ratio,
strike_price,
raw_instrument_id,
kUndefPrice,
kUndefPrice,
inst_attrib_value,
underlying_id,
market_depth_implied,
market_depth,
market_segment_id,
max_trade_vol,
min_lot_size,
min_lot_size_block,
min_lot_size_round_lot,
min_trade_vol,
contract_multiplier,
decay_quantity,
original_contract_size,
{},
{},
{},
{},
{},
{},
appl_id,
maturity_year,
decay_start_date,
channel_id,
{},
{},
currency,
settl_currency,
secsubtype,
{},
{},
{},
{},
{},
{},
{},
{},
{},
{},
instrument_class,
match_algorithm,
main_fraction,
price_display_format,
sub_fraction,
underlying_product,
security_update_action,
maturity_month,
maturity_day,
maturity_week,
user_defined_instrument,
contract_multiplier_unit,
flow_schedule_type,
tick_rule,
{},
Side::None,
{}};
std::copy(raw_symbol.begin(), raw_symbol.end(), ret.raw_symbol.begin());
std::copy(group.begin(), group.end(), ret.group.begin());
std::copy(exchange.begin(), exchange.end(), ret.exchange.begin());
std::copy(asset.begin(), asset.end(), ret.asset.begin());
std::copy(cfi.begin(), cfi.end(), ret.cfi.begin());
std::copy(security_type.begin(), security_type.end(),
ret.security_type.begin());
std::copy(unit_of_measure.begin(), unit_of_measure.end(),
ret.unit_of_measure.begin());
std::copy(underlying.begin(), underlying.end(), ret.underlying.begin());
std::copy(strike_price_currency.begin(), strike_price_currency.end(),
ret.strike_price_currency.begin());
return ret;
}

bool databento::operator==(const InstrumentDefMsg& lhs,
const InstrumentDefMsg& rhs) {
return lhs.hd == rhs.hd && lhs.ts_recv == rhs.ts_recv &&
Expand Down
Loading
Loading