diff --git a/.clang-format b/.clang-format index 4d7c290..b82bd08 100644 --- a/.clang-format +++ b/.clang-format @@ -1,5 +1,6 @@ --- BasedOnStyle: Google +ColumnLimit: 88 IncludeCategories: - Regex: '^<(httplib|nlohmann)' Priority: 1 diff --git a/CHANGELOG.md b/CHANGELOG.md index bb6813a..acb9212 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,23 @@ # Changelog +## 0.40.0 - 2025-07-29 + +### Enhancements +- Added `OhlcvEod` variant to `RType` +- Added documentation to more enums and record structs +- Aligned string representation of `RType` with Rust + +### Breaking changes +- Switched to `std::byte` for most padding fields in record structs. These fields are + now initialized by default +- Hidden padding fields now begin with `_` + +### Bug fixes +- Added missing `IndexTs()` method to `v1::InstrumentDefMsg`, `v2::InstrumentDefMsg`, + and `v1::SymbolMappingMsg` +- Fixed error in templated overload of `DbnDecoder::EncodeRecord()` +- Removed unused `Disk` and `S3` variants from `Delivery` enum + ## 0.39.1 - 2025-07-22 ### Bug fixes diff --git a/CMakeLists.txt b/CMakeLists.txt index 5162a4d..6741c4c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ cmake_minimum_required(VERSION 3.24..4.0) project( databento - VERSION 0.39.1 + VERSION 0.40.0 LANGUAGES CXX DESCRIPTION "Official Databento client library" ) diff --git a/examples/historical/batch.cpp b/examples/historical/batch.cpp index 36928c4..57444aa 100644 --- a/examples/historical/batch.cpp +++ b/examples/historical/batch.cpp @@ -9,9 +9,9 @@ int main() { auto client = databento::HistoricalBuilder{}.SetKeyFromEnv().Build(); - const auto job = client.BatchSubmitJob(databento::dataset::kGlbxMdp3, - {"GEZ2"}, databento::Schema::Trades, - {"2022-08-26", "2022-09-27"}); + const auto job = + client.BatchSubmitJob(databento::dataset::kGlbxMdp3, {"GEZ2"}, + databento::Schema::Trades, {"2022-08-26", "2022-09-27"}); const auto all_jobs = client.BatchListJobs(); const auto all_job_it = std::find_if( diff --git a/examples/historical/metadata.cpp b/examples/historical/metadata.cpp index 778005e..f52985e 100644 --- a/examples/historical/metadata.cpp +++ b/examples/historical/metadata.cpp @@ -31,16 +31,16 @@ int main() { } std::cout << '\n'; - const auto fields = client.MetadataListFields(databento::Encoding::Dbn, - databento::Schema::Trades); + const auto fields = + client.MetadataListFields(databento::Encoding::Dbn, databento::Schema::Trades); std::cout << "Fields:\n"; for (const auto& field_detail : fields) { std::cout << "- " << field_detail << '\n'; } std::cout << '\n'; - const auto dataset_conditions = client.MetadataGetDatasetCondition( - "GLBX.MDP3", {"2019-06-01", "2019-08-01"}); + const auto dataset_conditions = + client.MetadataGetDatasetCondition("GLBX.MDP3", {"2019-06-01", "2019-08-01"}); std::cout << "Conditions:\n"; for (const auto& dataset_condition : dataset_conditions) { std::cout << "- " << dataset_condition << "\n"; @@ -52,26 +52,22 @@ int main() { for (const auto& [mode, unit_prices] : all_unit_prices) { const auto* mode_str = ToString(mode); for (const auto [schema, price] : unit_prices) { - std::cout << "- (" << mode_str << ", " << schema << "): " << price - << '\n'; + std::cout << "- (" << mode_str << ", " << schema << "): " << price << '\n'; } } std::cout << '\n'; - const auto record_count = - client.MetadataGetRecordCount(kGlbxMdp3, {"2020-12-28", "2020-12-29"}, - {"ESH1"}, databento::Schema::Mbo); + const auto record_count = client.MetadataGetRecordCount( + kGlbxMdp3, {"2020-12-28", "2020-12-29"}, {"ESH1"}, databento::Schema::Mbo); std::cout << "Record count: " << record_count << "\n\n"; const std::size_t billable_size = client.MetadataGetBillableSize( kGlbxMdp3, {"2020-12-28", "2020-12-29"}, {"ESH1"}, databento::Schema::Mbo, databento::SType::RawSymbol, {}); - std::cout << "Billable size (uncompressed binary bytes): " << billable_size - << "\n\n"; + std::cout << "Billable size (uncompressed binary bytes): " << billable_size << "\n\n"; - const auto cost = - client.MetadataGetCost(kGlbxMdp3, {"2020-12-28", "2020-12-29"}, {"ESH1"}, - databento::Schema::Mbo); + const auto cost = client.MetadataGetCost(kGlbxMdp3, {"2020-12-28", "2020-12-29"}, + {"ESH1"}, databento::Schema::Mbo); std::cout << "Cost (in cents): " << cost << '\n'; return 0; diff --git a/examples/historical/readme.cpp b/examples/historical/readme.cpp index fc6bc91..b3d4443 100644 --- a/examples/historical/readme.cpp +++ b/examples/historical/readme.cpp @@ -16,13 +16,12 @@ int main() { }; auto print_trades = [&symbol_map](const Record& record) { const auto& trade_msg = record.Get(); - std::cout << "Received trade for " << symbol_map.At(trade_msg) << ": " - << trade_msg << '\n'; + std::cout << "Received trade for " << symbol_map.At(trade_msg) << ": " << trade_msg + << '\n'; return KeepGoing::Continue; }; - client.TimeseriesGetRange( - "GLBX.MDP3", {"2022-06-10T14:30", "2022-06-10T14:40"}, {"ESM2", "NQZ2"}, - Schema::Trades, SType::RawSymbol, SType::InstrumentId, {}, decode_symbols, - print_trades); + client.TimeseriesGetRange("GLBX.MDP3", {"2022-06-10T14:30", "2022-06-10T14:40"}, + {"ESM2", "NQZ2"}, Schema::Trades, SType::RawSymbol, + SType::InstrumentId, {}, decode_symbols, print_trades); } // NOLINTEND(google-build-using-namespace) diff --git a/examples/historical/timeseries_get_range_to_file.cpp b/examples/historical/timeseries_get_range_to_file.cpp index ec1269b..2700c75 100644 --- a/examples/historical/timeseries_get_range_to_file.cpp +++ b/examples/historical/timeseries_get_range_to_file.cpp @@ -14,10 +14,9 @@ int main() { auto client = databento::HistoricalBuilder{}.SetKeyFromEnv().Build(); const auto limit = 1000; databento::DbnFileStore dbn_file_store = client.TimeseriesGetRangeToFile( - databento::dataset::kGlbxMdp3, {"2022-10-03T00:00", "2022-10-04T00:00"}, - {"ESZ2"}, databento::Schema::Ohlcv1M, databento::SType::RawSymbol, - databento::SType::InstrumentId, limit, - "ESZ2-ohlcv1m-20201003-20201004.dbn.zst"); + databento::dataset::kGlbxMdp3, {"2022-10-03T00:00", "2022-10-04T00:00"}, {"ESZ2"}, + databento::Schema::Ohlcv1M, databento::SType::RawSymbol, + databento::SType::InstrumentId, limit, "ESZ2-ohlcv1m-20201003-20201004.dbn.zst"); dbn_file_store.Replay([](const databento::Record record) { const auto& ohlcv_bar = record.Get(); std::cout << ohlcv_bar << '\n'; diff --git a/examples/live/live_smoke_test.cpp b/examples/live/live_smoke_test.cpp index 3186138..fc05090 100644 --- a/examples/live/live_smoke_test.cpp +++ b/examples/live/live_smoke_test.cpp @@ -36,8 +36,7 @@ std::pair TryConvertToUnixNanos(const char* start) { return std::make_pair(true, UnixNanos{std::chrono::nanoseconds(result)}); } -void ProcessRecords(LiveBlocking& client, Schema schema, - bool start_from_epoch) { +void ProcessRecords(LiveBlocking& client, Schema schema, bool start_from_epoch) { client.Start(); std::cout << "Starting client...\n"; @@ -46,7 +45,7 @@ void ProcessRecords(LiveBlocking& client, Schema schema, // outside trading hours auto expected_rtype = Record::RTypeFromSchema(schema); if (!start_from_epoch) { - expected_rtype = databento::rtype::SymbolMapping; + expected_rtype = databento::RType::SymbolMapping; } constexpr auto timeout = std::chrono::seconds{30}; @@ -112,9 +111,9 @@ class ArgParser { void Parse(int argc, char* argv[]) { for (auto i = 1; i < argc;) { const auto cur_arg = argv[i]; - auto it = std::find_if( - args.begin(), args.end(), - [&cur_arg](const auto& arg) { return cur_arg == arg.arg; }); + auto it = std::find_if(args.begin(), args.end(), [&cur_arg](const auto& arg) { + return cur_arg == arg.arg; + }); if (it != args.end()) { it->value = argv[i + 1]; } @@ -123,9 +122,9 @@ class ArgParser { } const char* Get(const std::string& arg_name) const { - auto it = std::find_if( - args.begin(), args.end(), - [&arg_name](const auto& arg) { return arg_name == arg.name; }); + auto it = std::find_if(args.begin(), args.end(), [&arg_name](const auto& arg) { + return arg_name == arg.name; + }); if (it == args.end()) { return nullptr; @@ -144,8 +143,8 @@ ArgParser ParseArgs(int argc, char* argv[] ArgParser parser; parser.Add(ArgParser::Arg{"gateway", "--gateway"}); parser.Add(ArgParser::Arg{"port", "--port", "13000"}); - parser.Add(ArgParser::Arg{"api_key_env_var", "--api-key-env-var", - "DATABENTO_API_KEY"}); + parser.Add( + ArgParser::Arg{"api_key_env_var", "--api-key-env-var", "DATABENTO_API_KEY"}); parser.Add(ArgParser::Arg{"dataset", "--dataset"}); parser.Add(ArgParser::Arg{"schema", "--schema"}); parser.Add(ArgParser::Arg{"stype", "--stype"}); diff --git a/examples/live/readme.cpp b/examples/live/readme.cpp index 549b582..e32fcea 100644 --- a/examples/live/readme.cpp +++ b/examples/live/readme.cpp @@ -12,17 +12,14 @@ using namespace databento; int main() { PitSymbolMap symbol_mappings; - auto client = LiveBuilder{} - .SetKeyFromEnv() - .SetDataset(Dataset::GlbxMdp3) - .BuildThreaded(); + auto client = + LiveBuilder{}.SetKeyFromEnv().SetDataset(Dataset::GlbxMdp3).BuildThreaded(); auto handler = [&symbol_mappings](const Record& rec) { symbol_mappings.OnRecord(rec); if (const auto* trade = rec.GetIf()) { - std::cout << "Received trade for " - << symbol_mappings[trade->hd.instrument_id] << ':' << *trade - << '\n'; + std::cout << "Received trade for " << symbol_mappings[trade->hd.instrument_id] + << ':' << *trade << '\n'; } return KeepGoing::Continue; }; diff --git a/examples/live/simple.cpp b/examples/live/simple.cpp index 77f1dd7..37a73fb 100644 --- a/examples/live/simple.cpp +++ b/examples/live/simple.cpp @@ -16,8 +16,8 @@ static std::sig_atomic_t volatile gSignal; int main() { databento::PitSymbolMap symbol_mappings; - auto log_receiver = std::make_unique( - databento::LogLevel::Debug); + auto log_receiver = + std::make_unique(databento::LogLevel::Debug); auto client = databento::LiveBuilder{} .SetLogReceiver(log_receiver.get()) @@ -30,10 +30,8 @@ int main() { std::signal(SIGINT, [](int signal) { gSignal = signal; }); std::vector symbols{"ESZ5", "ESZ5 C6200", "ESZ5 P5500"}; - client.Subscribe(symbols, databento::Schema::Definition, - databento::SType::RawSymbol); - client.Subscribe(symbols, databento::Schema::Mbo, - databento::SType::RawSymbol); + client.Subscribe(symbols, databento::Schema::Definition, databento::SType::RawSymbol); + client.Subscribe(symbols, databento::Schema::Mbo, databento::SType::RawSymbol); auto metadata_callback = [](databento::Metadata&& metadata) { std::cout << metadata << '\n'; @@ -43,15 +41,14 @@ int main() { switch (rec.RType()) { case RType::Mbo: { auto ohlcv = rec.Get>(); - std::cout << "Received tick for " - << symbol_mappings[ohlcv.rec.hd.instrument_id] - << " with ts_out " << ohlcv.ts_out.time_since_epoch().count() - << ": " << ohlcv.rec << '\n'; + std::cout << "Received tick for " << symbol_mappings[ohlcv.rec.hd.instrument_id] + << " with ts_out " << ohlcv.ts_out.time_since_epoch().count() << ": " + << ohlcv.rec << '\n'; break; } case RType::InstrumentDef: { - std::cout << "Received definition: " - << rec.Get() << '\n'; + std::cout << "Received definition: " << rec.Get() + << '\n'; break; } case RType::SymbolMapping: { diff --git a/include/databento/constants.hpp b/include/databento/constants.hpp index 5770ca1..aa4eb3c 100644 --- a/include/databento/constants.hpp +++ b/include/databento/constants.hpp @@ -3,7 +3,7 @@ #include #include -#include "databento/system.hpp" // DATABENTO_CXX_COMPILER_*, DATABENTO_SYSTEM_* +#include "databento/system.hpp" // DATABENTO_CXX_COMPILER_*, DATABENTO_SYSTEM_* #include "databento/version.hpp" // DATABENTO_VERSION namespace databento { @@ -15,14 +15,11 @@ static constexpr std::int64_t kFixedPriceScale = 1000000000; // The sentinel value for an unset or null price. static constexpr auto kUndefPrice = std::numeric_limits::max(); // The sentinel value for an unset or null order size. -static constexpr auto kUndefOrderSize = - std::numeric_limits::max(); +static constexpr auto kUndefOrderSize = std::numeric_limits::max(); // The sentinel value for an unset statistic quantity. -static constexpr auto kUndefStatQuantity = - std::numeric_limits::max(); +static constexpr auto kUndefStatQuantity = std::numeric_limits::max(); // The sentinel value for an unset or null timestamp. -static constexpr auto kUndefTimestamp = - std::numeric_limits::max(); +static constexpr auto kUndefTimestamp = std::numeric_limits::max(); // The current version of the DBN encoding. static constexpr auto kDbnVersion = 3; // The length of fixed-length symbol strings. diff --git a/include/databento/datetime.hpp b/include/databento/datetime.hpp index 9ff8a0c..b8a329d 100644 --- a/include/databento/datetime.hpp +++ b/include/databento/datetime.hpp @@ -8,9 +8,8 @@ namespace databento { // Nanoseconds since the UNIX epoch. -using UnixNanos = - std::chrono::time_point>; +using UnixNanos = std::chrono::time_point>; // A representation of the difference between two timestamps. using TimeDeltaNanos = std::chrono::duration; std::string ToString(UnixNanos unix_nanos); @@ -25,8 +24,7 @@ template struct DateTimeRange { explicit DateTimeRange(T start_) : DateTimeRange{std::move(start_), {}} {} // underscore to prevent shadowing - DateTimeRange(T start_, T end_) - : start{std::move(start_)}, end{std::move(end_)} {} + DateTimeRange(T start_, T end_) : start{std::move(start_)}, end{std::move(end_)} {} T start; T end; @@ -34,13 +32,11 @@ struct DateTimeRange { using DateRange = DateTimeRange; template -inline bool operator==(const DateTimeRange& lhs, - const DateTimeRange& rhs) { +inline bool operator==(const DateTimeRange& lhs, const DateTimeRange& rhs) { return lhs.start == rhs.start && lhs.end == rhs.end; } template -inline bool operator!=(const DateTimeRange& lhs, - const DateTimeRange& rhs) { +inline bool operator!=(const DateTimeRange& lhs, const DateTimeRange& rhs) { return !(lhs == rhs); } diff --git a/include/databento/dbn.hpp b/include/databento/dbn.hpp index fc8391c..b349848 100644 --- a/include/databento/dbn.hpp +++ b/include/databento/dbn.hpp @@ -101,13 +101,12 @@ inline bool operator!=(const SymbolMapping& lhs, const SymbolMapping& rhs) { inline bool operator==(const Metadata& lhs, const Metadata& rhs) { return lhs.version == rhs.version && lhs.dataset == rhs.dataset && - lhs.schema == rhs.schema && lhs.start == rhs.start && - lhs.end == rhs.end && lhs.limit == rhs.limit && - lhs.stype_in == rhs.stype_in && lhs.stype_out == rhs.stype_out && - lhs.ts_out == rhs.ts_out && - lhs.symbol_cstr_len == rhs.symbol_cstr_len && - lhs.symbols == rhs.symbols && lhs.partial == rhs.partial && - lhs.not_found == rhs.not_found && lhs.mappings == rhs.mappings; + lhs.schema == rhs.schema && lhs.start == rhs.start && lhs.end == rhs.end && + lhs.limit == rhs.limit && lhs.stype_in == rhs.stype_in && + lhs.stype_out == rhs.stype_out && lhs.ts_out == rhs.ts_out && + lhs.symbol_cstr_len == rhs.symbol_cstr_len && lhs.symbols == rhs.symbols && + lhs.partial == rhs.partial && lhs.not_found == rhs.not_found && + lhs.mappings == rhs.mappings; } inline bool operator!=(const Metadata& lhs, const Metadata& rhs) { return !(lhs == rhs); diff --git a/include/databento/dbn_decoder.hpp b/include/databento/dbn_decoder.hpp index 97f4898..2456e01 100644 --- a/include/databento/dbn_decoder.hpp +++ b/include/databento/dbn_decoder.hpp @@ -26,15 +26,15 @@ class DbnDecoder { static std::pair DecodeMetadataVersionAndSize( const std::byte* buffer, std::size_t size); - static Metadata DecodeMetadataFields(std::uint8_t version, - const std::byte* buffer, + static Metadata DecodeMetadataFields(std::uint8_t version, const std::byte* buffer, const std::byte* buffer_end); // Decodes a record possibly applying upgrading the data according to the // given version and upgrade policy. If an upgrade is applied, // compat_buffer is modified. - static Record DecodeRecordCompat( - std::uint8_t version, VersionUpgradePolicy upgrade_policy, bool ts_out, - std::array* compat_buffer, Record rec); + static Record DecodeRecordCompat(std::uint8_t version, + VersionUpgradePolicy upgrade_policy, bool ts_out, + std::array* compat_buffer, + Record rec); // Should be called exactly once. Metadata DecodeMetadata(); @@ -45,12 +45,12 @@ class DbnDecoder { private: static std::string DecodeSymbol(std::size_t symbol_cstr_len, const std::byte*& buffer); - static std::vector DecodeRepeatedSymbol( - std::size_t symbol_cstr_len, const std::byte*& buffer, - const std::byte* buffer_end); - static std::vector DecodeSymbolMappings( - std::size_t symbol_cstr_len, const std::byte*& buffer, - const std::byte* buffer_end); + static std::vector DecodeRepeatedSymbol(std::size_t symbol_cstr_len, + const std::byte*& buffer, + const std::byte* buffer_end); + static std::vector DecodeSymbolMappings(std::size_t symbol_cstr_len, + const std::byte*& buffer, + const std::byte* buffer_end); static SymbolMapping DecodeSymbolMapping(std::size_t symbol_cstr_len, const std::byte*& buffer, const std::byte* buffer_end); diff --git a/include/databento/dbn_encoder.hpp b/include/databento/dbn_encoder.hpp index 62f8a01..8803bee 100644 --- a/include/databento/dbn_encoder.hpp +++ b/include/databento/dbn_encoder.hpp @@ -17,23 +17,24 @@ class DbnEncoder { template void EncodeRecord(const R& record) { - static_assert( - has_header::value, - "must be a DBN record struct with an `hd` RecordHeader field"); - EncodeRecord(Record{&record.hd}); + static_assert(has_header::value, + "must be a DBN record struct with an `hd` RecordHeader field"); + // Safe to cast away const as EncodeRecord will not modify data + const Record rec{const_cast(&record.hd)}; + EncodeRecord(rec); } template void EncodeRecord(const WithTsOut record) { - static_assert( - has_header::value, - "must be a DBN record struct with an `hd` RecordHeader field"); - EncodeRecord(Record{&record.rec.hd}); + static_assert(has_header::value, + "must be a DBN record struct with an `hd` RecordHeader field"); + // Safe to cast away const as EncodeRecord will not modify data + const Record rec{const_cast(&record.hd)}; + EncodeRecord(rec); } void EncodeRecord(const Record& record); private: - static std::pair CalcLength( - const Metadata& metadata); + static std::pair CalcLength(const Metadata& metadata); IWritable* output_; }; diff --git a/include/databento/dbn_file_store.hpp b/include/databento/dbn_file_store.hpp index f1febcf..935cf64 100644 --- a/include/databento/dbn_file_store.hpp +++ b/include/databento/dbn_file_store.hpp @@ -17,8 +17,7 @@ namespace databento { class DbnFileStore { public: explicit DbnFileStore(const std::filesystem::path& file_path); - DbnFileStore(ILogReceiver* log_receiver, - const std::filesystem::path& file_path, + DbnFileStore(ILogReceiver* log_receiver, const std::filesystem::path& file_path, VersionUpgradePolicy upgrade_policy); // Callback API: calling Replay consumes the input. diff --git a/include/databento/detail/buffer.hpp b/include/databento/detail/buffer.hpp index d618970..7488342 100644 --- a/include/databento/detail/buffer.hpp +++ b/include/databento/detail/buffer.hpp @@ -55,9 +55,7 @@ class Buffer : public IReadable, public IWritable { return static_cast(write_pos_ - read_pos_); } - std::size_t Capacity() const { - return static_cast(end_ - buf_.get()); - } + std::size_t Capacity() const { return static_cast(end_ - buf_.get()); } void Clear() { read_pos_ = buf_.get(); write_pos_ = buf_.get(); diff --git a/include/databento/detail/dbn_buffer_decoder.hpp b/include/databento/detail/dbn_buffer_decoder.hpp index e86c7a5..1a813a1 100644 --- a/include/databento/detail/dbn_buffer_decoder.hpp +++ b/include/databento/detail/dbn_buffer_decoder.hpp @@ -27,8 +27,7 @@ class DbnBufferDecoder { KeepGoing Process(const char* data, std::size_t length); std::size_t UnreadBytes() const { return dbn_buffer_.ReadCapacity(); } - friend std::ostream& operator<<(std::ostream& stream, - const DbnBufferDecoder& buffer); + friend std::ostream& operator<<(std::ostream& stream, const DbnBufferDecoder& buffer); private: enum class DecoderState : std::uint8_t { diff --git a/include/databento/detail/http_client.hpp b/include/databento/detail/http_client.hpp index fc8c3f5..bb1f8cc 100644 --- a/include/databento/detail/http_client.hpp +++ b/include/databento/detail/http_client.hpp @@ -21,14 +21,11 @@ class HttpClient { HttpClient(ILogReceiver* log_receiver, const std::string& key, const std::string& gateway, std::uint16_t port); - nlohmann::json GetJson(const std::string& path, - const httplib::Params& params); - nlohmann::json PostJson(const std::string& path, - const httplib::Params& form_params); + nlohmann::json GetJson(const std::string& path, const httplib::Params& params); + nlohmann::json PostJson(const std::string& path, const httplib::Params& form_params); void GetRawStream(const std::string& path, const httplib::Params& params, const httplib::ContentReceiver& callback); - void PostRawStream(const std::string& path, - const httplib::Params& form_params, + void PostRawStream(const std::string& path, const httplib::Params& form_params, const httplib::ContentReceiver& callback); private: diff --git a/include/databento/detail/json_helpers.hpp b/include/databento/detail/json_helpers.hpp index 1ac05f6..1a088f8 100644 --- a/include/databento/detail/json_helpers.hpp +++ b/include/databento/detail/json_helpers.hpp @@ -24,24 +24,22 @@ void SetIfNotEmpty(httplib::Params* params, const std::string& key, const std::vector& states); template -void SetIfPositive(httplib::Params* params, std::string_view key, - const T value) { +void SetIfPositive(httplib::Params* params, std::string_view key, const T value) { if (value > 0) { params->emplace(key, std::to_string(value)); } } template <> -inline void SetIfPositive( - httplib::Params* params, std::string_view key, - const databento::UnixNanos value) { +inline void SetIfPositive(httplib::Params* params, + std::string_view key, + const databento::UnixNanos value) { if (value.time_since_epoch().count()) { params->emplace(key, databento::ToString(value)); } } -const nlohmann::json& CheckedAt(std::string_view endpoint, - const nlohmann::json& json, +const nlohmann::json& CheckedAt(std::string_view endpoint, const nlohmann::json& json, std::string_view key); template @@ -49,16 +47,15 @@ T FromCheckedAtString(std::string_view endpoint, const nlohmann::json& json, std::string_view key) { const auto& val_json = CheckedAt(endpoint, json, key); if (!val_json.is_string()) { - throw JsonResponseError::TypeMismatch( - endpoint, std::string{key} + " string", val_json); + throw JsonResponseError::TypeMismatch(endpoint, std::string{key} + " string", + val_json); } return databento::FromString(val_json); } template -T FromCheckedAtStringOrNull(std::string_view endpoint, - const nlohmann::json& json, std::string_view key, - T null_value) { +T FromCheckedAtStringOrNull(std::string_view endpoint, const nlohmann::json& json, + std::string_view key, T null_value) { const auto& val_json = CheckedAt(endpoint, json, key); if (val_json.is_null()) { return null_value; @@ -66,13 +63,12 @@ T FromCheckedAtStringOrNull(std::string_view endpoint, if (val_json.is_string()) { return databento::FromString(val_json); } - throw JsonResponseError::TypeMismatch( - endpoint, std::string{key} + " null or string", val_json); + throw JsonResponseError::TypeMismatch(endpoint, std::string{key} + " null or string", + val_json); } template -T ParseAt(std::string_view endpoint, const nlohmann::json& json, - std::string_view key); +T ParseAt(std::string_view endpoint, const nlohmann::json& json, std::string_view key); template <> bool ParseAt(std::string_view endpoint, const nlohmann::json& json, std::string_view key); @@ -81,8 +77,7 @@ std::string ParseAt(std::string_view endpoint, const nlohmann::json& json, std::string_view key); template <> std::optional ParseAt(std::string_view endpoint, - const nlohmann::json& json, - std::string_view key); + const nlohmann::json& json, std::string_view key); template <> std::uint64_t ParseAt(std::string_view endpoint, const nlohmann::json& json, std::string_view key); @@ -93,11 +88,10 @@ template <> double ParseAt(std::string_view endpoint, const nlohmann::json& json, std::string_view key); template <> -std::vector ParseAt(std::string_view endpoint, - const nlohmann::json& json, +std::vector ParseAt(std::string_view endpoint, const nlohmann::json& json, std::string_view key); template <> -date::year_month_day ParseAt(std::string_view endpoint, - const nlohmann::json& json, std::string_view key); +date::year_month_day ParseAt(std::string_view endpoint, const nlohmann::json& json, + std::string_view key); } // namespace databento::detail diff --git a/include/databento/detail/scoped_thread.hpp b/include/databento/detail/scoped_thread.hpp index 9178370..8fe3581 100644 --- a/include/databento/detail/scoped_thread.hpp +++ b/include/databento/detail/scoped_thread.hpp @@ -12,8 +12,7 @@ class ScopedThread { template explicit ScopedThread(F&& func, A&&... args) : thread_{std::forward(func), std::forward(args)...} {} - ScopedThread(ScopedThread&& other) noexcept - : thread_{std::move(other.thread_)} {} + ScopedThread(ScopedThread&& other) noexcept : thread_{std::move(other.thread_)} {} ScopedThread& operator=(ScopedThread&& other) noexcept { if (Joinable()) { Join(); diff --git a/include/databento/detail/tcp_client.hpp b/include/databento/detail/tcp_client.hpp index 1060691..7aa800d 100644 --- a/include/databento/detail/tcp_client.hpp +++ b/include/databento/detail/tcp_client.hpp @@ -28,8 +28,7 @@ class TcpClient { }; TcpClient(const std::string& gateway, std::uint16_t port); - TcpClient(const std::string& gateway, std::uint16_t port, - RetryConf retry_conf); + TcpClient(const std::string& gateway, std::uint16_t port, RetryConf retry_conf); void WriteAll(std::string_view str); void WriteAll(const std::byte* buffer, std::size_t size); diff --git a/include/databento/enums.hpp b/include/databento/enums.hpp index 528a44b..60c8dc8 100644 --- a/include/databento/enums.hpp +++ b/include/databento/enums.hpp @@ -19,64 +19,6 @@ enum class FeedMode : std::uint8_t { Live, }; -// Represents a data record schema. -enum class Schema : std::uint16_t { - Mbo = 0, - Mbp1 = 1, - Mbp10 = 2, - Tbbo = 3, - Trades = 4, - Ohlcv1S = 5, - Ohlcv1M = 6, - Ohlcv1H = 7, - Ohlcv1D = 8, - Definition = 9, - Statistics = 10, - Status = 11, - Imbalance = 12, - Cmbp1 = 14, - Cbbo1S = 15, - Cbbo1M = 16, - Tcbbo = 17, - Bbo1S = 18, - Bbo1M = 19, -}; - -// Represents a data output encoding. -enum class Encoding : std::uint8_t { - Dbn = 0, - Csv = 1, - Json = 2, -}; - -// Represents a data compression format (if any). -enum class Compression : std::uint8_t { - None = 0, - Zstd = 1, -}; - -// Represents a symbology type. -namespace stype { -enum SType : std::uint8_t { - // Symbology using a unique numeric ID. - InstrumentId = 0, - // Symbology using the original symbols provided by the publisher. - RawSymbol = 1, - // A Databento-specific symbology where one symbol may point to different - // instruments at different points of time, e.g. to always refer to the front - // month future. - Continuous = 3, - // A Databento-specific symbology for referring to a group of symbols by one - // "parent" symbol, e.g. ES.FUT to refer to all ES futures. - Parent = 4, - // Symbology for US equities using NASDAQ Integrated suffix conventions. - NasdaqSymbol = 5, - // Symbology for US equities using CMS suffix conventions. - CmsSymbol = 6, -}; -} // namespace stype -using SType = stype::SType; - // Represents the duration of time at which batch files will be split. enum class SplitDuration : std::uint8_t { Day = 0, @@ -88,8 +30,6 @@ enum class SplitDuration : std::uint8_t { // Represents how a batch job will be delivered. enum class Delivery : std::uint8_t { Download, - S3, - Disk, }; // The current state of a batch job. @@ -109,55 +49,97 @@ enum class DatasetCondition : std::uint8_t { Missing, }; -// Sentinel values for different DBN record types. -// -// Additional rtypes may be added in the future. -namespace rtype { +// A record type sentinel. +namespace r_type { enum RType : std::uint8_t { + // none Mbp0 = 0x00, + // none Mbp1 = 0x01, + // Denotes a market-by-price record with a book depth of 10. Mbp10 = 0x0A, - // Deprecated in 0.4.0. Separated into separate rtypes for each OHLCV schema. + // Denotes an open, high, low, close, and volume record at an unspecified cadence. OhlcvDeprecated = 0x11, + // Denotes an open, high, low, close, and volume record at a 1-second cadence. Ohlcv1S = 0x20, + // Denotes an open, high, low, close, and volume record at a 1-minute cadence. Ohlcv1M = 0x21, + // Denotes an open, high, low, close, and volume record at an hourly cadence. Ohlcv1H = 0x22, + // Denotes an open, high, low, close, and volume record at a daily cadence + // based on the UTC date. Ohlcv1D = 0x23, + // Denotes an open, high, low, close, and volume record at a daily cadence + // based on the end of the trading session. + OhlcvEod = 0x24, + // Denotes an exchange status record. Status = 0x12, + // Denotes an instrument definition record. InstrumentDef = 0x13, + // Denotes an order imbalance record. Imbalance = 0x14, + // Denotes an error from gateway. Error = 0x15, + // Denotes a symbol mapping record. SymbolMapping = 0x16, + // Denotes a non-error message from the gateway. Also used for heartbeats. System = 0x17, + // Denotes a statistics record from the publisher (not calculated by Databento). Statistics = 0x18, + // Denotes a market-by-order record. Mbo = 0xA0, + // Denotes a consolidated best bid and offer record. Cmbp1 = 0xB1, + // Denotes a consolidated best bid and offer record subsampled on a one-second + // interval. Cbbo1S = 0xC0, + // Denotes a consolidated best bid and offer record subsampled on a one-minute + // interval. Cbbo1M = 0xC1, + // Denotes a consolidated best bid and offer trade record containing the + // consolidated BBO before the trade Tcbbo = 0xC2, + // Denotes a best bid and offer record subsampled on a one-second interval. Bbo1S = 0xC3, + // Denotes a best bid and offer record subsampled on a one-minute interval. Bbo1M = 0xC4, }; -} // namespace rtype -using rtype::RType; +} // namespace r_type +using r_type::RType; + +// A +// [side](https://databento.com/docs/standards-and-conventions/common-fields-enums-types) +// of the market. The side of the market for resting orders, or the side of the +// aggressor for trades. +namespace side { +enum Side : char { + // A sell order or sell aggressor in a trade. + Ask = 'A', + // A buy order or a buy aggressor in a trade. + Bid = 'B', + // No side specified by the original source. + None = 'N', +}; +} // namespace side +using side::Side; -// An order event or order book operation. +// An [order event or order book +// operation](https://databento.com/docs/api-reference-historical/basics/schemas-and-conventions). // // For example usage see: -// - https://databento.com/docs/examples/order-book/order-actions -// - https://databento.com/docs/examples/order-book/order-tracking +// - [Order actions](https://databento.com/docs/examples/order-book/order-actions) +// - [Order tracking](https://databento.com/docs/examples/order-book/order-tracking) namespace action { -// enum because future variants may be added in the future. enum Action : char { - // An existing order was modified. + // An existing order was modified: price and/or size. Modify = 'M', - // A trade executed. + // An aggressing order traded. Does not affect the book. Trade = 'T', - // An existing order was filled. + // An existing order was filled. Does not affect the book. Fill = 'F', - // An order was cancelled. + // An order was fully or partially cancelled. Cancel = 'C', - // A new order was added. + // A new order was added to the book. Add = 'A', // Reset the book; clear all orders for an instrument. Clear = 'R', @@ -167,144 +149,290 @@ enum Action : char { } // namespace action using action::Action; -// A side of the market. The side of the market for resting orders, or the side -// of the aggressor for trades. -enum class Side : char { - // A sell order. - Ask = 'A', - // A buy order. - Bid = 'B', - // None or unknown. - None = 'N', -}; - +// The class of instrument. +// +// For example usage see +// [Getting options with their +// underlying](https://databento.com/docs/examples/options/options-and-futures). namespace instrument_class { -// enum because future variants may be added in the future. enum InstrumentClass : char { + // A bond. Bond = 'B', + // A call option. Call = 'C', + // A future. Future = 'F', + // A stock. Stock = 'K', + // A spread composed of multiple instrument classes. MixedSpread = 'M', + // A put option. Put = 'P', + // A spread composed of futures. FutureSpread = 'S', + // A spread composed of options. OptionSpread = 'T', + // A foreign exchange spot. FxSpot = 'X', + // A commodity being traded for immediate delivery. CommoditySpot = 'Y', }; } // namespace instrument_class using instrument_class::InstrumentClass; +// The type of matching algorithm used for the instrument at the exchange. namespace match_algorithm { enum MatchAlgorithm : char { + // No matching algorithm was specified. Undefined = ' ', + // First-in-first-out matching. Fifo = 'F', + // A configurable match algorithm. Configurable = 'K', + // Trade quantity is allocated to resting orders based on a pro-rata percentage: + // resting order quantity divided by total quantity. ProRata = 'C', + // Like `FIFO` but with LMM allocations prior to FIFO allocations. FifoLmm = 'T', + // Like `PRO_RATA` but includes a configurable allocation to the first order that + // improves the market. ThresholdProRata = 'O', + // Like `FIFO_LMM` but includes a configurable allocation to the first order that + // improves the market. FifoTopLmm = 'S', + // Like `THRESHOLD_PRO_RATA` but includes a special priority to LMMs. ThresholdProRataLmm = 'Q', + // Special variant used only for Eurodollar futures on CME. EurodollarFutures = 'Y', + // Trade quantity is shared between all orders at the best price. Orders with the + // highest time priority receive a higher matched quantity. TimeProRata = 'P', + // A two-pass FIFO algorithm. The first pass fills the Institutional Group the + // aggressing + // order is associated with. The second pass matches orders without an Institutional + // Group + // association. See [CME + // documentation](https://cmegroupclientsite.atlassian.net/wiki/spaces/EPICSANDBOX/pages/457217267#InstitutionalPrioritizationMatchAlgorithm). InstitutionalPrioritization = 'V', }; } // namespace match_algorithm using match_algorithm::MatchAlgorithm; +// Whether the instrument is user-defined. +// +// For example usage see +// [Getting options with their +// underlying](https://databento.com/docs/examples/options/options-and-futures). +namespace user_defined_instrument { +enum UserDefinedInstrument : char { + // The instrument is not user-defined. + No = 'N', + // The instrument is user-defined. + Yes = 'Y', +}; +} // namespace user_defined_instrument +using user_defined_instrument::UserDefinedInstrument; + +// The type of `InstrumentDefMsg` update. namespace security_update_action { enum SecurityUpdateAction : char { + // A new instrument definition. Add = 'A', + // A modified instrument definition of an existing one. Modify = 'M', + // Removal of an instrument definition. Delete = 'D', }; -} +} // namespace security_update_action using security_update_action::SecurityUpdateAction; -namespace user_defined_instrument { -enum UserDefinedInstrument : char { - No = 'N', - Yes = 'Y', +// A symbology type. Refer to the +// [symbology +// documentation](https://databento.com/docs/api-reference-historical/basics/symbology) +// for more information. +namespace s_type { +enum SType : std::uint8_t { + // Symbology using a unique numeric ID. + InstrumentId = 0, + // Symbology using the original symbols provided by the publisher. + RawSymbol = 1, + // A set of Databento-specific symbologies for referring to groups of symbols. + Smart = 2, + // A Databento-specific symbology where one symbol may point to different + // instruments at different points of time, e.g. to always refer to the front month + // future. + Continuous = 3, + // A Databento-specific symbology for referring to a group of symbols by one + // "parent" symbol, e.g. ES.FUT to refer to all ES futures. + Parent = 4, + // Symbology for US equities using NASDAQ Integrated suffix conventions. + NasdaqSymbol = 5, + // Symbology for US equities using CMS suffix conventions. + CmsSymbol = 6, + // Symbology using International Security Identification Numbers (ISIN) - ISO 6166. + Isin = 7, + // Symbology using US domestic Committee on Uniform Securities Identification + // Procedure (CUSIP) codes. + UsCode = 8, + // Symbology using Bloomberg composite global IDs. + BbgCompId = 9, + // Symbology using Bloomberg composite tickers. + BbgCompTicker = 10, + // Symbology using Bloomberg FIGI exchange level IDs. + Figi = 11, + // Symbology using Bloomberg exchange level tickers. + FigiTicker = 12, }; -} -using user_defined_instrument::UserDefinedInstrument; +} // namespace s_type +using s_type::SType; +// A data record schema. +// +// Each schema has a particular record type associated with it. +// +// See [List of supported market data +// schemas](https://databento.com/docs/schemas-and-data-formats/whats-a-schema) for an +// overview of the differences and use cases of each schema. +enum class Schema : std::uint16_t { + // Market by order. + Mbo = 0, + // Market by price with a book depth of 1. + Mbp1 = 1, + // Market by price with a book depth of 10. + Mbp10 = 2, + // All trade events with the best bid and offer (BBO) immediately **before** the + // effect of + // the trade. + Tbbo = 3, + // All trade events. + Trades = 4, + // Open, high, low, close, and volume at a one-second interval. + Ohlcv1S = 5, + // Open, high, low, close, and volume at a one-minute interval. + Ohlcv1M = 6, + // Open, high, low, close, and volume at an hourly interval. + Ohlcv1H = 7, + // Open, high, low, close, and volume at a daily interval based on the UTC date. + Ohlcv1D = 8, + // Instrument definitions. + Definition = 9, + // Additional data disseminated by publishers. + Statistics = 10, + // Trading status events. + Status = 11, + // Auction imbalance events. + Imbalance = 12, + // Open, high, low, close, and volume at a daily cadence based on the end of the + // trading + // session. + OhlcvEod = 13, + // Consolidated best bid and offer. + Cmbp1 = 14, + // Consolidated best bid and offer subsampled at one-second intervals, in addition to + // trades. + Cbbo1S = 15, + // Consolidated best bid and offer subsampled at one-minute intervals, in addition to + // trades. + Cbbo1M = 16, + // All trade events with the consolidated best bid and offer (CBBO) immediately + // **before** + // the effect of the trade. + Tcbbo = 17, + // Best bid and offer subsampled at one-second intervals, in addition to trades. + Bbo1S = 18, + // Best bid and offer subsampled at one-minute intervals, in addition to trades. + Bbo1M = 19, +}; + +// A data encoding format. +enum class Encoding : std::uint8_t { + // Databento Binary Encoding. + Dbn = 0, + // Comma-separated values. + Csv = 1, + // JavaScript object notation. + Json = 2, +}; + +// A compression format or none if uncompressed. +enum class Compression : std::uint8_t { + // Uncompressed. + None = 0, + // Zstandard compressed. + Zstd = 1, +}; + +// The type of statistic contained in a `StatMsg`. namespace stat_type { -// The type of statistic contained in a StatMsg. enum StatType : std::uint16_t { // The price of the first trade of an instrument. `price` will be set. // `quantity` will be set when provided by the venue. OpeningPrice = 1, - // The probable price of the first trade of an instrument published during - // pre-open. Both `price` and `quantity` will be set. + // The probable price of the first trade of an instrument published during pre- + // open. Both `price` and `quantity` will be set. IndicativeOpeningPrice = 2, - // The settlement price of an instrument. `price` will be set and `flags` - // indicate whether the price is final or preliminary and actual or - // theoretical. `ts_ref` will indicate the trading date of the settlement - // price. + // The settlement price of an instrument. `price` will be set and `flags` indicate + // whether the price is final or preliminary and actual or theoretical. `ts_ref` + // will indicate the trading date of the settlement price. SettlementPrice = 3, - // The lowest trade price of an instrument during the trading session. - // `price` will be set. + // The lowest trade price of an instrument during the trading session. `price` will + // be set. TradingSessionLowPrice = 4, - // The highest trade price of an instrument during the trading session. - // `price` will be set. + // The highest trade price of an instrument during the trading session. `price` will + // be set. TradingSessionHighPrice = 5, - // The number of contracts cleared for an instrument on the previous trading - // date. `quantity` will be set. `ts_ref` will indicate the trading date of - // the volume. + // The number of contracts cleared for an instrument on the previous trading date. + // `quantity` will be set. `ts_ref` will indicate the trading date of the volume. ClearedVolume = 6, - // The lowest offer price for an instrument during the trading session. - // `price` will be set. + // The lowest offer price for an instrument during the trading session. `price` + // will be set. LowestOffer = 7, - // The highest bid price for an instrument during the trading session. - // `price` will be set. + // The highest bid price for an instrument during the trading session. `price` + // will be set. HighestBid = 8, - // The current number of outstanding contracts of an instrument. `quantity` - // will be set. `ts_ref` will indicate the trading date for which the open - // interest was calculated. + // The current number of outstanding contracts of an instrument. `quantity` will + // be set. `ts_ref` will indicate the trading date for which the open interest was + // calculated. OpenInterest = 9, - // The volume-weighted average price (VWAP) for a fixing period. `price` will - // be set. + // The volume-weighted average price (VWAP) for a fixing period. `price` will be + // set. FixingPrice = 10, // The last trade price during a trading session. `price` will be set. // `quantity` will be set when provided by the venue. ClosePrice = 11, - // The change in price from the close price of the previous trading session to - // the most recent trading session. `price` will be set. + // The change in price from the close price of the previous trading session to the + // most recent trading session. `price` will be set. NetChange = 12, - /// The volume-weighted average price (VWAP) during the trading session. - /// `price` will be set to the VWAP while `quantity` will be the traded - /// volume. + // The volume-weighted average price (VWAP) during the trading session. + // `price` will be set to the VWAP while `quantity` will be the traded + // volume. Vwap = 13, - // The implied volatility associated with the settlement price. `price` will - // be set with the standard precision. - Volatility = 14, - // The option delta associated with the settlement price. `price` will be set + // The implied volatility associated with the settlement price. `price` will be set // with the standard precision. + Volatility = 14, + // The option delta associated with the settlement price. `price` will be set with + // the standard precision. Delta = 15, - // The auction uncrossing price. This is used for auctions that are neither - // the - // official opening auction nor the official closing auction. `price` will be - // set. `quantity` will be set when provided by the venue. + // The auction uncrossing price. This is used for auctions that are neither the + // official opening auction nor the official closing auction. `price` will be set. + // `quantity` will be set when provided by the venue. UncrossingPrice = 16, - }; } // namespace stat_type using stat_type::StatType; -// The type of StatMsg update. -enum class StatUpdateAction : std::uint8_t { +// The type of `StatMsg` update. +namespace stat_update_action { +enum StatUpdateAction : std::uint8_t { + // A new statistic. New = 1, + // A removal of a statistic. Delete = 2, }; +} // namespace stat_update_action +using stat_update_action::StatUpdateAction; -// How to handle decoding DBN data from a prior version. -enum class VersionUpgradePolicy : std::uint8_t { - AsIs = 0, - UpgradeToV2 = 1, - UpgradeToV3 = 2, -}; - +// The primary enum for the type of `StatusMsg` update. namespace status_action { enum StatusAction : std::uint16_t { // No change. @@ -337,13 +465,15 @@ enum StatusAction : std::uint16_t { PostClose = 13, // A change in short-selling restrictions. SsrChange = 14, - // The instrument is not available for trading, either trading has closed or - // been halted. + // The instrument is not available for trading, either trading has closed or been + // halted. NotAvailableForTrading = 15, }; } // namespace status_action using status_action::StatusAction; +// The secondary enum for a `StatusMsg` update, explains +// the cause of a halt or other change in `action`. namespace status_reason { enum StatusReason : std::uint16_t { // No reason is given. @@ -364,8 +494,8 @@ enum StatusReason : std::uint16_t { Regulatory = 10, // The status change was caused by an administrative action. Administrative = 11, - // The status change was caused by the issuer not being compliance with - // regulatory requirements. + // The status change was caused by the issuer not being compliance with regulatory + // requirements. NonCompliance = 12, // Trading halted because the issuer's filings are not current. FilingsNotCurrent = 13, @@ -375,7 +505,7 @@ enum StatusReason : std::uint16_t { NewIssue = 15, // The status changed because an issue is available. IssueAvailable = 16, - // The status changed because the issue was reviewed. + // The status changed because the issue(s) were reviewed. IssuesReviewed = 17, // The status changed because the filing requirements were satisfied. FilingReqsSatisfied = 18, @@ -383,8 +513,8 @@ enum StatusReason : std::uint16_t { NewsPending = 30, // Relevant news was released. NewsReleased = 31, - // The news has been fully disseminated and times are available for the - // resumption in quoting and trading. + // The news has been fully disseminated and times are available for the resumption + // in quoting and trading. NewsAndResumptionTimes = 32, // The relevant news was not forthcoming. NewsNotForthcoming = 33, @@ -398,8 +528,7 @@ enum StatusReason : std::uint16_t { AdditionalInformationRequested = 70, // Trading halted due to merger becoming effective. MergerEffective = 80, - // Trading is halted in an ETF due to conditions with the component - // securities. + // Trading is halted in an ETF due to conditions with the component securities. Etf = 90, // Trading is halted for a corporate action. CorporateAction = 100, @@ -411,8 +540,8 @@ enum StatusReason : std::uint16_t { MarketWideHaltLevel2 = 121, // Halted due to the market-wide circuit breaker level 3. MarketWideHaltLevel3 = 122, - // Halted due to the carryover of a market-wide circuit breaker from the - // previous trading day. + // Halted due to the carryover of a market-wide circuit breaker from the previous + // trading day. MarketWideHaltCarryover = 123, // Resumption due to the end of a market-wide circuit breaker halt. MarketWideHaltResumption = 124, @@ -422,6 +551,7 @@ enum StatusReason : std::uint16_t { } // namespace status_reason using status_reason::StatusReason; +// Further information about a status update. namespace trading_event { enum TradingEvent : std::uint16_t { // No additional information given. @@ -438,41 +568,55 @@ enum TradingEvent : std::uint16_t { } // namespace trading_event using trading_event::TradingEvent; -// An enum for representing unknown, true, or false values. Equivalent to a -// std::optional. +// An enum for representing unknown, true, or false values. namespace tri_state { enum TriState : char { // The value is not applicable or not known. NotAvailable = '~', - // False + // False. No = 'N', - // True + // True. Yes = 'Y', }; } // namespace tri_state using tri_state::TriState; +// How to handle decoding DBN data from other versions. +enum class VersionUpgradePolicy { + // Decode data from all supported versions (less than or equal to + // `DBN_VERSION`) as-is. + AsIs, + // Decode and convert data from DBN versions prior to version 2 to that version. + // Attempting to decode data from newer versions will fail. + UpgradeToV2, + // Decode and convert data from DBN versions prior to version 3 to that version. + // Attempting to decode data from newer versions (when they're introduced) will + // fail. + UpgradeToV3, +}; + +// An error code from the live subscription gateway. namespace error_code { enum ErrorCode : std::uint8_t { // The authentication step failed. AuthFailed = 1, // The user account or API key were deactivated. ApiKeyDeactivated = 2, - // The user has exceeded their open connection limit + // The user has exceeded their open connection limit. ConnectionLimitExceeded = 3, // One or more symbols failed to resolve. SymbolResolutionFailed = 4, - // There was an issue with a subscription request (other than symbol - // resolution). + // There was an issue with a subscription request (other than symbol resolution). InvalidSubscription = 5, // An error occurred in the gateway. InternalError = 6, - Unset = 255, }; } // namespace error_code using error_code::ErrorCode; +// A `SystemMsg` code indicating the type of message from the live +// subscription gateway. namespace system_code { enum SystemCode : std::uint8_t { // A message sent in the absence of other records to indicate the connection @@ -484,7 +628,6 @@ enum SystemCode : std::uint8_t { SlowReaderWarning = 2, // Indicates a replay subscription has caught up with real-time data. ReplayCompleted = 3, - Unset = 255, }; } // namespace system_code @@ -493,72 +636,64 @@ using system_code::SystemCode; // Convert a HistoricalGateway to a URL. const char* UrlFromGateway(HistoricalGateway gateway); -const char* ToString(Schema schema); -const char* ToString(Encoding encoding); const char* ToString(FeedMode mode); -const char* ToString(Compression compression); -const char* ToString(SType stype); const char* ToString(SplitDuration duration_interval); const char* ToString(Delivery delivery); const char* ToString(JobState state); const char* ToString(DatasetCondition condition); -const char* ToString(RType rtype); -const char* ToString(Action action); +const char* ToString(RType r_type); const char* ToString(Side side); +const char* ToString(Action action); const char* ToString(InstrumentClass instrument_class); const char* ToString(MatchAlgorithm match_algorithm); -const char* ToString(SecurityUpdateAction update_action); -const char* ToString(UserDefinedInstrument user_def_instr); +const char* ToString(UserDefinedInstrument user_defined_instrument); +const char* ToString(SecurityUpdateAction security_update_action); +const char* ToString(SType s_type); +const char* ToString(Schema schema); +const char* ToString(Encoding encoding); +const char* ToString(Compression compression); const char* ToString(StatType stat_type); const char* ToString(StatUpdateAction stat_update_action); const char* ToString(StatusAction status_action); const char* ToString(StatusReason status_reason); const char* ToString(TradingEvent trading_event); const char* ToString(TriState tri_state); -const char* ToString(VersionUpgradePolicy upgrade_policy); +const char* ToString(VersionUpgradePolicy version_upgrade_policy); const char* ToString(ErrorCode error_code); const char* ToString(SystemCode system_code); -std::ostream& operator<<(std::ostream& out, Schema schema); -std::ostream& operator<<(std::ostream& out, Encoding encoding); std::ostream& operator<<(std::ostream& out, FeedMode mode); -std::ostream& operator<<(std::ostream& out, Compression compression); -std::ostream& operator<<(std::ostream& out, SType stype); std::ostream& operator<<(std::ostream& out, SplitDuration duration_interval); std::ostream& operator<<(std::ostream& out, Delivery delivery); std::ostream& operator<<(std::ostream& out, JobState state); std::ostream& operator<<(std::ostream& out, DatasetCondition condition); -std::ostream& operator<<(std::ostream& out, RType rtype); -std::ostream& operator<<(std::ostream& out, Action action); +std::ostream& operator<<(std::ostream& out, RType r_type); std::ostream& operator<<(std::ostream& out, Side side); +std::ostream& operator<<(std::ostream& out, Action action); std::ostream& operator<<(std::ostream& out, InstrumentClass instrument_class); std::ostream& operator<<(std::ostream& out, MatchAlgorithm match_algorithm); -std::ostream& operator<<(std::ostream& out, SecurityUpdateAction update_action); std::ostream& operator<<(std::ostream& out, - UserDefinedInstrument user_def_instr); -std::ostream& operator<<(std::ostream& out, StatType stat_type); + UserDefinedInstrument user_defined_instrument); std::ostream& operator<<(std::ostream& out, - StatUpdateAction stat_update_action); + SecurityUpdateAction security_update_action); +std::ostream& operator<<(std::ostream& out, SType s_type); +std::ostream& operator<<(std::ostream& out, Schema schema); +std::ostream& operator<<(std::ostream& out, Encoding encoding); +std::ostream& operator<<(std::ostream& out, Compression compression); +std::ostream& operator<<(std::ostream& out, StatType stat_type); +std::ostream& operator<<(std::ostream& out, StatUpdateAction stat_update_action); std::ostream& operator<<(std::ostream& out, StatusAction status_action); std::ostream& operator<<(std::ostream& out, StatusReason status_reason); std::ostream& operator<<(std::ostream& out, TradingEvent trading_event); std::ostream& operator<<(std::ostream& out, TriState tri_state); std::ostream& operator<<(std::ostream& out, - VersionUpgradePolicy upgrade_policy); + VersionUpgradePolicy version_upgrade_policy); std::ostream& operator<<(std::ostream& out, ErrorCode error_code); std::ostream& operator<<(std::ostream& out, SystemCode system_code); -template <> -Schema FromString(const std::string& str); -template <> -Encoding FromString(const std::string& str); template <> FeedMode FromString(const std::string& str); template <> -Compression FromString(const std::string& str); -template <> -SType FromString(const std::string& str); -template <> SplitDuration FromString(const std::string& str); template <> Delivery FromString(const std::string& str); @@ -566,4 +701,18 @@ template <> JobState FromString(const std::string& str); template <> DatasetCondition FromString(const std::string& str); +template <> +RType FromString(const std::string& str); +template <> +SType FromString(const std::string& str); +template <> +Schema FromString(const std::string& str); +template <> +Encoding FromString(const std::string& str); +template <> +Compression FromString(const std::string& str); +template <> +ErrorCode FromString(const std::string& str); +template <> +SystemCode FromString(const std::string& str); } // namespace databento diff --git a/include/databento/exceptions.hpp b/include/databento/exceptions.hpp index 3e91053..b10d0a7 100644 --- a/include/databento/exceptions.hpp +++ b/include/databento/exceptions.hpp @@ -73,8 +73,7 @@ class HttpResponseError : public Exception { class TcpError : public Exception { public: explicit TcpError(int err_num, std::string message) - : Exception{BuildMessage(err_num, std::move(message))}, - err_num_{err_num} {}; + : Exception{BuildMessage(err_num, std::move(message))}, err_num_{err_num} {}; int ErrNum() const { return err_num_; } @@ -111,8 +110,8 @@ class InvalidArgumentError : public Exception { // Exception indicating an error parsing a JSON response from the Databento API. class JsonResponseError : public Exception { public: - static JsonResponseError ParseError( - std::string_view path, const nlohmann::detail::parse_error& parse_error); + static JsonResponseError ParseError(std::string_view path, + const nlohmann::detail::parse_error& parse_error); static JsonResponseError MissingKey(std::string_view method_name, const nlohmann::json& key); static JsonResponseError TypeMismatch(std::string_view method_name, @@ -124,15 +123,13 @@ class JsonResponseError : public Exception { const nlohmann::json& value); private: - explicit JsonResponseError(std::string message) - : Exception{std::move(message)} {} + explicit JsonResponseError(std::string message) : Exception{std::move(message)} {} }; // Exception indicating an error parsing a DBN response from the Databento API. class DbnResponseError : public Exception { public: - explicit DbnResponseError(std::string message) - : Exception{std::move(message)} {} + explicit DbnResponseError(std::string message) : Exception{std::move(message)} {} }; // Exception indicating something internal to the live API, but unrelated to TCP diff --git a/include/databento/historical.hpp b/include/databento/historical.hpp index 82e07d0..6d117a1 100644 --- a/include/databento/historical.hpp +++ b/include/databento/historical.hpp @@ -12,7 +12,7 @@ #include "databento/detail/http_client.hpp" // HttpClient #include "databento/enums.hpp" // BatchState, Delivery, DurationInterval, Schema, SType, VersionUpgradePolicy #include "databento/metadata.hpp" // DatasetConditionDetail, DatasetRange, FieldDetail, PublisherDetail, UnitPricesForMode -#include "databento/symbology.hpp" // SymbologyResolution +#include "databento/symbology.hpp" // SymbologyResolution #include "databento/timeseries.hpp" // KeepGoing, MetadataCallback, RecordCallback namespace databento { @@ -24,8 +24,7 @@ class ILogReceiver; class Historical { public: // WARNING: Will be deprecated in the future in favor of the builder - Historical(ILogReceiver* log_receiver, std::string key, - HistoricalGateway gateway); + Historical(ILogReceiver* log_receiver, std::string key, HistoricalGateway gateway); /* * Getters @@ -42,31 +41,27 @@ class Historical { // // WARNING: Calling this method will incur a cost. BatchJob BatchSubmitJob(const std::string& dataset, - const std::vector& symbols, - Schema schema, + const std::vector& symbols, Schema schema, const DateTimeRange& datetime_range); BatchJob BatchSubmitJob(const std::string& dataset, - const std::vector& symbols, - Schema schema, + const std::vector& symbols, Schema schema, const DateTimeRange& datetime_range); BatchJob BatchSubmitJob(const std::string& dataset, - const std::vector& symbols, - Schema schema, + const std::vector& symbols, Schema schema, const DateTimeRange& datetime_range, - Encoding encoding, Compression compression, - bool pretty_px, bool pretty_ts, bool map_symbols, - bool split_symbols, SplitDuration split_duration, - std::uint64_t split_size, Delivery delivery, - SType stype_in, SType stype_out, std::uint64_t limit); + Encoding encoding, Compression compression, bool pretty_px, + bool pretty_ts, bool map_symbols, bool split_symbols, + SplitDuration split_duration, std::uint64_t split_size, + Delivery delivery, SType stype_in, SType stype_out, + std::uint64_t limit); BatchJob BatchSubmitJob(const std::string& dataset, - const std::vector& symbols, - Schema schema, + const std::vector& symbols, Schema schema, const DateTimeRange& datetime_range, - Encoding encoding, Compression compression, - bool pretty_px, bool pretty_ts, bool map_symbols, - bool split_symbols, SplitDuration split_duration, - std::uint64_t split_size, Delivery delivery, - SType stype_in, SType stype_out, std::uint64_t limit); + Encoding encoding, Compression compression, bool pretty_px, + bool pretty_ts, bool map_symbols, bool split_symbols, + SplitDuration split_duration, std::uint64_t split_size, + Delivery delivery, SType stype_in, SType stype_out, + std::uint64_t limit); // Lists previous batch jobs. std::vector BatchListJobs(); std::vector BatchListJobs(const std::vector& states, @@ -93,57 +88,52 @@ class Historical { std::vector MetadataListDatasets(const DateRange& date_range); std::vector MetadataListSchemas(const std::string& dataset); std::vector MetadataListFields(Encoding encoding, Schema schema); - std::vector MetadataListUnitPrices( - const std::string& dataset); + std::vector MetadataListUnitPrices(const std::string& dataset); std::vector MetadataGetDatasetCondition( const std::string& dataset); std::vector MetadataGetDatasetCondition( const std::string& dataset, const DateRange& date_range); DatasetRange MetadataGetDatasetRange(const std::string& dataset); - std::uint64_t MetadataGetRecordCount( - const std::string& dataset, - const DateTimeRange& datetime_range, - const std::vector& symbols, Schema schema); - std::uint64_t MetadataGetRecordCount( - const std::string& dataset, - const DateTimeRange& datetime_range, - const std::vector& symbols, Schema schema); - std::uint64_t MetadataGetRecordCount( - const std::string& dataset, - const DateTimeRange& datetime_range, - const std::vector& symbols, Schema schema, SType stype_in, - std::uint64_t limit); - std::uint64_t MetadataGetRecordCount( - const std::string& dataset, - const DateTimeRange& datetime_range, - const std::vector& symbols, Schema schema, SType stype_in, - std::uint64_t limit); - std::uint64_t MetadataGetBillableSize( - const std::string& dataset, - const DateTimeRange& datetime_range, - const std::vector& symbols, Schema schema); + std::uint64_t MetadataGetRecordCount(const std::string& dataset, + const DateTimeRange& datetime_range, + const std::vector& symbols, + Schema schema); + std::uint64_t MetadataGetRecordCount(const std::string& dataset, + const DateTimeRange& datetime_range, + const std::vector& symbols, + Schema schema); + std::uint64_t MetadataGetRecordCount(const std::string& dataset, + const DateTimeRange& datetime_range, + const std::vector& symbols, + Schema schema, SType stype_in, + std::uint64_t limit); + std::uint64_t MetadataGetRecordCount(const std::string& dataset, + const DateTimeRange& datetime_range, + const std::vector& symbols, + Schema schema, SType stype_in, + std::uint64_t limit); + std::uint64_t MetadataGetBillableSize(const std::string& dataset, + const DateTimeRange& datetime_range, + const std::vector& symbols, + Schema schema); std::uint64_t MetadataGetBillableSize( - const std::string& dataset, - const DateTimeRange& datetime_range, + const std::string& dataset, const DateTimeRange& datetime_range, const std::vector& symbols, Schema schema); + std::uint64_t MetadataGetBillableSize(const std::string& dataset, + const DateTimeRange& datetime_range, + const std::vector& symbols, + Schema schema, SType stype_in, + std::uint64_t limit); std::uint64_t MetadataGetBillableSize( - const std::string& dataset, - const DateTimeRange& datetime_range, - const std::vector& symbols, Schema schema, SType stype_in, - std::uint64_t limit); - std::uint64_t MetadataGetBillableSize( - const std::string& dataset, - const DateTimeRange& datetime_range, + const std::string& dataset, const DateTimeRange& datetime_range, const std::vector& symbols, Schema schema, SType stype_in, std::uint64_t limit); double MetadataGetCost(const std::string& dataset, const DateTimeRange& datetime_range, - const std::vector& symbols, - Schema schema); + const std::vector& symbols, Schema schema); double MetadataGetCost(const std::string& dataset, const DateTimeRange& datetime_range, - const std::vector& symbols, - Schema schema); + const std::vector& symbols, Schema schema); double MetadataGetCost(const std::string& dataset, const DateTimeRange& datetime_range, const std::vector& symbols, Schema schema, @@ -177,24 +167,22 @@ class Historical { // WARNING: Calling this method will incur a cost. void TimeseriesGetRange(const std::string& dataset, const DateTimeRange& datetime_range, - const std::vector& symbols, - Schema schema, const RecordCallback& record_callback); + const std::vector& symbols, Schema schema, + const RecordCallback& record_callback); void TimeseriesGetRange(const std::string& dataset, const DateTimeRange& datetime_range, - const std::vector& symbols, - Schema schema, const RecordCallback& record_callback); + const std::vector& symbols, Schema schema, + const RecordCallback& record_callback); void TimeseriesGetRange(const std::string& dataset, const DateTimeRange& datetime_range, - const std::vector& symbols, - Schema schema, SType stype_in, SType stype_out, - std::uint64_t limit, + const std::vector& symbols, Schema schema, + SType stype_in, SType stype_out, std::uint64_t limit, const MetadataCallback& metadata_callback, const RecordCallback& record_callback); void TimeseriesGetRange(const std::string& dataset, const DateTimeRange& datetime_range, - const std::vector& symbols, - Schema schema, SType stype_in, SType stype_out, - std::uint64_t limit, + const std::vector& symbols, Schema schema, + SType stype_in, SType stype_out, std::uint64_t limit, const MetadataCallback& metadata_callback, const RecordCallback& record_callback); // Stream historical market data to a file at `path`. Returns a `DbnFileStore` @@ -203,44 +191,39 @@ class Historical { // If a file at `file_path` already exists, it will be overwritten. // // WARNING: Calling this method will incur a cost. + DbnFileStore TimeseriesGetRangeToFile(const std::string& dataset, + const DateTimeRange& datetime_range, + const std::vector& symbols, + Schema schema, + const std::filesystem::path& file_path); DbnFileStore TimeseriesGetRangeToFile( - const std::string& dataset, - const DateTimeRange& datetime_range, - const std::vector& symbols, Schema schema, - const std::filesystem::path& file_path); - DbnFileStore TimeseriesGetRangeToFile( - const std::string& dataset, - const DateTimeRange& datetime_range, + const std::string& dataset, const DateTimeRange& datetime_range, const std::vector& symbols, Schema schema, const std::filesystem::path& file_path); + DbnFileStore TimeseriesGetRangeToFile(const std::string& dataset, + const DateTimeRange& datetime_range, + const std::vector& symbols, + Schema schema, SType stype_in, SType stype_out, + std::uint64_t limit, + const std::filesystem::path& file_path); DbnFileStore TimeseriesGetRangeToFile( - const std::string& dataset, - const DateTimeRange& datetime_range, - const std::vector& symbols, Schema schema, SType stype_in, - SType stype_out, std::uint64_t limit, - const std::filesystem::path& file_path); - DbnFileStore TimeseriesGetRangeToFile( - const std::string& dataset, - const DateTimeRange& datetime_range, + const std::string& dataset, const DateTimeRange& datetime_range, const std::vector& symbols, Schema schema, SType stype_in, - SType stype_out, std::uint64_t limit, - const std::filesystem::path& file_path); + SType stype_out, std::uint64_t limit, const std::filesystem::path& file_path); private: friend HistoricalBuilder; using HttplibParams = std::multimap; - Historical(ILogReceiver* log_receiver, std::string key, - HistoricalGateway gateway, VersionUpgradePolicy upgrade_policy, - std::string user_agent_ext); + Historical(ILogReceiver* log_receiver, std::string key, HistoricalGateway gateway, + VersionUpgradePolicy upgrade_policy, std::string user_agent_ext); Historical(ILogReceiver* log_receiver, std::string key, std::string gateway, std::uint16_t port, VersionUpgradePolicy upgrade_policy, std::string user_agent_ext); BatchJob BatchSubmitJob(const HttplibParams& params); - void DownloadFile(const std::string& url, - const std::filesystem::path& output_path); + void DownloadFile(const std::string& url, const std::filesystem::path& output_path); std::vector BatchListJobs(const HttplibParams& params); std::vector MetadataGetDatasetCondition( const HttplibParams& params); diff --git a/include/databento/live_blocking.hpp b/include/databento/live_blocking.hpp index c9aadf5..572369d 100644 --- a/include/databento/live_blocking.hpp +++ b/include/databento/live_blocking.hpp @@ -13,7 +13,7 @@ #include "databento/dbn.hpp" // Metadata #include "databento/detail/buffer.hpp" #include "databento/detail/tcp_client.hpp" // TcpClient -#include "databento/enums.hpp" // Schema, SType, VersionUpgradePolicy +#include "databento/enums.hpp" // Schema, SType, VersionUpgradePolicy #include "databento/live_subscription.hpp" #include "databento/record.hpp" // Record, RecordHeader @@ -42,9 +42,7 @@ class LiveBlocking { std::optional HeartbeatInterval() const { return heartbeat_interval_; } - const std::vector& Subscriptions() const { - return subscriptions_; - } + const std::vector& Subscriptions() const { return subscriptions_; } std::vector& Subscriptions() { return subscriptions_; } /* @@ -56,12 +54,12 @@ class LiveBlocking { // when the client disconnects in its destructor. void Subscribe(const std::vector& symbols, Schema schema, SType stype_in); - void Subscribe(const std::vector& symbols, Schema schema, - SType stype_in, UnixNanos start); - void Subscribe(const std::vector& symbols, Schema schema, - SType stype_in, const std::string& start); - void SubscribeWithSnapshot(const std::vector& symbols, - Schema schema, SType stype_in); + void Subscribe(const std::vector& symbols, Schema schema, SType stype_in, + UnixNanos start); + void Subscribe(const std::vector& symbols, Schema schema, SType stype_in, + const std::string& start); + void SubscribeWithSnapshot(const std::vector& symbols, Schema schema, + SType stype_in); // Notifies the gateway to start sending messages for all subscriptions. // // This method should only be called once per instance. @@ -107,8 +105,8 @@ class LiveBlocking { std::string EncodeAuthReq(std::string_view auth); std::uint64_t DecodeAuthResp(); void IncrementSubCounter(); - void Subscribe(std::string_view sub_msg, - const std::vector& symbols, bool use_snapshot); + void Subscribe(std::string_view sub_msg, const std::vector& symbols, + bool use_snapshot); detail::TcpClient::Result FillBuffer(std::chrono::milliseconds timeout); RecordHeader* BufferRecordHeader(); diff --git a/include/databento/live_threaded.hpp b/include/databento/live_threaded.hpp index a261c88..78f57b7 100644 --- a/include/databento/live_threaded.hpp +++ b/include/databento/live_threaded.hpp @@ -33,8 +33,7 @@ class LiveThreaded { // Close the connection and stop the callback thread. Stop, }; - using ExceptionCallback = - std::function; + using ExceptionCallback = std::function; LiveThreaded(const LiveThreaded&) = delete; LiveThreaded& operator=(const LiveThreaded&) = delete; @@ -65,12 +64,12 @@ class LiveThreaded { // when the client disconnects when it's destroyed. void Subscribe(const std::vector& symbols, Schema schema, SType stype_in); - void Subscribe(const std::vector& symbols, Schema schema, - SType stype_in, UnixNanos start); - void Subscribe(const std::vector& symbols, Schema schema, - SType stype_in, const std::string& start); - void SubscribeWithSnapshot(const std::vector& symbols, - Schema schema, SType stype_in); + void Subscribe(const std::vector& symbols, Schema schema, SType stype_in, + UnixNanos start); + void Subscribe(const std::vector& symbols, Schema schema, SType stype_in, + const std::string& start); + void SubscribeWithSnapshot(const std::vector& symbols, Schema schema, + SType stype_in); // Notifies the gateway to start sending messages for all subscriptions. // `metadata_callback` will be called exactly once, before any calls to // `record_callback`. `record_callback` will be called for records from all @@ -78,8 +77,7 @@ class LiveThreaded { // // This method should only be called once per instance. void Start(RecordCallback record_callback); - void Start(MetadataCallback metadata_callback, - RecordCallback record_callback); + void Start(MetadataCallback metadata_callback, RecordCallback record_callback); void Start(MetadataCallback metadata_callback, RecordCallback record_callback, ExceptionCallback exception_callback); // Closes the current connection, and attempts to reconnect to the gateway. @@ -98,10 +96,11 @@ class LiveThreaded { static void ProcessingThread(Impl* impl, MetadataCallback&& metadata_callback, RecordCallback&& record_callback, ExceptionCallback&& exception_callback); - static ExceptionAction ExceptionHandler( - Impl* impl, const ExceptionCallback& exception_callback, - const std::exception& exc, std::string_view pretty_function_name, - std::string_view message); + static ExceptionAction ExceptionHandler(Impl* impl, + const ExceptionCallback& exception_callback, + const std::exception& exc, + std::string_view pretty_function_name, + std::string_view message); LiveThreaded(ILogReceiver* log_receiver, std::string key, std::string dataset, bool send_ts_out, VersionUpgradePolicy upgrade_policy, diff --git a/include/databento/metadata.hpp b/include/databento/metadata.hpp index 6fb3c2d..25d6e5f 100644 --- a/include/databento/metadata.hpp +++ b/include/databento/metadata.hpp @@ -55,12 +55,10 @@ inline bool operator!=(const FieldDetail& lhs, const FieldDetail& rhs) { return !(lhs == rhs); } -inline bool operator==(const UnitPricesForMode& lhs, - const UnitPricesForMode& rhs) { +inline bool operator==(const UnitPricesForMode& lhs, const UnitPricesForMode& rhs) { return lhs.mode == rhs.mode && lhs.unit_prices == rhs.unit_prices; } -inline bool operator!=(const UnitPricesForMode& lhs, - const UnitPricesForMode& rhs) { +inline bool operator!=(const UnitPricesForMode& lhs, const UnitPricesForMode& rhs) { return !(lhs == rhs); } @@ -83,14 +81,12 @@ inline bool operator!=(const DatasetRange& lhs, const DatasetRange& rhs) { } std::string ToString(const PublisherDetail& publisher_detail); -std::ostream& operator<<(std::ostream& stream, - const PublisherDetail& publisher_detail); +std::ostream& operator<<(std::ostream& stream, const PublisherDetail& publisher_detail); std::string ToString(const FieldDetail& field_detail); std::ostream& operator<<(std::ostream& stream, const FieldDetail& field_detail); std::string ToString(const DatasetConditionDetail& condition_detail); std::ostream& operator<<(std::ostream& stream, const DatasetConditionDetail& condition_detail); std::string ToString(const DatasetRange& dataset_range); -std::ostream& operator<<(std::ostream& stream, - const DatasetRange& dataset_range); +std::ostream& operator<<(std::ostream& stream, const DatasetRange& dataset_range); } // namespace databento diff --git a/include/databento/record.hpp b/include/databento/record.hpp index e7fd04b..1f552f5 100644 --- a/include/databento/record.hpp +++ b/include/databento/record.hpp @@ -6,7 +6,6 @@ #include // strncmp #include #include -#include // tie #include #include "databento/constants.hpp" // kSymbolCstrLen @@ -19,8 +18,7 @@ namespace databento { // Common data for all Databento Records. struct RecordHeader { - static constexpr std::size_t kLengthMultiplier = - kRecordHeaderLengthMultiplier; + static constexpr std::size_t kLengthMultiplier = kRecordHeaderLengthMultiplier; // The length of the message in 32-bit words. std::uint8_t length; @@ -36,9 +34,7 @@ struct RecordHeader { std::size_t Size() const; // Retrieve the publisher based on the publisher ID. - enum Publisher Publisher() const { - return static_cast(publisher_id); - } + enum Publisher Publisher() const { return static_cast(publisher_id); } }; // Type trait helper for templated functions accepting DBN records. @@ -100,7 +96,7 @@ class Record { RecordHeader* record_; }; -// Market-by-order (MBO) message. +// A market-by-order (MBO) tick message. The record of the MBO schema. struct MboMsg { static bool HasRType(RType rtype) { return rtype == RType::Mbo; } @@ -119,8 +115,9 @@ struct MboMsg { std::uint32_t sequence; }; static_assert(sizeof(MboMsg) == 56, "MboMsg size must match Rust"); -static_assert(alignof(MboMsg) == 8, "Must have 8-byte alignment"); +static_assert(alignof(MboMsg) == 8, "MboMsg must have 8-byte alignment"); +// A price level. struct BidAskPair { std::int64_t bid_px; std::int64_t ask_px; @@ -130,23 +127,26 @@ struct BidAskPair { std::uint32_t ask_ct; }; static_assert(sizeof(BidAskPair) == 32, "BidAskPair size must match Rust"); -static_assert(alignof(BidAskPair) == 8, "Must have 8-byte alignment"); +static_assert(alignof(BidAskPair) == 8, "BidAskPair must have 8-byte alignment"); +// A price level consolidated from multiple venues. struct ConsolidatedBidAskPair { std::int64_t bid_px; std::int64_t ask_px; std::uint32_t bid_sz; std::uint32_t ask_sz; std::uint16_t bid_pb; - std::array reserved1; + std::array _reserved1{}; std::uint16_t ask_pb; - std::array reserved2; + std::array _reserved2{}; }; static_assert(sizeof(ConsolidatedBidAskPair) == 32, "ConsolidatedBidAskPair size must match Rust"); static_assert(alignof(ConsolidatedBidAskPair) == 8, - "Must have 8-byte alignment"); + "ConsolidatedBidAskPair must have 8-byte alignment"); +// Market-by-price implementation with a book depth of 0. Equivalent to MBP-0. The +// record of the Trades schema. struct TradeMsg { static bool HasRType(RType rtype) { return rtype == RType::Mbp0; } @@ -158,24 +158,18 @@ struct TradeMsg { Action action; Side side; FlagSet flags; - // Depth of the actual book change. std::uint8_t depth; UnixNanos ts_recv; TimeDeltaNanos ts_in_delta; std::uint32_t sequence; }; static_assert(sizeof(TradeMsg) == 48, "TradeMsg size must match Rust"); -static_assert(alignof(TradeMsg) == 8, "Must have 8-byte alignment"); +static_assert(alignof(TradeMsg) == 8, "TradeMsg must have 8-byte alignment"); +// Market-by-price implementation with a known book depth of 1. The record of the MBP-1 +// schema. struct Mbp1Msg { - static bool HasRType(RType rtype) { - switch (rtype) { - case RType::Mbp1: - return true; - default: - return false; - }; - } + static bool HasRType(RType rtype) { return rtype == RType::Mbp1; } UnixNanos IndexTs() const { return ts_recv; } @@ -185,20 +179,20 @@ struct Mbp1Msg { Action action; Side side; FlagSet flags; - // Depth of the actual book change. std::uint8_t depth; UnixNanos ts_recv; TimeDeltaNanos ts_in_delta; std::uint32_t sequence; std::array levels; }; -using TbboMsg = Mbp1Msg; -static_assert(alignof(Mbp1Msg) == 8, "Must have 8-byte alignment"); -static_assert(sizeof(Mbp1Msg) == sizeof(TradeMsg) + sizeof(BidAskPair), - "Mbp1Msg size must match Rust"); +static_assert(sizeof(Mbp1Msg) == 80, "Mbp1Msg size must match Rust"); +static_assert(alignof(Mbp1Msg) == 8, "Mbp1Msg must have 8-byte alignment"); +// Market-by-price implementation with a known book depth of 10. The record of the +// MBP-10 +// schema. struct Mbp10Msg { - static bool HasRType(RType rtype) { return rtype == rtype::Mbp10; } + static bool HasRType(RType rtype) { return rtype == RType::Mbp10; } UnixNanos IndexTs() const { return ts_recv; } @@ -208,27 +202,20 @@ struct Mbp10Msg { Action action; Side side; FlagSet flags; - // Depth of the actual book change. std::uint8_t depth; UnixNanos ts_recv; TimeDeltaNanos ts_in_delta; std::uint32_t sequence; std::array levels; }; -static_assert(alignof(Mbp10Msg) == 8, "Must have 8-byte alignment"); -static_assert(sizeof(Mbp10Msg) == sizeof(TradeMsg) + sizeof(BidAskPair) * 10, - "Mbp10Msg size must match Rust"); +static_assert(sizeof(Mbp10Msg) == 368, "Mbp10Msg size must match Rust"); +static_assert(alignof(Mbp10Msg) == 8, "Mbp10Msg must have 8-byte alignment"); +// Subsampled market by price with a known book depth of 1. The record of the BBO-1s and +// BBO-1m schemas. struct BboMsg { static bool HasRType(RType rtype) { - switch (rtype) { - case RType::Bbo1S: - [[fallthrough]]; - case RType::Bbo1M: - return true; - default: - return false; - }; + return rtype == RType::Bbo1S || rtype == RType::Bbo1M; } UnixNanos IndexTs() const { return ts_recv; } @@ -236,30 +223,24 @@ struct BboMsg { RecordHeader hd; std::int64_t price; std::uint32_t size; - char reserved1; + std::uint8_t _reserved1{}; Side side; FlagSet flags; - char reserved2; + std::uint8_t _reserved2{}; UnixNanos ts_recv; - std::array reserved3; + std::array _reserved3{}; std::uint32_t sequence; std::array 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"); +static_assert(sizeof(BboMsg) == 80, "BboMsg size must match Rust"); +static_assert(alignof(BboMsg) == 8, "BboMsg must have 8-byte alignment"); +// Consolidated market-by-price implementation with a known book depth of 1. The record +// of +// the CMBP-1 schema. struct Cmbp1Msg { static bool HasRType(RType rtype) { - switch (rtype) { - case RType::Cmbp1: - [[fallthrough]]; - case RType::Tcbbo: - return true; - default: - return false; - }; + return rtype == RType::Cmbp1 || rtype == RType::Tcbbo; } UnixNanos IndexTs() const { return ts_recv; } @@ -267,75 +248,64 @@ struct Cmbp1Msg { RecordHeader hd; std::int64_t price; std::uint32_t size; - char action; + Action action; Side side; FlagSet flags; - char reserved1; + std::array _reserved1{}; UnixNanos ts_recv; TimeDeltaNanos ts_in_delta; - std::array reserved2; + std::array _reserved2{}; std::array levels; }; -using TcbboMsg = Cmbp1Msg; -static_assert(alignof(Cmbp1Msg) == 8, "Must have 8-byte alignment"); -static_assert(sizeof(Cmbp1Msg) == - sizeof(TradeMsg) + sizeof(ConsolidatedBidAskPair), - "Cmbp1Msg size must match Rust"); +static_assert(sizeof(Cmbp1Msg) == 80, "Cmbp1Msg size must match Rust"); +static_assert(alignof(Cmbp1Msg) == 8, "Cmbp1Msg must have 8-byte alignment"); +// Subsampled consolidated market by price with a known book depth of 1. The record of +// the CBBO-1s and CBBO-1m schemas. struct CbboMsg { static bool HasRType(RType rtype) { - switch (rtype) { - case RType::Cbbo1S: - [[fallthrough]]; - case RType::Cbbo1M: - return true; - default: - return false; - }; + return rtype == RType::Cbbo1S || rtype == RType::Cbbo1M; } - static_assert(alignof(Cmbp1Msg) == 8, "Must have 8-byte alignment"); - static_assert(sizeof(Cmbp1Msg) == - sizeof(TradeMsg) + sizeof(ConsolidatedBidAskPair), - "Cmbp1Msg size must match Rust"); UnixNanos IndexTs() const { return ts_recv; } RecordHeader hd; std::int64_t price; std::uint32_t size; - char reserved1; + std::uint8_t _reserved1{}; Side side; FlagSet flags; - char reserved2; + std::uint8_t _reserved2{}; UnixNanos ts_recv; - std::array reserved3; - std::array reserved4; + std::array _reserved3{}; std::array levels; }; +static_assert(sizeof(CbboMsg) == 80, "CbboMsg size must match Rust"); +static_assert(alignof(CbboMsg) == 8, "CbboMsg must have 8-byte alignment"); + +// The record of the TBBO schema. +using TbboMsg = Mbp1Msg; +// The record of the BBO-1s schema. +using Bbo1SMsg = BboMsg; +// The record of the BBO-1m schema. +using Bbo1MMsg = BboMsg; +// The record of the TCBBO schema. +using TcbboMsg = Cmbp1Msg; +// The record of the CBBO-1s schema. using Cbbo1SMsg = CbboMsg; +// The record of the CBBO-1m schema. using Cbbo1MMsg = CbboMsg; -static_assert(alignof(CbboMsg) == 8, "Must have 8-byte alignment"); -static_assert(sizeof(CbboMsg) == - sizeof(TradeMsg) + sizeof(ConsolidatedBidAskPair), - "CbboMsg size must match Rust"); - -// Aggregate of open, high, low, and close prices with volume. +// Open, high, low, close, and volume. The record of the following schemas: +// - OHLCV-1s +// - OHLCV-1m +// - OHLCV-1h +// - OHLCV-1d +// - OHLCV-eod struct OhlcvMsg { static bool HasRType(RType rtype) { - switch (rtype) { - case RType::OhlcvDeprecated: - [[fallthrough]]; - case RType::Ohlcv1S: - [[fallthrough]]; - case RType::Ohlcv1M: - [[fallthrough]]; - case RType::Ohlcv1H: - [[fallthrough]]; - case RType::Ohlcv1D: - return true; - default: - return false; - } + return rtype == RType::Ohlcv1S || rtype == RType::Ohlcv1M || + rtype == RType::Ohlcv1H || rtype == RType::Ohlcv1D || + rtype == RType::OhlcvEod || rtype == RType::OhlcvDeprecated; } UnixNanos IndexTs() const { return hd.ts_event; } @@ -348,9 +318,9 @@ struct OhlcvMsg { std::uint64_t volume; }; static_assert(sizeof(OhlcvMsg) == 56, "OhlcvMsg size must match Rust"); -static_assert(alignof(OhlcvMsg) == 8, "Must have 8-byte alignment"); +static_assert(alignof(OhlcvMsg) == 8, "OhlcvMsg must have 8-byte alignment"); -// A trading status update message. +// A trading status update message. The record of the status schema. struct StatusMsg { static bool HasRType(RType rtype) { return rtype == RType::Status; } @@ -364,16 +334,17 @@ struct StatusMsg { TriState is_trading; TriState is_quoting; TriState is_short_sell_restricted; - std::array reserved; + std::array _reserved{}; }; static_assert(sizeof(StatusMsg) == 40, "StatusMsg size must match Rust"); -static_assert(alignof(StatusMsg) == 8, "Must have 8-byte alignment"); +static_assert(alignof(StatusMsg) == 8, "StatusMsg must have 8-byte alignment"); -// Instrument definition. +// A definition of an instrument. The record of the definition schema. 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(); } @@ -385,9 +356,7 @@ struct InstrumentDefMsg { 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* StrikePriceCurrency() const { return strike_price_currency.data(); } const char* LegRawSymbol() const { return leg_raw_symbol.data(); } RecordHeader hd; @@ -460,14 +429,13 @@ struct InstrumentDefMsg { std::uint8_t tick_rule; InstrumentClass leg_instrument_class; Side leg_side; - // padding for alignment - std::array reserved; + std::array _reserved{}; }; -static_assert(sizeof(InstrumentDefMsg) == 520, - "InstrumentDefMsg size must match Rust"); -static_assert(alignof(InstrumentDefMsg) == 8, "Must have 8-byte alignment"); +static_assert(sizeof(InstrumentDefMsg) == 520, "InstrumentDefMsg size must match Rust"); +static_assert(alignof(InstrumentDefMsg) == 8, + "InstrumentDefMsg must have 8-byte alignment"); -// An order imbalance message. +// An auction imbalance message. struct ImbalanceMsg { static bool HasRType(RType rtype) { return rtype == RType::Imbalance; } @@ -494,15 +462,13 @@ struct ImbalanceMsg { std::uint8_t num_extensions; Side unpaired_side; char significant_imbalance; - // padding for alignment - std::array reserved; + std::array _reserved{}; }; static_assert(sizeof(ImbalanceMsg) == 112, "ImbalanceMsg size must match Rust"); -static_assert(alignof(ImbalanceMsg) == 8, "Must have 8-byte alignment"); +static_assert(alignof(ImbalanceMsg) == 8, "ImbalanceMsg must have 8-byte alignment"); -/// A statistics message. A catchall for various data disseminated by -/// publishers. The `stat_type` indicates the statistic contained in the -/// message. +// 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; } @@ -519,17 +485,17 @@ struct StatMsg { std::uint16_t channel_id; StatUpdateAction update_action; std::uint8_t stat_flags; - std::array reserved; + std::array _reserved{}; }; static_assert(sizeof(StatMsg) == 80, "StatMsg size must match Rust"); -static_assert(alignof(StatMsg) == 8, "Must have 8-byte alignment"); +static_assert(alignof(StatMsg) == 8, "StatMsg must have 8-byte alignment"); -// An error message from the Live Subscription Gateway (LSG). This will never -// be present in historical data. +// An error message from the Databento Live Subscription Gateway (LSG). struct ErrorMsg { static bool HasRType(RType rtype) { return rtype == RType::Error; } UnixNanos IndexTs() const { return hd.ts_event; } + const char* Err() const { return err.data(); } RecordHeader hd; @@ -538,13 +504,15 @@ struct ErrorMsg { std::uint8_t is_last; }; static_assert(sizeof(ErrorMsg) == 320, "ErrorMsg size must match Rust"); -static_assert(alignof(ErrorMsg) == 8, "Must have 8-byte alignment"); +static_assert(alignof(ErrorMsg) == 8, "ErrorMsg must have 8-byte alignment"); -/// A symbol mapping message. +// A symbol mapping message from the live API which maps a symbol from one `SType` to +// another. struct SymbolMappingMsg { static bool HasRType(RType rtype) { return rtype == RType::SymbolMapping; } UnixNanos IndexTs() const { return hd.ts_event; } + const char* STypeInSymbol() const { return stype_in_symbol.data(); } const char* STypeOutSymbol() const { return stype_out_symbol.data(); } @@ -556,19 +524,21 @@ struct SymbolMappingMsg { UnixNanos start_ts; UnixNanos end_ts; }; -static_assert(sizeof(SymbolMappingMsg) == 176, - "SymbolMappingMsg size must match Rust"); -static_assert(alignof(SymbolMappingMsg) == 8, "Must have 8-byte alignment"); +static_assert(sizeof(SymbolMappingMsg) == 176, "SymbolMappingMsg size must match Rust"); +static_assert(alignof(SymbolMappingMsg) == 8, + "SymbolMappingMsg must have 8-byte alignment"); +// A non-error message from the Databento Live Subscription Gateway (LSG). Also used +// for heartbeating. struct SystemMsg { static bool HasRType(RType rtype) { return rtype == RType::System; } UnixNanos IndexTs() const { return hd.ts_event; } + const char* Msg() const { return msg.data(); } bool IsHeartbeat() const { // Check if code is unset - if (static_cast(code) == - std::numeric_limits::max()) { + if (static_cast(code) == std::numeric_limits::max()) { return std::strncmp(msg.data(), "Heartbeat", 9) == 0; } return code == SystemCode::Heartbeat; @@ -579,7 +549,7 @@ struct SystemMsg { SystemCode code; }; static_assert(sizeof(SystemMsg) == 320, "SystemMsg size must match Rust"); -static_assert(alignof(SystemMsg) == 8, "Must have 8-byte alignment"); +static_assert(alignof(SystemMsg) == 8, "SystemMsg must have 8-byte alignment"); inline bool operator==(const RecordHeader& lhs, const RecordHeader& rhs) { return lhs.length == rhs.length && lhs.rtype == rhs.rtype && @@ -591,17 +561,13 @@ inline bool operator!=(const RecordHeader& lhs, const RecordHeader& rhs) { } inline bool operator==(const MboMsg& lhs, const MboMsg& rhs) { - return lhs.hd == rhs.hd && lhs.order_id == rhs.order_id && - lhs.price == rhs.price && lhs.size == rhs.size && - lhs.flags == rhs.flags && lhs.channel_id == rhs.channel_id && - lhs.action == rhs.action && lhs.side == rhs.side && - lhs.ts_recv == rhs.ts_recv && lhs.ts_in_delta == rhs.ts_in_delta && - lhs.sequence == rhs.sequence; + return lhs.hd == rhs.hd && lhs.order_id == rhs.order_id && lhs.price == rhs.price && + lhs.size == rhs.size && lhs.flags == rhs.flags && + lhs.channel_id == rhs.channel_id && lhs.action == rhs.action && + lhs.side == rhs.side && lhs.ts_recv == rhs.ts_recv && + lhs.ts_in_delta == rhs.ts_in_delta && lhs.sequence == rhs.sequence; } -inline bool operator!=(const MboMsg& lhs, const MboMsg& rhs) { - return !(lhs == rhs); -} - +inline bool operator!=(const MboMsg& lhs, const MboMsg& rhs) { return !(lhs == rhs); } inline bool operator==(const BidAskPair& lhs, const BidAskPair& rhs) { return lhs.bid_px == rhs.bid_px && lhs.ask_px == rhs.ask_px && lhs.bid_sz == rhs.bid_sz && lhs.ask_sz == rhs.ask_sz && @@ -610,7 +576,6 @@ inline bool operator==(const BidAskPair& lhs, const BidAskPair& rhs) { inline bool operator!=(const BidAskPair& lhs, const BidAskPair& rhs) { return !(lhs == rhs); } - inline bool operator==(const ConsolidatedBidAskPair& lhs, const ConsolidatedBidAskPair& rhs) { return lhs.bid_px == rhs.bid_px && lhs.ask_px == rhs.ask_px && @@ -621,93 +586,73 @@ inline bool operator!=(const ConsolidatedBidAskPair& lhs, const ConsolidatedBidAskPair& rhs) { return !(lhs == rhs); } - -inline bool operator==(const Mbp1Msg& lhs, const Mbp1Msg& rhs) { +inline bool operator==(const TradeMsg& lhs, const TradeMsg& rhs) { return lhs.hd == rhs.hd && lhs.price == rhs.price && lhs.size == rhs.size && - lhs.action == rhs.action && lhs.side == rhs.side && - lhs.flags == rhs.flags && lhs.depth == rhs.depth && - lhs.ts_recv == rhs.ts_recv && lhs.ts_in_delta == rhs.ts_in_delta && - lhs.sequence == rhs.sequence && lhs.levels == rhs.levels; + lhs.action == rhs.action && lhs.side == rhs.side && lhs.flags == rhs.flags && + lhs.depth == rhs.depth && lhs.ts_recv == rhs.ts_recv && + lhs.ts_in_delta == rhs.ts_in_delta && lhs.sequence == rhs.sequence; } -inline bool operator!=(const Mbp1Msg& lhs, const Mbp1Msg& rhs) { +inline bool operator!=(const TradeMsg& lhs, const TradeMsg& rhs) { return !(lhs == rhs); } - +inline bool operator==(const Mbp1Msg& lhs, const Mbp1Msg& rhs) { + return lhs.hd == rhs.hd && lhs.price == rhs.price && lhs.size == rhs.size && + lhs.action == rhs.action && lhs.side == rhs.side && lhs.flags == rhs.flags && + lhs.depth == rhs.depth && lhs.ts_recv == rhs.ts_recv && + lhs.ts_in_delta == rhs.ts_in_delta && lhs.sequence == rhs.sequence && + lhs.levels == rhs.levels; +} +inline bool operator!=(const Mbp1Msg& lhs, const Mbp1Msg& rhs) { return !(lhs == rhs); } inline bool operator==(const Mbp10Msg& lhs, const Mbp10Msg& rhs) { return lhs.hd == rhs.hd && lhs.price == rhs.price && lhs.size == rhs.size && - lhs.action == rhs.action && lhs.side == rhs.side && - lhs.flags == rhs.flags && lhs.depth == rhs.depth && - lhs.ts_recv == rhs.ts_recv && lhs.ts_in_delta == rhs.ts_in_delta && - lhs.sequence == rhs.sequence && lhs.levels == rhs.levels; + lhs.action == rhs.action && lhs.side == rhs.side && lhs.flags == rhs.flags && + lhs.depth == rhs.depth && lhs.ts_recv == rhs.ts_recv && + lhs.ts_in_delta == rhs.ts_in_delta && lhs.sequence == rhs.sequence && + lhs.levels == rhs.levels; } 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); + return lhs.hd == rhs.hd && lhs.price == rhs.price && lhs.size == rhs.size && + lhs.side == rhs.side && lhs.flags == rhs.flags && lhs.ts_recv == rhs.ts_recv && + lhs.sequence == rhs.sequence && lhs.levels == rhs.levels; } - +inline bool operator!=(const BboMsg& lhs, const BboMsg& rhs) { return !(lhs == rhs); } inline bool operator==(const Cmbp1Msg& lhs, const Cmbp1Msg& rhs) { return lhs.hd == rhs.hd && lhs.price == rhs.price && lhs.size == rhs.size && - lhs.action == rhs.action && lhs.side == rhs.side && - lhs.flags == rhs.flags && lhs.ts_recv == rhs.ts_recv && - lhs.ts_in_delta == rhs.ts_in_delta && lhs.levels == rhs.levels; + lhs.action == rhs.action && lhs.side == rhs.side && lhs.flags == rhs.flags && + lhs.ts_recv == rhs.ts_recv && lhs.ts_in_delta == rhs.ts_in_delta && + lhs.levels == rhs.levels; } inline bool operator!=(const Cmbp1Msg& lhs, const Cmbp1Msg& 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.side == rhs.side && lhs.flags == rhs.flags && - lhs.ts_recv == rhs.ts_recv && lhs.levels == rhs.levels; -} -inline bool operator!=(const CbboMsg& lhs, const CbboMsg& rhs) { - return !(lhs == rhs); -} - -inline bool operator==(const TradeMsg& lhs, const TradeMsg& rhs) { - return lhs.hd == rhs.hd && lhs.price == rhs.price && lhs.size == rhs.size && - lhs.action == rhs.action && lhs.side == rhs.side && - lhs.flags == rhs.flags && lhs.depth == rhs.depth && - lhs.ts_recv == rhs.ts_recv && lhs.ts_in_delta == rhs.ts_in_delta && - lhs.sequence == rhs.sequence; + lhs.side == rhs.side && lhs.flags == rhs.flags && lhs.ts_recv == rhs.ts_recv && + lhs.levels == rhs.levels; } -inline bool operator!=(const TradeMsg& lhs, const TradeMsg& rhs) { - return !(lhs == rhs); -} - +inline bool operator!=(const CbboMsg& lhs, const CbboMsg& rhs) { return !(lhs == rhs); } inline bool operator==(const OhlcvMsg& lhs, const OhlcvMsg& rhs) { return lhs.hd == rhs.hd && lhs.open == rhs.open && lhs.high == rhs.high && - lhs.low == rhs.low && lhs.close == rhs.close && - lhs.volume == rhs.volume; + lhs.low == rhs.low && lhs.close == rhs.close && lhs.volume == rhs.volume; } inline bool operator!=(const OhlcvMsg& lhs, const OhlcvMsg& rhs) { return !(lhs == rhs); } - inline bool operator==(const StatusMsg& lhs, const StatusMsg& rhs) { - return std::tie(lhs.hd, lhs.ts_recv, lhs.action, lhs.reason, - lhs.trading_event, lhs.is_trading, lhs.is_quoting, - lhs.is_short_sell_restricted) == - std::tie(rhs.hd, rhs.ts_recv, rhs.action, rhs.reason, - rhs.trading_event, rhs.is_trading, rhs.is_quoting, - rhs.is_short_sell_restricted); + return lhs.hd == rhs.hd && lhs.ts_recv == rhs.ts_recv && lhs.action == rhs.action && + lhs.reason == rhs.reason && lhs.trading_event == rhs.trading_event && + lhs.is_trading == rhs.is_trading && lhs.is_quoting == rhs.is_quoting && + lhs.is_short_sell_restricted == rhs.is_short_sell_restricted; } inline bool operator!=(const StatusMsg& lhs, const StatusMsg& rhs) { return !(lhs == rhs); } bool operator==(const InstrumentDefMsg& lhs, const InstrumentDefMsg& rhs); -inline bool operator!=(const InstrumentDefMsg& lhs, - const InstrumentDefMsg& rhs) { +inline bool operator!=(const InstrumentDefMsg& lhs, const InstrumentDefMsg& rhs) { return !(lhs == rhs); } @@ -715,19 +660,14 @@ bool operator==(const ImbalanceMsg& lhs, const ImbalanceMsg& rhs); inline bool operator!=(const ImbalanceMsg& lhs, const ImbalanceMsg& 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); + return lhs.hd == rhs.hd && lhs.ts_recv == rhs.ts_recv && lhs.ts_ref == rhs.ts_ref && + lhs.price == rhs.price && lhs.quantity == rhs.quantity && + lhs.sequence == rhs.sequence && lhs.ts_in_delta == rhs.ts_in_delta && + lhs.stat_type == rhs.stat_type && lhs.channel_id == rhs.channel_id && + lhs.update_action == rhs.update_action && lhs.stat_flags == rhs.stat_flags; } -inline bool operator!=(const StatMsg& lhs, const StatMsg& rhs) { - return !(lhs == rhs); -} - +inline bool operator!=(const StatMsg& lhs, const StatMsg& rhs) { return !(lhs == rhs); } inline bool operator==(const ErrorMsg& lhs, const ErrorMsg& rhs) { return lhs.hd == rhs.hd && lhs.err == rhs.err && lhs.code == rhs.code && lhs.is_last == rhs.is_last; @@ -735,24 +675,19 @@ inline bool operator==(const ErrorMsg& lhs, const ErrorMsg& rhs) { inline bool operator!=(const ErrorMsg& lhs, const ErrorMsg& rhs) { return !(lhs == rhs); } - -inline bool operator==(const SystemMsg& lhs, const SystemMsg& rhs) { - return lhs.hd == rhs.hd && lhs.msg == rhs.msg && lhs.code == rhs.code; +inline bool operator==(const SymbolMappingMsg& lhs, const SymbolMappingMsg& rhs) { + return lhs.hd == rhs.hd && lhs.stype_in == rhs.stype_in && + lhs.stype_in_symbol == rhs.stype_in_symbol && lhs.stype_out == rhs.stype_out && + lhs.stype_out_symbol == rhs.stype_out_symbol && lhs.start_ts == rhs.start_ts && + lhs.end_ts == rhs.end_ts; } -inline bool operator!=(const SystemMsg& lhs, const SystemMsg& rhs) { +inline bool operator!=(const SymbolMappingMsg& lhs, const SymbolMappingMsg& rhs) { return !(lhs == rhs); } - -inline bool operator==(const SymbolMappingMsg& lhs, - const SymbolMappingMsg& rhs) { - return lhs.hd == rhs.hd && lhs.stype_in == rhs.stype_in && - lhs.stype_in_symbol == rhs.stype_in_symbol && - lhs.stype_out == rhs.stype_out && - lhs.stype_out_symbol == rhs.stype_out_symbol && - lhs.start_ts == rhs.start_ts && lhs.end_ts == rhs.end_ts; +inline bool operator==(const SystemMsg& lhs, const SystemMsg& rhs) { + return lhs.hd == rhs.hd && lhs.msg == rhs.msg && lhs.code == rhs.code; } -inline bool operator!=(const SymbolMappingMsg& lhs, - const SymbolMappingMsg& rhs) { +inline bool operator!=(const SystemMsg& lhs, const SystemMsg& rhs) { return !(lhs == rhs); } @@ -760,44 +695,44 @@ std::string ToString(const RecordHeader& header); std::ostream& operator<<(std::ostream& stream, const RecordHeader& header); std::string ToString(const Record& header); std::ostream& operator<<(std::ostream& stream, const Record& header); + std::string ToString(const MboMsg& mbo_msg); std::ostream& operator<<(std::ostream& stream, const MboMsg& mbo_msg); -std::string ToString(const BidAskPair& ba_pair); -std::ostream& operator<<(std::ostream& stream, const BidAskPair& ba_pair); -std::string ToString(const ConsolidatedBidAskPair& ba_pair); +std::string ToString(const BidAskPair& bid_ask_pair); +std::ostream& operator<<(std::ostream& stream, const BidAskPair& bid_ask_pair); +std::string ToString(const ConsolidatedBidAskPair& consolidated_bid_ask_pair); std::ostream& operator<<(std::ostream& stream, - const ConsolidatedBidAskPair& ba_pair); -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); + const ConsolidatedBidAskPair& consolidated_bid_ask_pair); +std::string ToString(const TradeMsg& trade_msg); +std::ostream& operator<<(std::ostream& stream, const TradeMsg& trade_msg); +std::string ToString(const Mbp1Msg& mbp1_msg); +std::ostream& operator<<(std::ostream& stream, const Mbp1Msg& mbp1_msg); +std::string ToString(const Mbp10Msg& mbp10_msg); +std::ostream& operator<<(std::ostream& stream, const Mbp10Msg& mbp10_msg); std::string ToString(const BboMsg& bbo_msg); std::ostream& operator<<(std::ostream& stream, const BboMsg& bbo_msg); std::string ToString(const Cmbp1Msg& cmbp1_msg); std::ostream& operator<<(std::ostream& stream, const Cmbp1Msg& cmbp1_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); std::ostream& operator<<(std::ostream& stream, const OhlcvMsg& ohlcv_msg); std::string ToString(const StatusMsg& status_msg); std::ostream& operator<<(std::ostream& stream, const StatusMsg& status_msg); -std::string ToString(const InstrumentDefMsg& instr_def_msg); +std::string ToString(const InstrumentDefMsg& instrument_def_msg); std::ostream& operator<<(std::ostream& stream, - const InstrumentDefMsg& instr_def_msg); + const InstrumentDefMsg& instrument_def_msg); std::string ToString(const ImbalanceMsg& imbalance_msg); -std::ostream& operator<<(std::ostream& stream, - const ImbalanceMsg& imbalance_msg); +std::ostream& operator<<(std::ostream& stream, const ImbalanceMsg& imbalance_msg); std::string ToString(const StatMsg& stat_msg); std::ostream& operator<<(std::ostream& stream, const StatMsg& stat_msg); -std::string ToString(const ErrorMsg& err_msg); -std::ostream& operator<<(std::ostream& stream, const ErrorMsg& err_msg); -std::string ToString(const SystemMsg& system_msg); -std::ostream& operator<<(std::ostream& stream, const SystemMsg& system_msg); +std::string ToString(const ErrorMsg& error_msg); +std::ostream& operator<<(std::ostream& stream, const ErrorMsg& error_msg); std::string ToString(const SymbolMappingMsg& symbol_mapping_msg); std::ostream& operator<<(std::ostream& stream, const SymbolMappingMsg& symbol_mapping_msg); +std::string ToString(const SystemMsg& system_msg); +std::ostream& operator<<(std::ostream& stream, const SystemMsg& system_msg); // The length in bytes of the largest record type. static constexpr std::size_t kMaxRecordLen = 520 + 8; diff --git a/include/databento/symbol_map.hpp b/include/databento/symbol_map.hpp index 30c1b63..b349484 100644 --- a/include/databento/symbol_map.hpp +++ b/include/databento/symbol_map.hpp @@ -36,22 +36,19 @@ class TsSymbolMap { } template Store::const_iterator Find(const R& rec) const { - static_assert( - has_header::value, - "must be a DBN record struct with an `hd` RecordHeader field"); + static_assert(has_header::value, + "must be a DBN record struct with an `hd` RecordHeader field"); date::year_month_day index_date{ date::sys_days{date::floor(rec.IndexTs())}}; return map_.find(std::make_pair(index_date, rec.hd.instrument_id)); } - const std::string& At(date::year_month_day date, - std::uint32_t instrument_id) const { + const std::string& At(date::year_month_day date, std::uint32_t instrument_id) const { return *map_.at(std::make_pair(date, instrument_id)); } template const std::string& At(const R& rec) const { - static_assert( - has_header::value, - "must be a DBN record struct with an `hd` RecordHeader field"); + static_assert(has_header::value, + "must be a DBN record struct with an `hd` RecordHeader field"); date::year_month_day index_date{ date::sys_days{date::floor(rec.IndexTs())}}; return *map_.at(std::make_pair(index_date, rec.hd.instrument_id)); @@ -87,9 +84,8 @@ class PitSymbolMap { } template const std::string& At(const R& rec) const { - static_assert( - has_header::value, - "must be a DBN record struct with an `hd` RecordHeader field"); + static_assert(has_header::value, + "must be a DBN record struct with an `hd` RecordHeader field"); return map_.at(rec.hd.instrument_id); } const std::string& At(const Record& rec) const { diff --git a/include/databento/symbology.hpp b/include/databento/symbology.hpp index 93234cd..5d5f00f 100644 --- a/include/databento/symbology.hpp +++ b/include/databento/symbology.hpp @@ -28,13 +28,11 @@ struct SymbologyResolution { // // Throws InvalidArgumentError if symbols is empty or the iterator range is // empty. -std::string JoinSymbolStrings( - const std::string& method_name, - std::vector::const_iterator symbols_begin, - std::vector::const_iterator symbols_end); +std::string JoinSymbolStrings(const std::string& method_name, + std::vector::const_iterator symbols_begin, + std::vector::const_iterator symbols_end); std::string JoinSymbolStrings(const std::string& method_name, const std::vector& symbols); std::string ToString(const SymbologyResolution& sym_res); -std::ostream& operator<<(std::ostream& stream, - const SymbologyResolution& sym_res); +std::ostream& operator<<(std::ostream& stream, const SymbologyResolution& sym_res); } // namespace databento diff --git a/include/databento/v1.hpp b/include/databento/v1.hpp index 6c44b61..a67b13d 100644 --- a/include/databento/v1.hpp +++ b/include/databento/v1.hpp @@ -1,5 +1,10 @@ #pragma once +#include +#include +#include +#include + #include "databento/datetime.hpp" // UnixNanos #include "databento/enums.hpp" #include "databento/record.hpp" @@ -14,8 +19,7 @@ namespace v1 { static constexpr std::uint8_t kDbnVersion = 1; static constexpr std::size_t kSymbolCstrLen = 22; static constexpr std::size_t kAssetCstrLen = 7; -static constexpr auto kUndefStatQuantity = - std::numeric_limits::max(); +static constexpr auto kUndefStatQuantity = std::numeric_limits::max(); using MboMsg = databento::MboMsg; using TradeMsg = databento::TradeMsg; @@ -34,13 +38,40 @@ using OhlcvMsg = databento::OhlcvMsg; using StatusMsg = databento::StatusMsg; using ImbalanceMsg = databento::ImbalanceMsg; +// An error message from the Databento Live Subscription Gateway (LSG) in DBN version 1. +struct ErrorMsg { + static bool HasRType(RType rtype) { return rtype == RType::Error; } + + UnixNanos IndexTs() const { return hd.ts_event; } + + databento::ErrorMsg ToV2() const; + + template + T Upgrade() const; + + const char* Err() const { return err.data(); } + + RecordHeader hd; + std::array err; +}; +static_assert(sizeof(ErrorMsg) == 80, "ErrorMsg size must match Rust"); +static_assert(alignof(ErrorMsg) == 8, "ErrorMsg must have 8-byte alignment"); +template <> +databento::ErrorMsg ErrorMsg::Upgrade() const; + +// A definition of an instrument in DBN version 1. The record of the definition schema. struct InstrumentDefMsg { static bool HasRType(RType rtype) { return rtype == RType::InstrumentDef; } + UnixNanos IndexTs() const { return ts_recv; } + v2::InstrumentDefMsg ToV2() const; + databento::InstrumentDefMsg ToV3() const; + template T Upgrade() const; + const char* Currency() const { return currency.data(); } const char* SettlCurrency() const { return settl_currency.data(); } const char* SecSubType() const { return secsubtype.data(); } @@ -52,9 +83,7 @@ struct InstrumentDefMsg { 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* StrikePriceCurrency() const { return strike_price_currency.data(); } RecordHeader hd; UnixNanos ts_recv; @@ -80,11 +109,11 @@ struct InstrumentDefMsg { std::int32_t min_lot_size_block; std::int32_t min_lot_size_round_lot; std::uint32_t min_trade_vol; - std::array _reserved2; + std::array _reserved2{}; std::int32_t contract_multiplier; std::int32_t decay_quantity; std::int32_t original_contract_size; - std::array _reserved3; + std::array _reserved3{}; std::uint16_t trading_reference_date; std::int16_t appl_id; std::uint16_t maturity_year; @@ -103,9 +132,9 @@ struct InstrumentDefMsg { std::array underlying; std::array strike_price_currency; InstrumentClass instrument_class; - std::array _reserved4; + std::array _reserved4{}; std::int64_t strike_price; - std::array _reserved5; + std::array _reserved5{}; MatchAlgorithm match_algorithm; std::uint8_t md_security_trading_status; std::uint8_t main_fraction; @@ -121,26 +150,29 @@ struct InstrumentDefMsg { std::int8_t contract_multiplier_unit; std::int8_t flow_schedule_type; std::uint8_t tick_rule; - // padding for alignment - std::array dummy; + std::array _dummy{}; }; +static_assert(sizeof(InstrumentDefMsg) == 360, "InstrumentDefMsg size must match Rust"); +static_assert(alignof(InstrumentDefMsg) == 8, + "InstrumentDefMsg must have 8-byte alignment"); + template <> -v2::InstrumentDefMsg InstrumentDefMsg::Upgrade() const; +databento::v2::InstrumentDefMsg InstrumentDefMsg::Upgrade() const; template <> databento::InstrumentDefMsg InstrumentDefMsg::Upgrade() const; -static_assert(sizeof(InstrumentDefMsg) == 360, "Size must match Rust"); -static_assert(alignof(InstrumentDefMsg) == 8, "Must have 8-byte alignment"); -/// A statistics message. A catchall for various data disseminated by -/// publishers. The `stat_type` indicates the statistic contained in the -/// message. +// A statistics message in DBN versions 1 and 2. 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; } + databento::StatMsg ToV3() const; + template T Upgrade() const; - UnixNanos IndexTs() const { return ts_recv; } RecordHeader hd; UnixNanos ts_recv; @@ -153,125 +185,117 @@ struct StatMsg { std::uint16_t channel_id; StatUpdateAction update_action; std::uint8_t stat_flags; - std::array reserved; + std::array _reserved{}; }; -template <> -databento::StatMsg StatMsg::Upgrade() const; static_assert(sizeof(StatMsg) == 64, "StatMsg size must match Rust"); -static_assert(alignof(StatMsg) == 8, "Must have 8-byte alignment"); - -// An error message from the Live Subscription Gateway (LSG). This will never -// be present in historical data. -struct ErrorMsg { - static bool HasRType(RType rtype) { return rtype == RType::Error; } - - databento::ErrorMsg ToV2() const; - template - T Upgrade() const; - UnixNanos IndexTs() const { return hd.ts_event; } - const char* Err() const { return err.data(); } - - RecordHeader hd; - std::array err; -}; +static_assert(alignof(StatMsg) == 8, "StatMsg must have 8-byte alignment"); template <> -ErrorMsg ErrorMsg::Upgrade() const; -static_assert(sizeof(ErrorMsg) == 80, "ErrorMsg size must match Rust"); -static_assert(alignof(ErrorMsg) == 8, "Must have 8-byte alignment"); +databento::StatMsg StatMsg::Upgrade() const; -/// A symbol mapping message. +// A symbol mapping message from the live API in DBN version 1. struct SymbolMappingMsg { static bool HasRType(RType rtype) { return rtype == RType::SymbolMapping; } + UnixNanos IndexTs() const { return hd.ts_event; } + databento::SymbolMappingMsg ToV2() const; + template T Upgrade() const; + const char* STypeInSymbol() const { return stype_in_symbol.data(); } const char* STypeOutSymbol() const { return stype_out_symbol.data(); } RecordHeader hd; std::array stype_in_symbol; std::array stype_out_symbol; - // padding for alignment - std::array dummy; + std::array _dummy{}; UnixNanos start_ts; UnixNanos end_ts; }; +static_assert(sizeof(SymbolMappingMsg) == 80, "SymbolMappingMsg size must match Rust"); +static_assert(alignof(SymbolMappingMsg) == 8, + "SymbolMappingMsg must have 8-byte alignment"); template <> -SymbolMappingMsg SymbolMappingMsg::Upgrade() const; -static_assert(sizeof(SymbolMappingMsg) == 80, "Size must match Rust"); -static_assert(alignof(SymbolMappingMsg) == 8, "Must have 8-byte alignment"); +databento::SymbolMappingMsg SymbolMappingMsg::Upgrade() const; +// A non-error message from the Databento Live Subscription Gateway (LSG) in DBN +// version 1. +// Also used for heartbeating. struct SystemMsg { static bool HasRType(RType rtype) { return rtype == RType::System; } + UnixNanos IndexTs() const { return hd.ts_event; } + databento::SystemMsg ToV2() const; + template T Upgrade() const; - UnixNanos IndexTs() const { return hd.ts_event; } + const char* Msg() const { return msg.data(); } - bool IsHeartbeat() const { - return std::strncmp(msg.data(), "Heartbeat", 9) == 0; - } + bool IsHeartbeat() const { return std::strncmp(msg.data(), "Heartbeat", 9) == 0; } RecordHeader hd; std::array msg; }; -template <> -SystemMsg SystemMsg::Upgrade() const; static_assert(sizeof(SystemMsg) == 80, "SystemMsg size must match Rust"); -static_assert(alignof(SystemMsg) == 8, "Must have 8-byte alignment"); +static_assert(alignof(SystemMsg) == 8, "SystemMsg must have 8-byte alignment"); +template <> +databento::SystemMsg SystemMsg::Upgrade() const; -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); -} inline bool operator==(const ErrorMsg& lhs, const ErrorMsg& rhs) { - return std::tie(lhs.hd, lhs.err) == std::tie(rhs.hd, rhs.err); + return lhs.hd == rhs.hd && lhs.err == rhs.err; } inline bool operator!=(const ErrorMsg& lhs, const ErrorMsg& rhs) { return !(lhs == rhs); } -inline bool operator==(const SymbolMappingMsg& lhs, - const SymbolMappingMsg& rhs) { - return std::tie(lhs.hd, lhs.stype_in_symbol, lhs.stype_out_symbol, - lhs.start_ts, lhs.end_ts) == - std::tie(rhs.hd, rhs.stype_in_symbol, rhs.stype_out_symbol, - rhs.start_ts, rhs.end_ts); + +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 lhs.hd == rhs.hd && lhs.ts_recv == rhs.ts_recv && lhs.ts_ref == rhs.ts_ref && + lhs.price == rhs.price && lhs.quantity == rhs.quantity && + lhs.sequence == rhs.sequence && lhs.ts_in_delta == rhs.ts_in_delta && + lhs.stat_type == rhs.stat_type && lhs.channel_id == rhs.channel_id && + lhs.update_action == rhs.update_action && lhs.stat_flags == rhs.stat_flags; } -inline bool operator!=(const SymbolMappingMsg& lhs, - const SymbolMappingMsg& rhs) { +inline bool operator!=(const StatMsg& lhs, const StatMsg& rhs) { return !(lhs == rhs); } + +inline bool operator==(const SymbolMappingMsg& lhs, const SymbolMappingMsg& rhs) { + return lhs.hd == rhs.hd && lhs.stype_in_symbol == rhs.stype_in_symbol && + lhs.stype_out_symbol == rhs.stype_out_symbol && lhs.start_ts == rhs.start_ts && + lhs.end_ts == rhs.end_ts; +} +inline bool operator!=(const SymbolMappingMsg& lhs, const SymbolMappingMsg& rhs) { return !(lhs == rhs); } + inline bool operator==(const SystemMsg& lhs, const SystemMsg& rhs) { - return std::tie(lhs.hd, lhs.msg) == std::tie(rhs.hd, rhs.msg); + return lhs.hd == rhs.hd && lhs.msg == rhs.msg; } inline bool operator!=(const SystemMsg& lhs, const SystemMsg& rhs) { return !(lhs == rhs); } -std::string ToString(const InstrumentDefMsg& instr_def_msg); + +std::string ToString(const ErrorMsg& error_msg); +std::ostream& operator<<(std::ostream& stream, const ErrorMsg& error_msg); + +std::string ToString(const InstrumentDefMsg& instrument_def_msg); std::ostream& operator<<(std::ostream& stream, - const InstrumentDefMsg& instr_def_msg); + const InstrumentDefMsg& instrument_def_msg); + std::string ToString(const StatMsg& stat_msg); std::ostream& operator<<(std::ostream& stream, const StatMsg& stat_msg); -std::string ToString(const ErrorMsg& err_msg); -std::ostream& operator<<(std::ostream& stream, const ErrorMsg& err_msg); + std::string ToString(const SymbolMappingMsg& symbol_mapping_msg); std::ostream& operator<<(std::ostream& stream, const SymbolMappingMsg& symbol_mapping_msg); -std::string ToString(const SystemMsg& sys_msg); -std::ostream& operator<<(std::ostream& stream, const SystemMsg& sys_msg); + +std::string ToString(const SystemMsg& system_msg); +std::ostream& operator<<(std::ostream& stream, const SystemMsg& system_msg); + } // namespace v1 } // namespace databento diff --git a/include/databento/v2.hpp b/include/databento/v2.hpp index 408e5a2..a87e4b0 100644 --- a/include/databento/v2.hpp +++ b/include/databento/v2.hpp @@ -31,14 +31,15 @@ using ErrorMsg = databento::ErrorMsg; using SymbolMappingMsg = databento::SymbolMappingMsg; using SystemMsg = databento::SystemMsg; -// An instrument definition message in DBN version 2. +// A definition of an instrument in DBN version 2. The record of the definition schema. struct InstrumentDefMsg { static bool HasRType(RType rtype) { return rtype == RType::InstrumentDef; } + UnixNanos IndexTs() const { return ts_recv; } + databento::InstrumentDefMsg ToV3() const; template T Upgrade() const; - UnixNanos IndexTs() const { return ts_recv; } const char* Currency() const { return currency.data(); } const char* SettlCurrency() const { return settl_currency.data(); } @@ -51,9 +52,7 @@ struct InstrumentDefMsg { 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* StrikePriceCurrency() const { return strike_price_currency.data(); } RecordHeader hd; UnixNanos ts_recv; @@ -116,21 +115,21 @@ struct InstrumentDefMsg { std::int8_t contract_multiplier_unit; std::int8_t flow_schedule_type; std::uint8_t tick_rule; - std::array reserved; + std::array _reserved{}; }; +static_assert(sizeof(InstrumentDefMsg) == 400, "InstrumentDefMsg size must match Rust"); +static_assert(alignof(InstrumentDefMsg) == 8, + "InstrumentDefMsg must have 8-byte alignment"); template <> databento::InstrumentDefMsg InstrumentDefMsg::Upgrade() const; -static_assert(sizeof(InstrumentDefMsg) == 400, - "InstrumentDefMsg size must match Rust"); -static_assert(alignof(InstrumentDefMsg) == 8, "Must have 8-byte alignment"); bool operator==(const InstrumentDefMsg& lhs, const InstrumentDefMsg& rhs); -inline 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::string ToString(const InstrumentDefMsg& instrument_def_msg); std::ostream& operator<<(std::ostream& stream, - const InstrumentDefMsg& instr_def_msg); + const InstrumentDefMsg& instrument_def_msg); + } // namespace databento::v2 diff --git a/include/databento/v3.hpp b/include/databento/v3.hpp index b68961d..9fd49e6 100644 --- a/include/databento/v3.hpp +++ b/include/databento/v3.hpp @@ -10,8 +10,7 @@ namespace databento::v3 { static constexpr std::uint8_t kDbnVersion = 3; static constexpr std::size_t kSymbolCstrLen = databento::kSymbolCstrLen; static constexpr std::size_t kAssetCstrLen = databento::kAssetCstrLen; -static constexpr std::int64_t kUndefStatQuantity = - databento::kUndefStatQuantity; +static constexpr std::int64_t kUndefStatQuantity = databento::kUndefStatQuantity; using MboMsg = databento::MboMsg; using TradeMsg = databento::TradeMsg; diff --git a/pkg/PKGBUILD b/pkg/PKGBUILD index ea2f96a..c378963 100644 --- a/pkg/PKGBUILD +++ b/pkg/PKGBUILD @@ -1,7 +1,7 @@ # Maintainer: Databento _pkgname=databento-cpp pkgname=databento-cpp-git -pkgver=0.39.1 +pkgver=0.40.0 pkgrel=1 pkgdesc="Official C++ client for Databento" arch=('any') diff --git a/src/batch.cpp b/src/batch.cpp index 6dd37a0..b3c9dbe 100644 --- a/src/batch.cpp +++ b/src/batch.cpp @@ -5,9 +5,7 @@ #include "stream_op_helper.hpp" namespace databento { -std::string ToString(const BatchJob& batch_job) { - return MakeString(batch_job); -} +std::string ToString(const BatchJob& batch_job) { return MakeString(batch_job); } std::ostream& operator<<(std::ostream& stream, const BatchJob& batch_job) { std::ostringstream symbol_stream; @@ -24,8 +22,7 @@ std::ostream& operator<<(std::ostream& stream, const BatchJob& batch_job) { .AddField("bill_id", batch_job.bill_id) .AddField("cost_usd", batch_job.cost_usd) .AddField("dataset", batch_job.dataset) - .AddField("symbols", - static_cast(symbol_helper.Finish())) + .AddField("symbols", static_cast(symbol_helper.Finish())) .AddField("stype_in", batch_job.stype_in) .AddField("stype_out", batch_job.stype_out) .AddField("schema", batch_job.schema) @@ -54,9 +51,7 @@ std::ostream& operator<<(std::ostream& stream, const BatchJob& batch_job) { .Finish(); } -std::string ToString(const BatchFileDesc& file_desc) { - return MakeString(file_desc); -} +std::string ToString(const BatchFileDesc& file_desc) { return MakeString(file_desc); } std::ostream& operator<<(std::ostream& stream, const BatchFileDesc& file_desc) { return StreamOpBuilder{stream} diff --git a/src/datetime.cpp b/src/datetime.cpp index 4319db2..36b7299 100644 --- a/src/datetime.cpp +++ b/src/datetime.cpp @@ -18,9 +18,9 @@ std::string ToIso8601(UnixNanos unix_nanos) { return "UNDEF_TIMESTAMP"; } std::array buf{}; - const std::time_t time = std::chrono::duration_cast( - unix_nanos.time_since_epoch()) - .count(); + const std::time_t time = + std::chrono::duration_cast(unix_nanos.time_since_epoch()) + .count(); std::tm tm = {}; #ifdef _WIN32 if (::gmtime_s(&tm, &time) != 0) { @@ -33,11 +33,10 @@ std::string ToIso8601(UnixNanos unix_nanos) { return ToString(unix_nanos); } #endif - const auto nanos = std::chrono::nanoseconds{ - unix_nanos.time_since_epoch() % - std::chrono::nanoseconds{std::chrono::seconds{1}}}; - const size_t count = - std::strftime(buf.data(), sizeof(buf), "%Y-%m-%dT%H:%M:%S", &tm); + const auto nanos = + std::chrono::nanoseconds{unix_nanos.time_since_epoch() % + std::chrono::nanoseconds{std::chrono::seconds{1}}}; + const size_t count = std::strftime(buf.data(), sizeof(buf), "%Y-%m-%dT%H:%M:%S", &tm); std::ostringstream time_ss; time_ss.write(buf.data(), static_cast(count)); time_ss << '.' << std::setw(9) << std::setfill('0') << nanos.count() << 'Z'; diff --git a/src/dbn.cpp b/src/dbn.cpp index 85873fe..92757ae 100644 --- a/src/dbn.cpp +++ b/src/dbn.cpp @@ -19,8 +19,7 @@ void Metadata::Upgrade(VersionUpgradePolicy upgrade_policy) { if (upgrade_policy == VersionUpgradePolicy::UpgradeToV2 && version < 2) { version = 2; symbol_cstr_len = kSymbolCstrLen; - } else if (upgrade_policy == VersionUpgradePolicy::UpgradeToV3 && - version < 3) { + } else if (upgrade_policy == VersionUpgradePolicy::UpgradeToV3 && version < 3) { version = kDbnVersion; symbol_cstr_len = kSymbolCstrLen; } @@ -45,10 +44,10 @@ std::ostream& operator<<(std::ostream& stream, const Metadata& metadata) { // format symbols, partial, and not_found constexpr auto kVecCount = 3; - constexpr std::array Metadata::*, kVecCount> - kStrVecs{&Metadata::symbols, &Metadata::partial, &Metadata::not_found}; - constexpr std::array kStrVecNames{ - "symbols", "partial", "not_found"}; + constexpr std::array Metadata::*, kVecCount> kStrVecs{ + &Metadata::symbols, &Metadata::partial, &Metadata::not_found}; + constexpr std::array kStrVecNames{"symbols", "partial", + "not_found"}; for (std::size_t i = 0; i < kVecCount; ++i) { std::ostringstream vec_stream; auto vec_helper = StreamOpBuilder{vec_stream}.SetSpacer(" ").Build(); @@ -67,14 +66,11 @@ std::ostream& operator<<(std::ostream& stream, const Metadata& metadata) { mappings_helper.AddItem(mapping); } return helper - .AddField("mappings", - static_cast(mappings_helper.Finish())) + .AddField("mappings", static_cast(mappings_helper.Finish())) .Finish(); } -std::string ToString(const SymbolMapping& mapping) { - return MakeString(mapping); -} +std::string ToString(const SymbolMapping& mapping) { return MakeString(mapping); } std::ostream& operator<<(std::ostream& stream, const SymbolMapping& mapping) { std::ostringstream intervals; auto intervals_helper = StreamOpBuilder{intervals}.SetSpacer(" ").Build(); @@ -91,11 +87,8 @@ std::ostream& operator<<(std::ostream& stream, const SymbolMapping& mapping) { .Finish(); } -std::string ToString(const MappingInterval& interval) { - return MakeString(interval); -} -std::ostream& operator<<(std::ostream& stream, - const MappingInterval& interval) { +std::string ToString(const MappingInterval& interval) { return MakeString(interval); } +std::ostream& operator<<(std::ostream& stream, const MappingInterval& interval) { return StreamOpBuilder{stream} .SetSpacer(" ") .SetTypeName("MappingInterval") diff --git a/src/dbn_constants.hpp b/src/dbn_constants.hpp index 059d73d..176199d 100644 --- a/src/dbn_constants.hpp +++ b/src/dbn_constants.hpp @@ -15,6 +15,5 @@ constexpr std::size_t kMetadataReservedLen = 53; constexpr std::size_t kMetadataReservedLenV1 = 47; constexpr std::uint16_t kNullSchema = std::numeric_limits::max(); constexpr std::uint8_t kNullSType = std::numeric_limits::max(); -constexpr std::uint64_t kNullRecordCount = - std::numeric_limits::max(); +constexpr std::uint64_t kNullRecordCount = std::numeric_limits::max(); } // namespace databento diff --git a/src/dbn_decoder.cpp b/src/dbn_decoder.cpp index 2649f48..ee91f99 100644 --- a/src/dbn_decoder.cpp +++ b/src/dbn_decoder.cpp @@ -65,23 +65,19 @@ date::year_month_day DecodeIso8601Date(std::uint32_t yyyymmdd_int) { } // namespace DbnDecoder::DbnDecoder(ILogReceiver* log_receiver, InFileStream file_stream) - : DbnDecoder(log_receiver, - std::make_unique(std::move(file_stream))) {} + : DbnDecoder(log_receiver, std::make_unique(std::move(file_stream))) { +} -DbnDecoder::DbnDecoder(ILogReceiver* log_receiver, - std::unique_ptr input) - : DbnDecoder(log_receiver, std::move(input), - VersionUpgradePolicy::UpgradeToV3) {} +DbnDecoder::DbnDecoder(ILogReceiver* log_receiver, std::unique_ptr input) + : DbnDecoder(log_receiver, std::move(input), VersionUpgradePolicy::UpgradeToV3) {} -DbnDecoder::DbnDecoder(ILogReceiver* log_receiver, - std::unique_ptr input, +DbnDecoder::DbnDecoder(ILogReceiver* log_receiver, std::unique_ptr input, VersionUpgradePolicy upgrade_policy) : log_receiver_{log_receiver}, upgrade_policy_{upgrade_policy}, input_{std::move(input)} { if (DetectCompression()) { - input_ = - std::make_unique(std::move(input_), buffer_); + input_ = std::make_unique(std::move(input_), buffer_); input_->ReadExact(buffer_.WriteBegin(), kMagicSize); buffer_.Fill(kMagicSize); const auto* buf_ptr = buffer_.ReadBegin(); @@ -108,16 +104,15 @@ std::pair DbnDecoder::DecodeMetadataVersionAndSize( return {version, static_cast(frame_size)}; } -databento::Metadata DbnDecoder::DecodeMetadataFields( - std::uint8_t version, const std::byte* buffer, - const std::byte* buffer_end) { +databento::Metadata DbnDecoder::DecodeMetadataFields(std::uint8_t version, + const std::byte* buffer, + const std::byte* buffer_end) { Metadata res; res.version = version; if (res.version > kDbnVersion) { - throw DbnResponseError{ - "Can't decode newer version of DBN. Decoder version is " + - std::to_string(kDbnVersion) + ", input version is " + - std::to_string(res.version)}; + throw DbnResponseError{"Can't decode newer version of DBN. Decoder version is " + + std::to_string(kDbnVersion) + ", input version is " + + std::to_string(res.version)}; } res.dataset = Consume(buffer, kDatasetCstrLen, "dataset"); const auto raw_schema = Consume(buffer); @@ -126,8 +121,7 @@ databento::Metadata DbnDecoder::DecodeMetadataFields( } else { res.schema = {static_cast(raw_schema)}; } - res.start = - UnixNanos{std::chrono::nanoseconds{Consume(buffer)}}; + res.start = UnixNanos{std::chrono::nanoseconds{Consume(buffer)}}; res.end = UnixNanos{std::chrono::nanoseconds{Consume(buffer)}}; res.limit = Consume(buffer); if (version == 1) { @@ -143,8 +137,7 @@ databento::Metadata DbnDecoder::DecodeMetadataFields( res.stype_out = static_cast(Consume(buffer)); res.ts_out = static_cast(Consume(buffer)); if (version > 1) { - res.symbol_cstr_len = - static_cast(Consume(buffer)); + res.symbol_cstr_len = static_cast(Consume(buffer)); } else { res.symbol_cstr_len = kSymbolCstrLenV1; } @@ -157,8 +150,7 @@ databento::Metadata DbnDecoder::DecodeMetadataFields( const auto schema_definition_length = Consume(buffer); if (schema_definition_length != 0) { - throw DbnResponseError{ - "This version of dbn can't parse schema definitions"}; + throw DbnResponseError{"This version of dbn can't parse schema definitions"}; } res.symbols = DbnDecoder::DecodeRepeatedSymbol(res.symbol_cstr_len, buffer, buffer_end); @@ -184,8 +176,8 @@ databento::Metadata DbnDecoder::DecodeMetadata() { buffer_.Reserve(size); input_->ReadExact(buffer_.WriteBegin(), size); buffer_.Fill(size); - auto metadata = DbnDecoder::DecodeMetadataFields( - version_, buffer_.ReadBegin(), buffer_.ReadEnd()); + auto metadata = DbnDecoder::DecodeMetadataFields(version_, buffer_.ReadBegin(), + buffer_.ReadEnd()); buffer_.Consume(size); // Metadata may leave buffer misaligned. Shift records to ensure 8-byte // alignment @@ -211,8 +203,7 @@ databento::Record UpgradeRecord( const auto& orig = rec.Get(); const U upgraded = orig.template Upgrade(); const auto upgraded_ptr = reinterpret_cast(&upgraded); - std::copy(upgraded_ptr, upgraded_ptr + upgraded.hd.Size(), - compat_buffer->data()); + std::copy(upgraded_ptr, upgraded_ptr + upgraded.hd.Size(), compat_buffer->data()); } return databento::Record{ reinterpret_cast(compat_buffer->data())}; @@ -233,54 +224,46 @@ databento::Record DbnDecoder::DecodeRecordCompat( ts_out, compat_buffer, rec); } case RType::Error: { - return UpgradeRecord(ts_out, compat_buffer, - rec); + return UpgradeRecord(ts_out, compat_buffer, rec); } case RType::System: { - return UpgradeRecord(ts_out, - compat_buffer, rec); + return UpgradeRecord(ts_out, compat_buffer, rec); } default: { break; } } - } else if (version == 1 && - upgrade_policy == VersionUpgradePolicy::UpgradeToV3) { + } else if (version == 1 && upgrade_policy == VersionUpgradePolicy::UpgradeToV3) { switch (rec.RType()) { case RType::InstrumentDef: { return UpgradeRecord( ts_out, compat_buffer, rec); } case RType::Statistics: { - return UpgradeRecord(ts_out, compat_buffer, - rec); + return UpgradeRecord(ts_out, compat_buffer, rec); } case RType::SymbolMapping: { return UpgradeRecord( ts_out, compat_buffer, rec); } case RType::Error: { - return UpgradeRecord(ts_out, compat_buffer, - rec); + return UpgradeRecord(ts_out, compat_buffer, rec); } case RType::System: { - return UpgradeRecord(ts_out, - compat_buffer, rec); + return UpgradeRecord(ts_out, compat_buffer, rec); } default: { break; } } - } else if (version == 2 && - upgrade_policy == VersionUpgradePolicy::UpgradeToV3) { + } else if (version == 2 && upgrade_policy == VersionUpgradePolicy::UpgradeToV3) { switch (rec.RType()) { case RType::InstrumentDef: { return UpgradeRecord( ts_out, compat_buffer, rec); } case RType::Statistics: { - return UpgradeRecord(ts_out, compat_buffer, - rec); + return UpgradeRecord(ts_out, compat_buffer, rec); } default: { break; @@ -302,18 +285,17 @@ const databento::Record* DbnDecoder::DecodeRecord() { while (buffer_.ReadCapacity() < BufferRecordHeader()->Size()) { if (FillBuffer() == 0) { if (buffer_.ReadCapacity() > 0) { - log_receiver_->Receive( - LogLevel::Warning, - "Unexpected partial record remaining in stream: " + - std::to_string(buffer_.ReadCapacity()) + " bytes"); + log_receiver_->Receive(LogLevel::Warning, + "Unexpected partial record remaining in stream: " + + std::to_string(buffer_.ReadCapacity()) + " bytes"); } return nullptr; } } current_record_ = Record{BufferRecordHeader()}; buffer_.ConsumeNoShift(current_record_.Size()); - current_record_ = DbnDecoder::DecodeRecordCompat( - version_, upgrade_policy_, ts_out_, &compat_buffer_, current_record_); + current_record_ = DbnDecoder::DecodeRecordCompat(version_, upgrade_policy_, ts_out_, + &compat_buffer_, current_record_); return ¤t_record_; } @@ -365,14 +347,11 @@ std::vector DbnDecoder::DecodeRepeatedSymbol( std::size_t symbol_cstr_len, const std::byte*& read_buf, const std::byte* read_buf_end) { if (read_buf + sizeof(std::uint32_t) > read_buf_end) { - throw DbnResponseError{ - "Unexpected end of metadata buffer while parsing symbol"}; + throw DbnResponseError{"Unexpected end of metadata buffer while parsing symbol"}; } const auto count = std::size_t{Consume(read_buf)}; - if (read_buf + static_cast(count * symbol_cstr_len) > - read_buf_end) { - throw DbnResponseError{ - "Unexpected end of metadata buffer while parsing symbol"}; + if (read_buf + static_cast(count * symbol_cstr_len) > read_buf_end) { + throw DbnResponseError{"Unexpected end of metadata buffer while parsing symbol"}; } std::vector res; res.reserve(count); @@ -386,15 +365,14 @@ std::vector DbnDecoder::DecodeSymbolMappings( std::size_t symbol_cstr_len, const std::byte*& read_buf, const std::byte* read_buf_end) { if (read_buf + sizeof(std::uint32_t) > read_buf_end) { - throw DbnResponseError{ - "Unexpected end of metadata buffer while parsing mappings"}; + throw DbnResponseError{"Unexpected end of metadata buffer while parsing mappings"}; } const auto count = std::size_t{Consume(read_buf)}; std::vector res; res.reserve(count); for (std::size_t i = 0; i < count; ++i) { - res.emplace_back(DbnDecoder::DecodeSymbolMapping(symbol_cstr_len, read_buf, - read_buf_end)); + res.emplace_back( + DbnDecoder::DecodeSymbolMapping(symbol_cstr_len, read_buf, read_buf_end)); } return res; } diff --git a/src/dbn_encoder.cpp b/src/dbn_encoder.cpp index 263c8a3..8e5c885 100644 --- a/src/dbn_encoder.cpp +++ b/src/dbn_encoder.cpp @@ -17,8 +17,7 @@ using databento::DbnEncoder; namespace { -void EncodeChars(const char* bytes, std::size_t length, - databento::IWritable* output) { +void EncodeChars(const char* bytes, std::size_t length, databento::IWritable* output) { output->WriteAll(reinterpret_cast(bytes), length); } @@ -31,8 +30,7 @@ void EncodeFixedLenCStr(std::size_t cstr_len, const std::string& str, std::string{"String is too long to encode, maximum length of "} + std::to_string(cstr_len - 1)}; } - output->WriteAll(reinterpret_cast(str.data()), - str.length()); + output->WriteAll(reinterpret_cast(str.data()), str.length()); // Null padding std::vector filler(cstr_len - str.length()); output->WriteAll(filler.data(), filler.size()); @@ -60,12 +58,10 @@ void EncodeRepeatedSymbolCStr(std::size_t cstr_len, } } -void EncodeSymbolMappings( - std::size_t cstr_len, - const std::vector& symbol_mappings, - databento::IWritable* output) { - const auto mappings_length = - static_cast(symbol_mappings.size()); +void EncodeSymbolMappings(std::size_t cstr_len, + const std::vector& symbol_mappings, + databento::IWritable* output) { + const auto mappings_length = static_cast(symbol_mappings.size()); EncodeAsBytes(mappings_length, output); for (const auto& symbol_mapping : symbol_mappings) { EncodeFixedLenCStr(cstr_len, symbol_mapping.raw_symbol, output); @@ -81,8 +77,7 @@ void EncodeSymbolMappings( } } // namespace -DbnEncoder::DbnEncoder(const Metadata& metadata, IWritable* output) - : output_{output} { +DbnEncoder::DbnEncoder(const Metadata& metadata, IWritable* output) : output_{output} { EncodeMetadata(metadata, output_); } @@ -90,8 +85,7 @@ void DbnEncoder::EncodeMetadata(const Metadata& metadata, IWritable* output) { if (metadata.version > kDbnVersion) { throw databento::InvalidArgumentError{ "EncodeMetadata", "metadata", - "Can't encode Metadata with version " + - std::to_string(+metadata.version) + + "Can't encode Metadata with version " + std::to_string(+metadata.version) + " which is greater than the maximum supported version " + std::to_string(+kDbnVersion)}; } @@ -121,21 +115,18 @@ void DbnEncoder::EncodeMetadata(const Metadata& metadata, IWritable* output) { EncodeAsBytes(metadata.stype_out, output); EncodeAsBytes(static_cast(metadata.ts_out), output); if (version > 1) { - const auto symbol_cstr_len = - static_cast(metadata.symbol_cstr_len); + const auto symbol_cstr_len = static_cast(metadata.symbol_cstr_len); EncodeAsBytes(symbol_cstr_len, output); } // padding + schema definition length - auto reserved_length = - version == 1 ? kMetadataReservedLenV1 : kMetadataReservedLen; + auto reserved_length = version == 1 ? kMetadataReservedLenV1 : kMetadataReservedLen; const std::vector padding(reserved_length + sizeof(std::uint32_t)); output->WriteAll(padding.data(), padding.size()); // variable-length data EncodeRepeatedSymbolCStr(metadata.symbol_cstr_len, metadata.symbols, output); EncodeRepeatedSymbolCStr(metadata.symbol_cstr_len, metadata.partial, output); - EncodeRepeatedSymbolCStr(metadata.symbol_cstr_len, metadata.not_found, - output); + EncodeRepeatedSymbolCStr(metadata.symbol_cstr_len, metadata.not_found, output); EncodeSymbolMappings(metadata.symbol_cstr_len, metadata.mappings, output); if (end_padding > 0) { std::array end_padding_buf{}; @@ -144,13 +135,10 @@ void DbnEncoder::EncodeMetadata(const Metadata& metadata, IWritable* output) { } void DbnEncoder::EncodeRecord(const Record& record, IWritable* output) { - output->WriteAll(reinterpret_cast(&record.Header()), - record.Size()); + output->WriteAll(reinterpret_cast(&record.Header()), record.Size()); } -void DbnEncoder::EncodeRecord(const Record& record) { - EncodeRecord(record, output_); -} +void DbnEncoder::EncodeRecord(const Record& record) { EncodeRecord(record, output_); } std::pair DbnEncoder::CalcLength( const Metadata& metadata) { @@ -160,12 +148,11 @@ std::pair DbnEncoder::CalcLength( // mappings_count const auto var_len_counts_size = sizeof(std::uint32_t) * 5; - const auto c_str_count = metadata.symbols.size() + metadata.partial.size() + - metadata.not_found.size(); + const auto c_str_count = + metadata.symbols.size() + metadata.partial.size() + metadata.not_found.size(); const auto mappings_len = std::accumulate( metadata.mappings.begin(), metadata.mappings.end(), std::size_t{0}, - [symbol_cstr_len, mapping_interval_len](std::size_t acc, - const SymbolMapping& m) { + [symbol_cstr_len, mapping_interval_len](std::size_t acc, const SymbolMapping& m) { return acc + symbol_cstr_len + sizeof(std::uint32_t) + m.intervals.size() * mapping_interval_len; }); diff --git a/src/detail/dbn_buffer_decoder.cpp b/src/detail/dbn_buffer_decoder.cpp index 55afbf0..7693b25 100644 --- a/src/detail/dbn_buffer_decoder.cpp +++ b/src/detail/dbn_buffer_decoder.cpp @@ -7,12 +7,11 @@ using databento::detail::DbnBufferDecoder; -databento::KeepGoing DbnBufferDecoder::Process(const char* data, - std::size_t length) { +databento::KeepGoing DbnBufferDecoder::Process(const char* data, std::size_t length) { zstd_buffer_->WriteAll(data, length); while (true) { - const auto read_size = zstd_stream_.ReadSome(dbn_buffer_.WriteBegin(), - dbn_buffer_.WriteCapacity()); + const auto read_size = + zstd_stream_.ReadSome(dbn_buffer_.WriteBegin(), dbn_buffer_.WriteCapacity()); dbn_buffer_.Fill(read_size); if (read_size == 0) { return KeepGoing::Continue; @@ -23,8 +22,8 @@ databento::KeepGoing DbnBufferDecoder::Process(const char* data, break; } std::tie(input_version_, bytes_needed_) = - DbnDecoder::DecodeMetadataVersionAndSize( - dbn_buffer_.ReadBegin(), dbn_buffer_.ReadCapacity()); + DbnDecoder::DecodeMetadataVersionAndSize(dbn_buffer_.ReadBegin(), + dbn_buffer_.ReadCapacity()); dbn_buffer_.Consume(kMetadataPreludeSize); dbn_buffer_.Reserve(bytes_needed_); state_ = DecoderState::Metadata; @@ -56,9 +55,8 @@ databento::KeepGoing DbnBufferDecoder::Process(const char* data, if (dbn_buffer_.ReadCapacity() < bytes_needed_) { break; } - record = - DbnDecoder::DecodeRecordCompat(input_version_, upgrade_policy_, - ts_out_, &compat_buffer_, record); + record = DbnDecoder::DecodeRecordCompat(input_version_, upgrade_policy_, + ts_out_, &compat_buffer_, record); if (record_callback_(record) == KeepGoing::Stop) { return KeepGoing::Stop; } diff --git a/src/detail/http_client.cpp b/src/detail/http_client.cpp index abe81e4..8921a83 100644 --- a/src/detail/http_client.cpp +++ b/src/detail/http_client.cpp @@ -5,7 +5,7 @@ #include "databento/constants.hpp" // kUserAgent #include "databento/exceptions.hpp" // HttpResponseError, HttpRequestError, JsonResponseError -#include "databento/log.hpp" // ILogReceiver, LogLevel +#include "databento/log.hpp" // ILogReceiver, LogLevel using databento::detail::HttpClient; @@ -15,8 +15,8 @@ const httplib::Headers HttpClient::kHeaders{ {"user-agent", kUserAgent}, }; -HttpClient::HttpClient(databento::ILogReceiver* log_receiver, - const std::string& key, const std::string& gateway) +HttpClient::HttpClient(databento::ILogReceiver* log_receiver, const std::string& key, + const std::string& gateway) : log_receiver_{log_receiver}, client_{gateway} { client_.set_default_headers(HttpClient::kHeaders); client_.set_basic_auth(key, ""); @@ -24,9 +24,8 @@ HttpClient::HttpClient(databento::ILogReceiver* log_receiver, client_.set_write_timeout(kTimeout); } -HttpClient::HttpClient(databento::ILogReceiver* log_receiver, - const std::string& key, const std::string& gateway, - std::uint16_t port) +HttpClient::HttpClient(databento::ILogReceiver* log_receiver, const std::string& key, + const std::string& gateway, std::uint16_t port) : log_receiver_{log_receiver}, client_{gateway, port} { client_.set_default_headers(HttpClient::kHeaders); client_.set_basic_auth(key, ""); @@ -47,24 +46,22 @@ nlohmann::json HttpClient::PostJson(const std::string& path, return HttpClient::CheckAndParseResponse(path, std::move(res)); } -void HttpClient::GetRawStream(const std::string& path, - const httplib::Params& params, +void HttpClient::GetRawStream(const std::string& path, const httplib::Params& params, const httplib::ContentReceiver& callback) { const std::string full_path = httplib::append_query_params(path, params); std::string err_body{}; int err_status{}; - const httplib::Result res = - client_.Get(full_path, MakeStreamResponseHandler(err_status), - [&callback, &err_body, &err_status](const char* data, - std::size_t length) { - // if an error response was received, read all content into - // err_body - if (err_status > 0) { - err_body.append(data, length); - return true; - } - return callback(data, length); - }); + const httplib::Result res = client_.Get( + full_path, MakeStreamResponseHandler(err_status), + [&callback, &err_body, &err_status](const char* data, std::size_t length) { + // if an error response was received, read all content into + // err_body + if (err_status > 0) { + err_body.append(data, length); + return true; + } + return callback(data, length); + }); CheckStatusAndStreamRes(path, err_status, std::move(err_body), res); } @@ -80,8 +77,8 @@ void HttpClient::PostRawStream(const std::string& path, req.body = httplib::detail::params_to_query_str(form_params); req.response_handler = MakeStreamResponseHandler(err_status); req.content_receiver = [&callback, &err_body, &err_status]( - const char* data, std::size_t length, - std::uint64_t, std::uint64_t) { + const char* data, std::size_t length, std::uint64_t, + std::uint64_t) { // if an error response was received, read all content into // err_body if (err_status > 0) { @@ -95,8 +92,7 @@ void HttpClient::PostRawStream(const std::string& path, CheckStatusAndStreamRes(path, err_status, std::move(err_body), res); } -httplib::ResponseHandler HttpClient::MakeStreamResponseHandler( - int& out_status) { +httplib::ResponseHandler HttpClient::MakeStreamResponseHandler(int& out_status) { return [this, &out_status](const httplib::Response& resp) { if (HttpClient::IsErrorStatus(resp.status)) { out_status = resp.status; @@ -106,8 +102,7 @@ httplib::ResponseHandler HttpClient::MakeStreamResponseHandler( }; } -void HttpClient::CheckStatusAndStreamRes(const std::string& path, - int status_code, +void HttpClient::CheckStatusAndStreamRes(const std::string& path, int status_code, std::string&& err_body, const httplib::Result& res) { if (status_code > 0) { diff --git a/src/detail/json_helpers.cpp b/src/detail/json_helpers.cpp index d8d1ea4..7d9bf75 100644 --- a/src/detail/json_helpers.cpp +++ b/src/detail/json_helpers.cpp @@ -19,16 +19,14 @@ void SetIfNotEmpty(httplib::Params* params, const std::string& key, std::string value = std::accumulate( states.begin(), states.end(), std::string{}, [](std::string acc, databento::JobState state) { - return acc.empty() - ? databento::ToString(state) - : std::move(acc) + "," + databento::ToString(state); + return acc.empty() ? databento::ToString(state) + : std::move(acc) + "," + databento::ToString(state); }); params->emplace(key, std::move(value)); } } -const nlohmann::json& CheckedAt(std::string_view endpoint, - const nlohmann::json& json, +const nlohmann::json& CheckedAt(std::string_view endpoint, const nlohmann::json& json, std::string_view key) { if (json.contains(key)) { return json.at(key); @@ -59,15 +57,14 @@ std::string ParseAt(std::string_view endpoint, const nlohmann::json& json, template <> std::optional ParseAt(std::string_view endpoint, - const nlohmann::json& json, - std::string_view key) { + const nlohmann::json& json, std::string_view key) { const auto& val_json = CheckedAt(endpoint, json, key); if (val_json.is_null()) { return {}; } if (!val_json.is_string()) { - throw JsonResponseError::TypeMismatch( - endpoint, std::string{key} + " string", val_json); + throw JsonResponseError::TypeMismatch(endpoint, std::string{key} + " string", + val_json); } return val_json; } @@ -108,15 +105,14 @@ double ParseAt(std::string_view endpoint, const nlohmann::json& json, return 0; } if (!val_json.is_number()) { - throw JsonResponseError::TypeMismatch( - endpoint, std::string{key} + " number", val_json); + throw JsonResponseError::TypeMismatch(endpoint, std::string{key} + " number", + val_json); } return val_json; } template <> -std::vector ParseAt(std::string_view endpoint, - const nlohmann::json& json, +std::vector ParseAt(std::string_view endpoint, const nlohmann::json& json, std::string_view key) { const auto& symbols_json = CheckedAt(endpoint, json, key); // if there's only one symbol, it returns a string not an array @@ -124,15 +120,14 @@ std::vector ParseAt(std::string_view endpoint, return {symbols_json}; } if (!symbols_json.is_array()) { - throw JsonResponseError::TypeMismatch(endpoint, std::string{key} + " array", - json); + throw JsonResponseError::TypeMismatch(endpoint, std::string{key} + " array", json); } return {symbols_json.begin(), symbols_json.end()}; } template <> -date::year_month_day ParseAt(std::string_view endpoint, - const nlohmann::json& json, std::string_view key) { +date::year_month_day ParseAt(std::string_view endpoint, const nlohmann::json& json, + std::string_view key) { std::string raw_start = detail::CheckedAt(endpoint, json, key); std::istringstream start_stream{raw_start}; date::year_month_day start; diff --git a/src/detail/scoped_fd.cpp b/src/detail/scoped_fd.cpp index b8f9a2c..2c7b422 100644 --- a/src/detail/scoped_fd.cpp +++ b/src/detail/scoped_fd.cpp @@ -8,9 +8,7 @@ using databento::detail::ScopedFd; -ScopedFd::ScopedFd(ScopedFd&& other) noexcept : fd_{other.fd_} { - other.fd_ = kUnset; -} +ScopedFd::ScopedFd(ScopedFd&& other) noexcept : fd_{other.fd_} { other.fd_ = kUnset; } ScopedFd& ScopedFd::operator=(ScopedFd&& other) noexcept { std::swap(fd_, other.fd_); diff --git a/src/detail/tcp_client.cpp b/src/detail/tcp_client.cpp index 75522bc..2ad2900 100644 --- a/src/detail/tcp_client.cpp +++ b/src/detail/tcp_client.cpp @@ -68,8 +68,7 @@ TcpClient::Result TcpClient::ReadSome(std::byte* buffer, std::size_t max_size) { if (res < 0) { throw TcpError{::GetErrNo(), "Error reading from socket"}; } - return {static_cast(res), - res == 0 ? Status::Closed : Status::Ok}; + return {static_cast(res), res == 0 ? Status::Closed : Status::Ok}; } TcpClient::Result TcpClient::ReadSome(std::byte* buffer, std::size_t max_size, @@ -77,8 +76,7 @@ TcpClient::Result TcpClient::ReadSome(std::byte* buffer, std::size_t max_size, pollfd fds{socket_.Get(), POLLIN, {}}; // passing a timeout of -1 blocks indefinitely, which is the equivalent of // having no timeout - const auto timeout_ms = - timeout.count() ? static_cast(timeout.count()) : -1; + const auto timeout_ms = timeout.count() ? static_cast(timeout.count()) : -1; while (true) { const int poll_status = #ifdef _WIN32 @@ -117,14 +115,12 @@ databento::detail::ScopedFd TcpClient::InitSocket(const std::string& gateway, hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; ::addrinfo* out; - const auto ret = ::getaddrinfo(gateway.c_str(), std::to_string(port).c_str(), - &hints, &out); + const auto ret = + ::getaddrinfo(gateway.c_str(), std::to_string(port).c_str(), &hints, &out); if (ret != 0) { - throw InvalidArgumentError{"TcpClient::TcpClient", "addr", - ::gai_strerror(ret)}; + throw InvalidArgumentError{"TcpClient::TcpClient", "addr", ::gai_strerror(ret)}; } - std::unique_ptr res{out, - &::freeaddrinfo}; + std::unique_ptr res{out, &::freeaddrinfo}; const auto max_attempts = std::max(retry_conf.max_attempts, 1); std::chrono::seconds backoff{1}; for (std::uint32_t attempt = 0; attempt < max_attempts; ++attempt) { @@ -132,8 +128,7 @@ databento::detail::ScopedFd TcpClient::InitSocket(const std::string& gateway, break; } else if (attempt + 1 == max_attempts) { std::ostringstream err_msg; - err_msg << "Socket failed to connect after " << max_attempts - << " attempts"; + err_msg << "Socket failed to connect after " << max_attempts << " attempts"; throw TcpError{::GetErrNo(), err_msg.str()}; } // TODO(cg): Log diff --git a/src/detail/zstd_stream.cpp b/src/detail/zstd_stream.cpp index d908716..45d5df1 100644 --- a/src/detail/zstd_stream.cpp +++ b/src/detail/zstd_stream.cpp @@ -35,22 +35,20 @@ void ZstdDecodeStream::ReadExact(std::byte* buffer, std::size_t length) { // check for end of stream without obtaining `length` bytes if (size < length) { std::ostringstream err_msg; - err_msg << "Reached end of Zstd stream without " << length - << " bytes, only " << size << " bytes available"; + err_msg << "Reached end of Zstd stream without " << length << " bytes, only " + << size << " bytes available"; throw DbnResponseError{err_msg.str()}; } } -std::size_t ZstdDecodeStream::ReadSome(std::byte* buffer, - std::size_t max_length) { +std::size_t ZstdDecodeStream::ReadSome(std::byte* buffer, std::size_t max_length) { ZSTD_outBuffer z_out_buffer{buffer, max_length, 0}; std::size_t read_size = 0; do { const auto unread_input = z_in_buffer_.size - z_in_buffer_.pos; if (unread_input > 0) { - std::copy( - in_buffer_.cbegin() + static_cast(z_in_buffer_.pos), - in_buffer_.cend(), in_buffer_.begin()); + std::copy(in_buffer_.cbegin() + static_cast(z_in_buffer_.pos), + in_buffer_.cend(), in_buffer_.begin()); } if (read_suggestion_ == 0) { // next frame @@ -79,8 +77,7 @@ using databento::detail::ZstdCompressStream; ZstdCompressStream::ZstdCompressStream(IWritable* output) : ZstdCompressStream{ILogReceiver::Default(), output} {} -ZstdCompressStream::ZstdCompressStream(ILogReceiver* log_receiver, - IWritable* output) +ZstdCompressStream::ZstdCompressStream(ILogReceiver* log_receiver, IWritable* output) : log_receiver_{log_receiver}, output_{output}, z_cstream_{::ZSTD_createCStream(), ::ZSTD_freeCStream}, @@ -103,10 +100,9 @@ ZstdCompressStream::~ZstdCompressStream() { break; } if (::ZSTD_isError(remaining) && log_receiver_) { - log_receiver_->Receive( - LogLevel::Error, - std::string{"Zstd error compressing end of stream: "} + - ::ZSTD_getErrorName(remaining)); + log_receiver_->Receive(LogLevel::Error, + std::string{"Zstd error compressing end of stream: "} + + ::ZSTD_getErrorName(remaining)); break; } } @@ -132,9 +128,8 @@ void ZstdCompressStream::WriteAll(const std::byte* buffer, std::size_t length) { // Shift unread input to front const auto unread_input = z_in_buffer_.size - z_in_buffer_.pos; if (unread_input > 0) { - std::copy( - in_buffer_.cbegin() + static_cast(z_in_buffer_.pos), - in_buffer_.cend(), in_buffer_.begin()); + std::copy(in_buffer_.cbegin() + static_cast(z_in_buffer_.pos), + in_buffer_.cend(), in_buffer_.begin()); } in_buffer_.resize(unread_input); if (z_out_buffer.pos > 0) { diff --git a/src/enums.cpp b/src/enums.cpp index 2e2bb10..975dd6f 100644 --- a/src/enums.cpp +++ b/src/enums.cpp @@ -15,90 +15,7 @@ const char* UrlFromGateway(HistoricalGateway gateway) { default: { throw InvalidArgumentError{ "UrlFromGateway", "gateway", - "unknown value " + - std::to_string(static_cast(gateway))}; - } - } -} - -const char* ToString(Schema schema) { - switch (schema) { - case Schema::Mbo: { - return "mbo"; - } - case Schema::Mbp1: { - return "mbp-1"; - } - case Schema::Mbp10: { - return "mbp-10"; - } - case Schema::Tbbo: { - return "tbbo"; - } - case Schema::Trades: { - return "trades"; - } - case Schema::Ohlcv1S: { - return "ohlcv-1s"; - } - case Schema::Ohlcv1M: { - return "ohlcv-1m"; - } - case Schema::Ohlcv1H: { - return "ohlcv-1h"; - } - case Schema::Ohlcv1D: { - return "ohlcv-1d"; - } - case Schema::Definition: { - return "definition"; - } - case Schema::Statistics: { - return "statistics"; - } - case Schema::Status: { - return "status"; - } - case Schema::Imbalance: { - return "imbalance"; - } - case Schema::Cmbp1: { - return "cmbp-1"; - } - case Schema::Cbbo1S: { - return "cbbo-1s"; - } - case Schema::Cbbo1M: { - return "cbbo-1m"; - } - case Schema::Tcbbo: { - return "tcbbo"; - } - case Schema::Bbo1S: { - return "bbo-1s"; - } - case Schema::Bbo1M: { - return "bbo-1m"; - } - default: { - return "unknown"; - } - } -} - -const char* ToString(Encoding encoding) { - switch (encoding) { - case Encoding::Dbn: { - return "dbn"; - } - case Encoding::Csv: { - return "csv"; - } - case Encoding::Json: { - return "json"; - } - default: { - return "unknown"; + "unknown value " + std::to_string(static_cast(gateway))}; } } } @@ -120,46 +37,6 @@ const char* ToString(FeedMode mode) { } } -const char* ToString(Compression compression) { - switch (compression) { - case Compression::None: { - return "none"; - } - case Compression::Zstd: { - return "zstd"; - } - default: { - return "unknown"; - } - } -} - -const char* ToString(SType stype) { - switch (stype) { - case SType::InstrumentId: { - return "instrument_id"; - } - case SType::RawSymbol: { - return "raw_symbol"; - } - case SType::Continuous: { - return "continuous"; - } - case SType::Parent: { - return "parent"; - } - case SType::NasdaqSymbol: { - return "nasdaq_symbol"; - } - case SType::CmsSymbol: { - return "cms_symbol"; - } - default: { - return "unknown"; - } - } -} - const char* ToString(SplitDuration duration_interval) { switch (duration_interval) { case SplitDuration::Day: { @@ -185,12 +62,6 @@ const char* ToString(Delivery delivery) { case Delivery::Download: { return "download"; } - case Delivery::S3: { - return "s3"; - } - case Delivery::Disk: { - return "disk"; - } default: { return "unknown"; } @@ -240,80 +111,95 @@ const char* ToString(DatasetCondition condition) { } } -const char* ToString(RType rtype) { - switch (rtype) { +const char* ToString(RType r_type) { + switch (r_type) { case RType::Mbp0: { - return "Mbp0"; + return "mbp-0"; } case RType::Mbp1: { - return "Mbp1"; + return "mbp-1"; } case RType::Mbp10: { - return "Mbp10"; - } - case RType::OhlcvDeprecated: { - return "OhlcvDeprecated"; + return "mbp-10"; } case RType::Ohlcv1S: { - return "Ohlcv1S"; + return "ohlcv-1s"; } case RType::Ohlcv1M: { - return "Ohlcv1M"; + return "ohlcv-1m"; } case RType::Ohlcv1H: { - return "Ohlcv1H"; + return "ohlcv-1h"; } case RType::Ohlcv1D: { - return "Ohlcv1D"; + return "ohlcv-1d"; + } + case RType::OhlcvEod: { + return "ohlcv-eod"; } case RType::Status: { - return "Status"; + return "status"; } case RType::InstrumentDef: { - return "InstrumentDef"; + return "instrument-def"; } case RType::Imbalance: { - return "Imbalance"; + return "imbalance"; } case RType::Error: { - return "Error"; + return "error"; } case RType::SymbolMapping: { - return "SymbolMapping"; + return "symbol-mapping"; } case RType::System: { - return "System"; + return "system"; } case RType::Statistics: { - return "Statistics"; + return "statistics"; } case RType::Mbo: { - return "Mbo"; + return "mbo"; } case RType::Cmbp1: { - return "Cmbp1"; + return "cmbp-1"; } case RType::Cbbo1S: { - return "Cbbo1S"; + return "cbbo-1s"; } case RType::Cbbo1M: { - return "Cbbo1M"; + return "cbbo-1m"; } case RType::Tcbbo: { - return "Tcbbo"; + return "tcbbo"; } case RType::Bbo1S: { - return "Bbo1S"; + return "bbo-1s"; } case RType::Bbo1M: { - return "Bbo1M"; + return "bbo-1m"; + } + default: { + return "Unknown"; + } + } +} +const char* ToString(Side side) { + switch (side) { + case Side::Ask: { + return "Ask"; + } + case Side::Bid: { + return "Bid"; + } + case Side::None: { + return "None"; } default: { return "Unknown"; } } } - const char* ToString(Action action) { switch (action) { case Action::Modify: { @@ -342,54 +228,36 @@ const char* ToString(Action action) { } } } - -const char* ToString(Side side) { - switch (side) { - case Side::Ask: { - return "Ask"; - } - case Side::Bid: { - return "Bid"; - } - case Side::None: { - return "None"; - } - default: { - return "Unknown"; - } - } -} - const char* ToString(InstrumentClass instrument_class) { switch (instrument_class) { - case instrument_class::Bond: { + case InstrumentClass::Bond: { return "Bond"; } - case instrument_class::Call: { + case InstrumentClass::Call: { return "Call"; } - case instrument_class::Future: { + case InstrumentClass::Future: { return "Future"; } - case instrument_class::Stock: { + case InstrumentClass::Stock: { return "Stock"; } - case instrument_class::MixedSpread: { + case InstrumentClass::MixedSpread: { return "MixedSpread"; } - case instrument_class::Put: { + case InstrumentClass::Put: { return "Put"; } - case instrument_class::FutureSpread: { + case InstrumentClass::FutureSpread: { return "FutureSpread"; } - case instrument_class::OptionSpread: { + case InstrumentClass::OptionSpread: { return "OptionSpread"; } - case instrument_class::FxSpot: { + case InstrumentClass::FxSpot: { return "FxSpot"; } - case instrument_class::CommoditySpot: { + case InstrumentClass::CommoditySpot: { return "CommoditySpot"; } default: { @@ -397,40 +265,39 @@ const char* ToString(InstrumentClass instrument_class) { } } } - const char* ToString(MatchAlgorithm match_algorithm) { switch (match_algorithm) { - case match_algorithm::Undefined: { + case MatchAlgorithm::Undefined: { return "Undefined"; } - case match_algorithm::Fifo: { + case MatchAlgorithm::Fifo: { return "Fifo"; } - case match_algorithm::Configurable: { + case MatchAlgorithm::Configurable: { return "Configurable"; } - case match_algorithm::ProRata: { + case MatchAlgorithm::ProRata: { return "ProRata"; } - case match_algorithm::FifoLmm: { + case MatchAlgorithm::FifoLmm: { return "FifoLmm"; } - case match_algorithm::ThresholdProRata: { + case MatchAlgorithm::ThresholdProRata: { return "ThresholdProRata"; } - case match_algorithm::FifoTopLmm: { + case MatchAlgorithm::FifoTopLmm: { return "FifoTopLmm"; } - case match_algorithm::ThresholdProRataLmm: { + case MatchAlgorithm::ThresholdProRataLmm: { return "ThresholdProRataLmm"; } - case match_algorithm::EurodollarFutures: { + case MatchAlgorithm::EurodollarFutures: { return "EurodollarFutures"; } - case match_algorithm::TimeProRata: { + case MatchAlgorithm::TimeProRata: { return "TimeProRata"; } - case match_algorithm::InstitutionalPrioritization: { + case MatchAlgorithm::InstitutionalPrioritization: { return "InstitutionalPrioritization"; } default: { @@ -438,26 +305,8 @@ const char* ToString(MatchAlgorithm match_algorithm) { } } } - -const char* ToString(SecurityUpdateAction update_action) { - switch (update_action) { - case SecurityUpdateAction::Add: { - return "Add"; - } - case SecurityUpdateAction::Modify: { - return "Modify"; - } - case SecurityUpdateAction::Delete: { - return "Delete"; - } - default: { - return "Unknown"; - } - } -} - -const char* ToString(UserDefinedInstrument user_def_instr) { - switch (user_def_instr) { +const char* ToString(UserDefinedInstrument user_defined_instrument) { + switch (user_defined_instrument) { case UserDefinedInstrument::No: { return "No"; } @@ -469,69 +318,222 @@ const char* ToString(UserDefinedInstrument user_def_instr) { } } } - -const char* ToString(StatType stat_type) { - switch (stat_type) { - case StatType::OpeningPrice: { - return "OpeningPrice"; +const char* ToString(SecurityUpdateAction security_update_action) { + switch (security_update_action) { + case SecurityUpdateAction::Add: { + return "Add"; } - case StatType::IndicativeOpeningPrice: { - return "IndicativeOpeningPrice"; + case SecurityUpdateAction::Modify: { + return "Modify"; } - case StatType::SettlementPrice: { - return "SettlementPrice"; + case SecurityUpdateAction::Delete: { + return "Delete"; } - case StatType::TradingSessionLowPrice: { - return "TradingSessionLowPrice"; + default: { + return "Unknown"; } - case StatType::TradingSessionHighPrice: { - return "TradingSessionHighPrice"; + } +} +const char* ToString(SType s_type) { + switch (s_type) { + case SType::InstrumentId: { + return "instrument_id"; } - case StatType::ClearedVolume: { - return "ClearedVolume"; + case SType::RawSymbol: { + return "raw_symbol"; } - case StatType::LowestOffer: { - return "LowestOffer"; + case SType::Continuous: { + return "continuous"; } - case StatType::HighestBid: { - return "HighestBid"; + case SType::Parent: { + return "parent"; } - case StatType::OpenInterest: { - return "OpenInterest"; + case SType::NasdaqSymbol: { + return "nasdaq_symbol"; } - case StatType::FixingPrice: { - return "FixingPrice"; + case SType::CmsSymbol: { + return "cms_symbol"; } - case StatType::ClosePrice: { - return "ClosePrice"; + case SType::Isin: { + return "isin"; } - case StatType::NetChange: { - return "NetChange"; + case SType::UsCode: { + return "us_code"; } - case StatType::Vwap: { - return "Vwap"; + case SType::BbgCompId: { + return "bbg_comp_id"; } - case StatType::Volatility: { - return "Volatility"; + case SType::BbgCompTicker: { + return "bbg_comp_ticker"; } - case StatType::Delta: { - return "Delta"; + case SType::Figi: { + return "figi"; } - case StatType::UncrossingPrice: { - return "UncrossingPrice"; + case SType::FigiTicker: { + return "figi_ticker"; } default: { return "Unknown"; } } } - -const char* ToString(StatUpdateAction stat_update_action) { - switch (stat_update_action) { - case StatUpdateAction::New: { - return "New"; - } - case StatUpdateAction::Delete: { +const char* ToString(Schema schema) { + switch (schema) { + case Schema::Mbo: { + return "mbo"; + } + case Schema::Mbp1: { + return "mbp-1"; + } + case Schema::Mbp10: { + return "mbp-10"; + } + case Schema::Tbbo: { + return "tbbo"; + } + case Schema::Trades: { + return "trades"; + } + case Schema::Ohlcv1S: { + return "ohlcv-1s"; + } + case Schema::Ohlcv1M: { + return "ohlcv-1m"; + } + case Schema::Ohlcv1H: { + return "ohlcv-1h"; + } + case Schema::Ohlcv1D: { + return "ohlcv-1d"; + } + case Schema::Definition: { + return "definition"; + } + case Schema::Statistics: { + return "statistics"; + } + case Schema::Status: { + return "status"; + } + case Schema::Imbalance: { + return "imbalance"; + } + case Schema::OhlcvEod: { + return "ohlcv-eod"; + } + case Schema::Cmbp1: { + return "cmbp-1"; + } + case Schema::Cbbo1S: { + return "cbbo-1s"; + } + case Schema::Cbbo1M: { + return "cbbo-1m"; + } + case Schema::Tcbbo: { + return "tcbbo"; + } + case Schema::Bbo1S: { + return "bbo-1s"; + } + case Schema::Bbo1M: { + return "bbo-1m"; + } + default: { + return "Unknown"; + } + } +} +const char* ToString(Encoding encoding) { + switch (encoding) { + case Encoding::Dbn: { + return "dbn"; + } + case Encoding::Csv: { + return "csv"; + } + case Encoding::Json: { + return "json"; + } + default: { + return "Unknown"; + } + } +} +const char* ToString(Compression compression) { + switch (compression) { + case Compression::None: { + return "none"; + } + case Compression::Zstd: { + return "zstd"; + } + default: { + return "Unknown"; + } + } +} +const char* ToString(StatType stat_type) { + switch (stat_type) { + case StatType::OpeningPrice: { + return "OpeningPrice"; + } + case StatType::IndicativeOpeningPrice: { + return "IndicativeOpeningPrice"; + } + case StatType::SettlementPrice: { + return "SettlementPrice"; + } + case StatType::TradingSessionLowPrice: { + return "TradingSessionLowPrice"; + } + case StatType::TradingSessionHighPrice: { + return "TradingSessionHighPrice"; + } + case StatType::ClearedVolume: { + return "ClearedVolume"; + } + case StatType::LowestOffer: { + return "LowestOffer"; + } + case StatType::HighestBid: { + return "HighestBid"; + } + case StatType::OpenInterest: { + return "OpenInterest"; + } + case StatType::FixingPrice: { + return "FixingPrice"; + } + case StatType::ClosePrice: { + return "ClosePrice"; + } + case StatType::NetChange: { + return "NetChange"; + } + case StatType::Vwap: { + return "Vwap"; + } + case StatType::Volatility: { + return "Volatility"; + } + case StatType::Delta: { + return "Delta"; + } + case StatType::UncrossingPrice: { + return "UncrossingPrice"; + } + default: { + return "Unknown"; + } + } +} +const char* ToString(StatUpdateAction stat_update_action) { + switch (stat_update_action) { + case StatUpdateAction::New: { + return "New"; + } + case StatUpdateAction::Delete: { return "Delete"; } default: { @@ -539,55 +541,54 @@ const char* ToString(StatUpdateAction stat_update_action) { } } } - const char* ToString(StatusAction status_action) { switch (status_action) { - case status_action::None: { + case StatusAction::None: { return "None"; } - case status_action::PreOpen: { + case StatusAction::PreOpen: { return "PreOpen"; } - case status_action::PreCross: { + case StatusAction::PreCross: { return "PreCross"; } - case status_action::Quoting: { + case StatusAction::Quoting: { return "Quoting"; } - case status_action::Cross: { + case StatusAction::Cross: { return "Cross"; } - case status_action::Rotation: { + case StatusAction::Rotation: { return "Rotation"; } - case status_action::NewPriceIndication: { + case StatusAction::NewPriceIndication: { return "NewPriceIndication"; } - case status_action::Trading: { + case StatusAction::Trading: { return "Trading"; } - case status_action::Halt: { + case StatusAction::Halt: { return "Halt"; } - case status_action::Pause: { + case StatusAction::Pause: { return "Pause"; } - case status_action::Suspend: { + case StatusAction::Suspend: { return "Suspend"; } - case status_action::PreClose: { + case StatusAction::PreClose: { return "PreClose"; } - case status_action::Close: { + case StatusAction::Close: { return "Close"; } - case status_action::PostClose: { + case StatusAction::PostClose: { return "PostClose"; } - case status_action::SsrChange: { + case StatusAction::SsrChange: { return "SsrChange"; } - case status_action::NotAvailableForTrading: { + case StatusAction::NotAvailableForTrading: { return "NotAvailableForTrading"; } default: { @@ -595,109 +596,108 @@ const char* ToString(StatusAction status_action) { } } } - const char* ToString(StatusReason status_reason) { switch (status_reason) { - case status_reason::None: { + case StatusReason::None: { return "None"; } - case status_reason::Scheduled: { + case StatusReason::Scheduled: { return "Scheduled"; } - case status_reason::SurveillanceIntervention: { + case StatusReason::SurveillanceIntervention: { return "SurveillanceIntervention"; } - case status_reason::MarketEvent: { + case StatusReason::MarketEvent: { return "MarketEvent"; } - case status_reason::InstrumentActivation: { + case StatusReason::InstrumentActivation: { return "InstrumentActivation"; } - case status_reason::InstrumentExpiration: { + case StatusReason::InstrumentExpiration: { return "InstrumentExpiration"; } - case status_reason::RecoveryInProcess: { + case StatusReason::RecoveryInProcess: { return "RecoveryInProcess"; } - case status_reason::Regulatory: { + case StatusReason::Regulatory: { return "Regulatory"; } - case status_reason::Administrative: { + case StatusReason::Administrative: { return "Administrative"; } - case status_reason::NonCompliance: { + case StatusReason::NonCompliance: { return "NonCompliance"; } - case status_reason::FilingsNotCurrent: { + case StatusReason::FilingsNotCurrent: { return "FilingsNotCurrent"; } - case status_reason::SecTradingSuspension: { + case StatusReason::SecTradingSuspension: { return "SecTradingSuspension"; } - case status_reason::NewIssue: { + case StatusReason::NewIssue: { return "NewIssue"; } - case status_reason::IssueAvailable: { + case StatusReason::IssueAvailable: { return "IssueAvailable"; } - case status_reason::IssuesReviewed: { + case StatusReason::IssuesReviewed: { return "IssuesReviewed"; } - case status_reason::FilingReqsSatisfied: { + case StatusReason::FilingReqsSatisfied: { return "FilingReqsSatisfied"; } - case status_reason::NewsPending: { + case StatusReason::NewsPending: { return "NewsPending"; } - case status_reason::NewsReleased: { + case StatusReason::NewsReleased: { return "NewsReleased"; } - case status_reason::NewsAndResumptionTimes: { + case StatusReason::NewsAndResumptionTimes: { return "NewsAndResumptionTimes"; } - case status_reason::NewsNotForthcoming: { + case StatusReason::NewsNotForthcoming: { return "NewsNotForthcoming"; } - case status_reason::OrderImbalance: { + case StatusReason::OrderImbalance: { return "OrderImbalance"; } - case status_reason::LuldPause: { + case StatusReason::LuldPause: { return "LuldPause"; } - case status_reason::Operational: { + case StatusReason::Operational: { return "Operational"; } - case status_reason::AdditionalInformationRequested: { + case StatusReason::AdditionalInformationRequested: { return "AdditionalInformationRequested"; } - case status_reason::MergerEffective: { + case StatusReason::MergerEffective: { return "MergerEffective"; } - case status_reason::Etf: { + case StatusReason::Etf: { return "Etf"; } - case status_reason::CorporateAction: { + case StatusReason::CorporateAction: { return "CorporateAction"; } - case status_reason::NewSecurityOffering: { + case StatusReason::NewSecurityOffering: { return "NewSecurityOffering"; } - case status_reason::MarketWideHaltLevel1: { + case StatusReason::MarketWideHaltLevel1: { return "MarketWideHaltLevel1"; } - case status_reason::MarketWideHaltLevel2: { + case StatusReason::MarketWideHaltLevel2: { return "MarketWideHaltLevel2"; } - case status_reason::MarketWideHaltLevel3: { + case StatusReason::MarketWideHaltLevel3: { return "MarketWideHaltLevel3"; } - case status_reason::MarketWideHaltCarryover: { + case StatusReason::MarketWideHaltCarryover: { return "MarketWideHaltCarryover"; } - case status_reason::MarketWideHaltResumption: { + case StatusReason::MarketWideHaltResumption: { return "MarketWideHaltResumption"; } - case status_reason::QuotationNotAvailable: { + case StatusReason::QuotationNotAvailable: { return "QuotationNotAvailable"; } default: { @@ -705,22 +705,21 @@ const char* ToString(StatusReason status_reason) { } } } - const char* ToString(TradingEvent trading_event) { switch (trading_event) { - case trading_event::None: { + case TradingEvent::None: { return "None"; } - case trading_event::NoCancel: { + case TradingEvent::NoCancel: { return "NoCancel"; } - case trading_event::ChangeTradingSession: { + case TradingEvent::ChangeTradingSession: { return "ChangeTradingSession"; } - case trading_event::ImpliedMatchingOn: { + case TradingEvent::ImpliedMatchingOn: { return "ImpliedMatchingOn"; } - case trading_event::ImpliedMatchingOff: { + case TradingEvent::ImpliedMatchingOff: { return "ImpliedMatchingOff"; } default: { @@ -728,7 +727,6 @@ const char* ToString(TradingEvent trading_event) { } } } - const char* ToString(TriState tri_state) { switch (tri_state) { case TriState::NotAvailable: { @@ -745,9 +743,8 @@ const char* ToString(TriState tri_state) { } } } - -const char* ToString(VersionUpgradePolicy upgrade_policy) { - switch (upgrade_policy) { +const char* ToString(VersionUpgradePolicy version_upgrade_policy) { + switch (version_upgrade_policy) { case VersionUpgradePolicy::AsIs: { return "AsIs"; } @@ -762,7 +759,6 @@ const char* ToString(VersionUpgradePolicy upgrade_policy) { } } } - const char* ToString(ErrorCode error_code) { switch (error_code) { case ErrorCode::AuthFailed: { @@ -788,7 +784,6 @@ const char* ToString(ErrorCode error_code) { } } } - const char* ToString(SystemCode system_code) { switch (system_code) { case SystemCode::Heartbeat: { @@ -809,31 +804,11 @@ const char* ToString(SystemCode system_code) { } } -std::ostream& operator<<(std::ostream& out, Schema schema) { - out << ToString(schema); - return out; -} - -std::ostream& operator<<(std::ostream& out, Encoding encoding) { - out << ToString(encoding); - return out; -} - std::ostream& operator<<(std::ostream& out, FeedMode mode) { out << ToString(mode); return out; } -std::ostream& operator<<(std::ostream& out, Compression compression) { - out << ToString(compression); - return out; -} - -std::ostream& operator<<(std::ostream& out, SType stype) { - out << ToString(stype); - return out; -} - std::ostream& operator<<(std::ostream& out, SplitDuration duration_interval) { out << ToString(duration_interval); return out; @@ -854,54 +829,60 @@ std::ostream& operator<<(std::ostream& out, DatasetCondition condition) { return out; } -std::ostream& operator<<(std::ostream& out, RType rtype) { - out << ToString(rtype); +std::ostream& operator<<(std::ostream& out, RType r_type) { + out << ToString(r_type); return out; } - -std::ostream& operator<<(std::ostream& out, Action action) { - out << ToString(action); - return out; -} - std::ostream& operator<<(std::ostream& out, Side side) { out << ToString(side); return out; } - +std::ostream& operator<<(std::ostream& out, Action action) { + out << ToString(action); + return out; +} std::ostream& operator<<(std::ostream& out, InstrumentClass instrument_class) { out << ToString(instrument_class); return out; } - std::ostream& operator<<(std::ostream& out, MatchAlgorithm match_algorithm) { out << ToString(match_algorithm); return out; } - std::ostream& operator<<(std::ostream& out, - SecurityUpdateAction update_action) { - out << ToString(update_action); + UserDefinedInstrument user_defined_instrument) { + out << ToString(user_defined_instrument); return out; } - std::ostream& operator<<(std::ostream& out, - UserDefinedInstrument user_def_instr) { - out << ToString(user_def_instr); + SecurityUpdateAction security_update_action) { + out << ToString(security_update_action); + return out; +} +std::ostream& operator<<(std::ostream& out, SType s_type) { + out << ToString(s_type); + return out; +} +std::ostream& operator<<(std::ostream& out, Schema schema) { + out << ToString(schema); + return out; +} +std::ostream& operator<<(std::ostream& out, Encoding encoding) { + out << ToString(encoding); + return out; +} +std::ostream& operator<<(std::ostream& out, Compression compression) { + out << ToString(compression); return out; } - std::ostream& operator<<(std::ostream& out, StatType stat_type) { out << ToString(stat_type); return out; } - -std::ostream& operator<<(std::ostream& out, - StatUpdateAction stat_update_action) { +std::ostream& operator<<(std::ostream& out, StatUpdateAction stat_update_action) { out << ToString(stat_update_action); return out; } - std::ostream& operator<<(std::ostream& out, StatusAction status_action) { out << ToString(status_action); return out; @@ -918,23 +899,219 @@ std::ostream& operator<<(std::ostream& out, TriState tri_state) { out << ToString(tri_state); return out; } - std::ostream& operator<<(std::ostream& out, - VersionUpgradePolicy upgrade_policy) { - out << ToString(upgrade_policy); + VersionUpgradePolicy version_upgrade_policy) { + out << ToString(version_upgrade_policy); return out; } - std::ostream& operator<<(std::ostream& out, ErrorCode error_code) { out << ToString(error_code); return out; } - std::ostream& operator<<(std::ostream& out, SystemCode system_code) { out << ToString(system_code); return out; } +template <> +FeedMode FromString(const std::string& str) { + if (str == "historical") { + return FeedMode::Historical; + } + if (str == "historical-streaming") { + return FeedMode::HistoricalStreaming; + } + if (str == "live") { + return FeedMode::Live; + } + throw InvalidArgumentError{"FromString", "str", + "unknown value '" + str + '\''}; +} + +template <> +SplitDuration FromString(const std::string& str) { + if (str == "day") { + return SplitDuration::Day; + } + if (str == "week") { + return SplitDuration::Week; + } + if (str == "month") { + return SplitDuration::Month; + } + if (str == "none") { + return SplitDuration::None; + } + throw InvalidArgumentError{"FromString", "str", + "unknown value '" + str + '\''}; +} + +template <> +Delivery FromString(const std::string& str) { + if (str == "download") { + return Delivery::Download; + } + throw InvalidArgumentError{"FromString", "str", + "unknown value '" + str + '\''}; +} + +template <> +JobState FromString(const std::string& str) { + if (str == "received") { + return JobState::Received; + } + if (str == "queued") { + return JobState::Queued; + } + if (str == "processing") { + return JobState::Processing; + } + if (str == "done") { + return JobState::Done; + } + if (str == "expired") { + return JobState::Expired; + } + throw InvalidArgumentError{"FromString", "str", + "unknown value '" + str + '\''}; +} + +template <> +DatasetCondition FromString(const std::string& str) { + if (str == "available") { + return DatasetCondition::Available; + } + if (str == "degraded") { + return DatasetCondition::Degraded; + } + if (str == "pending") { + return DatasetCondition::Pending; + } + if (str == "missing") { + return DatasetCondition::Missing; + } + throw InvalidArgumentError{"FromString", "str", + "unknown value '" + str + '\''}; +} + +template <> +RType FromString(const std::string& str) { + if (str == "mbp-0") { + return RType::Mbp0; + } + if (str == "mbp-1") { + return RType::Mbp1; + } + if (str == "mbp-10") { + return RType::Mbp10; + } + if (str == "ohlcv-deprecated") { + return RType::OhlcvDeprecated; + } + if (str == "ohlcv-1s") { + return RType::Ohlcv1S; + } + if (str == "ohlcv-1m") { + return RType::Ohlcv1M; + } + if (str == "ohlcv-1h") { + return RType::Ohlcv1H; + } + if (str == "ohlcv-1d") { + return RType::Ohlcv1D; + } + if (str == "ohlcv-eod") { + return RType::OhlcvEod; + } + if (str == "status") { + return RType::Status; + } + if (str == "instrument-def") { + return RType::InstrumentDef; + } + if (str == "imbalance") { + return RType::Imbalance; + } + if (str == "error") { + return RType::Error; + } + if (str == "symbol-mapping") { + return RType::SymbolMapping; + } + if (str == "system") { + return RType::System; + } + if (str == "statistics") { + return RType::Statistics; + } + if (str == "mbo") { + return RType::Mbo; + } + if (str == "cmbp-1") { + return RType::Cmbp1; + } + if (str == "cbbo-1s") { + return RType::Cbbo1S; + } + if (str == "cbbo-1m") { + return RType::Cbbo1M; + } + if (str == "tcbbo") { + return RType::Tcbbo; + } + if (str == "bbo-1s") { + return RType::Bbo1S; + } + if (str == "bbo-1m") { + return RType::Bbo1M; + } + throw InvalidArgumentError{"FromString", "str", + "unknown value '" + str + '\''}; +} +template <> +SType FromString(const std::string& str) { + if (str == "instrument_id" || str == "product_id") { + return SType::InstrumentId; + } + if (str == "raw_symbol" || str == "native") { + return SType::RawSymbol; + } + if (str == "smart") { + return SType::Smart; + } + if (str == "continuous") { + return SType::Continuous; + } + if (str == "parent") { + return SType::Parent; + } + if (str == "nasdaq_symbol" || str == "nasdaq") { + return SType::NasdaqSymbol; + } + if (str == "cms_symbol" || str == "cms") { + return SType::CmsSymbol; + } + if (str == "isin") { + return SType::Isin; + } + if (str == "us_code") { + return SType::UsCode; + } + if (str == "bbg_comp_id") { + return SType::BbgCompId; + } + if (str == "bbg_comp_ticker") { + return SType::BbgCompTicker; + } + if (str == "figi") { + return SType::Figi; + } + if (str == "figi_ticker") { + return SType::FigiTicker; + } + throw InvalidArgumentError{"FromString", "str", + "unknown value '" + str + '\''}; +} template <> Schema FromString(const std::string& str) { if (str == "mbo") { @@ -976,6 +1153,9 @@ Schema FromString(const std::string& str) { if (str == "imbalance") { return Schema::Imbalance; } + if (str == "ohlcv-eod") { + return Schema::OhlcvEod; + } if (str == "cmbp-1") { return Schema::Cmbp1; } @@ -997,10 +1177,9 @@ Schema FromString(const std::string& str) { throw InvalidArgumentError{"FromString", "str", "unknown value '" + str + '\''}; } - template <> Encoding FromString(const std::string& str) { - if (str == "dbn") { + if (str == "dbn" || str == "dbz") { return Encoding::Dbn; } if (str == "csv") { @@ -1012,22 +1191,6 @@ Encoding FromString(const std::string& str) { throw InvalidArgumentError{"FromString", "str", "unknown value '" + str + '\''}; } - -template <> -FeedMode FromString(const std::string& str) { - if (str == "historical") { - return FeedMode::Historical; - } - if (str == "historical-streaming") { - return FeedMode::HistoricalStreaming; - } - if (str == "live") { - return FeedMode::Live; - } - throw InvalidArgumentError{"FromString", "str", - "unknown value '" + str + '\''}; -} - template <> Compression FromString(const std::string& str) { if (str == "none") { @@ -1039,100 +1202,44 @@ Compression FromString(const std::string& str) { throw InvalidArgumentError{"FromString", "str", "unknown value '" + str + '\''}; } - -template <> -SType FromString(const std::string& str) { - if (str == "instrument_id") { - return SType::InstrumentId; - } - if (str == "raw_symbol") { - return SType::RawSymbol; - } - if (str == "continuous") { - return SType::Continuous; - } - if (str == "parent") { - return SType::Parent; - } - if (str == "nasdaq_symbol" || str == "nasdaq") { - return SType::NasdaqSymbol; - } - if (str == "cms_symbol" || str == "cms") { - return SType::CmsSymbol; - } - throw InvalidArgumentError{"FromString", "str", - "unknown value '" + str + '\''}; -} - template <> -SplitDuration FromString(const std::string& str) { - if (str == "day") { - return SplitDuration::Day; +ErrorCode FromString(const std::string& str) { + if (str == "auth_failed") { + return ErrorCode::AuthFailed; } - if (str == "week") { - return SplitDuration::Week; + if (str == "api_key_deactivated") { + return ErrorCode::ApiKeyDeactivated; } - if (str == "month") { - return SplitDuration::Month; + if (str == "connection_limit_exceeded") { + return ErrorCode::ConnectionLimitExceeded; } - if (str == "none") { - return SplitDuration::None; + if (str == "symbol_resolution_failed") { + return ErrorCode::SymbolResolutionFailed; } - throw InvalidArgumentError{"FromString", "str", - "unknown value '" + str + '\''}; -} - -template <> -Delivery FromString(const std::string& str) { - if (str == "download") { - return Delivery::Download; - } - if (str == "s3") { - return Delivery::S3; + if (str == "invalid_subscription") { + return ErrorCode::InvalidSubscription; } - if (str == "disk") { - return Delivery::Disk; + if (str == "internal_error") { + return ErrorCode::InternalError; } - throw InvalidArgumentError{"FromString", "str", + throw InvalidArgumentError{"FromString", "str", "unknown value '" + str + '\''}; } - template <> -JobState FromString(const std::string& str) { - if (str == "received") { - return JobState::Received; +SystemCode FromString(const std::string& str) { + if (str == "heartbeat") { + return SystemCode::Heartbeat; } - if (str == "queued") { - return JobState::Queued; - } - if (str == "processing") { - return JobState::Processing; - } - if (str == "done") { - return JobState::Done; - } - if (str == "expired") { - return JobState::Expired; - } - throw InvalidArgumentError{"FromString", "str", - "unknown value '" + str + '\''}; -} - -template <> -DatasetCondition FromString(const std::string& str) { - if (str == "available") { - return DatasetCondition::Available; - } - if (str == "degraded") { - return DatasetCondition::Degraded; + if (str == "subscription_ack") { + return SystemCode::SubscriptionAck; } - if (str == "pending") { - return DatasetCondition::Pending; + if (str == "slow_reader_warning") { + return SystemCode::SlowReaderWarning; } - if (str == "missing") { - return DatasetCondition::Missing; + if (str == "replay_completed") { + return SystemCode::ReplayCompleted; } - throw InvalidArgumentError{"FromString", "str", + throw InvalidArgumentError{"FromString", "str", "unknown value '" + str + '\''}; } } // namespace databento diff --git a/src/exceptions.cpp b/src/exceptions.cpp index fc20ac8..1fc5ada 100644 --- a/src/exceptions.cpp +++ b/src/exceptions.cpp @@ -22,8 +22,8 @@ using databento::TcpError; std::string TcpError::BuildMessage(int err_num, std::string message) { #ifdef _WIN32 char errbuf[300]; - ::FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, {}, err_num, {}, errbuf, - sizeof(errbuf), {}); + ::FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, {}, err_num, {}, errbuf, sizeof(errbuf), + {}); return std::move(message) + ": " + errbuf; #else return std::move(message) + ": " + std::strerror(err_num); @@ -37,8 +37,7 @@ std::string HttpResponseError::BuildMessage(std::string_view request_path, std::string_view response_body) { std::ostringstream err_msg; err_msg << "Received an error response from request to " << request_path - << " with status " << status_code << " and body '" << response_body - << '\''; + << " with status " << status_code << " and body '" << response_body << '\''; return err_msg.str(); } @@ -56,8 +55,7 @@ std::string InvalidArgumentError::BuildMessage(std::string_view method_name, using databento::JsonResponseError; JsonResponseError JsonResponseError::ParseError( - std::string_view method_name, - const nlohmann::json::parse_error& parse_error) { + std::string_view method_name, const nlohmann::json::parse_error& parse_error) { std::ostringstream err_msg; err_msg << "Error parsing JSON response to " << method_name << ' ' << parse_error.what(); @@ -71,22 +69,23 @@ JsonResponseError JsonResponseError::MissingKey(std::string_view path, return JsonResponseError{err_msg.str()}; } -JsonResponseError JsonResponseError::TypeMismatch( - std::string_view method_name, std::string_view expected_type_name, - const nlohmann::json& json) { +JsonResponseError JsonResponseError::TypeMismatch(std::string_view method_name, + std::string_view expected_type_name, + const nlohmann::json& json) { std::ostringstream err_msg; - err_msg << "Expected JSON " << expected_type_name << " response for " - << method_name << ", got " << json.type_name(); + err_msg << "Expected JSON " << expected_type_name << " response for " << method_name + << ", got " << json.type_name(); return JsonResponseError{err_msg.str()}; } -JsonResponseError JsonResponseError::TypeMismatch( - std::string_view method_name, std::string_view expected_type_name, - const nlohmann::json& key, const nlohmann::json& value) { +JsonResponseError JsonResponseError::TypeMismatch(std::string_view method_name, + std::string_view expected_type_name, + const nlohmann::json& key, + const nlohmann::json& value) { std::ostringstream err_msg; - err_msg << "Expected " << expected_type_name - << " values in JSON response for " << method_name << ", got " - << value.type_name() << " " << value << " for key " << key; + err_msg << "Expected " << expected_type_name << " values in JSON response for " + << method_name << ", got " << value.type_name() << " " << value << " for key " + << key; return JsonResponseError{err_msg.str()}; } diff --git a/src/file_stream.cpp b/src/file_stream.cpp index 7fe9cbb..8ffb0dd 100644 --- a/src/file_stream.cpp +++ b/src/file_stream.cpp @@ -10,9 +10,8 @@ using databento::InFileStream; InFileStream::InFileStream(const std::filesystem::path& file_path) : stream_{file_path, std::ios::binary} { if (stream_.fail()) { - throw InvalidArgumentError{ - "InFileStream", "file_path", - "Non-existent or invalid file at " + file_path.string()}; + throw InvalidArgumentError{"InFileStream", "file_path", + "Non-existent or invalid file at " + file_path.string()}; } } @@ -20,8 +19,7 @@ void InFileStream::ReadExact(std::byte* buffer, std::size_t length) { const auto size = ReadSome(buffer, length); if (size != length) { std::ostringstream err_msg; - err_msg << "Unexpected end of file, expected " << length << " bytes, got " - << size; + err_msg << "Unexpected end of file, expected " << length << " bytes, got " << size; throw DbnResponseError{err_msg.str()}; } } diff --git a/src/historical.cpp b/src/historical.cpp index a398ee5..6432565 100644 --- a/src/historical.cpp +++ b/src/historical.cpp @@ -52,8 +52,7 @@ constexpr auto kDefaultEncoding = databento::Encoding::Dbn; constexpr auto kDefaultCompression = databento::Compression::Zstd; constexpr auto kDefaultSTypeOut = databento::SType::InstrumentId; -databento::BatchJob Parse(const std::string& endpoint, - const nlohmann::json& json) { +databento::BatchJob Parse(const std::string& endpoint, const nlohmann::json& json) { using databento::Compression; using databento::Delivery; using databento::Encoding; @@ -101,8 +100,7 @@ databento::BatchJob Parse(const std::string& endpoint, res.state = FromCheckedAtString(endpoint, json, "state"); res.ts_received = ParseAt(endpoint, json, "ts_received"); res.ts_queued = ParseAt(endpoint, json, "ts_queued"); - res.ts_process_start = - ParseAt(endpoint, json, "ts_process_start"); + res.ts_process_start = ParseAt(endpoint, json, "ts_process_start"); res.ts_process_done = ParseAt(endpoint, json, "ts_process_done"); res.ts_expiration = ParseAt(endpoint, json, "ts_expiration"); return res; @@ -132,8 +130,7 @@ Historical::Historical(ILogReceiver* log_receiver, std::string key, client_{log_receiver, key_, gateway_} {} Historical::Historical(ILogReceiver* log_receiver, std::string key, - HistoricalGateway gateway, - VersionUpgradePolicy upgrade_policy, + HistoricalGateway gateway, VersionUpgradePolicy upgrade_policy, std::string user_agent_ext) : log_receiver_{log_receiver}, key_{std::move(key)}, @@ -142,9 +139,8 @@ Historical::Historical(ILogReceiver* log_receiver, std::string key, upgrade_policy_{upgrade_policy}, client_{log_receiver, key_, gateway_} {} -Historical::Historical(ILogReceiver* log_receiver, std::string key, - std::string gateway, std::uint16_t port, - VersionUpgradePolicy upgrade_policy, +Historical::Historical(ILogReceiver* log_receiver, std::string key, std::string gateway, + std::uint16_t port, VersionUpgradePolicy upgrade_policy, std::string user_agent_ext) : log_receiver_{log_receiver}, key_{std::move(key)}, @@ -156,28 +152,27 @@ Historical::Historical(ILogReceiver* log_receiver, std::string key, static const std::string kBatchSubmitJobEndpoint = "Historical::BatchSubmitJob"; databento::BatchJob Historical::BatchSubmitJob( - const std::string& dataset, const std::vector& symbols, - Schema schema, const DateTimeRange& datetime_range) { + const std::string& dataset, const std::vector& symbols, Schema schema, + const DateTimeRange& datetime_range) { return this->BatchSubmitJob(dataset, symbols, schema, datetime_range, - kDefaultEncoding, kDefaultCompression, {}, {}, {}, - {}, SplitDuration::Day, {}, Delivery::Download, + kDefaultEncoding, kDefaultCompression, {}, {}, {}, {}, + SplitDuration::Day, {}, Delivery::Download, kDefaultSTypeIn, kDefaultSTypeOut, {}); } databento::BatchJob Historical::BatchSubmitJob( - const std::string& dataset, const std::vector& symbols, - Schema schema, const DateTimeRange& datetime_range) { + const std::string& dataset, const std::vector& symbols, Schema schema, + const DateTimeRange& datetime_range) { return this->BatchSubmitJob(dataset, symbols, schema, datetime_range, - kDefaultEncoding, kDefaultCompression, {}, {}, {}, - {}, SplitDuration::Day, {}, Delivery::Download, + kDefaultEncoding, kDefaultCompression, {}, {}, {}, {}, + SplitDuration::Day, {}, Delivery::Download, kDefaultSTypeIn, kDefaultSTypeOut, {}); } databento::BatchJob Historical::BatchSubmitJob( - const std::string& dataset, const std::vector& symbols, - Schema schema, const DateTimeRange& datetime_range, - Encoding encoding, Compression compression, bool pretty_px, bool pretty_ts, - bool map_symbols, bool split_symbols, SplitDuration split_duration, - std::uint64_t split_size, Delivery delivery, SType stype_in, - SType stype_out, std::uint64_t limit) { + const std::string& dataset, const std::vector& symbols, Schema schema, + const DateTimeRange& datetime_range, Encoding encoding, + Compression compression, bool pretty_px, bool pretty_ts, bool map_symbols, + bool split_symbols, SplitDuration split_duration, std::uint64_t split_size, + Delivery delivery, SType stype_in, SType stype_out, std::uint64_t limit) { httplib::Params params{ {"dataset", dataset}, {"start", ToString(datetime_range.start)}, @@ -199,12 +194,11 @@ databento::BatchJob Historical::BatchSubmitJob( return this->BatchSubmitJob(params); } databento::BatchJob Historical::BatchSubmitJob( - const std::string& dataset, const std::vector& symbols, - Schema schema, const DateTimeRange& datetime_range, - Encoding encoding, Compression compression, bool pretty_px, bool pretty_ts, - bool map_symbols, bool split_symbols, SplitDuration split_duration, - std::uint64_t split_size, Delivery delivery, SType stype_in, - SType stype_out, std::uint64_t limit) { + const std::string& dataset, const std::vector& symbols, Schema schema, + const DateTimeRange& datetime_range, Encoding encoding, + Compression compression, bool pretty_px, bool pretty_ts, bool map_symbols, + bool split_symbols, SplitDuration split_duration, std::uint64_t split_size, + Delivery delivery, SType stype_in, SType stype_out, std::uint64_t limit) { httplib::Params params{ {"dataset", dataset}, {"start", datetime_range.start}, @@ -233,8 +227,7 @@ databento::BatchJob Historical::BatchSubmitJob(const httplib::Params& params) { std::vector Historical::BatchListJobs() { static const std::vector kDefaultStates = { - JobState::Received, JobState::Queued, JobState::Processing, - JobState::Done}; + JobState::Received, JobState::Queued, JobState::Processing, JobState::Done}; return this->BatchListJobs(kDefaultStates, UnixNanos{}); } std::vector Historical::BatchListJobs( @@ -260,9 +253,8 @@ std::vector Historical::BatchListJobs( throw JsonResponseError::TypeMismatch(kEndpoint, "array", json); } std::vector jobs; - std::transform( - json.begin(), json.end(), std::back_inserter(jobs), - [](const nlohmann::json& item) { return ::Parse(kEndpoint, item); }); + std::transform(json.begin(), json.end(), std::back_inserter(jobs), + [](const nlohmann::json& item) { return ::Parse(kEndpoint, item); }); return jobs; } @@ -281,14 +273,11 @@ std::vector Historical::BatchListFiles( for (const auto& file_json : json.items()) { const auto& file_obj = file_json.value(); BatchFileDesc file_desc; - file_desc.filename = - detail::ParseAt(kEndpoint, file_obj, "filename"); - file_desc.size = - detail::ParseAt(kEndpoint, file_obj, "size"); + file_desc.filename = detail::ParseAt(kEndpoint, file_obj, "filename"); + file_desc.size = detail::ParseAt(kEndpoint, file_obj, "size"); file_desc.hash = detail::ParseAt(kEndpoint, file_obj, "hash"); const auto& url_obj = detail::CheckedAt(kEndpoint, file_obj, "urls"); - file_desc.https_url = - detail::ParseAt(kEndpoint, url_obj, "https"); + file_desc.https_url = detail::ParseAt(kEndpoint, url_obj, "https"); file_desc.ftp_url = detail::ParseAt(kEndpoint, url_obj, "ftp"); files.emplace_back(file_desc); } @@ -322,8 +311,7 @@ std::filesystem::path Historical::BatchDownload( return file_desc.filename == filename_to_download; }); if (file_desc_it == file_descs.end()) { - throw InvalidArgumentError{"Historical::BatchDownload", - "filename_to_download", + throw InvalidArgumentError{"Historical::BatchDownload", "filename_to_download", "Filename not found for batch job " + job_id}; } std::filesystem::path output_path = job_dir / file_desc_it->filename; @@ -352,8 +340,7 @@ void Historical::DownloadFile(const std::string& url, path = url.substr(slash); } std::ostringstream ss; - ss << '[' << kMethod << "] Downloading batch file " << path << " to " - << output_path; + ss << '[' << kMethod << "] Downloading batch file " << path << " to " << output_path; log_receiver_->Receive(LogLevel::Info, ss.str()); OutFileStream out_file{output_path}; @@ -384,8 +371,7 @@ std::vector Historical::MetadataListPublishers() { } const auto id = detail::ParseAt(kEndpoint, detail_json, "publisher_id"); - auto dataset = - detail::ParseAt(kEndpoint, detail_json, "dataset"); + auto dataset = detail::ParseAt(kEndpoint, detail_json, "dataset"); auto venue = detail::ParseAt(kEndpoint, detail_json, "venue"); auto description = detail::ParseAt(kEndpoint, detail_json, "description"); @@ -398,8 +384,7 @@ std::vector Historical::MetadataListPublishers() { std::vector Historical::MetadataListDatasets() { return this->MetadataListDatasets(DateRange{{}}); } -std::vector Historical::MetadataListDatasets( - const DateRange& date_range) { +std::vector Historical::MetadataListDatasets(const DateRange& date_range) { static const std::string kEndpoint = "Historical::MetadataListDatasets"; static const std::string kPath = ::BuildMetadataPath(".list_datasets"); httplib::Params params{}; @@ -442,8 +427,8 @@ std::vector Historical::MetadataListSchemas( return schemas; } -std::vector Historical::MetadataListFields( - Encoding encoding, Schema schema) { +std::vector Historical::MetadataListFields(Encoding encoding, + Schema schema) { static const std::string kEndpoint = "Historical::MetadataListFields"; static const std::string kPath = ::BuildMetadataPath(".list_fields"); const nlohmann::json json = client_.GetJson( @@ -488,37 +473,32 @@ std::vector Historical::MetadataListUnitPrices( } for (const auto& schema_json : unit_prices_json.items()) { if (!schema_json.value().is_number()) { - throw JsonResponseError::TypeMismatch( - kEndpoint, "nested number", schema_json.key(), schema_json.value()); + throw JsonResponseError::TypeMismatch(kEndpoint, "nested number", + schema_json.key(), schema_json.value()); } - unit_prices.emplace(FromString(schema_json.key()), - schema_json.value()); + unit_prices.emplace(FromString(schema_json.key()), schema_json.value()); } res.emplace_back(UnitPricesForMode{mode, std::move(unit_prices)}); } return res; } -std::vector -Historical::MetadataGetDatasetCondition(const std::string& dataset) { +std::vector Historical::MetadataGetDatasetCondition( + const std::string& dataset) { return MetadataGetDatasetCondition(httplib::Params{{"dataset", dataset}}); } -std::vector -Historical::MetadataGetDatasetCondition(const std::string& dataset, - const DateRange& date_range) { - httplib::Params params{{"dataset", dataset}, - {"start_date", date_range.start}}; +std::vector Historical::MetadataGetDatasetCondition( + const std::string& dataset, const DateRange& date_range) { + httplib::Params params{{"dataset", dataset}, {"start_date", date_range.start}}; detail::SetIfNotEmpty(¶ms, "end_date", date_range.end); return MetadataGetDatasetCondition(params); } -std::vector -Historical::MetadataGetDatasetCondition(const httplib::Params& params) { - static const std::string kEndpoint = - "Historical::MetadataGetDatasetCondition"; - static const std::string kPath = - ::BuildMetadataPath(".get_dataset_condition"); +std::vector Historical::MetadataGetDatasetCondition( + const httplib::Params& params) { + static const std::string kEndpoint = "Historical::MetadataGetDatasetCondition"; + static const std::string kPath = ::BuildMetadataPath(".get_dataset_condition"); const nlohmann::json json = client_.GetJson(kPath, params); if (!json.is_array()) { throw JsonResponseError::TypeMismatch(kEndpoint, "array", json); @@ -555,13 +535,10 @@ databento::DatasetRange Historical::MetadataGetDatasetRange( std::map> range_by_schema; for (const auto& schema_item : schema_json.items()) { if (!schema_item.value().is_object()) { - throw JsonResponseError::TypeMismatch(kEndpoint, "nested schema object", - json); + throw JsonResponseError::TypeMismatch(kEndpoint, "nested schema object", json); } - auto start = - detail::ParseAt(kEndpoint, schema_item.value(), "start"); - auto end = - detail::ParseAt(kEndpoint, schema_item.value(), "end"); + auto start = detail::ParseAt(kEndpoint, schema_item.value(), "start"); + auto end = detail::ParseAt(kEndpoint, schema_item.value(), "end"); range_by_schema.emplace( FromString(schema_item.key()), DateTimeRange{std::move(start), std::move(end)}); @@ -581,8 +558,7 @@ std::uint64_t Historical::MetadataGetRecordCount( kDefaultSTypeIn, {}); } std::uint64_t Historical::MetadataGetRecordCount( - const std::string& dataset, - const DateTimeRange& datetime_range, + const std::string& dataset, const DateTimeRange& datetime_range, const std::vector& symbols, Schema schema) { return this->MetadataGetRecordCount(dataset, datetime_range, symbols, schema, kDefaultSTypeIn, {}); @@ -602,8 +578,7 @@ std::uint64_t Historical::MetadataGetRecordCount( return this->MetadataGetRecordCount(params); } std::uint64_t Historical::MetadataGetRecordCount( - const std::string& dataset, - const DateTimeRange& datetime_range, + const std::string& dataset, const DateTimeRange& datetime_range, const std::vector& symbols, Schema schema, SType stype_in, std::uint64_t limit) { httplib::Params params{ @@ -616,8 +591,7 @@ std::uint64_t Historical::MetadataGetRecordCount( detail::SetIfPositive(¶ms, "limit", limit); return this->MetadataGetRecordCount(params); } -std::uint64_t Historical::MetadataGetRecordCount( - const httplib::Params& params) { +std::uint64_t Historical::MetadataGetRecordCount(const httplib::Params& params) { static const std::string kPath = ::BuildMetadataPath(".get_record_count"); const nlohmann::json json = client_.PostJson(kPath, params); if (!json.is_number_unsigned()) { @@ -637,8 +611,7 @@ std::uint64_t Historical::MetadataGetBillableSize( kDefaultSTypeIn, {}); } std::uint64_t Historical::MetadataGetBillableSize( - const std::string& dataset, - const DateTimeRange& datetime_range, + const std::string& dataset, const DateTimeRange& datetime_range, const std::vector& symbols, Schema schema) { return this->MetadataGetBillableSize(dataset, datetime_range, symbols, schema, kDefaultSTypeIn, {}); @@ -659,8 +632,7 @@ std::uint64_t Historical::MetadataGetBillableSize( return this->MetadataGetBillableSize(params); } std::uint64_t Historical::MetadataGetBillableSize( - const std::string& dataset, - const DateTimeRange& datetime_range, + const std::string& dataset, const DateTimeRange& datetime_range, const std::vector& symbols, Schema schema, SType stype_in, std::uint64_t limit) { httplib::Params params{ @@ -673,8 +645,7 @@ std::uint64_t Historical::MetadataGetBillableSize( detail::SetIfPositive(¶ms, "limit", limit); return this->MetadataGetBillableSize(params); } -std::uint64_t Historical::MetadataGetBillableSize( - const httplib::Params& params) { +std::uint64_t Historical::MetadataGetBillableSize(const httplib::Params& params) { static const std::string kPath = ::BuildMetadataPath(".get_billable_size"); const nlohmann::json json = client_.PostJson(kPath, params); if (!json.is_number_unsigned()) { @@ -684,28 +655,27 @@ std::uint64_t Historical::MetadataGetBillableSize( return json; } -static const std::string kMetadataGetCostEndpoint = - "Historical::MetadataGetCost"; +static const std::string kMetadataGetCostEndpoint = "Historical::MetadataGetCost"; -double Historical::MetadataGetCost( - const std::string& dataset, const DateTimeRange& datetime_range, - const std::vector& symbols, Schema schema) { +double Historical::MetadataGetCost(const std::string& dataset, + const DateTimeRange& datetime_range, + const std::vector& symbols, + Schema schema) { return this->MetadataGetCost(dataset, datetime_range, symbols, schema, - FeedMode::HistoricalStreaming, kDefaultSTypeIn, - {}); + FeedMode::HistoricalStreaming, kDefaultSTypeIn, {}); } -double Historical::MetadataGetCost( - const std::string& dataset, - const DateTimeRange& datetime_range, - const std::vector& symbols, Schema schema) { +double Historical::MetadataGetCost(const std::string& dataset, + const DateTimeRange& datetime_range, + const std::vector& symbols, + Schema schema) { return this->MetadataGetCost(dataset, datetime_range, symbols, schema, - FeedMode::HistoricalStreaming, kDefaultSTypeIn, - {}); + FeedMode::HistoricalStreaming, kDefaultSTypeIn, {}); } -double Historical::MetadataGetCost( - const std::string& dataset, const DateTimeRange& datetime_range, - const std::vector& symbols, Schema schema, FeedMode mode, - SType stype_in, std::uint64_t limit) { +double Historical::MetadataGetCost(const std::string& dataset, + const DateTimeRange& datetime_range, + const std::vector& symbols, + Schema schema, FeedMode mode, SType stype_in, + std::uint64_t limit) { httplib::Params params{ {"dataset", dataset}, {"start", ToString(datetime_range.start)}, @@ -717,11 +687,11 @@ double Historical::MetadataGetCost( detail::SetIfPositive(¶ms, "limit", limit); return this->MetadataGetCost(params); } -double Historical::MetadataGetCost( - const std::string& dataset, - const DateTimeRange& datetime_range, - const std::vector& symbols, Schema schema, FeedMode mode, - SType stype_in, std::uint64_t limit) { +double Historical::MetadataGetCost(const std::string& dataset, + const DateTimeRange& datetime_range, + const std::vector& symbols, + Schema schema, FeedMode mode, SType stype_in, + std::uint64_t limit) { httplib::Params params{ {"dataset", dataset}, {"start", datetime_range.start}, @@ -737,15 +707,15 @@ double Historical::MetadataGetCost(const HttplibParams& params) { static const std::string kPath = ::BuildMetadataPath(".get_cost"); const nlohmann::json json = client_.PostJson(kPath, params); if (!json.is_number()) { - throw JsonResponseError::TypeMismatch("Historical::MetadataGetCost", - "number", json); + throw JsonResponseError::TypeMismatch("Historical::MetadataGetCost", "number", + json); } return json; } databento::SymbologyResolution Historical::SymbologyResolve( - const std::string& dataset, const std::vector& symbols, - SType stype_in, SType stype_out, const DateRange& date_range) { + const std::string& dataset, const std::vector& symbols, SType stype_in, + SType stype_out, const DateRange& date_range) { static const std::string kEndpoint = "Historical::SymbologyResolve"; static const std::string kPath = ::BuildSymbologyPath(".resolve"); httplib::Params params{{"dataset", dataset}, @@ -763,8 +733,7 @@ databento::SymbologyResolution Historical::SymbologyResolve( const auto& not_found_json = detail::CheckedAt(kEndpoint, json, "not_found"); SymbologyResolution res{{}, {}, {}, stype_in, stype_out}; if (!mappings_json.is_object()) { - throw JsonResponseError::TypeMismatch(kEndpoint, "mappings object", - mappings_json); + throw JsonResponseError::TypeMismatch(kEndpoint, "mappings object", mappings_json); } res.mappings.reserve(mappings_json.size()); for (const auto& mapping : mappings_json.items()) { @@ -774,74 +743,68 @@ databento::SymbologyResolution Historical::SymbologyResolve( mapping_json); } std::vector mapping_intervals; - std::transform(mapping_json.begin(), mapping_json.end(), - std::back_inserter(mapping_intervals), - [](const nlohmann::json& interval_json) { - return MappingInterval{ - detail::ParseAt( - kEndpoint, interval_json, "d0"), - detail::ParseAt( - kEndpoint, interval_json, "d1"), - detail::CheckedAt(kEndpoint, interval_json, "s"), - }; - }); + std::transform( + mapping_json.begin(), mapping_json.end(), std::back_inserter(mapping_intervals), + [](const nlohmann::json& interval_json) { + return MappingInterval{ + detail::ParseAt(kEndpoint, interval_json, "d0"), + detail::ParseAt(kEndpoint, interval_json, "d1"), + detail::CheckedAt(kEndpoint, interval_json, "s"), + }; + }); res.mappings.emplace(mapping.key(), std::move(mapping_intervals)); } if (!partial_json.is_array()) { - throw JsonResponseError::TypeMismatch(kEndpoint, "partial array", - partial_json); + throw JsonResponseError::TypeMismatch(kEndpoint, "partial array", partial_json); } res.partial.reserve(partial_json.size()); for (const auto& symbol : partial_json.items()) { if (!symbol.value().is_string()) { - throw JsonResponseError::TypeMismatch(kEndpoint, "nested string", - symbol.key(), symbol.value()); + throw JsonResponseError::TypeMismatch(kEndpoint, "nested string", symbol.key(), + symbol.value()); } res.partial.emplace_back(symbol.value()); } if (!not_found_json.is_array()) { - throw JsonResponseError::TypeMismatch(kEndpoint, "not_found array", - not_found_json); + throw JsonResponseError::TypeMismatch(kEndpoint, "not_found array", not_found_json); } res.not_found.reserve(not_found_json.size()); for (const auto& symbol : not_found_json.items()) { if (!symbol.value().is_string()) { - throw JsonResponseError::TypeMismatch(kEndpoint, "nested string", - symbol.key(), symbol.value()); + throw JsonResponseError::TypeMismatch(kEndpoint, "nested string", symbol.key(), + symbol.value()); } res.not_found.emplace_back(symbol.value()); } return res; } -static const std::string kTimeseriesGetRangeEndpoint = - "Historical::TimeseriesGetRange"; -static const std::string kTimeseriesGetRangePath = - ::BuildTimeseriesPath(".get_range"); +static const std::string kTimeseriesGetRangeEndpoint = "Historical::TimeseriesGetRange"; +static const std::string kTimeseriesGetRangePath = ::BuildTimeseriesPath(".get_range"); -void Historical::TimeseriesGetRange( - const std::string& dataset, const DateTimeRange& datetime_range, - const std::vector& symbols, Schema schema, - const RecordCallback& record_callback) { - this->TimeseriesGetRange(dataset, datetime_range, symbols, schema, - kDefaultSTypeIn, kDefaultSTypeOut, {}, {}, - record_callback); -} -void Historical::TimeseriesGetRange( - const std::string& dataset, - const DateTimeRange& datetime_range, - const std::vector& symbols, Schema schema, - const RecordCallback& record_callback) { - this->TimeseriesGetRange(dataset, datetime_range, symbols, schema, - kDefaultSTypeIn, kDefaultSTypeOut, {}, {}, - record_callback); +void Historical::TimeseriesGetRange(const std::string& dataset, + const DateTimeRange& datetime_range, + const std::vector& symbols, + Schema schema, + const RecordCallback& record_callback) { + this->TimeseriesGetRange(dataset, datetime_range, symbols, schema, kDefaultSTypeIn, + kDefaultSTypeOut, {}, {}, record_callback); } -void Historical::TimeseriesGetRange( - const std::string& dataset, const DateTimeRange& datetime_range, - const std::vector& symbols, Schema schema, SType stype_in, - SType stype_out, std::uint64_t limit, - const MetadataCallback& metadata_callback, - const RecordCallback& record_callback) { +void Historical::TimeseriesGetRange(const std::string& dataset, + const DateTimeRange& datetime_range, + const std::vector& symbols, + Schema schema, + const RecordCallback& record_callback) { + this->TimeseriesGetRange(dataset, datetime_range, symbols, schema, kDefaultSTypeIn, + kDefaultSTypeOut, {}, {}, record_callback); +} +void Historical::TimeseriesGetRange(const std::string& dataset, + const DateTimeRange& datetime_range, + const std::vector& symbols, + Schema schema, SType stype_in, SType stype_out, + std::uint64_t limit, + const MetadataCallback& metadata_callback, + const RecordCallback& record_callback) { httplib::Params params{ {"dataset", dataset}, {"encoding", "dbn"}, @@ -856,13 +819,13 @@ void Historical::TimeseriesGetRange( this->TimeseriesGetRange(params, metadata_callback, record_callback); } -void Historical::TimeseriesGetRange( - const std::string& dataset, - const DateTimeRange& datetime_range, - const std::vector& symbols, Schema schema, SType stype_in, - SType stype_out, std::uint64_t limit, - const MetadataCallback& metadata_callback, - const RecordCallback& record_callback) { +void Historical::TimeseriesGetRange(const std::string& dataset, + const DateTimeRange& datetime_range, + const std::vector& symbols, + Schema schema, SType stype_in, SType stype_out, + std::uint64_t limit, + const MetadataCallback& metadata_callback, + const RecordCallback& record_callback) { httplib::Params params{ {"dataset", dataset}, {"encoding", "dbn"}, @@ -886,8 +849,7 @@ enum class DecoderState : std::uint8_t { void Historical::TimeseriesGetRange(const HttplibParams& params, const MetadataCallback& metadata_callback, const RecordCallback& record_callback) { - detail::DbnBufferDecoder decoder{upgrade_policy_, metadata_callback, - record_callback}; + detail::DbnBufferDecoder decoder{upgrade_policy_, metadata_callback, record_callback}; bool early_exit = false; this->client_.PostRawStream( @@ -915,31 +877,28 @@ databento::DbnFileStore Historical::TimeseriesGetRangeToFile( const std::string& dataset, const DateTimeRange& datetime_range, const std::vector& symbols, Schema schema, const std::filesystem::path& file_path) { - return this->TimeseriesGetRangeToFile(dataset, datetime_range, symbols, - schema, kDefaultSTypeIn, - kDefaultSTypeOut, {}, file_path); + return this->TimeseriesGetRangeToFile(dataset, datetime_range, symbols, schema, + kDefaultSTypeIn, kDefaultSTypeOut, {}, + file_path); } databento::DbnFileStore Historical::TimeseriesGetRangeToFile( - const std::string& dataset, - const DateTimeRange& datetime_range, + const std::string& dataset, const DateTimeRange& datetime_range, const std::vector& symbols, Schema schema, const std::filesystem::path& file_path) { - return this->TimeseriesGetRangeToFile(dataset, datetime_range, symbols, - schema, kDefaultSTypeIn, - kDefaultSTypeOut, {}, file_path); + return this->TimeseriesGetRangeToFile(dataset, datetime_range, symbols, schema, + kDefaultSTypeIn, kDefaultSTypeOut, {}, + file_path); } databento::DbnFileStore Historical::TimeseriesGetRangeToFile( const std::string& dataset, const DateTimeRange& datetime_range, const std::vector& symbols, Schema schema, SType stype_in, - SType stype_out, std::uint64_t limit, - const std::filesystem::path& file_path) { + SType stype_out, std::uint64_t limit, const std::filesystem::path& file_path) { httplib::Params params{ {"dataset", dataset}, {"encoding", "dbn"}, {"compression", "zstd"}, {"start", ToString(datetime_range.start)}, - {"symbols", - JoinSymbolStrings(kTimeseriesGetRangeToFileEndpoint, symbols)}, + {"symbols", JoinSymbolStrings(kTimeseriesGetRangeToFileEndpoint, symbols)}, {"schema", ToString(schema)}, {"stype_in", ToString(stype_in)}, {"stype_out", ToString(stype_out)}}; @@ -948,18 +907,15 @@ databento::DbnFileStore Historical::TimeseriesGetRangeToFile( return this->TimeseriesGetRangeToFile(params, file_path); } databento::DbnFileStore Historical::TimeseriesGetRangeToFile( - const std::string& dataset, - const DateTimeRange& datetime_range, + const std::string& dataset, const DateTimeRange& datetime_range, const std::vector& symbols, Schema schema, SType stype_in, - SType stype_out, std::uint64_t limit, - const std::filesystem::path& file_path) { + SType stype_out, std::uint64_t limit, const std::filesystem::path& file_path) { httplib::Params params{ {"dataset", dataset}, {"encoding", "dbn"}, {"compression", "zstd"}, {"start", datetime_range.start}, - {"symbols", - JoinSymbolStrings(kTimeseriesGetRangeToFileEndpoint, symbols)}, + {"symbols", JoinSymbolStrings(kTimeseriesGetRangeToFileEndpoint, symbols)}, {"schema", ToString(schema)}, {"stype_in", ToString(stype_in)}, {"stype_out", ToString(stype_out)}}; @@ -971,12 +927,12 @@ databento::DbnFileStore Historical::TimeseriesGetRangeToFile( const HttplibParams& params, const std::filesystem::path& file_path) { { OutFileStream out_file{file_path}; - this->client_.PostRawStream( - kTimeseriesGetRangePath, params, - [&out_file](const char* data, std::size_t length) { - out_file.WriteAll(reinterpret_cast(data), length); - return true; - }); + this->client_.PostRawStream(kTimeseriesGetRangePath, params, + [&out_file](const char* data, std::size_t length) { + out_file.WriteAll( + reinterpret_cast(data), length); + return true; + }); } // Flush out_file return DbnFileStore{log_receiver_, file_path, upgrade_policy_}; } @@ -986,8 +942,7 @@ using databento::HistoricalBuilder; HistoricalBuilder& HistoricalBuilder::SetKeyFromEnv() { char const* env_key = std::getenv("DATABENTO_API_KEY"); if (env_key == nullptr) { - throw Exception{ - "Expected environment variable DATABENTO_API_KEY to be set"}; + throw Exception{"Expected environment variable DATABENTO_API_KEY to be set"}; } return this->SetKey(env_key); } @@ -1002,8 +957,7 @@ HistoricalBuilder& HistoricalBuilder::SetGateway(HistoricalGateway gateway) { return *this; } -HistoricalBuilder& HistoricalBuilder::SetLogReceiver( - ILogReceiver* log_receiver) { +HistoricalBuilder& HistoricalBuilder::SetLogReceiver(ILogReceiver* log_receiver) { log_receiver_ = log_receiver; return *this; } @@ -1034,8 +988,7 @@ Historical HistoricalBuilder::Build() { log_receiver_ = databento::ILogReceiver::Default(); } if (gateway_override_.empty()) { - return Historical{log_receiver_, key_, gateway_, upgrade_policy_, - user_agent_ext_}; + return Historical{log_receiver_, key_, gateway_, upgrade_policy_, user_agent_ext_}; } return Historical{log_receiver_, key_, gateway_override_, port_, upgrade_policy_, user_agent_ext_}; diff --git a/src/live.cpp b/src/live.cpp index 68d230e..2ecd0bb 100644 --- a/src/live.cpp +++ b/src/live.cpp @@ -17,8 +17,7 @@ LiveBuilder::LiveBuilder() : buffer_size_{detail::Buffer::kDefaultBufSize} {} LiveBuilder& LiveBuilder::SetKeyFromEnv() { char const* env_key = std::getenv("DATABENTO_API_KEY"); if (env_key == nullptr) { - throw Exception{ - "Expected environment variable DATABENTO_API_KEY to be set"}; + throw Exception{"Expected environment variable DATABENTO_API_KEY to be set"}; } return this->SetKey(env_key); } @@ -48,14 +47,12 @@ LiveBuilder& LiveBuilder::SetSendTsOut(bool send_ts_out) { return *this; } -LiveBuilder& LiveBuilder::SetUpgradePolicy( - VersionUpgradePolicy upgrade_policy) { +LiveBuilder& LiveBuilder::SetUpgradePolicy(VersionUpgradePolicy upgrade_policy) { upgrade_policy_ = upgrade_policy; return *this; } -LiveBuilder& LiveBuilder::SetLogReceiver( - databento::ILogReceiver* log_receiver) { +LiveBuilder& LiveBuilder::SetLogReceiver(databento::ILogReceiver* log_receiver) { log_receiver_ = log_receiver; return *this; } diff --git a/src/live_blocking.cpp b/src/live_blocking.cpp index 9611d04..b271557 100644 --- a/src/live_blocking.cpp +++ b/src/live_blocking.cpp @@ -27,11 +27,11 @@ namespace { constexpr std::size_t kBucketIdLength = 5; } // namespace -LiveBlocking::LiveBlocking( - ILogReceiver* log_receiver, std::string key, std::string dataset, - bool send_ts_out, VersionUpgradePolicy upgrade_policy, - std::optional heartbeat_interval, - std::size_t buffer_size, std::string user_agent_ext) +LiveBlocking::LiveBlocking(ILogReceiver* log_receiver, std::string key, + std::string dataset, bool send_ts_out, + VersionUpgradePolicy upgrade_policy, + std::optional heartbeat_interval, + std::size_t buffer_size, std::string user_agent_ext) : log_receiver_{log_receiver}, key_{std::move(key)}, @@ -46,12 +46,11 @@ LiveBlocking::LiveBlocking( buffer_{buffer_size}, session_id_{this->Authenticate()} {} -LiveBlocking::LiveBlocking( - ILogReceiver* log_receiver, std::string key, std::string dataset, - std::string gateway, std::uint16_t port, bool send_ts_out, - VersionUpgradePolicy upgrade_policy, - std::optional heartbeat_interval, - std::size_t buffer_size, std::string user_agent_ext) +LiveBlocking::LiveBlocking(ILogReceiver* log_receiver, std::string key, + std::string dataset, std::string gateway, std::uint16_t port, + bool send_ts_out, VersionUpgradePolicy upgrade_policy, + std::optional heartbeat_interval, + std::size_t buffer_size, std::string user_agent_ext) : log_receiver_{log_receiver}, key_{std::move(key)}, dataset_{std::move(dataset)}, @@ -65,13 +64,13 @@ LiveBlocking::LiveBlocking( buffer_{buffer_size}, session_id_{this->Authenticate()} {} -void LiveBlocking::Subscribe(const std::vector& symbols, - Schema schema, SType stype_in) { +void LiveBlocking::Subscribe(const std::vector& symbols, Schema schema, + SType stype_in) { Subscribe(symbols, schema, stype_in, std::string{""}); } -void LiveBlocking::Subscribe(const std::vector& symbols, - Schema schema, SType stype_in, UnixNanos start) { +void LiveBlocking::Subscribe(const std::vector& symbols, Schema schema, + SType stype_in, UnixNanos start) { IncrementSubCounter(); std::ostringstream sub_msg; sub_msg << "schema=" << ToString(schema) << "|stype_in=" << ToString(stype_in) @@ -82,9 +81,8 @@ void LiveBlocking::Subscribe(const std::vector& symbols, LiveSubscription{symbols, schema, stype_in, start, sub_counter_}); } -void LiveBlocking::Subscribe(const std::vector& symbols, - Schema schema, SType stype_in, - const std::string& start) { +void LiveBlocking::Subscribe(const std::vector& symbols, Schema schema, + SType stype_in, const std::string& start) { IncrementSubCounter(); std::ostringstream sub_msg; sub_msg << "schema=" << ToString(schema) << "|stype_in=" << ToString(stype_in) @@ -102,8 +100,8 @@ void LiveBlocking::Subscribe(const std::vector& symbols, } } -void LiveBlocking::SubscribeWithSnapshot( - const std::vector& symbols, Schema schema, SType stype_in) { +void LiveBlocking::SubscribeWithSnapshot(const std::vector& symbols, + Schema schema, SType stype_in) { IncrementSubCounter(); std::ostringstream sub_msg; sub_msg << "schema=" << ToString(schema) << "|stype_in=" << ToString(stype_in) @@ -152,8 +150,8 @@ databento::Metadata LiveBlocking::Start() { buffer_.Reserve(size); client_.ReadExact(buffer_.WriteBegin(), size); buffer_.Fill(size); - auto metadata = DbnDecoder::DecodeMetadataFields(version, buffer_.ReadBegin(), - buffer_.ReadEnd()); + auto metadata = + DbnDecoder::DecodeMetadataFields(version, buffer_.ReadBegin(), buffer_.ReadEnd()); buffer_.Consume(size); // Metadata may leave buffer misaligned. Shift records to ensure 8-byte // alignment @@ -165,8 +163,7 @@ databento::Metadata LiveBlocking::Start() { const databento::Record& LiveBlocking::NextRecord() { return *NextRecord({}); } -const databento::Record* LiveBlocking::NextRecord( - std::chrono::milliseconds timeout) { +const databento::Record* LiveBlocking::NextRecord(std::chrono::milliseconds timeout) { // need some unread_bytes const auto unread_bytes = buffer_.ReadCapacity(); if (unread_bytes == 0) { @@ -191,9 +188,8 @@ const databento::Record* LiveBlocking::NextRecord( current_record_ = Record{BufferRecordHeader()}; const auto bytes_to_consume = current_record_.Size(); buffer_.ConsumeNoShift(bytes_to_consume); - current_record_ = - DbnDecoder::DecodeRecordCompat(version_, upgrade_policy_, send_ts_out_, - &compat_buffer_, current_record_); + current_record_ = DbnDecoder::DecodeRecordCompat( + version_, upgrade_policy_, send_ts_out_, &compat_buffer_, current_record_); return ¤t_record_; } @@ -222,9 +218,8 @@ void LiveBlocking::Resubscribe() { sub_msg << "schema=" << ToString(subscription.schema) << "|stype_in=" << ToString(subscription.stype_in) << "|id=" << std::to_string(sub_counter_); - Subscribe( - sub_msg.str(), subscription.symbols, - std::holds_alternative(subscription.start)); + Subscribe(sub_msg.str(), subscription.symbols, + std::holds_alternative(subscription.start)); } } @@ -245,17 +240,15 @@ std::string LiveBlocking::DecodeChallenge() { } auto first_nl_pos = response.find('\n'); if (first_nl_pos == std::string::npos) { - throw LiveApiError::UnexpectedMsg("Received malformed initial message", - response); + throw LiveApiError::UnexpectedMsg("Received malformed initial message", response); } const auto find_start = first_nl_pos + 1; - auto next_nl_pos = find_start == response.length() - ? std::string::npos - : response.find('\n', find_start); + auto next_nl_pos = find_start == response.length() ? std::string::npos + : response.find('\n', find_start); while (next_nl_pos == std::string::npos) { // read more - buffer_.Fill(client_.ReadSome(buffer_.WriteBegin(), buffer_.WriteCapacity()) - .read_size); + buffer_.Fill( + client_.ReadSome(buffer_.WriteBegin(), buffer_.WriteCapacity()).read_size); if (buffer_.ReadCapacity() == 0) { throw LiveApiError{"Gateway closed socket during authentication"}; } @@ -263,11 +256,10 @@ std::string LiveBlocking::DecodeChallenge() { buffer_.ReadCapacity()}; next_nl_pos = response.find('\n', find_start); } - const auto challenge_line = - response.substr(find_start, next_nl_pos - find_start); + const auto challenge_line = response.substr(find_start, next_nl_pos - find_start); if (challenge_line.compare(0, 4, "cram") != 0) { - throw LiveApiError::UnexpectedMsg( - "Did not receive CRAM challenge when expected", challenge_line); + throw LiveApiError::UnexpectedMsg("Did not receive CRAM challenge when expected", + challenge_line); } const auto equal_pos = challenge_line.find('='); if (equal_pos == std::string::npos || equal_pos + 1 > challenge_line.size()) { @@ -342,24 +334,22 @@ std::uint64_t LiveBlocking::DecodeAuthResp() { buffer_.Clear(); do { const auto read_size = - client_.ReadSome(buffer_.WriteBegin(), buffer_.WriteCapacity()) - .read_size; + client_.ReadSome(buffer_.WriteBegin(), buffer_.WriteCapacity()).read_size; if (read_size == 0) { throw LiveApiError{ "Unexpected end of message received from server after replying to " "CRAM"}; } buffer_.Fill(read_size); - newline_ptr = std::find(buffer_.ReadBegin(), buffer_.ReadEnd(), - static_cast('\n')); + newline_ptr = + std::find(buffer_.ReadBegin(), buffer_.ReadEnd(), static_cast('\n')); } while (newline_ptr == buffer_.ReadEnd()); const std::string response{ reinterpret_cast(buffer_.ReadBegin()), static_cast(newline_ptr - buffer_.ReadBegin())}; { std::ostringstream log_ss; - log_ss << "[LiveBlocking::DecodeAuthResp] Authentication response: " - << response; + log_ss << "[LiveBlocking::DecodeAuthResp] Authentication response: " << response; log_receiver_->Receive(LogLevel::Debug, log_ss.str()); } // set in case Read call also read records. One beyond newline @@ -379,8 +369,7 @@ std::uint64_t LiveBlocking::DecodeAuthResp() { const std::string kv_pair = response.substr(pos, count - pos); const std::size_t eq_pos = kv_pair.find('='); if (eq_pos == std::string::npos) { - throw LiveApiError::UnexpectedMsg("Malformed authentication response", - response); + throw LiveApiError::UnexpectedMsg("Malformed authentication response", response); } const std::string key = kv_pair.substr(0, eq_pos); if (key == "success") { @@ -400,8 +389,7 @@ std::uint64_t LiveBlocking::DecodeAuthResp() { pos = count + 1; } if (!found_success) { - throw LiveApiError{ - "Did not receive success indicator from authentication attempt"}; + throw LiveApiError{"Did not receive success indicator from authentication attempt"}; } if (is_error) { throw InvalidArgumentError{"LiveBlocking::LiveBlocking", "key", @@ -412,9 +400,8 @@ std::uint64_t LiveBlocking::DecodeAuthResp() { void LiveBlocking::IncrementSubCounter() { if (sub_counter_ == std::numeric_limits::max()) { - log_receiver_->Receive( - LogLevel::Warning, - "[LiveBlocking::Subscribe] Exhausted all subscription IDs"); + log_receiver_->Receive(LogLevel::Warning, + "[LiveBlocking::Subscribe] Exhausted all subscription IDs"); } else { ++sub_counter_; } diff --git a/src/live_threaded.cpp b/src/live_threaded.cpp index afb1757..86b231c 100644 --- a/src/live_threaded.cpp +++ b/src/live_threaded.cpp @@ -18,8 +18,7 @@ using databento::LiveThreaded; struct LiveThreaded::Impl { template explicit Impl(ILogReceiver* log_recv, A&&... args) - : log_receiver{log_recv}, - blocking{log_receiver, std::forward(args)...} {} + : log_receiver{log_recv}, blocking{log_receiver, std::forward(args)...} {} void NotifyOfStop() { const std::lock_guard lock{last_cb_ret_mutex}; @@ -55,36 +54,30 @@ LiveThreaded::~LiveThreaded() { } } -LiveThreaded::LiveThreaded( - ILogReceiver* log_receiver, std::string key, std::string dataset, - bool send_ts_out, VersionUpgradePolicy upgrade_policy, - std::optional heartbeat_interval, - std::size_t buffer_size, std::string user_agent_ext) - : impl_{std::make_unique(log_receiver, std::move(key), - std::move(dataset), send_ts_out, - upgrade_policy, heartbeat_interval, +LiveThreaded::LiveThreaded(ILogReceiver* log_receiver, std::string key, + std::string dataset, bool send_ts_out, + VersionUpgradePolicy upgrade_policy, + std::optional heartbeat_interval, + std::size_t buffer_size, std::string user_agent_ext) + : impl_{std::make_unique(log_receiver, std::move(key), std::move(dataset), + send_ts_out, upgrade_policy, heartbeat_interval, buffer_size, std::move(user_agent_ext))} {} -LiveThreaded::LiveThreaded( - ILogReceiver* log_receiver, std::string key, std::string dataset, - std::string gateway, std::uint16_t port, bool send_ts_out, - VersionUpgradePolicy upgrade_policy, - std::optional heartbeat_interval, - std::size_t buffer_size, std::string user_agent_ext) - : impl_{std::make_unique( - log_receiver, std::move(key), std::move(dataset), std::move(gateway), - port, send_ts_out, upgrade_policy, heartbeat_interval, buffer_size, - std::move(user_agent_ext))} {} +LiveThreaded::LiveThreaded(ILogReceiver* log_receiver, std::string key, + std::string dataset, std::string gateway, std::uint16_t port, + bool send_ts_out, VersionUpgradePolicy upgrade_policy, + std::optional heartbeat_interval, + std::size_t buffer_size, std::string user_agent_ext) + : impl_{std::make_unique(log_receiver, std::move(key), std::move(dataset), + std::move(gateway), port, send_ts_out, + upgrade_policy, heartbeat_interval, buffer_size, + std::move(user_agent_ext))} {} const std::string& LiveThreaded::Key() const { return impl_->blocking.Key(); } -const std::string& LiveThreaded::Dataset() const { - return impl_->blocking.Dataset(); -} +const std::string& LiveThreaded::Dataset() const { return impl_->blocking.Dataset(); } -const std::string& LiveThreaded::Gateway() const { - return impl_->blocking.Gateway(); -} +const std::string& LiveThreaded::Gateway() const { return impl_->blocking.Gateway(); } std::uint16_t LiveThreaded::Port() const { return impl_->blocking.Port(); } @@ -98,8 +91,7 @@ std::optional LiveThreaded::HeartbeatInterval() const { return impl_->blocking.HeartbeatInterval(); } -const std::vector& LiveThreaded::Subscriptions() - const { +const std::vector& LiveThreaded::Subscriptions() const { return impl_->blocking.Subscriptions(); } @@ -107,24 +99,23 @@ std::vector& LiveThreaded::Subscriptions() { return impl_->blocking.Subscriptions(); } -void LiveThreaded::Subscribe(const std::vector& symbols, - Schema schema, SType stype_in) { +void LiveThreaded::Subscribe(const std::vector& symbols, Schema schema, + SType stype_in) { impl_->blocking.Subscribe(symbols, schema, stype_in); } -void LiveThreaded::Subscribe(const std::vector& symbols, - Schema schema, SType stype_in, UnixNanos start) { +void LiveThreaded::Subscribe(const std::vector& symbols, Schema schema, + SType stype_in, UnixNanos start) { impl_->blocking.Subscribe(symbols, schema, stype_in, start); } -void LiveThreaded::Subscribe(const std::vector& symbols, - Schema schema, SType stype_in, - const std::string& start) { +void LiveThreaded::Subscribe(const std::vector& symbols, Schema schema, + SType stype_in, const std::string& start) { impl_->blocking.Subscribe(symbols, schema, stype_in, start); } -void LiveThreaded::SubscribeWithSnapshot( - const std::vector& symbols, Schema schema, SType stype_in) { +void LiveThreaded::SubscribeWithSnapshot(const std::vector& symbols, + Schema schema, SType stype_in) { impl_->blocking.SubscribeWithSnapshot(symbols, schema, stype_in); } @@ -149,10 +140,9 @@ void LiveThreaded::Start(MetadataCallback metadata_callback, return; } // Safe to pass raw pointer because `thread_` cannot outlive `impl_` - thread_ = detail::ScopedThread{&LiveThreaded::ProcessingThread, impl_.get(), - std::move(metadata_callback), - std::move(record_callback), - std::move(exception_callback)}; + thread_ = detail::ScopedThread{ + &LiveThreaded::ProcessingThread, impl_.get(), std::move(metadata_callback), + std::move(record_callback), std::move(exception_callback)}; } void LiveThreaded::Reconnect() { impl_->blocking.Reconnect(); } @@ -163,25 +153,22 @@ void LiveThreaded::BlockForStop() { std::unique_lock lock{impl_->last_cb_ret_mutex}; auto* impl = impl_.get(); // wait for stop - impl_->last_cb_ret_cv.wait( - lock, [impl] { return impl->last_cb_ret == KeepGoing::Stop; }); + impl_->last_cb_ret_cv.wait(lock, + [impl] { return impl->last_cb_ret == KeepGoing::Stop; }); } -databento::KeepGoing LiveThreaded::BlockForStop( - std::chrono::milliseconds timeout) { +databento::KeepGoing LiveThreaded::BlockForStop(std::chrono::milliseconds timeout) { std::unique_lock lock{impl_->last_cb_ret_mutex}; auto* impl = impl_.get(); // wait for stop - if (impl_->last_cb_ret_cv.wait_for(lock, timeout, [impl] { - return impl->last_cb_ret == KeepGoing::Stop; - })) { + if (impl_->last_cb_ret_cv.wait_for( + lock, timeout, [impl] { return impl->last_cb_ret == KeepGoing::Stop; })) { return KeepGoing::Stop; } return KeepGoing::Continue; } -void LiveThreaded::ProcessingThread(Impl* impl, - MetadataCallback&& metadata_callback, +void LiveThreaded::ProcessingThread(Impl* impl, MetadataCallback&& metadata_callback, RecordCallback&& record_callback, ExceptionCallback&& exception_callback) { // Thread safety: non-const calls to `blocking` are only performed from this @@ -236,11 +223,9 @@ void LiveThreaded::ProcessingThread(Impl* impl, } LiveThreaded::ExceptionAction LiveThreaded::ExceptionHandler( - Impl* impl, const ExceptionCallback& exception_callback, - const std::exception& exc, std::string_view pretty_function_name, - std::string_view message) { - if (exception_callback && - exception_callback(exc) == ExceptionAction::Restart) { + Impl* impl, const ExceptionCallback& exception_callback, const std::exception& exc, + std::string_view pretty_function_name, std::string_view message) { + if (exception_callback && exception_callback(exc) == ExceptionAction::Restart) { std::ostringstream log_ss; log_ss << pretty_function_name << ' ' << message << exc.what() << ". Attempting to restart session."; diff --git a/src/metadata.cpp b/src/metadata.cpp index 32513b5..23e5f31 100644 --- a/src/metadata.cpp +++ b/src/metadata.cpp @@ -25,8 +25,7 @@ std::ostream& operator<<(std::ostream& stream, std::string ToString(const FieldDetail& field_detail) { return MakeString(field_detail); } -std::ostream& operator<<(std::ostream& stream, - const FieldDetail& field_detail) { +std::ostream& operator<<(std::ostream& stream, const FieldDetail& field_detail) { return StreamOpBuilder{stream} .SetSpacer(" ") .SetTypeName("FieldDetail") @@ -54,13 +53,10 @@ std::ostream& operator<<(std::ostream& stream, std::string ToString(const DatasetRange& dataset_range) { return MakeString(dataset_range); } -std::ostream& operator<<(std::ostream& stream, - const DatasetRange& dataset_range) { +std::ostream& operator<<(std::ostream& stream, const DatasetRange& dataset_range) { std::ostringstream range_by_schema_ss; - auto range_by_schema_helper = StreamOpBuilder{range_by_schema_ss} - .SetSpacer("\n ") - .SetIndent(" ") - .Build(); + auto range_by_schema_helper = + StreamOpBuilder{range_by_schema_ss}.SetSpacer("\n ").SetIndent(" ").Build(); for (const auto& [schema, range] : dataset_range.range_by_schema) { range_by_schema_helper.AddKeyVal(schema, range); } diff --git a/src/pretty.cpp b/src/pretty.cpp index 1f6f193..509017c 100644 --- a/src/pretty.cpp +++ b/src/pretty.cpp @@ -9,8 +9,8 @@ namespace databento::pretty { std::ostream& operator<<(std::ostream& stream, Px px) { - constexpr std::array kDivisors = { - 0, 100'000'000, 10'000'000, 1'000'000, 100'000, 10'000}; + constexpr std::array kDivisors = {0, 100'000'000, 10'000'000, + 1'000'000, 100'000, 10'000}; if (px.IsUndefined()) { stream << "UNDEF_PRICE"; return stream; @@ -32,9 +32,9 @@ std::ostream& operator<<(std::ostream& stream, Px px) { // however by default we want to print all 9 digits const auto precision = orig_precision < 6 ? orig_precision : 9; ss << price_integer << '.' << std::setw(precision) << std::setfill('0') - << (precision == 9 ? price_fraction - : price_fraction / - kDivisors[static_cast(precision)]); + << (precision == 9 + ? price_fraction + : price_fraction / kDivisors[static_cast(precision)]); } stream << ss.str(); return stream; diff --git a/src/record.cpp b/src/record.cpp index 27f4746..6f252ed 100644 --- a/src/record.cpp +++ b/src/record.cpp @@ -54,8 +54,7 @@ std::size_t Record::SizeOfSchema(const Schema schema) { default: { throw InvalidArgumentError{ "Record::SizeOfSchema", "schema", - "unknown value '" + - std::to_string(static_cast(schema)) + "'"}; + "unknown value '" + std::to_string(static_cast(schema)) + "'"}; } } } @@ -101,27 +100,24 @@ databento::RType Record::RTypeFromSchema(const Schema schema) { default: { throw InvalidArgumentError{ "Record::RTypeFromSchema", "schema", - "unknown value '" + - std::to_string(static_cast(schema)) + "'"}; + "unknown value '" + std::to_string(static_cast(schema)) + "'"}; } } } using databento::InstrumentDefMsg; -bool databento::operator==(const InstrumentDefMsg& lhs, - const InstrumentDefMsg& rhs) { +bool databento::operator==(const InstrumentDefMsg& lhs, const InstrumentDefMsg& rhs) { return lhs.hd == rhs.hd && lhs.ts_recv == rhs.ts_recv && lhs.min_price_increment == rhs.min_price_increment && - lhs.display_factor == rhs.display_factor && - lhs.expiration == rhs.expiration && lhs.activation == rhs.activation && + lhs.display_factor == rhs.display_factor && lhs.expiration == rhs.expiration && + lhs.activation == rhs.activation && lhs.high_limit_price == rhs.high_limit_price && lhs.low_limit_price == rhs.low_limit_price && lhs.max_price_variation == rhs.max_price_variation && lhs.unit_of_measure_qty == rhs.unit_of_measure_qty && lhs.min_price_increment_amount == rhs.min_price_increment_amount && - lhs.price_ratio == rhs.price_ratio && - lhs.strike_price == rhs.strike_price && + lhs.price_ratio == rhs.price_ratio && lhs.strike_price == rhs.strike_price && lhs.raw_instrument_id == rhs.raw_instrument_id && lhs.leg_price == rhs.leg_price && lhs.leg_delta == rhs.leg_delta && lhs.inst_attrib_value == rhs.inst_attrib_value && @@ -142,15 +138,14 @@ bool databento::operator==(const InstrumentDefMsg& lhs, lhs.leg_ratio_price_denominator == rhs.leg_ratio_price_denominator && lhs.leg_ratio_qty_numerator == rhs.leg_ratio_qty_numerator && lhs.leg_ratio_qty_denominator == rhs.leg_ratio_qty_denominator && - lhs.leg_underlying_id == rhs.leg_underlying_id && - lhs.appl_id == rhs.appl_id && lhs.maturity_year == rhs.maturity_year && + lhs.leg_underlying_id == rhs.leg_underlying_id && lhs.appl_id == rhs.appl_id && + lhs.maturity_year == rhs.maturity_year && lhs.decay_start_date == rhs.decay_start_date && lhs.channel_id == rhs.channel_id && lhs.leg_count == rhs.leg_count && lhs.leg_index == rhs.leg_index && lhs.currency == rhs.currency && - lhs.settl_currency == rhs.settl_currency && - lhs.secsubtype == rhs.secsubtype && lhs.raw_symbol == rhs.raw_symbol && - lhs.group == rhs.group && lhs.exchange == rhs.exchange && - lhs.asset == rhs.asset && lhs.cfi == rhs.cfi && + lhs.settl_currency == rhs.settl_currency && lhs.secsubtype == rhs.secsubtype && + lhs.raw_symbol == rhs.raw_symbol && lhs.group == rhs.group && + lhs.exchange == rhs.exchange && lhs.asset == rhs.asset && lhs.cfi == rhs.cfi && lhs.security_type == rhs.security_type && lhs.unit_of_measure == rhs.unit_of_measure && lhs.underlying == rhs.underlying && @@ -178,20 +173,17 @@ using databento::ImbalanceMsg; bool databento::operator==(const ImbalanceMsg& lhs, const ImbalanceMsg& rhs) { return lhs.hd == rhs.hd && lhs.ts_recv == rhs.ts_recv && - lhs.ref_price == rhs.ref_price && - lhs.auction_time == rhs.auction_time && + lhs.ref_price == rhs.ref_price && lhs.auction_time == rhs.auction_time && lhs.cont_book_clr_price == rhs.cont_book_clr_price && lhs.auct_interest_clr_price == rhs.auct_interest_clr_price && lhs.ssr_filling_price == rhs.ssr_filling_price && lhs.ind_match_price == rhs.ind_match_price && - lhs.upper_collar == rhs.upper_collar && - lhs.lower_collar == rhs.lower_collar && + lhs.upper_collar == rhs.upper_collar && lhs.lower_collar == rhs.lower_collar && lhs.paired_qty == rhs.paired_qty && lhs.total_imbalance_qty == rhs.total_imbalance_qty && lhs.market_imbalance_qty == rhs.market_imbalance_qty && - lhs.unpaired_qty == rhs.unpaired_qty && - lhs.auction_type == rhs.auction_type && lhs.side == rhs.side && - lhs.auction_status == rhs.auction_status && + lhs.unpaired_qty == rhs.unpaired_qty && lhs.auction_type == rhs.auction_type && + lhs.side == rhs.side && lhs.auction_status == rhs.auction_status && lhs.freeze_status == rhs.freeze_status && lhs.num_extensions == rhs.num_extensions && lhs.unpaired_side == rhs.unpaired_side && @@ -221,6 +213,7 @@ std::ostream& operator<<(std::ostream& stream, const RecordHeader& header) { .AddField("ts_event", header.ts_event) .Finish(); } + std::string ToString(const MboMsg& mbo_msg) { return MakeString(mbo_msg); } std::ostream& operator<<(std::ostream& stream, const MboMsg& mbo_msg) { return StreamOpBuilder{stream} @@ -240,87 +233,113 @@ std::ostream& operator<<(std::ostream& stream, const MboMsg& mbo_msg) { .AddField("sequence", mbo_msg.sequence) .Finish(); } -std::string ToString(const BidAskPair& ba_pair) { return MakeString(ba_pair); } -std::ostream& operator<<(std::ostream& stream, const BidAskPair& ba_pair) { + +std::string ToString(const BidAskPair& bid_ask_pair) { + return MakeString(bid_ask_pair); +} +std::ostream& operator<<(std::ostream& stream, const BidAskPair& bid_ask_pair) { return StreamOpBuilder{stream} .SetSpacer(" ") .SetTypeName("BidAskPair") .Build() - .AddField("bid_px", pretty::Px{ba_pair.bid_px}) - .AddField("ask_px", pretty::Px{ba_pair.ask_px}) - .AddField("bid_sz", ba_pair.bid_sz) - .AddField("ask_sz", ba_pair.ask_sz) - .AddField("bid_ct", ba_pair.bid_ct) - .AddField("ask_ct", ba_pair.ask_ct) + .AddField("bid_px", pretty::Px{bid_ask_pair.bid_px}) + .AddField("ask_px", pretty::Px{bid_ask_pair.ask_px}) + .AddField("bid_sz", bid_ask_pair.bid_sz) + .AddField("ask_sz", bid_ask_pair.ask_sz) + .AddField("bid_ct", bid_ask_pair.bid_ct) + .AddField("ask_ct", bid_ask_pair.ask_ct) .Finish(); } -std::string ToString(const ConsolidatedBidAskPair& ba_pair) { - return MakeString(ba_pair); + +std::string ToString(const ConsolidatedBidAskPair& consolidated_bid_ask_pair) { + return MakeString(consolidated_bid_ask_pair); } std::ostream& operator<<(std::ostream& stream, - const ConsolidatedBidAskPair& ba_pair) { + const ConsolidatedBidAskPair& consolidated_bid_ask_pair) { return StreamOpBuilder{stream} .SetSpacer(" ") .SetTypeName("ConsolidatedBidAskPair") .Build() - .AddField("bid_px", pretty::Px{ba_pair.bid_px}) - .AddField("ask_px", pretty::Px{ba_pair.ask_px}) - .AddField("bid_sz", ba_pair.bid_sz) - .AddField("ask_sz", ba_pair.ask_sz) - .AddField("bid_pb", ba_pair.bid_pb) - .AddField("ask_pb", ba_pair.ask_pb) + .AddField("bid_px", pretty::Px{consolidated_bid_ask_pair.bid_px}) + .AddField("ask_px", pretty::Px{consolidated_bid_ask_pair.ask_px}) + .AddField("bid_sz", consolidated_bid_ask_pair.bid_sz) + .AddField("ask_sz", consolidated_bid_ask_pair.ask_sz) + .AddField("bid_pb", consolidated_bid_ask_pair.bid_pb) + .AddField("ask_pb", consolidated_bid_ask_pair.ask_pb) .Finish(); } -std::string ToString(const Mbp1Msg& mbp_msg) { return MakeString(mbp_msg); } -std::ostream& operator<<(std::ostream& stream, const Mbp1Msg& mbp_msg) { + +std::string ToString(const TradeMsg& trade_msg) { return MakeString(trade_msg); } +std::ostream& operator<<(std::ostream& stream, const TradeMsg& trade_msg) { return StreamOpBuilder{stream} - .SetTypeName("Mbp1Msg") .SetSpacer("\n ") + .SetTypeName("TradeMsg") .Build() - .AddField("hd", mbp_msg.hd) - .AddField("price", pretty::Px{mbp_msg.price}) - .AddField("size", mbp_msg.size) - .AddField("action", mbp_msg.action) - .AddField("side", mbp_msg.side) - .AddField("flags", mbp_msg.flags) - .AddField("depth", mbp_msg.depth) - .AddField("ts_recv", mbp_msg.ts_recv) - .AddField("ts_in_delta", mbp_msg.ts_in_delta) - .AddField("sequence", mbp_msg.sequence) - .AddField("levels", std::get<0>(mbp_msg.levels)) + .AddField("hd", trade_msg.hd) + .AddField("price", pretty::Px{trade_msg.price}) + .AddField("size", trade_msg.size) + .AddField("action", trade_msg.action) + .AddField("side", trade_msg.side) + .AddField("flags", trade_msg.flags) + .AddField("depth", trade_msg.depth) + .AddField("ts_recv", trade_msg.ts_recv) + .AddField("ts_in_delta", trade_msg.ts_in_delta) + .AddField("sequence", trade_msg.sequence) .Finish(); } -std::string ToString(const Mbp10Msg& mbp_msg) { return MakeString(mbp_msg); } -std::ostream& operator<<(std::ostream& stream, const Mbp10Msg& mbp_msg) { - std::ostringstream levelss; - auto levels_helper = - StreamOpBuilder{levelss}.SetSpacer("\n ").SetIndent(" ").Build(); - for (const auto& levels : mbp_msg.levels) { - levels_helper.AddItem(levels); + +std::string ToString(const Mbp1Msg& mbp1_msg) { return MakeString(mbp1_msg); } +std::ostream& operator<<(std::ostream& stream, const Mbp1Msg& mbp1_msg) { + return StreamOpBuilder{stream} + .SetSpacer("\n ") + .SetTypeName("Mbp1Msg") + .Build() + .AddField("hd", mbp1_msg.hd) + .AddField("price", pretty::Px{mbp1_msg.price}) + .AddField("size", mbp1_msg.size) + .AddField("action", mbp1_msg.action) + .AddField("side", mbp1_msg.side) + .AddField("flags", mbp1_msg.flags) + .AddField("depth", mbp1_msg.depth) + .AddField("ts_recv", mbp1_msg.ts_recv) + .AddField("ts_in_delta", mbp1_msg.ts_in_delta) + .AddField("sequence", mbp1_msg.sequence) + + .AddField("levels", std::get<0>(mbp1_msg.levels)) + .Finish(); +} + +std::string ToString(const Mbp10Msg& mbp10_msg) { return MakeString(mbp10_msg); } +std::ostream& operator<<(std::ostream& stream, const Mbp10Msg& mbp10_msg) { + std::ostringstream sub_ss; + auto helper = StreamOpBuilder{sub_ss}.SetSpacer("\n ").SetIndent(" ").Build(); + for (const auto& level : mbp10_msg.levels) { + helper.AddItem(level); } + return StreamOpBuilder{stream} - .SetTypeName("Mbp10Msg") .SetSpacer("\n ") + .SetTypeName("Mbp10Msg") .Build() - .AddField("hd", mbp_msg.hd) - .AddField("price", pretty::Px{mbp_msg.price}) - .AddField("size", mbp_msg.size) - .AddField("action", mbp_msg.action) - .AddField("side", mbp_msg.side) - .AddField("flags", mbp_msg.flags) - .AddField("depth", mbp_msg.depth) - .AddField("ts_recv", mbp_msg.ts_recv) - .AddField("ts_in_delta", mbp_msg.ts_in_delta) - .AddField("sequence", mbp_msg.sequence) - .AddField("levels", - static_cast(levels_helper.Finish())) + .AddField("hd", mbp10_msg.hd) + .AddField("price", pretty::Px{mbp10_msg.price}) + .AddField("size", mbp10_msg.size) + .AddField("action", mbp10_msg.action) + .AddField("side", mbp10_msg.side) + .AddField("flags", mbp10_msg.flags) + .AddField("depth", mbp10_msg.depth) + .AddField("ts_recv", mbp10_msg.ts_recv) + .AddField("ts_in_delta", mbp10_msg.ts_in_delta) + .AddField("sequence", mbp10_msg.sequence) + .AddField("levels", static_cast(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 ") + .SetTypeName("BboMsg") .Build() .AddField("hd", bbo_msg.hd) .AddField("price", pretty::Px{bbo_msg.price}) @@ -329,14 +348,16 @@ std::ostream& operator<<(std::ostream& stream, const BboMsg& bbo_msg) { .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 Cmbp1Msg& cbbo_msg) { return MakeString(cbbo_msg); } + +std::string ToString(const Cmbp1Msg& cmbp1_msg) { return MakeString(cmbp1_msg); } std::ostream& operator<<(std::ostream& stream, const Cmbp1Msg& cmbp1_msg) { return StreamOpBuilder{stream} - .SetTypeName("Cmbp1Msg") .SetSpacer("\n ") + .SetTypeName("Cmbp1Msg") .Build() .AddField("hd", cmbp1_msg.hd) .AddField("price", pretty::Px{cmbp1_msg.price}) @@ -346,14 +367,16 @@ std::ostream& operator<<(std::ostream& stream, const Cmbp1Msg& cmbp1_msg) { .AddField("flags", cmbp1_msg.flags) .AddField("ts_recv", cmbp1_msg.ts_recv) .AddField("ts_in_delta", cmbp1_msg.ts_in_delta) + .AddField("levels", std::get<0>(cmbp1_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} - .SetTypeName("CbboMsg") .SetSpacer("\n ") + .SetTypeName("CbboMsg") .Build() .AddField("hd", cbbo_msg.hd) .AddField("price", pretty::Px{cbbo_msg.price}) @@ -361,32 +384,12 @@ std::ostream& operator<<(std::ostream& stream, const CbboMsg& cbbo_msg) { .AddField("side", cbbo_msg.side) .AddField("flags", cbbo_msg.flags) .AddField("ts_recv", cbbo_msg.ts_recv) + .AddField("levels", std::get<0>(cbbo_msg.levels)) .Finish(); } -std::string ToString(const TradeMsg& trade_msg) { - return MakeString(trade_msg); -} -std::ostream& operator<<(std::ostream& stream, const TradeMsg& trade_msg) { - return StreamOpBuilder{stream} - .SetSpacer("\n ") - .SetTypeName("TradeMsg") - .Build() - .AddField("hd", trade_msg.hd) - .AddField("price", pretty::Px{trade_msg.price}) - .AddField("size", trade_msg.size) - .AddField("action", trade_msg.action) - .AddField("side", trade_msg.side) - .AddField("flags", trade_msg.flags) - .AddField("depth", trade_msg.depth) - .AddField("ts_recv", trade_msg.ts_recv) - .AddField("ts_in_delta", trade_msg.ts_in_delta) - .AddField("sequence", trade_msg.sequence) - .Finish(); -} -std::string ToString(const OhlcvMsg& ohlcv_msg) { - return MakeString(ohlcv_msg); -} + +std::string ToString(const OhlcvMsg& ohlcv_msg) { return MakeString(ohlcv_msg); } std::ostream& operator<<(std::ostream& stream, const OhlcvMsg& ohlcv_msg) { return StreamOpBuilder{stream} .SetSpacer("\n ") @@ -400,9 +403,8 @@ std::ostream& operator<<(std::ostream& stream, const OhlcvMsg& ohlcv_msg) { .AddField("volume", ohlcv_msg.volume) .Finish(); } -std::string ToString(const StatusMsg& status_msg) { - return MakeString(status_msg); -} + +std::string ToString(const StatusMsg& status_msg) { return MakeString(status_msg); } std::ostream& operator<<(std::ostream& stream, const StatusMsg& status_msg) { return StreamOpBuilder{stream} .SetSpacer("\n ") @@ -418,103 +420,100 @@ std::ostream& operator<<(std::ostream& stream, const StatusMsg& status_msg) { .AddField("is_short_sell_restricted", status_msg.is_short_sell_restricted) .Finish(); } -std::string ToString(const InstrumentDefMsg& instr_def_msg) { - return MakeString(instr_def_msg); + +std::string ToString(const InstrumentDefMsg& instrument_def_msg) { + return MakeString(instrument_def_msg); } std::ostream& operator<<(std::ostream& stream, - const InstrumentDefMsg& instr_def_msg) { + const InstrumentDefMsg& instrument_def_msg) { return StreamOpBuilder{stream} .SetSpacer("\n ") .SetTypeName("InstrumentDefMsg") .Build() - .AddField("hd", instr_def_msg.hd) - .AddField("ts_recv", instr_def_msg.ts_recv) + .AddField("hd", instrument_def_msg.hd) + .AddField("ts_recv", instrument_def_msg.ts_recv) .AddField("min_price_increment", - pretty::Px{instr_def_msg.min_price_increment}) - .AddField("display_factor", pretty::Px{instr_def_msg.display_factor}) - .AddField("expiration", instr_def_msg.expiration) - .AddField("activation", instr_def_msg.activation) - .AddField("high_limit_price", pretty::Px{instr_def_msg.high_limit_price}) - .AddField("low_limit_price", pretty::Px{instr_def_msg.low_limit_price}) + pretty::Px{instrument_def_msg.min_price_increment}) + .AddField("display_factor", pretty::Px{instrument_def_msg.display_factor}) + .AddField("expiration", instrument_def_msg.expiration) + .AddField("activation", instrument_def_msg.activation) + .AddField("high_limit_price", pretty::Px{instrument_def_msg.high_limit_price}) + .AddField("low_limit_price", pretty::Px{instrument_def_msg.low_limit_price}) .AddField("max_price_variation", - pretty::Px{instr_def_msg.max_price_variation}) + pretty::Px{instrument_def_msg.max_price_variation}) .AddField("unit_of_measure_qty", - pretty::Px{instr_def_msg.unit_of_measure_qty}) + pretty::Px{instrument_def_msg.unit_of_measure_qty}) .AddField("min_price_increment_amount", - pretty::Px{instr_def_msg.min_price_increment_amount}) - .AddField("price_ratio", pretty::Px{instr_def_msg.price_ratio}) - .AddField("strike_price", pretty::Px{instr_def_msg.strike_price}) - .AddField("raw_instrument_id", instr_def_msg.raw_instrument_id) - .AddField("leg_price", pretty::Px{instr_def_msg.leg_price}) - .AddField("leg_delta", pretty::Px{instr_def_msg.leg_delta}) - .AddField("inst_attrib_value", instr_def_msg.inst_attrib_value) - .AddField("underlying_id", instr_def_msg.underlying_id) - .AddField("market_depth_implied", instr_def_msg.market_depth_implied) - .AddField("market_depth", instr_def_msg.market_depth) - .AddField("market_segment_id", instr_def_msg.market_segment_id) - .AddField("max_trade_vol", instr_def_msg.max_trade_vol) - .AddField("min_lot_size", instr_def_msg.min_lot_size) - .AddField("min_lot_size_block", instr_def_msg.min_lot_size_block) - .AddField("min_lot_size_round_lot", instr_def_msg.min_lot_size_round_lot) - .AddField("min_trade_vol", instr_def_msg.min_trade_vol) - .AddField("contract_multiplier", instr_def_msg.contract_multiplier) - .AddField("decay_quantity", instr_def_msg.decay_quantity) - .AddField("original_contract_size", instr_def_msg.original_contract_size) - .AddField("leg_instrument_id", instr_def_msg.leg_instrument_id) + pretty::Px{instrument_def_msg.min_price_increment_amount}) + .AddField("price_ratio", pretty::Px{instrument_def_msg.price_ratio}) + .AddField("strike_price", pretty::Px{instrument_def_msg.strike_price}) + .AddField("raw_instrument_id", instrument_def_msg.raw_instrument_id) + .AddField("leg_price", pretty::Px{instrument_def_msg.leg_price}) + .AddField("leg_delta", pretty::Px{instrument_def_msg.leg_delta}) + .AddField("inst_attrib_value", instrument_def_msg.inst_attrib_value) + .AddField("underlying_id", instrument_def_msg.underlying_id) + .AddField("market_depth_implied", instrument_def_msg.market_depth_implied) + .AddField("market_depth", instrument_def_msg.market_depth) + .AddField("market_segment_id", instrument_def_msg.market_segment_id) + .AddField("max_trade_vol", instrument_def_msg.max_trade_vol) + .AddField("min_lot_size", instrument_def_msg.min_lot_size) + .AddField("min_lot_size_block", instrument_def_msg.min_lot_size_block) + .AddField("min_lot_size_round_lot", instrument_def_msg.min_lot_size_round_lot) + .AddField("min_trade_vol", instrument_def_msg.min_trade_vol) + .AddField("contract_multiplier", instrument_def_msg.contract_multiplier) + .AddField("decay_quantity", instrument_def_msg.decay_quantity) + .AddField("original_contract_size", instrument_def_msg.original_contract_size) + .AddField("leg_instrument_id", instrument_def_msg.leg_instrument_id) .AddField("leg_ratio_price_numerator", - instr_def_msg.leg_ratio_price_numerator) + instrument_def_msg.leg_ratio_price_numerator) .AddField("leg_ratio_price_denominator", - instr_def_msg.leg_ratio_price_denominator) - .AddField("leg_ratio_qty_numerator", - instr_def_msg.leg_ratio_qty_numerator) + instrument_def_msg.leg_ratio_price_denominator) + .AddField("leg_ratio_qty_numerator", instrument_def_msg.leg_ratio_qty_numerator) .AddField("leg_ratio_qty_denominator", - instr_def_msg.leg_ratio_qty_denominator) - .AddField("leg_underlying_id", instr_def_msg.leg_underlying_id) - .AddField("appl_id", instr_def_msg.appl_id) - .AddField("maturity_year", instr_def_msg.maturity_year) - .AddField("decay_start_date", instr_def_msg.decay_start_date) - .AddField("channel_id", instr_def_msg.channel_id) - .AddField("leg_count", instr_def_msg.leg_count) - .AddField("leg_index", instr_def_msg.leg_index) - .AddField("currency", instr_def_msg.currency) - .AddField("settl_currency", instr_def_msg.settl_currency) - .AddField("secsubtype", instr_def_msg.secsubtype) - .AddField("raw_symbol", instr_def_msg.raw_symbol) - .AddField("group", instr_def_msg.group) - .AddField("exchange", instr_def_msg.exchange) - .AddField("asset", instr_def_msg.asset) - .AddField("cfi", instr_def_msg.cfi) - .AddField("security_type", instr_def_msg.security_type) - .AddField("unit_of_measure", instr_def_msg.unit_of_measure) - .AddField("underlying", instr_def_msg.underlying) - .AddField("strike_price_currency", instr_def_msg.strike_price_currency) - .AddField("leg_raw_symbol", instr_def_msg.leg_raw_symbol) - .AddField("instrument_class", instr_def_msg.instrument_class) - .AddField("match_algorithm", instr_def_msg.match_algorithm) - .AddField("main_fraction", instr_def_msg.main_fraction) - .AddField("price_display_format", instr_def_msg.price_display_format) - .AddField("sub_fraction", instr_def_msg.sub_fraction) - .AddField("underlying_product", instr_def_msg.underlying_product) - .AddField("security_update_action", instr_def_msg.security_update_action) - .AddField("maturity_month", instr_def_msg.maturity_month) - .AddField("maturity_day", instr_def_msg.maturity_day) - .AddField("maturity_week", instr_def_msg.maturity_week) - .AddField("user_defined_instrument", - instr_def_msg.user_defined_instrument) - .AddField("contract_multiplier_unit", - instr_def_msg.contract_multiplier_unit) - .AddField("flow_schedule_type", instr_def_msg.flow_schedule_type) - .AddField("tick_rule", instr_def_msg.tick_rule) - .AddField("leg_instrument_class", instr_def_msg.leg_instrument_class) - .AddField("leg_side", instr_def_msg.leg_side) + instrument_def_msg.leg_ratio_qty_denominator) + .AddField("leg_underlying_id", instrument_def_msg.leg_underlying_id) + .AddField("appl_id", instrument_def_msg.appl_id) + .AddField("maturity_year", instrument_def_msg.maturity_year) + .AddField("decay_start_date", instrument_def_msg.decay_start_date) + .AddField("channel_id", instrument_def_msg.channel_id) + .AddField("leg_count", instrument_def_msg.leg_count) + .AddField("leg_index", instrument_def_msg.leg_index) + .AddField("currency", instrument_def_msg.currency) + .AddField("settl_currency", instrument_def_msg.settl_currency) + .AddField("secsubtype", instrument_def_msg.secsubtype) + .AddField("raw_symbol", instrument_def_msg.raw_symbol) + .AddField("group", instrument_def_msg.group) + .AddField("exchange", instrument_def_msg.exchange) + .AddField("asset", instrument_def_msg.asset) + .AddField("cfi", instrument_def_msg.cfi) + .AddField("security_type", instrument_def_msg.security_type) + .AddField("unit_of_measure", instrument_def_msg.unit_of_measure) + .AddField("underlying", instrument_def_msg.underlying) + .AddField("strike_price_currency", instrument_def_msg.strike_price_currency) + .AddField("leg_raw_symbol", instrument_def_msg.leg_raw_symbol) + .AddField("instrument_class", instrument_def_msg.instrument_class) + .AddField("match_algorithm", instrument_def_msg.match_algorithm) + .AddField("main_fraction", instrument_def_msg.main_fraction) + .AddField("price_display_format", instrument_def_msg.price_display_format) + .AddField("sub_fraction", instrument_def_msg.sub_fraction) + .AddField("underlying_product", instrument_def_msg.underlying_product) + .AddField("security_update_action", instrument_def_msg.security_update_action) + .AddField("maturity_month", instrument_def_msg.maturity_month) + .AddField("maturity_day", instrument_def_msg.maturity_day) + .AddField("maturity_week", instrument_def_msg.maturity_week) + .AddField("user_defined_instrument", instrument_def_msg.user_defined_instrument) + .AddField("contract_multiplier_unit", instrument_def_msg.contract_multiplier_unit) + .AddField("flow_schedule_type", instrument_def_msg.flow_schedule_type) + .AddField("tick_rule", instrument_def_msg.tick_rule) + .AddField("leg_instrument_class", instrument_def_msg.leg_instrument_class) + .AddField("leg_side", instrument_def_msg.leg_side) .Finish(); } std::string ToString(const ImbalanceMsg& imbalance_msg) { return MakeString(imbalance_msg); } -std::ostream& operator<<(std::ostream& stream, - const ImbalanceMsg& imbalance_msg) { +std::ostream& operator<<(std::ostream& stream, const ImbalanceMsg& imbalance_msg) { return StreamOpBuilder{stream} .SetSpacer("\n ") .SetTypeName("ImbalanceMsg") @@ -523,12 +522,10 @@ std::ostream& operator<<(std::ostream& stream, .AddField("ts_recv", imbalance_msg.ts_recv) .AddField("ref_price", pretty::Px{imbalance_msg.ref_price}) .AddField("auction_time", imbalance_msg.auction_time) - .AddField("cont_book_clr_price", - pretty::Px{imbalance_msg.cont_book_clr_price}) + .AddField("cont_book_clr_price", pretty::Px{imbalance_msg.cont_book_clr_price}) .AddField("auct_interest_clr_price", pretty::Px{imbalance_msg.auct_interest_clr_price}) - .AddField("ssr_filling_price", - pretty::Px{imbalance_msg.ssr_filling_price}) + .AddField("ssr_filling_price", pretty::Px{imbalance_msg.ssr_filling_price}) .AddField("ind_match_price", pretty::Px{imbalance_msg.ind_match_price}) .AddField("upper_collar", pretty::Px{imbalance_msg.upper_collar}) .AddField("lower_collar", pretty::Px{imbalance_msg.lower_collar}) @@ -566,30 +563,16 @@ std::ostream& operator<<(std::ostream& stream, const StatMsg& stat_msg) { .Finish(); } -std::string ToString(const ErrorMsg& err_msg) { return MakeString(err_msg); } -std::ostream& operator<<(std::ostream& stream, const ErrorMsg& err_msg) { +std::string ToString(const ErrorMsg& error_msg) { return MakeString(error_msg); } +std::ostream& operator<<(std::ostream& stream, const ErrorMsg& error_msg) { return StreamOpBuilder{stream} .SetSpacer("\n ") .SetTypeName("ErrorMsg") .Build() - .AddField("hd", err_msg.hd) - .AddField("err", err_msg.err) - .AddField("code", err_msg.code) - .AddField("is_last", err_msg.is_last) - .Finish(); -} - -std::string ToString(const SystemMsg& system_msg) { - return MakeString(system_msg); -} -std::ostream& operator<<(std::ostream& stream, const SystemMsg& system_msg) { - return StreamOpBuilder{stream} - .SetSpacer("\n ") - .SetTypeName("SystemMsg") - .Build() - .AddField("hd", system_msg.hd) - .AddField("msg", system_msg.msg) - .AddField("code", system_msg.code) + .AddField("hd", error_msg.hd) + .AddField("err", error_msg.err) + .AddField("code", error_msg.code) + .AddField("is_last", error_msg.is_last) .Finish(); } @@ -611,4 +594,17 @@ std::ostream& operator<<(std::ostream& stream, .AddField("end_ts", symbol_mapping_msg.end_ts) .Finish(); } + +std::string ToString(const SystemMsg& system_msg) { return MakeString(system_msg); } +std::ostream& operator<<(std::ostream& stream, const SystemMsg& system_msg) { + return StreamOpBuilder{stream} + .SetSpacer("\n ") + .SetTypeName("SystemMsg") + .Build() + .AddField("hd", system_msg.hd) + .AddField("msg", system_msg.msg) + .AddField("code", system_msg.code) + .Finish(); +} + } // namespace databento diff --git a/src/stream_op_helper.hpp b/src/stream_op_helper.hpp index 2e5b650..9b53823 100644 --- a/src/stream_op_helper.hpp +++ b/src/stream_op_helper.hpp @@ -69,17 +69,14 @@ class StreamOpHelper { template void FmtToStream(const std::array& val) { stream_ << '"'; - stream_.write(val.data(), - static_cast(::strlen(val.data()))); + stream_.write(val.data(), static_cast(::strlen(val.data()))); stream_ << '"'; } public: - StreamOpHelper(std::ostream& stream, std::string_view type_name, - std::string spacer, std::string indent) - : stream_{stream}, - spacer_{std::move(spacer)}, - indent_{std::move(indent)} { + StreamOpHelper(std::ostream& stream, std::string_view type_name, std::string spacer, + std::string indent) + : stream_{stream}, spacer_{std::move(spacer)}, indent_{std::move(indent)} { if (type_name.empty()) { stream_ << '{'; } else { diff --git a/src/symbol_map.cpp b/src/symbol_map.cpp index 4eade88..e305764 100644 --- a/src/symbol_map.cpp +++ b/src/symbol_map.cpp @@ -32,8 +32,7 @@ bool IsInverse(const databento::Metadata& metadata) { TsSymbolMap::TsSymbolMap(const Metadata& metadata) { if (::IsInverse(metadata)) { for (const auto& mapping : metadata.mappings) { - const auto iid = - static_cast(std::stoul(mapping.raw_symbol)); + const auto iid = static_cast(std::stoul(mapping.raw_symbol)); for (const auto& interval : mapping.intervals) { // Handle old symbology format if (interval.symbol.empty()) { @@ -51,16 +50,14 @@ TsSymbolMap::TsSymbolMap(const Metadata& metadata) { if (interval.symbol.empty()) { continue; } - const auto iid = - static_cast(std::stoul(interval.symbol)); + const auto iid = static_cast(std::stoul(interval.symbol)); Insert(iid, interval.start_date, interval.end_date, symbol); } } } } -void TsSymbolMap::Insert(std::uint32_t instrument_id, - date::year_month_day start_date, +void TsSymbolMap::Insert(std::uint32_t instrument_id, date::year_month_day start_date, date::year_month_day end_date, const std::shared_ptr& symbol) { if (start_date > end_date) { @@ -72,15 +69,13 @@ void TsSymbolMap::Insert(std::uint32_t instrument_id, return; } for (date::sys_days day = start_date; day < end_date; day += date::days{1}) { - map_.emplace(std::make_pair(date::year_month_day{day}, instrument_id), - symbol); + map_.emplace(std::make_pair(date::year_month_day{day}, instrument_id), symbol); } } using databento::PitSymbolMap; -PitSymbolMap::PitSymbolMap(const Metadata& metadata, - date::year_month_day date) { +PitSymbolMap::PitSymbolMap(const Metadata& metadata, date::year_month_day date) { if (date::sys_days{date} < date::floor(metadata.start) || // need to compare with `end` as datetime to handle midnight case UnixNanos{date::sys_days{date}} >= metadata.end) { @@ -89,22 +84,20 @@ PitSymbolMap::PitSymbolMap(const Metadata& metadata, } const auto is_inverse = IsInverse(metadata); for (const auto& mapping : metadata.mappings) { - const auto interval_it = std::find_if( - mapping.intervals.begin(), mapping.intervals.end(), - [date](const MappingInterval& interval) { - return date >= interval.start_date && date < interval.end_date; - }); + const auto interval_it = + std::find_if(mapping.intervals.begin(), mapping.intervals.end(), + [date](const MappingInterval& interval) { + return date >= interval.start_date && date < interval.end_date; + }); // Empty symbols in old symbology format if (interval_it == mapping.intervals.end() || interval_it->symbol.empty()) { continue; } if (is_inverse) { - const auto iid = - static_cast(std::stoul(mapping.raw_symbol)); + const auto iid = static_cast(std::stoul(mapping.raw_symbol)); map_.emplace(iid, interval_it->symbol); } else { - const auto iid = - static_cast(std::stoul(interval_it->symbol)); + const auto iid = static_cast(std::stoul(interval_it->symbol)); map_.emplace(iid, mapping.raw_symbol); } } @@ -114,8 +107,7 @@ template void PitSymbolMap::OnSymbolMapping(const SymbolMappingRec& symbol_mapping) { const auto it = map_.find(symbol_mapping.hd.instrument_id); if (it == map_.end()) { - map_.emplace(symbol_mapping.hd.instrument_id, - symbol_mapping.STypeOutSymbol()); + map_.emplace(symbol_mapping.hd.instrument_id, symbol_mapping.STypeOutSymbol()); } else { it->second = symbol_mapping.STypeOutSymbol(); } @@ -133,7 +125,5 @@ void PitSymbolMap::OnRecord(const Record& record) { } // Explicit instantiation -template void PitSymbolMap::OnSymbolMapping( - const SymbolMappingMsgV1& symbol_mapping); -template void PitSymbolMap::OnSymbolMapping( - const SymbolMappingMsgV2& symbol_mapping); +template void PitSymbolMap::OnSymbolMapping(const SymbolMappingMsgV1& symbol_mapping); +template void PitSymbolMap::OnSymbolMapping(const SymbolMappingMsgV2& symbol_mapping); diff --git a/src/symbology.cpp b/src/symbology.cpp index 4414d30..aa93e4f 100644 --- a/src/symbology.cpp +++ b/src/symbology.cpp @@ -25,8 +25,7 @@ TsSymbolMap SymbologyResolution::CreateSymbolMap() const { for (const auto& [orig_symbol, intervals] : mappings) { auto symbol = std::make_shared(orig_symbol); for (const auto& interval : intervals) { - const auto iid = - static_cast(std::stoul(interval.symbol)); + const auto iid = static_cast(std::stoul(interval.symbol)); res.Insert(iid, interval.start_date, interval.end_date, symbol); } } @@ -34,17 +33,15 @@ TsSymbolMap SymbologyResolution::CreateSymbolMap() const { return res; } -std::string JoinSymbolStrings( - const std::string& method_name, - std::vector::const_iterator symbols_begin, - std::vector::const_iterator symbols_end) { +std::string JoinSymbolStrings(const std::string& method_name, + std::vector::const_iterator symbols_begin, + std::vector::const_iterator symbols_end) { if (symbols_begin == symbols_end) { throw InvalidArgumentError{method_name, "symbols", "Cannot be empty"}; } return std::accumulate(symbols_begin, symbols_end, std::string{}, [](std::string acc, const std::string& sym) { - return acc.empty() ? sym - : std::move(acc) + ',' + sym; + return acc.empty() ? sym : std::move(acc) + ',' + sym; }); } @@ -56,12 +53,9 @@ std::string JoinSymbolStrings(const std::string& method_name, return JoinSymbolStrings(method_name, symbols.begin(), symbols.end()); } -std::string ToString(const SymbologyResolution& sym_res) { - return MakeString(sym_res); -} +std::string ToString(const SymbologyResolution& sym_res) { return MakeString(sym_res); } -std::ostream& operator<<(std::ostream& stream, - const SymbologyResolution& sym_res) { +std::ostream& operator<<(std::ostream& stream, const SymbologyResolution& sym_res) { auto stream_helper = StreamOpBuilder{stream} .SetSpacer("\n ") .SetTypeName("SymbologyResolution") @@ -86,17 +80,16 @@ std::ostream& operator<<(std::ostream& stream, .AddItem(static_cast(interval_helper.Finish())) .Finish())); } - stream_helper.AddField( - "mappings", static_cast(mappings_helper.Finish())); + stream_helper.AddField("mappings", + static_cast(mappings_helper.Finish())); intermediate.str(""); - auto partial_helper = - intermediate_builder.SetIndent("").SetSpacer(" ").Build(); + auto partial_helper = intermediate_builder.SetIndent("").SetSpacer(" ").Build(); for (const auto& symbol : sym_res.partial) { partial_helper.AddItem(symbol); } - stream_helper.AddField( - "partial", static_cast(partial_helper.Finish())); + stream_helper.AddField("partial", + static_cast(partial_helper.Finish())); intermediate.str(""); auto not_found_helper = intermediate_builder.Build(); diff --git a/src/v1.cpp b/src/v1.cpp index 8ad1a1a..40d0304 100644 --- a/src/v1.cpp +++ b/src/v1.cpp @@ -14,9 +14,9 @@ namespace databento::v1 { v2::InstrumentDefMsg InstrumentDefMsg::ToV2() const { v2::InstrumentDefMsg ret{ - RecordHeader{ - sizeof(v2::InstrumentDefMsg) / RecordHeader::kLengthMultiplier, - RType::InstrumentDef, hd.publisher_id, hd.instrument_id, hd.ts_event}, + RecordHeader{sizeof(v2::InstrumentDefMsg) / RecordHeader::kLengthMultiplier, + RType::InstrumentDef, hd.publisher_id, hd.instrument_id, + hd.ts_event}, ts_recv, min_price_increment, display_factor, @@ -79,16 +79,14 @@ v2::InstrumentDefMsg InstrumentDefMsg::ToV2() const { tick_rule, {}}; std::copy(currency.begin(), currency.end(), ret.currency.begin()); - std::copy(settl_currency.begin(), settl_currency.end(), - ret.settl_currency.begin()); + std::copy(settl_currency.begin(), settl_currency.end(), ret.settl_currency.begin()); std::copy(secsubtype.begin(), secsubtype.end(), ret.secsubtype.begin()); 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(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()); @@ -99,9 +97,9 @@ v2::InstrumentDefMsg InstrumentDefMsg::ToV2() const { 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}, + RecordHeader{sizeof(v3::InstrumentDefMsg) / RecordHeader::kLengthMultiplier, + RType::InstrumentDef, hd.publisher_id, hd.instrument_id, + hd.ts_event}, ts_recv, min_price_increment, display_factor, @@ -177,8 +175,7 @@ v3::InstrumentDefMsg InstrumentDefMsg::ToV3() const { 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(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()); @@ -187,20 +184,10 @@ v3::InstrumentDefMsg InstrumentDefMsg::ToV3() const { return ret; } -template <> -v2::InstrumentDefMsg InstrumentDefMsg::Upgrade() const { - return ToV2(); -} -template <> -v3::InstrumentDefMsg InstrumentDefMsg::Upgrade() const { - return ToV3(); -} - v3::StatMsg StatMsg::ToV3() const { return v3::StatMsg{ RecordHeader{sizeof(v3::StatMsg) / RecordHeader::kLengthMultiplier, - RType::Statistics, hd.publisher_id, hd.instrument_id, - hd.ts_event}, + RType::Statistics, hd.publisher_id, hd.instrument_id, hd.ts_event}, ts_recv, ts_ref, price, @@ -214,16 +201,10 @@ v3::StatMsg StatMsg::ToV3() const { {}}; } -template <> -v3::StatMsg StatMsg::Upgrade() const { - return ToV3(); -} - v2::ErrorMsg ErrorMsg::ToV2() const { v2::ErrorMsg ret{ - RecordHeader{sizeof(v2::ErrorMsg) / RecordHeader::kLengthMultiplier, - RType::Error, hd.publisher_id, hd.instrument_id, - hd.ts_event}, + RecordHeader{sizeof(v2::ErrorMsg) / RecordHeader::kLengthMultiplier, RType::Error, + hd.publisher_id, hd.instrument_id, hd.ts_event}, {}, ErrorCode::Unset, std::numeric_limits::max()}; @@ -231,16 +212,11 @@ v2::ErrorMsg ErrorMsg::ToV2() const { return ret; } -template <> -v2::ErrorMsg ErrorMsg::Upgrade() const { - return ToV2(); -} - v2::SymbolMappingMsg SymbolMappingMsg::ToV2() const { v2::SymbolMappingMsg ret{ - RecordHeader{ - sizeof(v2::SymbolMappingMsg) / RecordHeader::kLengthMultiplier, - RType::SymbolMapping, hd.publisher_id, hd.instrument_id, hd.ts_event}, + RecordHeader{sizeof(v2::SymbolMappingMsg) / RecordHeader::kLengthMultiplier, + RType::SymbolMapping, hd.publisher_id, hd.instrument_id, + hd.ts_event}, // Intentionally invalid // NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange) static_cast(std::numeric_limits::max()), @@ -258,16 +234,10 @@ v2::SymbolMappingMsg SymbolMappingMsg::ToV2() const { return ret; } -template <> -v2::SymbolMappingMsg SymbolMappingMsg::Upgrade() const { - return ToV2(); -} - v2::SystemMsg SystemMsg::ToV2() const { v2::SystemMsg ret{ RecordHeader{sizeof(v2::SystemMsg) / RecordHeader::kLengthMultiplier, - RType::System, hd.publisher_id, hd.instrument_id, - hd.ts_event}, + RType::System, hd.publisher_id, hd.instrument_id, hd.ts_event}, {}, IsHeartbeat() ? SystemCode::Heartbeat : SystemCode::Unset}; std::copy(msg.begin(), msg.end(), ret.msg.begin()); @@ -275,15 +245,26 @@ v2::SystemMsg SystemMsg::ToV2() const { } template <> -v2::SystemMsg SystemMsg::Upgrade() const { +v2::ErrorMsg ErrorMsg::Upgrade() const { return ToV2(); } +std::string ToString(const ErrorMsg& error_msg) { return MakeString(error_msg); } +std::ostream& operator<<(std::ostream& stream, const ErrorMsg& error_msg) { + return StreamOpBuilder{stream} + .SetSpacer("\n ") + .SetTypeName("ErrorMsg") + .Build() + .AddField("hd", error_msg.hd) + .AddField("err", error_msg.err) + .Finish(); +} + bool operator==(const InstrumentDefMsg& lhs, const InstrumentDefMsg& rhs) { return lhs.hd == rhs.hd && lhs.ts_recv == rhs.ts_recv && lhs.min_price_increment == rhs.min_price_increment && - lhs.display_factor == rhs.display_factor && - lhs.expiration == rhs.expiration && lhs.activation == rhs.activation && + lhs.display_factor == rhs.display_factor && lhs.expiration == rhs.expiration && + lhs.activation == rhs.activation && lhs.high_limit_price == rhs.high_limit_price && lhs.low_limit_price == rhs.low_limit_price && lhs.max_price_variation == rhs.max_price_variation && @@ -309,10 +290,9 @@ bool operator==(const InstrumentDefMsg& lhs, const InstrumentDefMsg& rhs) { lhs.appl_id == rhs.appl_id && lhs.maturity_year == rhs.maturity_year && lhs.decay_start_date == rhs.decay_start_date && lhs.channel_id == rhs.channel_id && lhs.currency == rhs.currency && - lhs.settl_currency == rhs.settl_currency && - lhs.secsubtype == rhs.secsubtype && lhs.raw_symbol == rhs.raw_symbol && - lhs.group == rhs.group && lhs.exchange == rhs.exchange && - lhs.asset == rhs.asset && lhs.cfi == rhs.cfi && + lhs.settl_currency == rhs.settl_currency && lhs.secsubtype == rhs.secsubtype && + lhs.raw_symbol == rhs.raw_symbol && lhs.group == rhs.group && + lhs.exchange == rhs.exchange && lhs.asset == rhs.asset && lhs.cfi == rhs.cfi && lhs.security_type == rhs.security_type && lhs.unit_of_measure == rhs.unit_of_measure && lhs.underlying == rhs.underlying && @@ -336,87 +316,100 @@ bool operator==(const InstrumentDefMsg& lhs, const InstrumentDefMsg& rhs) { lhs.tick_rule == rhs.tick_rule; } -std::string ToString(const InstrumentDefMsg& instr_def_msg) { - return MakeString(instr_def_msg); +template <> +v2::InstrumentDefMsg InstrumentDefMsg::Upgrade() const { + return ToV2(); +} + +template <> +v3::InstrumentDefMsg InstrumentDefMsg::Upgrade() const { + return ToV3(); +} + +std::string ToString(const InstrumentDefMsg& instrument_def_msg) { + return MakeString(instrument_def_msg); } std::ostream& operator<<(std::ostream& stream, - const InstrumentDefMsg& instr_def_msg) { + const InstrumentDefMsg& instrument_def_msg) { return StreamOpBuilder{stream} .SetSpacer("\n ") - .SetTypeName("v1::InstrumentDefMsg") + .SetTypeName("InstrumentDefMsg") .Build() - .AddField("hd", instr_def_msg.hd) - .AddField("ts_recv", instr_def_msg.ts_recv) + .AddField("hd", instrument_def_msg.hd) + .AddField("ts_recv", instrument_def_msg.ts_recv) .AddField("min_price_increment", - pretty::Px{instr_def_msg.min_price_increment}) - .AddField("display_factor", pretty::Px{instr_def_msg.display_factor}) - .AddField("expiration", instr_def_msg.expiration) - .AddField("activation", instr_def_msg.activation) - .AddField("high_limit_price", pretty::Px{instr_def_msg.high_limit_price}) - .AddField("low_limit_price", pretty::Px{instr_def_msg.low_limit_price}) + pretty::Px{instrument_def_msg.min_price_increment}) + .AddField("display_factor", pretty::Px{instrument_def_msg.display_factor}) + .AddField("expiration", instrument_def_msg.expiration) + .AddField("activation", instrument_def_msg.activation) + .AddField("high_limit_price", pretty::Px{instrument_def_msg.high_limit_price}) + .AddField("low_limit_price", pretty::Px{instrument_def_msg.low_limit_price}) .AddField("max_price_variation", - pretty::Px{instr_def_msg.max_price_variation}) + pretty::Px{instrument_def_msg.max_price_variation}) .AddField("trading_reference_price", - pretty::Px{instr_def_msg.trading_reference_price}) + pretty::Px{instrument_def_msg.trading_reference_price}) .AddField("unit_of_measure_qty", - pretty::Px{instr_def_msg.unit_of_measure_qty}) + pretty::Px{instrument_def_msg.unit_of_measure_qty}) .AddField("min_price_increment_amount", - pretty::Px{instr_def_msg.min_price_increment_amount}) - .AddField("price_ratio", pretty::Px{instr_def_msg.price_ratio}) - .AddField("inst_attrib_value", instr_def_msg.inst_attrib_value) - .AddField("underlying_id", instr_def_msg.underlying_id) - .AddField("raw_instrument_id", instr_def_msg.raw_instrument_id) - .AddField("market_depth_implied", instr_def_msg.market_depth_implied) - .AddField("market_depth", instr_def_msg.market_depth) - .AddField("market_segment_id", instr_def_msg.market_segment_id) - .AddField("max_trade_vol", instr_def_msg.max_trade_vol) - .AddField("min_lot_size", instr_def_msg.min_lot_size) - .AddField("min_lot_size_block", instr_def_msg.min_lot_size_block) - .AddField("min_lot_size_round_lot", instr_def_msg.min_lot_size_round_lot) - .AddField("min_trade_vol", instr_def_msg.min_trade_vol) - .AddField("contract_multiplier", instr_def_msg.contract_multiplier) - .AddField("decay_quantity", instr_def_msg.decay_quantity) - .AddField("original_contract_size", instr_def_msg.original_contract_size) - .AddField("trading_reference_date", instr_def_msg.trading_reference_date) - .AddField("appl_id", instr_def_msg.appl_id) - .AddField("maturity_year", instr_def_msg.maturity_year) - .AddField("decay_start_date", instr_def_msg.decay_start_date) - .AddField("channel_id", instr_def_msg.channel_id) - .AddField("currency", instr_def_msg.currency) - .AddField("settl_currency", instr_def_msg.settl_currency) - .AddField("secsubtype", instr_def_msg.secsubtype) - .AddField("raw_symbol", instr_def_msg.raw_symbol) - .AddField("group", instr_def_msg.group) - .AddField("exchange", instr_def_msg.exchange) - .AddField("asset", instr_def_msg.asset) - .AddField("cfi", instr_def_msg.cfi) - .AddField("security_type", instr_def_msg.security_type) - .AddField("unit_of_measure", instr_def_msg.unit_of_measure) - .AddField("underlying", instr_def_msg.underlying) - .AddField("strike_price_currency", instr_def_msg.strike_price_currency) - .AddField("instrument_class", instr_def_msg.instrument_class) - .AddField("strike_price", pretty::Px{instr_def_msg.strike_price}) - .AddField("match_algorithm", instr_def_msg.match_algorithm) + pretty::Px{instrument_def_msg.min_price_increment_amount}) + .AddField("price_ratio", pretty::Px{instrument_def_msg.price_ratio}) + .AddField("inst_attrib_value", instrument_def_msg.inst_attrib_value) + .AddField("underlying_id", instrument_def_msg.underlying_id) + .AddField("raw_instrument_id", instrument_def_msg.raw_instrument_id) + .AddField("market_depth_implied", instrument_def_msg.market_depth_implied) + .AddField("market_depth", instrument_def_msg.market_depth) + .AddField("market_segment_id", instrument_def_msg.market_segment_id) + .AddField("max_trade_vol", instrument_def_msg.max_trade_vol) + .AddField("min_lot_size", instrument_def_msg.min_lot_size) + .AddField("min_lot_size_block", instrument_def_msg.min_lot_size_block) + .AddField("min_lot_size_round_lot", instrument_def_msg.min_lot_size_round_lot) + .AddField("min_trade_vol", instrument_def_msg.min_trade_vol) + .AddField("contract_multiplier", instrument_def_msg.contract_multiplier) + .AddField("decay_quantity", instrument_def_msg.decay_quantity) + .AddField("original_contract_size", instrument_def_msg.original_contract_size) + .AddField("trading_reference_date", instrument_def_msg.trading_reference_date) + .AddField("appl_id", instrument_def_msg.appl_id) + .AddField("maturity_year", instrument_def_msg.maturity_year) + .AddField("decay_start_date", instrument_def_msg.decay_start_date) + .AddField("channel_id", instrument_def_msg.channel_id) + .AddField("currency", instrument_def_msg.currency) + .AddField("settl_currency", instrument_def_msg.settl_currency) + .AddField("secsubtype", instrument_def_msg.secsubtype) + .AddField("raw_symbol", instrument_def_msg.raw_symbol) + .AddField("group", instrument_def_msg.group) + .AddField("exchange", instrument_def_msg.exchange) + .AddField("asset", instrument_def_msg.asset) + .AddField("cfi", instrument_def_msg.cfi) + .AddField("security_type", instrument_def_msg.security_type) + .AddField("unit_of_measure", instrument_def_msg.unit_of_measure) + .AddField("underlying", instrument_def_msg.underlying) + .AddField("strike_price_currency", instrument_def_msg.strike_price_currency) + .AddField("instrument_class", instrument_def_msg.instrument_class) + .AddField("strike_price", pretty::Px{instrument_def_msg.strike_price}) + .AddField("match_algorithm", instrument_def_msg.match_algorithm) .AddField("md_security_trading_status", - instr_def_msg.md_security_trading_status) - .AddField("main_fraction", instr_def_msg.main_fraction) - .AddField("price_display_format", instr_def_msg.price_display_format) - .AddField("settl_price_type", instr_def_msg.settl_price_type) - .AddField("sub_fraction", instr_def_msg.sub_fraction) - .AddField("underlying_product", instr_def_msg.underlying_product) - .AddField("security_update_action", instr_def_msg.security_update_action) - .AddField("maturity_month", instr_def_msg.maturity_month) - .AddField("maturity_day", instr_def_msg.maturity_day) - .AddField("maturity_week", instr_def_msg.maturity_week) - .AddField("user_defined_instrument", - instr_def_msg.user_defined_instrument) - .AddField("contract_multiplier_unit", - instr_def_msg.contract_multiplier_unit) - .AddField("flow_schedule_type", instr_def_msg.flow_schedule_type) - .AddField("tick_rule", instr_def_msg.tick_rule) + instrument_def_msg.md_security_trading_status) + .AddField("main_fraction", instrument_def_msg.main_fraction) + .AddField("price_display_format", instrument_def_msg.price_display_format) + .AddField("settl_price_type", instrument_def_msg.settl_price_type) + .AddField("sub_fraction", instrument_def_msg.sub_fraction) + .AddField("underlying_product", instrument_def_msg.underlying_product) + .AddField("security_update_action", instrument_def_msg.security_update_action) + .AddField("maturity_month", instrument_def_msg.maturity_month) + .AddField("maturity_day", instrument_def_msg.maturity_day) + .AddField("maturity_week", instrument_def_msg.maturity_week) + .AddField("user_defined_instrument", instrument_def_msg.user_defined_instrument) + .AddField("contract_multiplier_unit", instrument_def_msg.contract_multiplier_unit) + .AddField("flow_schedule_type", instrument_def_msg.flow_schedule_type) + .AddField("tick_rule", instrument_def_msg.tick_rule) .Finish(); } +template <> +v3::StatMsg StatMsg::Upgrade() const { + return ToV3(); +} + std::string ToString(const StatMsg& stat_msg) { return MakeString(stat_msg); } std::ostream& operator<<(std::ostream& stream, const StatMsg& stat_msg) { return StreamOpBuilder{stream} @@ -437,16 +430,11 @@ std::ostream& operator<<(std::ostream& stream, const StatMsg& stat_msg) { .Finish(); } -std::string ToString(const ErrorMsg& err_msg) { return MakeString(err_msg); } -std::ostream& operator<<(std::ostream& stream, const ErrorMsg& err_msg) { - return StreamOpBuilder{stream} - .SetSpacer("\n ") - .SetTypeName("v1::ErrorMsg") - .Build() - .AddField("hd", err_msg.hd) - .AddField("err", err_msg.err) - .Finish(); +template <> +v2::SymbolMappingMsg SymbolMappingMsg::Upgrade() const { + return ToV2(); } + std::string ToString(const SymbolMappingMsg& symbol_mapping_msg) { return MakeString(symbol_mapping_msg); } @@ -454,7 +442,7 @@ std::ostream& operator<<(std::ostream& stream, const SymbolMappingMsg& symbol_mapping_msg) { return StreamOpBuilder{stream} .SetSpacer("\n ") - .SetTypeName("v1::SymbolMappingMsg") + .SetTypeName("SymbolMappingMsg") .Build() .AddField("hd", symbol_mapping_msg.hd) .AddField("stype_in_symbol", symbol_mapping_msg.stype_in_symbol) @@ -463,16 +451,21 @@ std::ostream& operator<<(std::ostream& stream, .AddField("end_ts", symbol_mapping_msg.end_ts) .Finish(); } -std::string ToString(const SystemMsg& system_msg) { - return MakeString(system_msg); + +template <> +v2::SystemMsg SystemMsg::Upgrade() const { + return ToV2(); } + +std::string ToString(const SystemMsg& system_msg) { return MakeString(system_msg); } std::ostream& operator<<(std::ostream& stream, const SystemMsg& system_msg) { return StreamOpBuilder{stream} .SetSpacer("\n ") - .SetTypeName("v1::SystemMsg") + .SetTypeName("SystemMsg") .Build() .AddField("hd", system_msg.hd) .AddField("msg", system_msg.msg) .Finish(); } + } // namespace databento::v1 diff --git a/src/v2.cpp b/src/v2.cpp index 7000dc9..e6f006c 100644 --- a/src/v2.cpp +++ b/src/v2.cpp @@ -7,9 +7,9 @@ namespace databento::v2 { 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}, + RecordHeader{sizeof(v3::InstrumentDefMsg) / RecordHeader::kLengthMultiplier, + RType::InstrumentDef, hd.publisher_id, hd.instrument_id, + hd.ts_event}, ts_recv, min_price_increment, display_factor, @@ -85,8 +85,7 @@ databento::v3::InstrumentDefMsg InstrumentDefMsg::ToV3() const { 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(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()); @@ -95,24 +94,18 @@ databento::v3::InstrumentDefMsg InstrumentDefMsg::ToV3() const { return ret; } -template <> -v3::InstrumentDefMsg InstrumentDefMsg::Upgrade() const { - return ToV3(); -} - bool operator==(const InstrumentDefMsg& lhs, const InstrumentDefMsg& rhs) { return lhs.hd == rhs.hd && lhs.ts_recv == rhs.ts_recv && lhs.min_price_increment == rhs.min_price_increment && - lhs.display_factor == rhs.display_factor && - lhs.expiration == rhs.expiration && lhs.activation == rhs.activation && + lhs.display_factor == rhs.display_factor && lhs.expiration == rhs.expiration && + lhs.activation == rhs.activation && lhs.high_limit_price == rhs.high_limit_price && lhs.low_limit_price == rhs.low_limit_price && lhs.max_price_variation == rhs.max_price_variation && lhs.trading_reference_price == rhs.trading_reference_price && lhs.unit_of_measure_qty == rhs.unit_of_measure_qty && lhs.min_price_increment_amount == rhs.min_price_increment_amount && - lhs.price_ratio == rhs.price_ratio && - lhs.strike_price == rhs.strike_price && + lhs.price_ratio == rhs.price_ratio && lhs.strike_price == rhs.strike_price && lhs.inst_attrib_value == rhs.inst_attrib_value && lhs.underlying_id == rhs.underlying_id && lhs.raw_instrument_id == rhs.raw_instrument_id && @@ -131,10 +124,9 @@ bool operator==(const InstrumentDefMsg& lhs, const InstrumentDefMsg& rhs) { lhs.appl_id == rhs.appl_id && lhs.maturity_year == rhs.maturity_year && lhs.decay_start_date == rhs.decay_start_date && lhs.channel_id == rhs.channel_id && lhs.currency == rhs.currency && - lhs.settl_currency == rhs.settl_currency && - lhs.secsubtype == rhs.secsubtype && lhs.raw_symbol == rhs.raw_symbol && - lhs.group == rhs.group && lhs.exchange == rhs.exchange && - lhs.asset == rhs.asset && lhs.cfi == rhs.cfi && + lhs.settl_currency == rhs.settl_currency && lhs.secsubtype == rhs.secsubtype && + lhs.raw_symbol == rhs.raw_symbol && lhs.group == rhs.group && + lhs.exchange == rhs.exchange && lhs.asset == rhs.asset && lhs.cfi == rhs.cfi && lhs.security_type == rhs.security_type && lhs.unit_of_measure == rhs.unit_of_measure && lhs.underlying == rhs.underlying && @@ -157,84 +149,87 @@ bool operator==(const InstrumentDefMsg& lhs, const InstrumentDefMsg& rhs) { lhs.tick_rule == rhs.tick_rule; } -std::string ToString(const InstrumentDefMsg& instr_def_msg) { - return MakeString(instr_def_msg); +template <> +databento::InstrumentDefMsg InstrumentDefMsg::Upgrade() const { + return ToV3(); +} + +std::string ToString(const InstrumentDefMsg& instrument_def_msg) { + return MakeString(instrument_def_msg); } std::ostream& operator<<(std::ostream& stream, - const InstrumentDefMsg& instr_def_msg) { + const InstrumentDefMsg& instrument_def_msg) { return StreamOpBuilder{stream} .SetSpacer("\n ") - .SetTypeName("v2::InstrumentDefMsg") + .SetTypeName("InstrumentDefMsg") .Build() - .AddField("hd", instr_def_msg.hd) - .AddField("ts_recv", instr_def_msg.ts_recv) + .AddField("hd", instrument_def_msg.hd) + .AddField("ts_recv", instrument_def_msg.ts_recv) .AddField("min_price_increment", - pretty::Px{instr_def_msg.min_price_increment}) - .AddField("display_factor", pretty::Px{instr_def_msg.display_factor}) - .AddField("expiration", instr_def_msg.expiration) - .AddField("activation", instr_def_msg.activation) - .AddField("high_limit_price", pretty::Px{instr_def_msg.high_limit_price}) - .AddField("low_limit_price", pretty::Px{instr_def_msg.low_limit_price}) + pretty::Px{instrument_def_msg.min_price_increment}) + .AddField("display_factor", pretty::Px{instrument_def_msg.display_factor}) + .AddField("expiration", instrument_def_msg.expiration) + .AddField("activation", instrument_def_msg.activation) + .AddField("high_limit_price", pretty::Px{instrument_def_msg.high_limit_price}) + .AddField("low_limit_price", pretty::Px{instrument_def_msg.low_limit_price}) .AddField("max_price_variation", - pretty::Px{instr_def_msg.max_price_variation}) + pretty::Px{instrument_def_msg.max_price_variation}) .AddField("trading_reference_price", - pretty::Px{instr_def_msg.trading_reference_price}) + pretty::Px{instrument_def_msg.trading_reference_price}) .AddField("unit_of_measure_qty", - pretty::Px{instr_def_msg.unit_of_measure_qty}) + pretty::Px{instrument_def_msg.unit_of_measure_qty}) .AddField("min_price_increment_amount", - pretty::Px{instr_def_msg.min_price_increment_amount}) - .AddField("price_ratio", pretty::Px{instr_def_msg.price_ratio}) - .AddField("strike_price", pretty::Px{instr_def_msg.strike_price}) - .AddField("inst_attrib_value", instr_def_msg.inst_attrib_value) - .AddField("underlying_id", instr_def_msg.underlying_id) - .AddField("raw_instrument_id", instr_def_msg.raw_instrument_id) - .AddField("market_depth_implied", instr_def_msg.market_depth_implied) - .AddField("market_depth", instr_def_msg.market_depth) - .AddField("market_segment_id", instr_def_msg.market_segment_id) - .AddField("max_trade_vol", instr_def_msg.max_trade_vol) - .AddField("min_lot_size", instr_def_msg.min_lot_size) - .AddField("min_lot_size_block", instr_def_msg.min_lot_size_block) - .AddField("min_lot_size_round_lot", instr_def_msg.min_lot_size_round_lot) - .AddField("min_trade_vol", instr_def_msg.min_trade_vol) - .AddField("contract_multiplier", instr_def_msg.contract_multiplier) - .AddField("decay_quantity", instr_def_msg.decay_quantity) - .AddField("original_contract_size", instr_def_msg.original_contract_size) - .AddField("trading_reference_date", instr_def_msg.trading_reference_date) - .AddField("appl_id", instr_def_msg.appl_id) - .AddField("maturity_year", instr_def_msg.maturity_year) - .AddField("decay_start_date", instr_def_msg.decay_start_date) - .AddField("channel_id", instr_def_msg.channel_id) - .AddField("currency", instr_def_msg.currency) - .AddField("settl_currency", instr_def_msg.settl_currency) - .AddField("secsubtype", instr_def_msg.secsubtype) - .AddField("raw_symbol", instr_def_msg.raw_symbol) - .AddField("group", instr_def_msg.group) - .AddField("exchange", instr_def_msg.exchange) - .AddField("asset", instr_def_msg.asset) - .AddField("cfi", instr_def_msg.cfi) - .AddField("security_type", instr_def_msg.security_type) - .AddField("unit_of_measure", instr_def_msg.unit_of_measure) - .AddField("underlying", instr_def_msg.underlying) - .AddField("strike_price_currency", instr_def_msg.strike_price_currency) - .AddField("instrument_class", instr_def_msg.instrument_class) - .AddField("match_algorithm", instr_def_msg.match_algorithm) + pretty::Px{instrument_def_msg.min_price_increment_amount}) + .AddField("price_ratio", pretty::Px{instrument_def_msg.price_ratio}) + .AddField("strike_price", pretty::Px{instrument_def_msg.strike_price}) + .AddField("inst_attrib_value", instrument_def_msg.inst_attrib_value) + .AddField("underlying_id", instrument_def_msg.underlying_id) + .AddField("raw_instrument_id", instrument_def_msg.raw_instrument_id) + .AddField("market_depth_implied", instrument_def_msg.market_depth_implied) + .AddField("market_depth", instrument_def_msg.market_depth) + .AddField("market_segment_id", instrument_def_msg.market_segment_id) + .AddField("max_trade_vol", instrument_def_msg.max_trade_vol) + .AddField("min_lot_size", instrument_def_msg.min_lot_size) + .AddField("min_lot_size_block", instrument_def_msg.min_lot_size_block) + .AddField("min_lot_size_round_lot", instrument_def_msg.min_lot_size_round_lot) + .AddField("min_trade_vol", instrument_def_msg.min_trade_vol) + .AddField("contract_multiplier", instrument_def_msg.contract_multiplier) + .AddField("decay_quantity", instrument_def_msg.decay_quantity) + .AddField("original_contract_size", instrument_def_msg.original_contract_size) + .AddField("trading_reference_date", instrument_def_msg.trading_reference_date) + .AddField("appl_id", instrument_def_msg.appl_id) + .AddField("maturity_year", instrument_def_msg.maturity_year) + .AddField("decay_start_date", instrument_def_msg.decay_start_date) + .AddField("channel_id", instrument_def_msg.channel_id) + .AddField("currency", instrument_def_msg.currency) + .AddField("settl_currency", instrument_def_msg.settl_currency) + .AddField("secsubtype", instrument_def_msg.secsubtype) + .AddField("raw_symbol", instrument_def_msg.raw_symbol) + .AddField("group", instrument_def_msg.group) + .AddField("exchange", instrument_def_msg.exchange) + .AddField("asset", instrument_def_msg.asset) + .AddField("cfi", instrument_def_msg.cfi) + .AddField("security_type", instrument_def_msg.security_type) + .AddField("unit_of_measure", instrument_def_msg.unit_of_measure) + .AddField("underlying", instrument_def_msg.underlying) + .AddField("strike_price_currency", instrument_def_msg.strike_price_currency) + .AddField("instrument_class", instrument_def_msg.instrument_class) + .AddField("match_algorithm", instrument_def_msg.match_algorithm) .AddField("md_security_trading_status", - instr_def_msg.md_security_trading_status) - .AddField("main_fraction", instr_def_msg.main_fraction) - .AddField("price_display_format", instr_def_msg.price_display_format) - .AddField("settl_price_type", instr_def_msg.settl_price_type) - .AddField("sub_fraction", instr_def_msg.sub_fraction) - .AddField("underlying_product", instr_def_msg.underlying_product) - .AddField("security_update_action", instr_def_msg.security_update_action) - .AddField("maturity_month", instr_def_msg.maturity_month) - .AddField("maturity_day", instr_def_msg.maturity_day) - .AddField("maturity_week", instr_def_msg.maturity_week) - .AddField("user_defined_instrument", - instr_def_msg.user_defined_instrument) - .AddField("contract_multiplier_unit", - instr_def_msg.contract_multiplier_unit) - .AddField("flow_schedule_type", instr_def_msg.flow_schedule_type) - .AddField("tick_rule", instr_def_msg.tick_rule) + instrument_def_msg.md_security_trading_status) + .AddField("main_fraction", instrument_def_msg.main_fraction) + .AddField("price_display_format", instrument_def_msg.price_display_format) + .AddField("settl_price_type", instrument_def_msg.settl_price_type) + .AddField("sub_fraction", instrument_def_msg.sub_fraction) + .AddField("underlying_product", instrument_def_msg.underlying_product) + .AddField("security_update_action", instrument_def_msg.security_update_action) + .AddField("maturity_month", instrument_def_msg.maturity_month) + .AddField("maturity_day", instrument_def_msg.maturity_day) + .AddField("maturity_week", instrument_def_msg.maturity_week) + .AddField("user_defined_instrument", instrument_def_msg.user_defined_instrument) + .AddField("contract_multiplier_unit", instrument_def_msg.contract_multiplier_unit) + .AddField("flow_schedule_type", instrument_def_msg.flow_schedule_type) + .AddField("tick_rule", instrument_def_msg.tick_rule) .Finish(); } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index c555bfa..344906d 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -31,6 +31,7 @@ set( src/datetime_tests.cpp src/dbn_decoder_tests.cpp src/dbn_encoder_tests.cpp + src/dbn_file_store_tests.cpp src/dbn_tests.cpp src/file_stream_tests.cpp src/flag_set_tests.cpp diff --git a/tests/include/mock/mock_http_server.hpp b/tests/include/mock/mock_http_server.hpp index 17cd368..10e512f 100644 --- a/tests/include/mock/mock_http_server.hpp +++ b/tests/include/mock/mock_http_server.hpp @@ -16,8 +16,7 @@ namespace databento::tests::mock { class MockHttpServer { public: explicit MockHttpServer(std::string api_key) - : port_{server_.bind_to_any_port("localhost")}, - api_key_{std::move(api_key)} {} + : port_{server_.bind_to_any_port("localhost")}, api_key_{std::move(api_key)} {} MockHttpServer(MockHttpServer&&) = delete; MockHttpServer& operator=(MockHttpServer&&) = delete; MockHttpServer(const MockHttpServer&) = delete; @@ -43,12 +42,11 @@ class MockHttpServer { const std::map& params, const std::string& dbn_path); void MockPostDbn(const std::string& path, - const std::map& params, - Record record, std::size_t count, std::size_t chunk_size); + const std::map& params, Record record, + std::size_t count, std::size_t chunk_size); void MockPostDbn(const std::string& path, - const std::map& params, - Record record, std::size_t count, std::size_t extra_bytes, - std::size_t chunk_size); + const std::map& params, Record record, + std::size_t count, std::size_t extra_bytes, std::size_t chunk_size); private: using SharedConstBuffer = std::shared_ptr; @@ -59,8 +57,8 @@ class MockHttpServer { const httplib::Request& req); static SharedConstBuffer EncodeToBuffer(const std::string& dbn_path); static httplib::Server::Handler MakeDbnStreamHandler( - const std::map& params, - SharedConstBuffer&& buffer, std::size_t chunk_size); + const std::map& params, SharedConstBuffer&& buffer, + std::size_t chunk_size); httplib::Server server_{}; const int port_{}; diff --git a/tests/include/mock/mock_log_receiver.hpp b/tests/include/mock/mock_log_receiver.hpp index b7a6fda..0c737c7 100644 --- a/tests/include/mock/mock_log_receiver.hpp +++ b/tests/include/mock/mock_log_receiver.hpp @@ -20,12 +20,11 @@ class MockLogReceiver : public databento::ILogReceiver { : callback_{std::move(callback)}, min_level_{min_level} {} static MockLogReceiver AssertNoLogs(databento::LogLevel min_level) { - return MockLogReceiver{ - min_level, - [min_level](auto, databento::LogLevel level, const std::string& msg) { - FAIL() << "Received unexpected log message with level " << level - << ": " << msg; - }}; + return MockLogReceiver{min_level, [min_level](auto, databento::LogLevel level, + const std::string& msg) { + FAIL() << "Received unexpected log message with level " + << level << ": " << msg; + }}; } void Receive(databento::LogLevel level, const std::string& msg) override { diff --git a/tests/include/mock/mock_lsg_server.hpp b/tests/include/mock/mock_lsg_server.hpp index 6571b33..aa17d9b 100644 --- a/tests/include/mock/mock_lsg_server.hpp +++ b/tests/include/mock/mock_lsg_server.hpp @@ -50,12 +50,12 @@ class MockLsgServer { void Accept(); void Authenticate(); - void Subscribe(const std::vector& symbols, Schema schema, - SType stype, bool is_last); - void Subscribe(const std::vector& symbols, Schema schema, - SType stype, const std::string& start, bool is_last); - void SubscribeWithSnapshot(const std::vector& symbols, - Schema schema, SType stype, bool is_last); + void Subscribe(const std::vector& symbols, Schema schema, SType stype, + bool is_last); + void Subscribe(const std::vector& symbols, Schema schema, SType stype, + const std::string& start, bool is_last); + void SubscribeWithSnapshot(const std::vector& symbols, Schema schema, + SType stype, bool is_last); void Start(); std::size_t Send(const std::string& msg); ::ssize_t UncheckedSend(const std::string& msg); @@ -91,9 +91,8 @@ class MockLsgServer { template std::size_t SendBytes(T bytes) { - const auto write_size = - ::send(conn_fd_.Get(), reinterpret_cast(&bytes), - sizeof(bytes), {}); + const auto write_size = ::send( + conn_fd_.Get(), reinterpret_cast(&bytes), sizeof(bytes), {}); EXPECT_EQ(write_size, sizeof(bytes)) << ::strerror(errno); return static_cast(write_size); } diff --git a/tests/include/mock/mock_tcp_server.hpp b/tests/include/mock/mock_tcp_server.hpp index e67fc96..341b75a 100644 --- a/tests/include/mock/mock_tcp_server.hpp +++ b/tests/include/mock/mock_tcp_server.hpp @@ -16,8 +16,7 @@ class MockTcpServer { explicit MockTcpServer(std::function serve_fn); static std::pair InitSocket(); - static std::pair InitSocket( - std::uint16_t port); + static std::pair InitSocket(std::uint16_t port); std::uint16_t Port() const { return port_; } // Set the data the server will send to its client. diff --git a/tests/src/buffer_tests.cpp b/tests/src/buffer_tests.cpp index 1d2c238..45f1b1d 100644 --- a/tests/src/buffer_tests.cpp +++ b/tests/src/buffer_tests.cpp @@ -44,8 +44,7 @@ TEST(BufferTests, TestWriteRead) { ASSERT_EQ(write_len, 10); std::array read_buf{}; target.ReadExact(read_buf.data(), read_buf.size()); - std::string_view res{reinterpret_cast(read_buf.data()), - read_buf.size()}; + std::string_view res{reinterpret_cast(read_buf.data()), read_buf.size()}; ASSERT_EQ(res, "BufferTest"sv); } diff --git a/tests/src/dbn_decoder_tests.cpp b/tests/src/dbn_decoder_tests.cpp index fbab127..15a4207 100644 --- a/tests/src/dbn_decoder_tests.cpp +++ b/tests/src/dbn_decoder_tests.cpp @@ -153,8 +153,8 @@ TEST_F(DbnDecoderTests, TestDecodeStatUpgrade) { const auto record1 = target_->DecodeRecord(); ASSERT_NE(record1, nullptr); - AssertStatHas(record1, StatType::LowestOffer, - 100 * kFixedPriceScale, v3::kUndefStatQuantity); + AssertStatHas(record1, StatType::LowestOffer, 100 * kFixedPriceScale, + v3::kUndefStatQuantity); const auto record2 = target_->DecodeRecord(); ASSERT_NE(record2, nullptr); @@ -171,12 +171,11 @@ TEST_F(DbnDecoderTests, TestUpgradeSymbolMappingWithTsOut) { {}, {}, {}}; - WithTsOut orig{ - sym_map, UnixNanos{std::chrono::system_clock::now()}}; + WithTsOut orig{sym_map, + UnixNanos{std::chrono::system_clock::now()}}; std::array compat_buffer{}; - const auto res = - DbnDecoder::DecodeRecordCompat(1, VersionUpgradePolicy::UpgradeToV2, true, - &compat_buffer, Record{&orig.rec.hd}); + const auto res = DbnDecoder::DecodeRecordCompat( + 1, VersionUpgradePolicy::UpgradeToV2, true, &compat_buffer, Record{&orig.rec.hd}); const auto& upgraded = res.Get>(); EXPECT_EQ(orig.rec.hd.rtype, upgraded.rec.hd.rtype); EXPECT_EQ(orig.rec.hd.instrument_id, upgraded.rec.hd.instrument_id); @@ -192,32 +191,27 @@ TEST_F(DbnDecoderTests, TestUpgradeSymbolMappingWithTsOut) { // `length` properly set EXPECT_EQ(upgraded.rec.hd.Size(), sizeof(upgraded)); // used compat buffer - EXPECT_EQ(reinterpret_cast(&upgraded), - compat_buffer.data()); + EXPECT_EQ(reinterpret_cast(&upgraded), compat_buffer.data()); } TEST_F(DbnDecoderTests, TestUpgradeMbp1WithTsOut) { WithTsOut orig{ - Mbp1Msg{{sizeof(Mbp1Msg) / RecordHeader::kLengthMultiplier, - RType::Mbp1, - {}, - {}, - {}}, - 1'250'000'000, - {}, - {}, - Side::Ask, - {}, - {}, - {}, - {}, - {}, - {}}, + Mbp1Msg{ + {sizeof(Mbp1Msg) / RecordHeader::kLengthMultiplier, RType::Mbp1, {}, {}, {}}, + 1'250'000'000, + {}, + {}, + Side::Ask, + {}, + {}, + {}, + {}, + {}, + {}}, {std::chrono::system_clock::now()}}; std::array compat_buffer{}; - const auto res = - DbnDecoder::DecodeRecordCompat(1, VersionUpgradePolicy::UpgradeToV2, true, - &compat_buffer, Record{&orig.rec.hd}); + const auto res = DbnDecoder::DecodeRecordCompat( + 1, VersionUpgradePolicy::UpgradeToV2, true, &compat_buffer, Record{&orig.rec.hd}); const auto& upgraded = res.Get>(); // compat buffer unused and pointer unchanged ASSERT_EQ(&orig, &upgraded); @@ -225,26 +219,23 @@ TEST_F(DbnDecoderTests, TestUpgradeMbp1WithTsOut) { class DbnDecoderSchemaTests : public DbnDecoderTests, - public testing::WithParamInterface> { -}; + public testing::WithParamInterface> {}; -INSTANTIATE_TEST_SUITE_P(TestFiles, DbnDecoderSchemaTests, - testing::Values(std::make_pair(".dbn.zst", 1), - std::make_pair(".dbn.zst", 2), - std::make_pair(".dbn.zst", 3)), - [](const testing::TestParamInfo< - std::pair>& test_info) { - const auto extension = test_info.param.first; - const auto version = test_info.param.second; - const auto size = ::strlen(extension); - return "ZstdDBNv" + std::to_string(version); - }); +INSTANTIATE_TEST_SUITE_P( + TestFiles, DbnDecoderSchemaTests, + testing::Values(std::make_pair(".dbn.zst", 1), std::make_pair(".dbn.zst", 2), + std::make_pair(".dbn.zst", 3)), + [](const testing::TestParamInfo>& test_info) { + const auto extension = test_info.param.first; + const auto version = test_info.param.second; + const auto size = ::strlen(extension); + return "ZstdDBNv" + std::to_string(version); + }); // Expected data for these tests obtained using the `dbn` CLI tool TEST_P(DbnDecoderSchemaTests, TestDecodeMbo) { - const auto extension = GetParam().first; - const auto version = GetParam().second; + const auto [extension, version] = GetParam(); ReadFromFile("mbo", extension, version); const Metadata metadata = target_->DecodeMetadata(); @@ -301,8 +292,7 @@ TEST_P(DbnDecoderSchemaTests, TestDecodeMbo) { } TEST_P(DbnDecoderSchemaTests, TestDecodeMbp1) { - const auto extension = GetParam().first; - const auto version = GetParam().second; + const auto [extension, version] = GetParam(); ReadFromFile("mbp-1", extension, version); const Metadata metadata = target_->DecodeMetadata(); @@ -369,8 +359,7 @@ TEST_P(DbnDecoderSchemaTests, TestDecodeMbp1) { } TEST_P(DbnDecoderSchemaTests, TestDecodeMbp10) { - const auto extension = GetParam().first; - const auto version = GetParam().second; + const auto [extension, version] = GetParam(); ReadFromFile("mbp-10", extension, version); const Metadata metadata = target_->DecodeMetadata(); @@ -460,8 +449,7 @@ TEST_P(DbnDecoderSchemaTests, TestDecodeMbp10) { } TEST_P(DbnDecoderSchemaTests, TestDecodeCmbp1) { - const auto extension = GetParam().first; - const auto version = GetParam().second; + const auto [extension, version] = GetParam(); ReadFromFile("cmbp-1", extension, version); const Metadata metadata = target_->DecodeMetadata(); @@ -522,8 +510,7 @@ TEST_P(DbnDecoderSchemaTests, TestDecodeCmbp1) { } TEST_P(DbnDecoderSchemaTests, TestDecodeCbbo) { - const auto extension = GetParam().first; - const auto version = GetParam().second; + const auto [extension, version] = GetParam(); ReadFromFile("cbbo-1s", extension, version); const Metadata metadata = target_->DecodeMetadata(); @@ -580,8 +567,7 @@ TEST_P(DbnDecoderSchemaTests, TestDecodeCbbo) { } TEST_P(DbnDecoderSchemaTests, TestDecodeTbbo) { - const auto extension = GetParam().first; - const auto version = GetParam().second; + const auto [extension, version] = GetParam(); ReadFromFile("tbbo", extension, version); const Metadata metadata = target_->DecodeMetadata(); @@ -646,8 +632,7 @@ TEST_P(DbnDecoderSchemaTests, TestDecodeTbbo) { } TEST_P(DbnDecoderSchemaTests, TestDecodeTrades) { - const auto extension = GetParam().first; - const auto version = GetParam().second; + const auto [extension, version] = GetParam(); ReadFromFile("trades", extension, version); const Metadata metadata = target_->DecodeMetadata(); @@ -700,8 +685,7 @@ TEST_P(DbnDecoderSchemaTests, TestDecodeTrades) { } TEST_P(DbnDecoderSchemaTests, TestDecodeOhlcv1D) { - const auto extension = GetParam().first; - const auto version = GetParam().second; + const auto [extension, version] = GetParam(); ReadFromFile("ohlcv-1d", extension, version); const Metadata metadata = target_->DecodeMetadata(); @@ -720,8 +704,7 @@ TEST_P(DbnDecoderSchemaTests, TestDecodeOhlcv1D) { } TEST_P(DbnDecoderSchemaTests, TestDecodeOhlcv1H) { - const auto extension = GetParam().first; - const auto version = GetParam().second; + const auto [extension, version] = GetParam(); ReadFromFile("ohlcv-1h", extension, version); const Metadata metadata = target_->DecodeMetadata(); @@ -766,8 +749,7 @@ TEST_P(DbnDecoderSchemaTests, TestDecodeOhlcv1H) { } TEST_P(DbnDecoderSchemaTests, TestDecodeOhlcv1M) { - const auto extension = GetParam().first; - const auto version = GetParam().second; + const auto [extension, version] = GetParam(); ReadFromFile("ohlcv-1m", extension, version); const Metadata metadata = target_->DecodeMetadata(); @@ -812,8 +794,7 @@ TEST_P(DbnDecoderSchemaTests, TestDecodeOhlcv1M) { } TEST_P(DbnDecoderSchemaTests, TestDecodeOhlcv1S) { - const auto extension = GetParam().first; - const auto version = GetParam().second; + const auto [extension, version] = GetParam(); ReadFromFile("ohlcv-1s", extension, version); const Metadata metadata = target_->DecodeMetadata(); @@ -858,8 +839,7 @@ TEST_P(DbnDecoderSchemaTests, TestDecodeOhlcv1S) { } TEST_P(DbnDecoderSchemaTests, TestDecodeDefinition) { - const auto extension = GetParam().first; - const auto version = GetParam().second; + const auto [extension, version] = GetParam(); ReadFromFile("definition", extension, version); const Metadata metadata = target_->DecodeMetadata(); @@ -903,8 +883,7 @@ TEST_P(DbnDecoderSchemaTests, TestDecodeDefinition) { } TEST_P(DbnDecoderSchemaTests, TestDecodeImbalance) { - const auto extension = GetParam().first; - const auto version = GetParam().second; + const auto [extension, version] = GetParam(); ReadFromFile("imbalance", extension, version); const Metadata metadata = target_->DecodeMetadata(); @@ -936,8 +915,7 @@ TEST_P(DbnDecoderSchemaTests, TestDecodeImbalance) { } TEST_P(DbnDecoderSchemaTests, TestDecodeStatistics) { - const auto extension = GetParam().first; - const auto version = GetParam().second; + const auto [extension, version] = GetParam(); ReadFromFile("statistics", extension, version); const Metadata metadata = target_->DecodeMetadata(); @@ -956,11 +934,11 @@ TEST_P(DbnDecoderSchemaTests, TestDecodeStatistics) { const auto record1 = target_->DecodeRecord(); if (version < 3) { - AssertStatHas(record1, StatType::LowestOffer, - 100 * kFixedPriceScale, v1::kUndefStatQuantity); + AssertStatHas(record1, StatType::LowestOffer, 100 * kFixedPriceScale, + v1::kUndefStatQuantity); } else { - AssertStatHas(record1, StatType::LowestOffer, - 100 * kFixedPriceScale, v3::kUndefStatQuantity); + AssertStatHas(record1, StatType::LowestOffer, 100 * kFixedPriceScale, + v3::kUndefStatQuantity); } const auto record2 = target_->DecodeRecord(); @@ -973,8 +951,8 @@ TEST_P(DbnDecoderSchemaTests, TestDecodeStatistics) { } } -class DbnIdentityTests : public testing::TestWithParam< - std::tuple> { +class DbnIdentityTests + : public testing::TestWithParam> { protected: mock::MockLogReceiver logger_ = mock::MockLogReceiver::AssertNoLogs(LogLevel::Warning); @@ -1031,8 +1009,8 @@ INSTANTIATE_TEST_SUITE_P( std::make_tuple(3, Schema::Cmbp1, Compression::Zstd), std::make_tuple(3, Schema::Cbbo1S, Compression::Zstd), std::make_tuple(3, Schema::Status, Compression::Zstd)), - [](const testing::TestParamInfo< - std::tuple>& test_info) { + [](const testing::TestParamInfo>& + test_info) { const auto version = std::get<0>(test_info.param); const auto schema = std::get<1>(test_info.param); const auto compression = std::get<2>(test_info.param); @@ -1047,13 +1025,10 @@ INSTANTIATE_TEST_SUITE_P( }); TEST_P(DbnIdentityTests, TestIdentity) { - const auto version = std::get<0>(GetParam()); - const auto schema = std::get<1>(GetParam()); - const auto compression = std::get<2>(GetParam()); - const auto file_name = - std::string{TEST_DATA_DIR "/test_data."} + ToString(schema) + ".v" + - std::to_string(+version) + - (compression == Compression::Zstd ? ".dbn.zst" : ".dbn"); + const auto [version, schema, compression] = GetParam(); + const auto file_name = std::string{TEST_DATA_DIR "/test_data."} + ToString(schema) + + ".v" + std::to_string(+version) + + (compression == Compression::Zstd ? ".dbn.zst" : ".dbn"); DbnDecoder file_decoder{&logger_, std::make_unique(file_name), VersionUpgradePolicy::AsIs}; const Metadata file_metadata = file_decoder.DecodeMetadata(); @@ -1064,9 +1039,8 @@ TEST_P(DbnIdentityTests, TestIdentity) { if (compression == Compression::Zstd) { zstd_io = std::make_unique(&buf_io); } - DbnEncoder encoder{ - file_metadata, - zstd_io ? static_cast(zstd_io.get()) : &buf_io}; + DbnEncoder encoder{file_metadata, + zstd_io ? static_cast(zstd_io.get()) : &buf_io}; while (auto* record = file_decoder.DecodeRecord()) { encoder.EncodeRecord(*record); } @@ -1078,8 +1052,7 @@ TEST_P(DbnIdentityTests, TestIdentity) { file_decoder.DecodeMetadata(); auto input = std::make_unique(std::move(buf_io)); - DbnDecoder buf_decoder{&logger_, std::move(input), - VersionUpgradePolicy::AsIs}; + DbnDecoder buf_decoder{&logger_, std::move(input), VersionUpgradePolicy::AsIs}; const auto buf_metadata = buf_decoder.DecodeMetadata(); EXPECT_EQ(file_metadata, buf_metadata); while (auto* buf_record = buf_decoder.DecodeRecord()) { @@ -1122,11 +1095,9 @@ TEST_P(DbnIdentityTests, TestIdentity) { } } else if (buf_record->Header().rtype == RType::Statistics) { if (buf_record->Size() == sizeof(v1::StatMsg)) { - EXPECT_EQ(buf_record->Get(), - file_record->Get()); + EXPECT_EQ(buf_record->Get(), file_record->Get()); } else if (buf_record->Size() == sizeof(v3::StatMsg)) { - EXPECT_EQ(buf_record->Get(), - file_record->Get()); + EXPECT_EQ(buf_record->Get(), file_record->Get()); } else { FAIL() << "Unknown stats size"; } @@ -1137,6 +1108,4 @@ TEST_P(DbnIdentityTests, TestIdentity) { } ASSERT_EQ(file_decoder.DecodeRecord(), nullptr); } - -TEST_F(DbnDecoderTests, TestDbnIdentityWithTsOut) {} } // namespace databento::tests diff --git a/tests/src/dbn_encoder_tests.cpp b/tests/src/dbn_encoder_tests.cpp index b99e154..e1dc3f9 100644 --- a/tests/src/dbn_encoder_tests.cpp +++ b/tests/src/dbn_encoder_tests.cpp @@ -31,8 +31,7 @@ TEST(DbnEncoderTests, TestEncodeDecodeMetadataIdentity) { {"ES", "NG"}, {"ESM2"}, {"QQQQQ"}, - {{"ES.0", - {{date::year{2022} / 7 / 26, date::year{2022} / 9 / 1, "ESU2"}}}, + {{"ES.0", {{date::year{2022} / 7 / 26, date::year{2022} / 9 / 1, "ESU2"}}}, {"NG.0", {{date::year{2022} / 7 / 26, date::year{2022} / 8 / 29, "NGU2"}, {date::year{2022} / 8 / 29, date::year{2022} / 9 / 1, "NGV2"}}}}}; diff --git a/tests/src/dbn_file_store_tests.cpp b/tests/src/dbn_file_store_tests.cpp new file mode 100644 index 0000000..fbc7347 --- /dev/null +++ b/tests/src/dbn_file_store_tests.cpp @@ -0,0 +1,118 @@ +#include +#include +#include + +#include "databento/datetime.hpp" +#include "databento/dbn.hpp" +#include "databento/dbn_encoder.hpp" +#include "databento/dbn_file_store.hpp" +#include "databento/detail/zstd_stream.hpp" +#include "databento/enums.hpp" +#include "databento/file_stream.hpp" +#include "databento/flag_set.hpp" +#include "databento/record.hpp" +#include "databento/v1.hpp" +#include "temp_file.hpp" + +namespace databento::tests { +TEST(DbnFileStoreTests, TestDecodeExtended) { + const auto record_gen = [](const std::size_t i) { + auto flags = FlagSet{}; + if (i % 2 == 0) { + flags.SetBadTsRecv(); + } + Action action; + switch (i % 5) { + case 0: { + action = Action::Add; + break; + } + case 1: { + action = Action::Modify; + break; + } + case 2: { + action = Action::Cancel; + break; + } + case 3: { + action = Action::Trade; + break; + } + case 4: + default: { + action = Action::Fill; + } + } + Side side; + switch (i % 7) { + case 0: + case 1: + case 2: { + side = Side::Ask; + } + case 3: + case 4: + case 5: { + side = Side::Bid; + } + case 6: + default: { + side = Side::None; + } + } + return MboMsg{ + RecordHeader{sizeof(MboMsg) / RecordHeader::kLengthMultiplier, RType::Mbo, + static_cast(Publisher::GlbxMdp3Glbx), + static_cast(i), + UnixNanos{std::chrono::milliseconds{i}}}, + i % 5, + 25'000'000 + static_cast(i), + static_cast(i) % 1'000, + flags, + static_cast(i % 16), + action, + side, + UnixNanos{std::chrono::milliseconds{i} + + std::chrono::nanoseconds{10 + i % 100}}, + std::chrono::milliseconds{2 + i % 34}, + static_cast(i) / 2 + + }; + }; + TempFile temp_file{std::filesystem::temp_directory_path() / + "test_decode_extended.dbn.zst"}; + + constexpr auto kExpSize = 100'000; + { + OutFileStream out_file{temp_file.Path()}; + detail::ZstdCompressStream stream{&out_file}; + DbnEncoder encoder{Metadata{1, + ToString(Dataset::GlbxMdp3), + Schema::Mbo, + {}, + {}, + {}, + {}, + {}, + false, + databento::v1::kSymbolCstrLen, + std::vector(4571)}, + &stream}; + for (std::size_t i = 0; i < kExpSize; ++i) { + auto flags = FlagSet{}; + encoder.EncodeRecord(record_gen(i)); + } + } + std::size_t count = 0; + DbnFileStore target{temp_file.Path()}; + while (const auto* rec = target.NextRecord()) { + const auto* mbo = rec->GetIf(); + ASSERT_NE(mbo, nullptr) << "Found non-MBO record with hd = " << rec->Header() + << " at count = " << count; + ASSERT_EQ(*mbo, record_gen(count)) << "MboMsg mismatch at count = " << count; + ++count; + } + ASSERT_EQ(count, kExpSize); +} +} // namespace databento::tests diff --git a/tests/src/file_stream_tests.cpp b/tests/src/file_stream_tests.cpp index a4a5328..df7670e 100644 --- a/tests/src/file_stream_tests.cpp +++ b/tests/src/file_stream_tests.cpp @@ -16,8 +16,7 @@ TEST(InFileStreamTests, TestReadExactInsufficient) { target.ReadExact(buffer.data(), buffer.size()); FAIL() << "Expected throw"; } catch (const databento::Exception& exc) { - ASSERT_STREQ(exc.what(), - "Unexpected end of file, expected 1024 bytes, got 472"); + ASSERT_STREQ(exc.what(), "Unexpected end of file, expected 1024 bytes, got 472"); } } diff --git a/tests/src/historical_tests.cpp b/tests/src/historical_tests.cpp index e9589b9..9fe2011 100644 --- a/tests/src/historical_tests.cpp +++ b/tests/src/historical_tests.cpp @@ -113,9 +113,8 @@ TEST_F(HistoricalTests, TestBatchSubmitJob) { const auto port = mock_server_.ListenOnThread(); databento::Historical target = Client(port); - const auto res = - target.BatchSubmitJob(dataset::kXnasItch, {"CLH3"}, Schema::Trades, - {"2022-05-17", "2022-07-03"}); + const auto res = target.BatchSubmitJob(dataset::kXnasItch, {"CLH3"}, Schema::Trades, + {"2022-05-17", "2022-07-03"}); EXPECT_EQ(res.symbols, std::vector{"CLH3"}); EXPECT_NEAR(res.cost_usd, 0.11908, 1e-2); EXPECT_EQ(res.encoding, Encoding::Dbn); @@ -125,73 +124,72 @@ TEST_F(HistoricalTests, TestBatchSubmitJob) { } TEST_F(HistoricalTests, TestBatchListJobs) { - const nlohmann::json kResp{ - {{"actual_size", 2022690}, - {"bill_id", "a670"}, - {"billed_size", 5156064}, - {"compression", "zstd"}, - {"cost_usd", 0.119089}, - {"dataset", "GLBX.MDP3"}, - {"delivery", "download"}, - {"encoding", "dbn"}, - {"end", "2022-09-27 00:00:00+00:00"}, - {"id", "CKXF"}, - {"limit", nullptr}, - {"package_size", 2026761}, - {"packaging", nullptr}, - {"pretty_px", false}, - {"pretty_ts", false}, - {"map_symbols", false}, - {"progress", 100}, - {"record_count", 107418}, - {"schema", "trades"}, - {"split_duration", "day"}, - {"split_size", nullptr}, - {"split_symbols", false}, - {"start", "2022-08-26 00:00:00+00:00"}, - {"state", "done"}, - {"stype_in", "raw_symbol"}, - {"stype_out", "instrument_id"}, - {"symbols", "GEZ2"}, - {"ts_expiration", "2022-11-30 15:27:10.148788+00:00"}, - {"ts_process_done", "2022-10-31 15:27:10.148788+00:00"}, - {"ts_process_start", "2022-10-31 15:27:08.018759+00:00"}, - {"ts_queued", "2022-10-31 15:26:58.654241+00:00"}, - {"ts_received", "2022-10-31 15:26:58.112496+00:00"}, - {"user_id", "A_USER"}}, - {{"actual_size", 2022690}, - {"bill_id", "a1b7"}, - {"billed_size", 5156064}, - {"compression", "zstd"}, - {"cost_usd", 0.119089}, - {"dataset", "GLBX.MDP3"}, - {"delivery", "download"}, - {"encoding", "dbn"}, - {"end", "2022-09-27 00:00:00+00:00"}, - {"id", "8UPL"}, - {"limit", nullptr}, - {"package_size", 2026761}, - {"packaging", nullptr}, - {"pretty_px", false}, - {"pretty_ts", false}, - {"map_symbols", false}, - {"progress", 100}, - {"record_count", 107418}, - {"schema", "trades"}, - {"split_duration", "day"}, - {"split_size", nullptr}, - {"split_symbols", false}, - {"start", "2022-08-26 00:00:00+00:00"}, - {"state", "done"}, - {"stype_in", "raw_symbol"}, - {"stype_out", "instrument_id"}, - {"symbols", {"GEZ2", "GEH3"}}, - {"ts_expiration", "2022-11-30 15:29:03.010429+00:00"}, - {"ts_process_done", "2022-10-31 15:29:03.010429+00:00"}, - {"ts_process_start", "2022-10-31 15:29:01.104930+00:00"}, - {"ts_queued", "2022-10-31 15:28:58.933725+00:00"}, - {"ts_received", "2022-10-31 15:28:58.233520+00:00"}, - {"user_id", "A_USER"}}}; + const nlohmann::json kResp{{{"actual_size", 2022690}, + {"bill_id", "a670"}, + {"billed_size", 5156064}, + {"compression", "zstd"}, + {"cost_usd", 0.119089}, + {"dataset", "GLBX.MDP3"}, + {"delivery", "download"}, + {"encoding", "dbn"}, + {"end", "2022-09-27 00:00:00+00:00"}, + {"id", "CKXF"}, + {"limit", nullptr}, + {"package_size", 2026761}, + {"packaging", nullptr}, + {"pretty_px", false}, + {"pretty_ts", false}, + {"map_symbols", false}, + {"progress", 100}, + {"record_count", 107418}, + {"schema", "trades"}, + {"split_duration", "day"}, + {"split_size", nullptr}, + {"split_symbols", false}, + {"start", "2022-08-26 00:00:00+00:00"}, + {"state", "done"}, + {"stype_in", "raw_symbol"}, + {"stype_out", "instrument_id"}, + {"symbols", "GEZ2"}, + {"ts_expiration", "2022-11-30 15:27:10.148788+00:00"}, + {"ts_process_done", "2022-10-31 15:27:10.148788+00:00"}, + {"ts_process_start", "2022-10-31 15:27:08.018759+00:00"}, + {"ts_queued", "2022-10-31 15:26:58.654241+00:00"}, + {"ts_received", "2022-10-31 15:26:58.112496+00:00"}, + {"user_id", "A_USER"}}, + {{"actual_size", 2022690}, + {"bill_id", "a1b7"}, + {"billed_size", 5156064}, + {"compression", "zstd"}, + {"cost_usd", 0.119089}, + {"dataset", "GLBX.MDP3"}, + {"delivery", "download"}, + {"encoding", "dbn"}, + {"end", "2022-09-27 00:00:00+00:00"}, + {"id", "8UPL"}, + {"limit", nullptr}, + {"package_size", 2026761}, + {"packaging", nullptr}, + {"pretty_px", false}, + {"pretty_ts", false}, + {"map_symbols", false}, + {"progress", 100}, + {"record_count", 107418}, + {"schema", "trades"}, + {"split_duration", "day"}, + {"split_size", nullptr}, + {"split_symbols", false}, + {"start", "2022-08-26 00:00:00+00:00"}, + {"state", "done"}, + {"stype_in", "raw_symbol"}, + {"stype_out", "instrument_id"}, + {"symbols", {"GEZ2", "GEH3"}}, + {"ts_expiration", "2022-11-30 15:29:03.010429+00:00"}, + {"ts_process_done", "2022-10-31 15:29:03.010429+00:00"}, + {"ts_process_start", "2022-10-31 15:29:01.104930+00:00"}, + {"ts_queued", "2022-10-31 15:28:58.933725+00:00"}, + {"ts_received", "2022-10-31 15:28:58.233520+00:00"}, + {"user_id", "A_USER"}}}; mock_server_.MockGetJson("/v0/batch.list_jobs", kResp); const auto port = mock_server_.ListenOnThread(); @@ -222,8 +220,7 @@ TEST_F(HistoricalTests, TestBatchListFiles) { ASSERT_EQ(file_desc.filename, "test.json"); ASSERT_EQ(file_desc.size, 2148); ASSERT_EQ(file_desc.hash, "9e7fe0b36"); - ASSERT_EQ(file_desc.https_url, - "https://api.databento.com/v0/job_id/test.json"); + ASSERT_EQ(file_desc.https_url, "https://api.databento.com/v0/job_id/test.json"); ASSERT_EQ(file_desc.ftp_url, "ftp://ftp.databento.com/job_id/test.json"); } @@ -266,14 +263,13 @@ TEST_F(HistoricalTests, TestBatchDownloadAll) { temp_metadata_file.Path().lexically_normal(); }), paths.end()); - EXPECT_NE( - std::find_if(paths.begin(), paths.end(), - [&temp_dbn_file](const auto& path) { - return std::filesystem::path{path}.lexically_normal() == - std::filesystem::path{temp_dbn_file.Path()} - .lexically_normal(); - }), - paths.end()); + EXPECT_NE(std::find_if( + paths.begin(), paths.end(), + [&temp_dbn_file](const auto& path) { + return std::filesystem::path{path}.lexically_normal() == + std::filesystem::path{temp_dbn_file.Path()}.lexically_normal(); + }), + paths.end()); } TEST_F(HistoricalTests, TestBatchDownloadSingle) { @@ -289,8 +285,7 @@ TEST_F(HistoricalTests, TestBatchDownloadSingle) { const std::filesystem::path path = target.BatchDownload(tmp_path_, kJobId, "test_metadata.json"); EXPECT_TRUE(temp_metadata_file.Exists()); - EXPECT_EQ(path.lexically_normal(), - temp_metadata_file.Path().lexically_normal()); + EXPECT_EQ(path.lexically_normal(), temp_metadata_file.Path().lexically_normal()); } TEST_F(HistoricalTests, TestBatchDownloadSingleInvalidFile) { @@ -321,8 +316,7 @@ TEST_F(HistoricalTests, TestMetadataListPublishers) { databento::Historical target = Client(port); const auto res = target.MetadataListPublishers(); EXPECT_EQ(res.size(), kResp.size()); - const auto glbx_exp = - PublisherDetail{1, "GLBX.MDP3", "GLBX", "CME Globex MDP 3.0"}; + const auto glbx_exp = PublisherDetail{1, "GLBX.MDP3", "GLBX", "CME Globex MDP 3.0"}; const auto xnas_exp = PublisherDetail{2, "XNAS.ITCH", "XNAS", "Nasdaq TotalView-ITCH"}; EXPECT_EQ(res[0], glbx_exp); @@ -346,8 +340,8 @@ TEST_F(HistoricalTests, TestMetadataListDatasets_Simple) { TEST_F(HistoricalTests, TestMetadataListDatasets_Full) { const nlohmann::json kResp{dataset::kXnasItch}; - mock_server_.MockGetJson("/v0/metadata.list_datasets", - {{"start_date", "2021-01-05"}}, kResp); + mock_server_.MockGetJson("/v0/metadata.list_datasets", {{"start_date", "2021-01-05"}}, + kResp); const auto port = mock_server_.ListenOnThread(); databento::Historical target = Client(port); @@ -357,19 +351,17 @@ TEST_F(HistoricalTests, TestMetadataListDatasets_Full) { } TEST_F(HistoricalTests, TestMetadataListSchemas_Simple) { - const nlohmann::json kResp{"mbo", "mbp-1", "mbp-10", - "tbbo", "trades", "ohlcv-1s", - "ohlcv-1m", "ohlcv-1h", "ohlcv-1d"}; + const nlohmann::json kResp{"mbo", "mbp-1", "mbp-10", "tbbo", "trades", + "ohlcv-1s", "ohlcv-1m", "ohlcv-1h", "ohlcv-1d"}; mock_server_.MockGetJson("/v0/metadata.list_schemas", {{"dataset", dataset::kGlbxMdp3}}, kResp); const auto port = mock_server_.ListenOnThread(); databento::Historical target = Client(port); const auto res = target.MetadataListSchemas(dataset::kGlbxMdp3); - const std::vector kExp{ - Schema::Mbo, Schema::Mbp1, Schema::Mbp10, - Schema::Tbbo, Schema::Trades, Schema::Ohlcv1S, - Schema::Ohlcv1M, Schema::Ohlcv1H, Schema::Ohlcv1D}; + const std::vector kExp{Schema::Mbo, Schema::Mbp1, Schema::Mbp10, + Schema::Tbbo, Schema::Trades, Schema::Ohlcv1S, + Schema::Ohlcv1M, Schema::Ohlcv1H, Schema::Ohlcv1D}; ASSERT_EQ(res.size(), kResp.size()); ASSERT_EQ(res.size(), kExp.size()); for (std::size_t i = 0; i < res.size(); ++i) { @@ -378,8 +370,7 @@ TEST_F(HistoricalTests, TestMetadataListSchemas_Simple) { } TEST_F(HistoricalTests, TestMetadataListSchemas_Full) { - const nlohmann::json kResp{"mbo", "mbp-1", "ohlcv-1m", "ohlcv-1h", - "ohlcv-1d"}; + const nlohmann::json kResp{"mbo", "mbp-1", "ohlcv-1m", "ohlcv-1h", "ohlcv-1d"}; mock_server_.MockGetJson("/v0/metadata.list_schemas", {{"dataset", dataset::kGlbxMdp3}}, kResp); const auto port = mock_server_.ListenOnThread(); @@ -431,8 +422,8 @@ TEST_F(HistoricalTests, TestMetadataGetDatasetCondition) { const auto port = mock_server_.ListenOnThread(); databento::Historical target = Client(port); - const auto res = target.MetadataGetDatasetCondition( - dataset::kXnasItch, {"2022-11-06", "2022-11-10"}); + const auto res = target.MetadataGetDatasetCondition(dataset::kXnasItch, + {"2022-11-06", "2022-11-10"}); const std::vector kExp{ {"2022-11-07", DatasetCondition::Available, "2023-03-01"}, {"2022-11-08", DatasetCondition::Degraded, "2023-03-01"}, @@ -460,22 +451,21 @@ TEST_F(HistoricalTests, TestMetadataListUnitPrices) { } TEST_F(HistoricalTests, TestMetadataGetDatasetRange) { - const nlohmann::json kResp = { - {"start", "2017-05-21T00:00:00.000000000Z"}, - {"end", "2022-12-01T00:00:00.000000000Z"}, - {"schema", - { - {"bbo-1m", - {{"start", "2020-08-02T00:00:00.000000000Z"}, - {"end", "2023-03-23T00:00:00.000000000Z"}}}, - {"ohlcv-1s", - {{"start", "2020-08-02T00:00:00.000000000Z"}, - {"end", "2023-03-23T00:00:00.000000000Z"}}}, - {"ohlcv-1m", - {{"start", "2020-08-02T00:00:00.000000000Z"}, - {"end", "2023-03-23T00:00:00.000000000Z"}}}, - - }}}; + const nlohmann::json kResp = {{"start", "2017-05-21T00:00:00.000000000Z"}, + {"end", "2022-12-01T00:00:00.000000000Z"}, + {"schema", + { + {"bbo-1m", + {{"start", "2020-08-02T00:00:00.000000000Z"}, + {"end", "2023-03-23T00:00:00.000000000Z"}}}, + {"ohlcv-1s", + {{"start", "2020-08-02T00:00:00.000000000Z"}, + {"end", "2023-03-23T00:00:00.000000000Z"}}}, + {"ohlcv-1m", + {{"start", "2020-08-02T00:00:00.000000000Z"}, + {"end", "2023-03-23T00:00:00.000000000Z"}}}, + + }}}; mock_server_.MockGetJson("/v0/metadata.get_dataset_range", {{"dataset", dataset::kXnasItch}}, kResp); const auto port = mock_server_.ListenOnThread(); @@ -499,8 +489,8 @@ TEST_F(HistoricalTests, TestMetadataGetRecordCount) { databento::Historical target = Client(port); const auto res = target.MetadataGetRecordCount( - dataset::kGlbxMdp3, {"2020-06-06T00:00", "2021-03-02T00:00"}, - {"ESZ3", "ESH4"}, Schema::Trades); + dataset::kGlbxMdp3, {"2020-06-06T00:00", "2021-03-02T00:00"}, {"ESZ3", "ESH4"}, + Schema::Trades); ASSERT_EQ(res, kResp); } @@ -553,9 +543,9 @@ TEST_F(HistoricalTests, TestMetadataGetCost_Simple) { const auto port = mock_server_.ListenOnThread(); databento::Historical target = Client(port); - const auto res = target.MetadataGetCost( - dataset::kGlbxMdp3, {"2020-06-06T00:00", "2021-03-02T00:00"}, - {"MESN1", "MESQ1"}, Schema::Trades); + const auto res = target.MetadataGetCost(dataset::kGlbxMdp3, + {"2020-06-06T00:00", "2021-03-02T00:00"}, + {"MESN1", "MESQ1"}, Schema::Trades); ASSERT_DOUBLE_EQ(res, kResp); } @@ -575,8 +565,8 @@ TEST_F(HistoricalTests, TestMetadataGetCost_Full) { databento::Historical target = Client(port); const auto res = target.MetadataGetCost( dataset::kGlbxMdp3, {"2020-06-06T00:00", "2021-03-02T00:00"}, - {"MES.OPT", "EW.OPT"}, Schema::Tbbo, FeedMode::HistoricalStreaming, - SType::Parent, {}); + {"MES.OPT", "EW.OPT"}, Schema::Tbbo, FeedMode::HistoricalStreaming, SType::Parent, + {}); ASSERT_DOUBLE_EQ(res, kResp); } @@ -613,9 +603,9 @@ TEST_F(HistoricalTests, TestSymbologyResolve) { const auto port = mock_server_.ListenOnThread(); databento::Historical target = Client(port); - const auto res = target.SymbologyResolve( - dataset::kGlbxMdp3, {"ESM2"}, SType::RawSymbol, SType::InstrumentId, - {"2022-06-06", "2022-06-10"}); + const auto res = + target.SymbologyResolve(dataset::kGlbxMdp3, {"ESM2"}, SType::RawSymbol, + SType::InstrumentId, {"2022-06-06", "2022-06-10"}); EXPECT_TRUE(res.not_found.empty()); EXPECT_TRUE(res.partial.empty()); ASSERT_EQ(res.mappings.size(), 1); @@ -703,11 +693,10 @@ TEST_F(HistoricalTests, TestTimeseriesGetRange_BadRequest) { [](Metadata&&) {}, [](const Record&) { return KeepGoing::Continue; }); FAIL() << "Call to TimeseriesGetRange was supposed to throw"; } catch (const std::exception& exc) { - ASSERT_STREQ( - exc.what(), - "Received an error response from request to " - "/v0/timeseries.get_range with status 400 and body " - "'{\"detail\":\"Authorization failed: illegal chars in username.\"}'" + ASSERT_STREQ(exc.what(), + "Received an error response from request to " + "/v0/timeseries.get_range with status 400 and body " + "'{\"detail\":\"Authorization failed: illegal chars in username.\"}'" ); } @@ -719,15 +708,14 @@ TEST_F(HistoricalTests, TestTimeseriesGetRange_CallbackException) { const auto port = mock_server_.ListenOnThread(); databento::Historical target = Client(port); - ASSERT_THROW( - target.TimeseriesGetRange( - dataset::kGlbxMdp3, - {UnixNanos{std::chrono::nanoseconds{1609160400000711344}}, - UnixNanos{std::chrono::nanoseconds{1609160800000711344}}}, - {"ESH1"}, Schema::Mbo, SType::RawSymbol, SType::InstrumentId, 2, - [](Metadata&&) { throw std::logic_error{"Test failure"}; }, - [](const Record&) { return KeepGoing::Continue; }), - std::logic_error); + ASSERT_THROW(target.TimeseriesGetRange( + dataset::kGlbxMdp3, + {UnixNanos{std::chrono::nanoseconds{1609160400000711344}}, + UnixNanos{std::chrono::nanoseconds{1609160800000711344}}}, + {"ESH1"}, Schema::Mbo, SType::RawSymbol, SType::InstrumentId, 2, + [](Metadata&&) { throw std::logic_error{"Test failure"}; }, + [](const Record&) { return KeepGoing::Continue; }), + std::logic_error); } TEST_F(HistoricalTests, TestTimeseriesGetRange_Cancellation) { @@ -753,12 +741,11 @@ TEST_F(HistoricalTests, TestTimeseriesGetRange_Cancellation) { } TEST_F(HistoricalTests, TestTimeseriesGetRange_LargeChunks) { - Mbp1Msg mbp1{ - RecordHeader{sizeof(Mbp1Msg) / kRecordHeaderLengthMultiplier, - RType::Mbp1, - static_cast(Publisher::IfusImpactIfus), - 10005, - {}}}; + Mbp1Msg mbp1{RecordHeader{sizeof(Mbp1Msg) / kRecordHeaderLengthMultiplier, + RType::Mbp1, + static_cast(Publisher::IfusImpactIfus), + 10005, + {}}}; constexpr auto kRecordCount = 50'000; mock_server_.MockPostDbn("/v0/timeseries.get_range", {{"dataset", ToString(Dataset::IfusImpact)}}, @@ -767,8 +754,8 @@ TEST_F(HistoricalTests, TestTimeseriesGetRange_LargeChunks) { databento::Historical target = Client(port); std::size_t counter = 0; - target.TimeseriesGetRange(ToString(Dataset::IfusImpact), - {"2024-05", "2025-05"}, kAllSymbols, Schema::Mbp1, + target.TimeseriesGetRange(ToString(Dataset::IfusImpact), {"2024-05", "2025-05"}, + kAllSymbols, Schema::Mbp1, [&counter, &mbp1](const Record& record) { ++counter; EXPECT_TRUE(record.Holds()); @@ -779,28 +766,27 @@ TEST_F(HistoricalTests, TestTimeseriesGetRange_LargeChunks) { } TEST_F(HistoricalTests, TestTimeseriesGetRange_UnreadBytes) { - Mbp1Msg mbp1{ - RecordHeader{sizeof(Mbp1Msg) / kRecordHeaderLengthMultiplier, - RType::Mbp1, - static_cast(Publisher::IfusImpactIfus), - 10005, - {}}}; + Mbp1Msg mbp1{RecordHeader{sizeof(Mbp1Msg) / kRecordHeaderLengthMultiplier, + RType::Mbp1, + static_cast(Publisher::IfusImpactIfus), + 10005, + {}}}; constexpr auto kRecordCount = 1'000; mock_server_.MockPostDbn("/v0/timeseries.get_range", {{"dataset", ToString(Dataset::IfusImpact)}}, Record{&mbp1.hd}, kRecordCount, 20, 75'000); const auto port = mock_server_.ListenOnThread(); - logger_ = mock::MockLogReceiver{[](auto count, LogLevel level, - const std::string& msg) { - EXPECT_THAT(msg, testing::EndsWith( - "Partial or incomplete record remaining of 20 bytes")); - }}; + logger_ = + mock::MockLogReceiver{[](auto count, LogLevel level, const std::string& msg) { + EXPECT_THAT(msg, testing::EndsWith( + "Partial or incomplete record remaining of 20 bytes")); + }}; databento::Historical target = Client(port); std::size_t counter = 0; - target.TimeseriesGetRange(ToString(Dataset::IfusImpact), - {"2024-05", "2025-05"}, kAllSymbols, Schema::Mbp1, + target.TimeseriesGetRange(ToString(Dataset::IfusImpact), {"2024-05", "2025-05"}, + kAllSymbols, Schema::Mbp1, [&counter, &mbp1](const Record& record) { ++counter; EXPECT_TRUE(record.Holds()); @@ -825,11 +811,10 @@ TEST_F(HistoricalTests, TestTimeseriesGetRangeToFile) { const auto port = mock_server_.ListenOnThread(); databento::Historical target = Client(port); - const TempFile temp_file{testing::TempDir() + - "/TestTimeseriesGetRangeToFile"}; + const TempFile temp_file{testing::TempDir() + "/TestTimeseriesGetRangeToFile"}; target.TimeseriesGetRangeToFile(dataset::kGlbxMdp3, - {"2022-10-21T13:30", "2022-10-21T20:00"}, - {"CYZ2"}, Schema::Tbbo, temp_file.Path()); + {"2022-10-21T13:30", "2022-10-21T20:00"}, {"CYZ2"}, + Schema::Tbbo, temp_file.Path()); // running it a second time should overwrite previous data DbnFileStore bento = target.TimeseriesGetRangeToFile( dataset::kGlbxMdp3, {"2022-10-21T13:30", "2022-10-21T20:00"}, {"CYZ2"}, @@ -842,8 +827,7 @@ TEST_F(HistoricalTests, TestTimeseriesGetRangeToFile) { ASSERT_EQ(counter, 2); } -TEST(JsonImplementationTests, - TestParsingNumberNotPreciselyRepresentableAsDouble) { +TEST(JsonImplementationTests, TestParsingNumberNotPreciselyRepresentableAsDouble) { auto const number_json = nlohmann::json::parse("1609160400000711344"); EXPECT_TRUE(number_json.is_number()); EXPECT_EQ(number_json, 1609160400000711344); @@ -877,9 +861,7 @@ TEST(HistoricalBuilderTests, TestSetKeyFromEnv) { } TEST(HistoricalBuilderTests, TestSetKeyFromEnvMissing) { - ASSERT_EQ(::unsetenv("DATABENTO_API_KEY"), 0) - << "Failed to set environment variable"; - ASSERT_THROW(databento::HistoricalBuilder().SetKeyFromEnv().Build(), - Exception); + ASSERT_EQ(::unsetenv("DATABENTO_API_KEY"), 0) << "Failed to set environment variable"; + ASSERT_THROW(databento::HistoricalBuilder().SetKeyFromEnv().Build(), Exception); } } // namespace databento::tests diff --git a/tests/src/http_client_tests.cpp b/tests/src/http_client_tests.cpp index bce9194..831a31b 100644 --- a/tests/src/http_client_tests.cpp +++ b/tests/src/http_client_tests.cpp @@ -16,19 +16,17 @@ class HttpClientTests : public ::testing::Test { }; TEST_F(HttpClientTests, TestLogWarnings) { - const nlohmann::json warnings{ - "DeprecationWarning: stype product_id is deprecated", - "Warning: Large request"}; + const nlohmann::json warnings{"DeprecationWarning: stype product_id is deprecated", + "Warning: Large request"}; mock_server_.MockGetJson("/warn", {}, {}, warnings); const auto port = mock_server_.ListenOnThread(); databento::tests::mock::MockLogReceiver mock_logger{ [](auto call_count, databento::LogLevel level, const std::string& msg) { EXPECT_EQ(level, LogLevel::Warning); if (call_count == 0) { - EXPECT_THAT( - msg, - testing::EndsWith( - "Server DeprecationWarning: stype product_id is deprecated")); + EXPECT_THAT(msg, + testing::EndsWith( + "Server DeprecationWarning: stype product_id is deprecated")); } else { EXPECT_THAT(msg, testing::EndsWith("Server Warning: Large request")); } diff --git a/tests/src/live_blocking_tests.cpp b/tests/src/live_blocking_tests.cpp index 7caf7ad..7074a5d 100644 --- a/tests/src/live_blocking_tests.cpp +++ b/tests/src/live_blocking_tests.cpp @@ -30,8 +30,7 @@ class LiveBlockingTests : public testing::Test { protected: template static constexpr RecordHeader DummyHeader(RType rtype) { - return {sizeof(T) / RecordHeader::kLengthMultiplier, rtype, 1, 1, - UnixNanos{}}; + return {sizeof(T) / RecordHeader::kLengthMultiplier, rtype, 1, 1, UnixNanos{}}; } static constexpr auto kKey = "32-character-with-lots-of-filler"; @@ -45,8 +44,7 @@ class LiveBlockingTests : public testing::Test { TEST_F(LiveBlockingTests, TestAuthentication) { constexpr auto kTsOut = false; constexpr auto kHeartbeatInterval = std::chrono::seconds{10}; - const mock::MockLsgServer mock_server{dataset::kXnasItch, kTsOut, - kHeartbeatInterval, + const mock::MockLsgServer mock_server{dataset::kXnasItch, kTsOut, kHeartbeatInterval, [](mock::MockLsgServer& self) { self.Accept(); self.Authenticate(); @@ -91,8 +89,7 @@ TEST_F(LiveBlockingTests, TestSubscribe) { const auto kSType = SType::RawSymbol; const mock::MockLsgServer mock_server{ - kDataset, kTsOut, - [&kSymbols, kSchema, kSType](mock::MockLsgServer& self) { + kDataset, kTsOut, [&kSymbols, kSchema, kSType](mock::MockLsgServer& self) { self.Accept(); self.Authenticate(); self.Subscribe(kSymbols, kSchema, kSType, true); @@ -172,8 +169,7 @@ TEST_F(LiveBlockingTests, TestSubscriptionChunkingStringStart) { const mock::MockLsgServer mock_server{ kDataset, kTsOut, - [kSymbol, kSymbolCount, kSchema, kSType, - kStart](mock::MockLsgServer& self) { + [kSymbol, kSymbolCount, kSchema, kSType, kStart](mock::MockLsgServer& self) { self.Accept(); self.Authenticate(); std::size_t i{}; @@ -255,14 +251,14 @@ TEST_F(LiveBlockingTests, TestNextRecord) { constexpr auto kTsOut = false; const auto kRecCount = 12; constexpr OhlcvMsg kRec{DummyHeader(RType::Ohlcv1M), 1, 2, 3, 4, 5}; - const mock::MockLsgServer mock_server{ - dataset::kXnasItch, kTsOut, [kRec, kRecCount](mock::MockLsgServer& self) { - self.Accept(); - self.Authenticate(); - for (size_t i = 0; i < kRecCount; ++i) { - self.SendRecord(kRec); - } - }}; + const mock::MockLsgServer mock_server{dataset::kXnasItch, kTsOut, + [kRec, kRecCount](mock::MockLsgServer& self) { + self.Accept(); + self.Authenticate(); + for (size_t i = 0; i < kRecCount; ++i) { + self.SendRecord(kRec); + } + }}; LiveBlocking target = builder_.SetDataset(dataset::kXnasItch) .SetSendTsOut(kTsOut) @@ -310,8 +306,7 @@ TEST_F(LiveBlockingTests, TestNextRecordTimeout) { { // wait for client to read first record std::unique_lock lock{receive_mutex}; - receive_cv.wait(lock, - [&received_first_msg] { return received_first_msg; }); + receive_cv.wait(lock, [&received_first_msg] { return received_first_msg; }); } self.SendRecord(kRec); }}; @@ -409,8 +404,7 @@ TEST_F(LiveBlockingTests, TestNextRecordWithTsOut) { 2}, UnixNanos{std::chrono::seconds{1678910279000000000}}}; const mock::MockLsgServer mock_server{ - dataset::kXnasItch, kTsOut, - [send_rec, kRecCount](mock::MockLsgServer& self) { + dataset::kXnasItch, kTsOut, [send_rec, kRecCount](mock::MockLsgServer& self) { self.Accept(); self.Authenticate(); for (size_t i = 0; i < kRecCount; ++i) { @@ -448,8 +442,7 @@ TEST_F(LiveBlockingTests, TestStop) { UnixNanos{std::chrono::seconds{1678910279000000000}}}; std::atomic has_stopped{false}; auto mock_server = std::make_unique( - dataset::kXnasItch, kTsOut, - [send_rec, &has_stopped](mock::MockLsgServer& self) { + dataset::kXnasItch, kTsOut, [send_rec, &has_stopped](mock::MockLsgServer& self) { self.Accept(); self.Authenticate(); self.SendRecord(send_rec); @@ -458,8 +451,7 @@ TEST_F(LiveBlockingTests, TestStop) { } const std::string rec_str{reinterpret_cast(&send_rec), sizeof(send_rec)}; - while (self.UncheckedSend(rec_str) == - static_cast<::ssize_t>(rec_str.size())) { + while (self.UncheckedSend(rec_str) == static_cast<::ssize_t>(rec_str.size())) { } }); @@ -505,8 +497,7 @@ TEST_F(LiveBlockingTests, TestReconnectAndResubscribe) { &should_close_cv, &should_close_mutex](mock::MockLsgServer& self) { self.Accept(); self.Authenticate(); - self.Subscribe(kAllSymbols, Schema::Trades, SType::RawSymbol, "0", - true); + self.Subscribe(kAllSymbols, Schema::Trades, SType::RawSymbol, "0", true); self.Start(); self.SendRecord(kRec); { diff --git a/tests/src/live_tests.cpp b/tests/src/live_tests.cpp index 1410e88..de1a100 100644 --- a/tests/src/live_tests.cpp +++ b/tests/src/live_tests.cpp @@ -23,12 +23,10 @@ TEST(LiveBuilderTests, TestMissingKey) { } TEST(LiveBuilderTests, TestMissingDataset) { - ASSERT_THROW(databento::LiveBuilder().SetKey(kKey).BuildThreaded(), - Exception); + ASSERT_THROW(databento::LiveBuilder().SetKey(kKey).BuildThreaded(), Exception); } TEST(LiveBuilderTests, TestSetKeyFromEnvMissing) { - ASSERT_THROW(databento::LiveBuilder().SetKeyFromEnv().BuildThreaded(), - Exception); + ASSERT_THROW(databento::LiveBuilder().SetKeyFromEnv().BuildThreaded(), Exception); } } // namespace databento::tests diff --git a/tests/src/live_threaded_tests.cpp b/tests/src/live_threaded_tests.cpp index 049e506..a335d91 100644 --- a/tests/src/live_threaded_tests.cpp +++ b/tests/src/live_threaded_tests.cpp @@ -29,8 +29,7 @@ class LiveThreadedTests : public testing::Test { protected: template static constexpr RecordHeader DummyHeader(RType rtype) { - return {sizeof(T) / RecordHeader::kLengthMultiplier, rtype, 1, 1, - UnixNanos{}}; + return {sizeof(T) / RecordHeader::kLengthMultiplier, rtype, 1, 1, UnixNanos{}}; } static constexpr auto kKey = "32-character-with-lots-of-filler"; @@ -55,8 +54,7 @@ TEST_F(LiveThreadedTests, TestBasic) { TimeDeltaNanos{}, 100}; constexpr auto kHeartbeatInterval = std::chrono::seconds{5}; - const mock::MockLsgServer mock_server{dataset::kGlbxMdp3, kTsOut, - kHeartbeatInterval, + const mock::MockLsgServer mock_server{dataset::kGlbxMdp3, kTsOut, kHeartbeatInterval, [&kRec](mock::MockLsgServer& self) { self.Accept(); self.Authenticate(); @@ -94,8 +92,7 @@ TEST_F(LiveThreadedTests, TestTimeoutRecovery) { 100}; std::atomic call_count{}; const mock::MockLsgServer mock_server{ - dataset::kXnasItch, kTsOut, - [&kRec, &call_count](mock::MockLsgServer& self) { + dataset::kXnasItch, kTsOut, [&kRec, &call_count](mock::MockLsgServer& self) { self.Accept(); self.Authenticate(); self.Start(); @@ -112,14 +109,13 @@ TEST_F(LiveThreadedTests, TestTimeoutRecovery) { .SetSendTsOut(kTsOut) .SetAddress(kLocalhost, mock_server.Port()) .BuildThreaded(); - target.Start( - [](Metadata&& metadata) { EXPECT_FALSE(metadata.schema.has_value()); }, - [&call_count, &kRec](const Record& rec) { - ++call_count; - EXPECT_TRUE(rec.Holds()); - EXPECT_EQ(rec.Get(), kRec); - return databento::KeepGoing::Continue; - }); + target.Start([](Metadata&& metadata) { EXPECT_FALSE(metadata.schema.has_value()); }, + [&call_count, &kRec](const Record& rec) { + ++call_count; + EXPECT_TRUE(rec.Holds()); + EXPECT_EQ(rec.Get(), kRec); + return databento::KeepGoing::Continue; + }); while (call_count < 2) { std::this_thread::yield(); } @@ -139,8 +135,7 @@ TEST_F(LiveThreadedTests, TestStop) { 100}; std::atomic call_count{}; auto mock_server = std::make_unique( - dataset::kXnasItch, kTsOut, - [&kRec, &call_count](mock::MockLsgServer& self) { + dataset::kXnasItch, kTsOut, [&kRec, &call_count](mock::MockLsgServer& self) { self.Accept(); self.Authenticate(); self.Start(); @@ -149,10 +144,8 @@ TEST_F(LiveThreadedTests, TestStop) { while (call_count < 1) { std::this_thread::yield(); } - const std::string rec_str{reinterpret_cast(&kRec), - sizeof(kRec)}; - while (self.UncheckedSend(rec_str) == - static_cast<::ssize_t>(rec_str.size())) { + const std::string rec_str{reinterpret_cast(&kRec), sizeof(kRec)}; + while (self.UncheckedSend(rec_str) == static_cast<::ssize_t>(rec_str.size())) { std::this_thread::yield(); } }); @@ -161,15 +154,14 @@ TEST_F(LiveThreadedTests, TestStop) { .SetSendTsOut(kTsOut) .SetAddress(kLocalhost, mock_server->Port()) .BuildThreaded(); - target.Start( - [](Metadata&& metadata) { EXPECT_FALSE(metadata.schema.has_value()); }, - [&call_count, &kRec](const Record& rec) { - ++call_count; - EXPECT_EQ(call_count, 1) << "Record callback called more than once"; - EXPECT_TRUE(rec.Holds()); - EXPECT_EQ(rec.Get(), kRec); - return databento::KeepGoing::Stop; - }); + target.Start([](Metadata&& metadata) { EXPECT_FALSE(metadata.schema.has_value()); }, + [&call_count, &kRec](const Record& rec) { + ++call_count; + EXPECT_EQ(call_count, 1) << "Record callback called more than once"; + EXPECT_TRUE(rec.Holds()); + EXPECT_EQ(rec.Get(), kRec); + return databento::KeepGoing::Stop; + }); // kill mock server and join thread before client goes out of scope // to ensure Stop is killing the connection, not the client's destructor mock_server.reset(); @@ -195,8 +187,8 @@ TEST_F(LiveThreadedTests, TestExceptionCallbackReconnectAndResubscribe) { std::condition_variable should_close_cv; const mock::MockLsgServer mock_server{ dataset::kXnasItch, kTsOut, - [&should_close, &should_close_mutex, &should_close_cv, kRec, kSchema, - kSType, kUseSnapshot](mock::MockLsgServer& self) { + [&should_close, &should_close_mutex, &should_close_cv, kRec, kSchema, kSType, + kUseSnapshot](mock::MockLsgServer& self) { self.Accept(); self.Authenticate(); self.Subscribe(kAllSymbols, kSchema, kSType, "0", true); @@ -204,8 +196,7 @@ TEST_F(LiveThreadedTests, TestExceptionCallbackReconnectAndResubscribe) { self.SendRecord(kRec); { std::unique_lock shutdown_lock{should_close_mutex}; - should_close_cv.wait(shutdown_lock, - [&should_close] { return should_close; }); + should_close_cv.wait(shutdown_lock, [&should_close] { return should_close; }); } self.Close(); self.Accept(); @@ -217,10 +208,9 @@ TEST_F(LiveThreadedTests, TestExceptionCallbackReconnectAndResubscribe) { logger_ = mock::MockLogReceiver{ LogLevel::Warning, [](auto count, databento::LogLevel level, const std::string& msg) { - EXPECT_THAT( - msg, - testing::EndsWith( - "Gateway closed the session. Attempting to restart session.")); + EXPECT_THAT(msg, + testing::EndsWith( + "Gateway closed the session. Attempting to restart session.")); }}; LiveThreaded target = builder_.SetDataset(dataset::kXnasItch) .SetSendTsOut(kTsOut) @@ -232,8 +222,7 @@ TEST_F(LiveThreadedTests, TestExceptionCallbackReconnectAndResubscribe) { EXPECT_FALSE(metadata.schema.has_value()); }; std::atomic record_calls{}; - const auto record_cb = [&record_calls, kRec, &should_close_mutex, - &should_close, + const auto record_cb = [&record_calls, kRec, &should_close_mutex, &should_close, &should_close_cv](const Record& record) { ++record_calls; EXPECT_EQ(record.Get(), kRec); @@ -300,8 +289,7 @@ TEST_F(LiveThreadedTests, TestDeadlockPrevention) { self.Start(); { std::unique_lock shutdown_lock{should_close_mutex}; - should_close_cv.wait(shutdown_lock, - [&should_close] { return should_close; }); + should_close_cv.wait(shutdown_lock, [&should_close] { return should_close; }); } self.Close(); self.Accept(); @@ -326,8 +314,8 @@ TEST_F(LiveThreadedTests, TestDeadlockPrevention) { ++record_calls; return KeepGoing::Continue; }; - const auto exception_cb = [&target, &metadata_cb, &record_cb, &kSymbols, - kSchema, kSType](const std::exception& exc) { + const auto exception_cb = [&target, &metadata_cb, &record_cb, &kSymbols, kSchema, + kSType](const std::exception& exc) { EXPECT_NE(dynamic_cast(&exc), nullptr) << "Unexpected exception type"; target.Reconnect(); @@ -358,7 +346,6 @@ TEST_F(LiveThreadedTests, TestBlockForStopTimeout) { .SetAddress(kLocalhost, mock_server.Port()) .BuildThreaded(); target.Start([](const Record&) { return KeepGoing::Continue; }); - ASSERT_EQ(target.BlockForStop(std::chrono::milliseconds{100}), - KeepGoing::Continue); + ASSERT_EQ(target.BlockForStop(std::chrono::milliseconds{100}), KeepGoing::Continue); } } // namespace databento::tests diff --git a/tests/src/log_tests.cpp b/tests/src/log_tests.cpp index b027e18..d16d509 100644 --- a/tests/src/log_tests.cpp +++ b/tests/src/log_tests.cpp @@ -40,15 +40,14 @@ TEST(ILogReceiverTests, TestDefault) { } TEST(ILogReceiverTests, TestLogPlatformInfo) { - mock::MockLogReceiver receiver{ - [](auto, LogLevel lvl, const std::string& msg) { - EXPECT_EQ(lvl, LogLevel::Info); - EXPECT_THAT(msg, testing::HasSubstr(DATABENTO_SYSTEM_ID)); - EXPECT_THAT(msg, testing::HasSubstr(DATABENTO_SYSTEM_VERSION)); - EXPECT_THAT(msg, testing::HasSubstr(DATABENTO_CXX_COMPILER_ID)); - EXPECT_THAT(msg, testing::HasSubstr(DATABENTO_CXX_COMPILER_VERSION)); - EXPECT_THAT(msg, testing::HasSubstr(DATABENTO_VERSION)); - }}; + mock::MockLogReceiver receiver{[](auto, LogLevel lvl, const std::string& msg) { + EXPECT_EQ(lvl, LogLevel::Info); + EXPECT_THAT(msg, testing::HasSubstr(DATABENTO_SYSTEM_ID)); + EXPECT_THAT(msg, testing::HasSubstr(DATABENTO_SYSTEM_VERSION)); + EXPECT_THAT(msg, testing::HasSubstr(DATABENTO_CXX_COMPILER_ID)); + EXPECT_THAT(msg, testing::HasSubstr(DATABENTO_CXX_COMPILER_VERSION)); + EXPECT_THAT(msg, testing::HasSubstr(DATABENTO_VERSION)); + }}; LogPlatformInfo(&receiver); ASSERT_EQ(receiver.CallCount(), 1); } diff --git a/tests/src/metadata_tests.cpp b/tests/src/metadata_tests.cpp index a81d10d..d016fd7 100644 --- a/tests/src/metadata_tests.cpp +++ b/tests/src/metadata_tests.cpp @@ -5,13 +5,12 @@ namespace databento::tests { TEST(MetadataTests, TestDatasetConditionDetailToString) { - const DatasetConditionDetail available{ - "2022-11-10", DatasetCondition::Available, "2023-03-01"}; + const DatasetConditionDetail available{"2022-11-10", DatasetCondition::Available, + "2023-03-01"}; EXPECT_EQ( ToString(available), R"(DatasetConditionDetail { date = "2022-11-10", condition = available, last_modified_date = "2023-03-01" })"); - const DatasetConditionDetail missing{ - "2022-11-11", DatasetCondition::Missing, {}}; + const DatasetConditionDetail missing{"2022-11-11", DatasetCondition::Missing, {}}; EXPECT_EQ( ToString(missing), R"(DatasetConditionDetail { date = "2022-11-11", condition = missing, last_modified_date = nullopt })"); diff --git a/tests/src/mock_http_server.cpp b/tests/src/mock_http_server.cpp index e8cde50..5947694 100644 --- a/tests/src/mock_http_server.cpp +++ b/tests/src/mock_http_server.cpp @@ -17,8 +17,7 @@ using databento::tests::mock::MockHttpServer; int MockHttpServer::ListenOnThread() { - listen_thread_ = - detail::ScopedThread{[this] { this->server_.listen_after_bind(); }}; + listen_thread_ = detail::ScopedThread{[this] { this->server_.listen_after_bind(); }}; return port_; } @@ -30,20 +29,20 @@ void MockHttpServer::MockBadPostRequest(const std::string& path, }); } -void MockHttpServer::MockGetJson(const std::string& path, - const nlohmann::json& json) { +void MockHttpServer::MockGetJson(const std::string& path, const nlohmann::json& json) { this->MockGetJson(path, {}, json); } -void MockHttpServer::MockGetJson( - const std::string& path, const std::map& params, - const nlohmann::json& json) { +void MockHttpServer::MockGetJson(const std::string& path, + const std::map& params, + const nlohmann::json& json) { this->MockGetJson(path, params, json, {}); } -void MockHttpServer::MockGetJson( - const std::string& path, const std::map& params, - const nlohmann::json& json, const nlohmann::json& warnings) { +void MockHttpServer::MockGetJson(const std::string& path, + const std::map& params, + const nlohmann::json& json, + const nlohmann::json& warnings) { server_.Get(path, [json, params, warnings](const httplib::Request& req, httplib::Response& resp) { if (!req.has_header("Authorization")) { @@ -60,59 +59,57 @@ void MockHttpServer::MockGetJson( }); } -void MockHttpServer::MockPostJson( - const std::string& path, - const std::map& form_params, - const nlohmann::json& json) { - server_.Post(path, [json, form_params](const httplib::Request& req, - httplib::Response& resp) { - if (!req.has_header("Authorization")) { - resp.status = 401; - return; - } - [[maybe_unused]] auto _auth = req.get_header_value("Authorization"); - CheckFormParams(form_params, req); - resp.set_content(json.dump(), "application/json"); - resp.status = 200; - }); +void MockHttpServer::MockPostJson(const std::string& path, + const std::map& form_params, + const nlohmann::json& json) { + server_.Post( + path, [json, form_params](const httplib::Request& req, httplib::Response& resp) { + if (!req.has_header("Authorization")) { + resp.status = 401; + return; + } + [[maybe_unused]] auto _auth = req.get_header_value("Authorization"); + CheckFormParams(form_params, req); + resp.set_content(json.dump(), "application/json"); + resp.status = 200; + }); } -void MockHttpServer::MockGetDbn( - const std::string& path, const std::map& params, - const std::string& dbn_path) { +void MockHttpServer::MockGetDbn(const std::string& path, + const std::map& params, + const std::string& dbn_path) { constexpr std::size_t kChunkSize = 32; // Read contents into buffer auto buffer = EncodeToBuffer(dbn_path); // Serve - server_.Get(path, - MakeDbnStreamHandler(params, std::move(buffer), kChunkSize)); + server_.Get(path, MakeDbnStreamHandler(params, std::move(buffer), kChunkSize)); } -void MockHttpServer::MockPostDbn( - const std::string& path, const std::map& params, - const std::string& dbn_path) { +void MockHttpServer::MockPostDbn(const std::string& path, + const std::map& params, + const std::string& dbn_path) { constexpr std::size_t kChunkSize = 32; // Read contents into buffer auto buffer = EncodeToBuffer(dbn_path); // Serve - server_.Post(path, - MakeDbnStreamHandler(params, std::move(buffer), kChunkSize)); + server_.Post(path, MakeDbnStreamHandler(params, std::move(buffer), kChunkSize)); } -void MockHttpServer::MockPostDbn( - const std::string& path, const std::map& params, - Record record, std::size_t count, std::size_t chunk_size) { +void MockHttpServer::MockPostDbn(const std::string& path, + const std::map& params, + Record record, std::size_t count, + std::size_t chunk_size) { MockPostDbn(path, params, record, count, 0, chunk_size); } -void MockHttpServer::MockPostDbn( - const std::string& path, const std::map& params, - Record record, std::size_t count, std::size_t extra_bytes, - std::size_t chunk_size) { +void MockHttpServer::MockPostDbn(const std::string& path, + const std::map& params, + Record record, std::size_t count, + std::size_t extra_bytes, std::size_t chunk_size) { // Needs to be copy-constructable for use in server auto buffer = std::make_shared(); { @@ -134,35 +131,29 @@ void MockHttpServer::MockPostDbn( zstd_stream.WriteAll(empty.data(), empty.size()); } } - server_.Post(path, - MakeDbnStreamHandler(params, std::move(buffer), chunk_size)); + server_.Post(path, MakeDbnStreamHandler(params, std::move(buffer), chunk_size)); } -void MockHttpServer::CheckParams( - const std::map& params, - const httplib::Request& req) { +void MockHttpServer::CheckParams(const std::map& params, + const httplib::Request& req) { for (const auto& param : params) { - EXPECT_TRUE(req.has_param(param.first)) - << "Missing query param " << param.first; + EXPECT_TRUE(req.has_param(param.first)) << "Missing query param " << param.first; EXPECT_EQ(req.get_param_value(param.first), param.second) << "Incorrect query param value for " << param.first << ". Expected " << param.second << ", found " << req.get_param_value(param.first); } } -void MockHttpServer::CheckFormParams( - const std::map& params, - const httplib::Request& req) { - EXPECT_EQ(req.get_header_value("content-type"), - "application/x-www-form-urlencoded") +void MockHttpServer::CheckFormParams(const std::map& params, + const httplib::Request& req) { + EXPECT_EQ(req.get_header_value("content-type"), "application/x-www-form-urlencoded") << "Request body is not form data"; httplib::Params form_params; httplib::detail::parse_query_text(req.body, form_params); for (const auto& param : params) { const auto param_it = form_params.find(param.first); if (param_it == form_params.end()) { - EXPECT_NE(param_it, form_params.end()) - << "Missing for mparam " << param.first; + EXPECT_NE(param_it, form_params.end()) << "Missing for mparam " << param.first; } else { EXPECT_EQ(param_it->second, param.second) << "Incorrect form param value for " << param.first << ". Expected " @@ -186,10 +177,10 @@ MockHttpServer::SharedConstBuffer MockHttpServer::EncodeToBuffer( } httplib::Server::Handler MockHttpServer::MakeDbnStreamHandler( - const std::map& params, - SharedConstBuffer&& buffer, std::size_t chunk_size) { - return [buffer = std::move(buffer), chunk_size, params]( - const httplib::Request& req, httplib::Response& resp) { + const std::map& params, SharedConstBuffer&& buffer, + std::size_t chunk_size) { + return [buffer = std::move(buffer), chunk_size, params](const httplib::Request& req, + httplib::Response& resp) { if (!req.has_header("Authorization")) { resp.status = 401; return; @@ -199,12 +190,10 @@ httplib::Server::Handler MockHttpServer::MakeDbnStreamHandler( resp.set_header("Content-Disposition", "attachment; filename=test.dbn.zst"); resp.set_content_provider( "application/octet-stream", - [buffer, chunk_size](const std::size_t offset, - httplib::DataSink& sink) { + [buffer, chunk_size](const std::size_t offset, httplib::DataSink& sink) { if (offset < buffer->ReadCapacity()) { - sink.write( - reinterpret_cast(&buffer->ReadBegin()[offset]), - std::min(chunk_size, buffer->ReadCapacity() - offset)); + sink.write(reinterpret_cast(&buffer->ReadBegin()[offset]), + std::min(chunk_size, buffer->ReadCapacity() - offset)); } else { sink.done(); } diff --git a/tests/src/mock_lsg_server.cpp b/tests/src/mock_lsg_server.cpp index e5e0a14..67161a0 100644 --- a/tests/src/mock_lsg_server.cpp +++ b/tests/src/mock_lsg_server.cpp @@ -28,8 +28,8 @@ void SocketStream::WriteAll(const std::byte* buffer, std::size_t length) { constexpr int MSG_NOSIGNAL = {}; #endif // Don't send a SIGPIPE if the connection is closed - last_write_size_ = ::send(socket_, reinterpret_cast(buffer), - length, MSG_NOSIGNAL); + last_write_size_ = + ::send(socket_, reinterpret_cast(buffer), length, MSG_NOSIGNAL); } using databento::tests::mock::MockLsgServer; @@ -98,8 +98,7 @@ void MockLsgServer::Authenticate() { Send("cram=t7kNhwj4xqR0QYjzFKtBEG2ec2pXJ4FK\n"); const auto received = Receive(); const auto auth_start = received.find('=') + 1; - const auto auth = - received.substr(auth_start, received.find('-') - auth_start); + const auto auth = received.substr(auth_start, received.find('-') - auth_start); EXPECT_EQ(auth.length(), SHA256_DIGEST_LENGTH * 2); for (const char c : auth) { EXPECT_TRUE((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f')) @@ -107,8 +106,7 @@ void MockLsgServer::Authenticate() { } EXPECT_NE(received.find("dataset=" + dataset_), std::string::npos); EXPECT_NE(received.find("encoding=dbn"), std::string::npos); - EXPECT_NE(received.find("ts_out=" + std::to_string(ts_out_)), - std::string::npos); + EXPECT_NE(received.find("ts_out=" + std::to_string(ts_out_)), std::string::npos); if (heartbeat_interval_.count() > 0) { EXPECT_NE(received.find("heartbeat_interval_s=" + std::to_string(heartbeat_interval_.count())), @@ -119,19 +117,17 @@ void MockLsgServer::Authenticate() { Send("success=1|session_id=5|\n"); } -void MockLsgServer::Subscribe(const std::vector& symbols, - Schema schema, SType stype, bool is_last) { +void MockLsgServer::Subscribe(const std::vector& symbols, Schema schema, + SType stype, bool is_last) { Subscribe(symbols, schema, stype, "", is_last); } -void MockLsgServer::SubscribeWithSnapshot( - const std::vector& symbols, Schema schema, SType stype, - bool is_last) { +void MockLsgServer::SubscribeWithSnapshot(const std::vector& symbols, + Schema schema, SType stype, bool is_last) { const auto received = Receive(); - EXPECT_NE( - received.find("symbols=" + - JoinSymbolStrings("MockLsgServer::Subscribe", symbols)), - std::string::npos); + EXPECT_NE(received.find("symbols=" + + JoinSymbolStrings("MockLsgServer::Subscribe", symbols)), + std::string::npos); EXPECT_NE(received.find(std::string{"schema="} + ToString(schema)), std::string::npos); EXPECT_NE(received.find(std::string{"stype_in="} + ToString(stype)), @@ -143,14 +139,12 @@ void MockLsgServer::SubscribeWithSnapshot( std::string::npos); } -void MockLsgServer::Subscribe(const std::vector& symbols, - Schema schema, SType stype, - const std::string& start, bool is_last) { +void MockLsgServer::Subscribe(const std::vector& symbols, Schema schema, + SType stype, const std::string& start, bool is_last) { const auto received = Receive(); - EXPECT_NE( - received.find("symbols=" + - JoinSymbolStrings("MockLsgServer::Subscribe", symbols)), - std::string::npos); + EXPECT_NE(received.find("symbols=" + + JoinSymbolStrings("MockLsgServer::Subscribe", symbols)), + std::string::npos); EXPECT_NE(received.find(std::string{"schema="} + ToString(schema)), std::string::npos); EXPECT_NE(received.find(std::string{"stype_in="} + ToString(stype)), diff --git a/tests/src/mock_tcp_server.cpp b/tests/src/mock_tcp_server.cpp index 0f04847..678472b 100644 --- a/tests/src/mock_tcp_server.cpp +++ b/tests/src/mock_tcp_server.cpp @@ -19,8 +19,7 @@ MockTcpServer::MockTcpServer() : MockTcpServer([](MockTcpServer& self) { self.Serve(); }) {} MockTcpServer::MockTcpServer(std::function serve_fn) - : socket_{InitSocketAndSetPort()}, - thread_{std::move(serve_fn), std::ref(*this)} {} + : socket_{InitSocketAndSetPort()}, thread_{std::move(serve_fn), std::ref(*this)} {} void MockTcpServer::SetSend(std::string send) { const std::lock_guard lock{send_mutex_}; @@ -57,8 +56,8 @@ void MockTcpServer::Accept() { #endif // Disable Nagle's algorithm for finer control over when packets are sent // during testing - const auto res = ::setsockopt(socket_.Get(), IPPROTO_TCP, TCP_NODELAY, - flag_ptr, sizeof(int)); + const auto res = + ::setsockopt(socket_.Get(), IPPROTO_TCP, TCP_NODELAY, flag_ptr, sizeof(int)); if (res < 0) { throw TcpError{errno, "Failed to disable Nagle's algorithm"}; } @@ -76,15 +75,13 @@ void MockTcpServer::Receive() { void MockTcpServer::Send() { const std::lock_guard send_guard{send_mutex_}; - const auto write_size = - ::send(conn_fd_.Get(), send_.data(), send_.length(), {}); + const auto write_size = ::send(conn_fd_.Get(), send_.data(), send_.length(), {}); ASSERT_EQ(write_size, send_.length()); } void MockTcpServer::Close() { conn_fd_.Close(); } -std::pair -MockTcpServer::InitSocket() { +std::pair MockTcpServer::InitSocket() { return InitSocket(0); // port will be assigned } @@ -98,14 +95,12 @@ std::pair MockTcpServer::InitSocket( addr_in.sin_family = AF_INET; addr_in.sin_port = port; addr_in.sin_addr.s_addr = INADDR_ANY; - if (::bind(fd, reinterpret_cast(&addr_in), - sizeof(addr_in)) != 0) { + if (::bind(fd, reinterpret_cast(&addr_in), sizeof(addr_in)) != 0) { throw TcpError{errno, "Failed to bind to port"}; } sockaddr_in addr_actual{}; auto addr_size = static_cast(sizeof(addr_actual)); - if (::getsockname(fd, reinterpret_cast(&addr_actual), - &addr_size) == -1) { + if (::getsockname(fd, reinterpret_cast(&addr_actual), &addr_size) == -1) { throw TcpError{errno, "Error fetching port"}; } const auto actual_port = ntohs(addr_actual.sin_port); diff --git a/tests/src/pretty_tests.cpp b/tests/src/pretty_tests.cpp index 099bd6d..6a5ebfc 100644 --- a/tests/src/pretty_tests.cpp +++ b/tests/src/pretty_tests.cpp @@ -15,12 +15,11 @@ namespace databento::pretty::tests { TEST(PrettyTests, TestPrettyPx) { std::ostringstream ss; - std::vector> cases{ - {-100'000, "-0.000100000"}, - {32'500'000'000, "32.500000000"}, - {101'005'000'000, "101.005000000"}, - {0, "0.000000000"}, - {kUndefPrice, "UNDEF_PRICE"}}; + std::vector> cases{{-100'000, "-0.000100000"}, + {32'500'000'000, "32.500000000"}, + {101'005'000'000, "101.005000000"}, + {0, "0.000000000"}, + {kUndefPrice, "UNDEF_PRICE"}}; for (const auto& [num, exp] : cases) { ss << Px{num}; ASSERT_EQ(ss.str(), exp); @@ -56,13 +55,11 @@ TEST(PrettyTests, TestDefaultFill) { ASSERT_EQ(ss.str(), exp_right); ss.str(""); // Left - ss << std::setw(width) << std::left << std::setprecision(precision) - << Px{num}; + ss << std::setw(width) << std::left << std::setprecision(precision) << Px{num}; ASSERT_EQ(ss.str(), exp_left); ss.str(""); // Right - ss << std::setw(width) << std::right << std::setprecision(precision) - << Px{num}; + ss << std::setw(width) << std::right << std::setprecision(precision) << Px{num}; ASSERT_EQ(ss.str(), exp_right); ss.str(""); } diff --git a/tests/src/record_tests.cpp b/tests/src/record_tests.cpp index 0a2ea47..fd84cd9 100644 --- a/tests/src/record_tests.cpp +++ b/tests/src/record_tests.cpp @@ -11,26 +11,24 @@ namespace databento::tests { TEST(RecordTests, TestRecordToString) { - TradeMsg target{ - RecordHeader{sizeof(TradeMsg) / RecordHeader::kLengthMultiplier, - RType::Mbp0, - static_cast(Publisher::OpraPillarEdgo), - 1, - {}}, - 55000000000, - 500, - Action::Add, - Side::Bid, - {}, - 0, - {}, - {}, - 126239}; + TradeMsg target{RecordHeader{sizeof(TradeMsg) / RecordHeader::kLengthMultiplier, + RType::Mbp0, + static_cast(Publisher::OpraPillarEdgo), + 1, + {}}, + 55000000000, + 500, + Action::Add, + Side::Bid, + {}, + 0, + {}, + {}, + 126239}; const Record rec{&target.hd}; - EXPECT_EQ( - ToString(rec), - "Record { ptr = RecordHeader { length = 12, rtype = Mbp0, publisher_id = " - "24, instrument_id = 1, ts_event = 1970-01-01T00:00:00.000000000Z } }"); + EXPECT_EQ(ToString(rec), + "Record { ptr = RecordHeader { length = 12, rtype = mbp-0, publisher_id " + "= 24, instrument_id = 1, ts_event = 1970-01-01T00:00:00.000000000Z } }"); } TEST(RecordTests, TestPublisher) { const TradeMsg target{ @@ -53,19 +51,18 @@ TEST(RecordTests, TestPublisher) { EXPECT_EQ(PublisherDataset(target.hd.Publisher()), Dataset::OpraPillar); } TEST(RecordTests, TestMbp10MsgToString) { - Mbp10Msg target{ - RecordHeader{sizeof(Mbp10Msg) / RecordHeader::kLengthMultiplier, - RType::Mbp10, 1, 1, UnixNanos{}}, - 100000000, - 10, - Action::Add, - Side::Bid, - {}, - 0, - UnixNanos{std::chrono::nanoseconds{1'696'957'072'000'020'500}}, - TimeDeltaNanos{100}, - 50, - {}}; + Mbp10Msg target{RecordHeader{sizeof(Mbp10Msg) / RecordHeader::kLengthMultiplier, + RType::Mbp10, 1, 1, UnixNanos{}}, + 100000000, + 10, + Action::Add, + Side::Bid, + {}, + 0, + UnixNanos{std::chrono::nanoseconds{1'696'957'072'000'020'500}}, + TimeDeltaNanos{100}, + 50, + {}}; for (std::uint32_t i = 0; i < 10; ++i) { target.levels[i].ask_ct = i; target.levels[i].bid_ct = i * 2; @@ -76,7 +73,7 @@ TEST(RecordTests, TestMbp10MsgToString) { } const auto res = ToString(target); ASSERT_EQ(res, R"(Mbp10Msg { - hd = RecordHeader { length = 92, rtype = Mbp10, publisher_id = 1, instrument_id = 1, ts_event = 1970-01-01T00:00:00.000000000Z }, + hd = RecordHeader { length = 92, rtype = mbp-10, publisher_id = 1, instrument_id = 1, ts_event = 1970-01-01T00:00:00.000000000Z }, price = 0.100000000, size = 10, action = Add, @@ -176,7 +173,7 @@ TEST(RecordTests, TestInstrumentDefMsgToString) { Side::Bid}; const auto res = ToString(target); ASSERT_EQ(res, R"(InstrumentDefMsg { - hd = RecordHeader { length = 130, rtype = InstrumentDef, publisher_id = 1, instrument_id = 1, ts_event = 1970-01-01T00:00:00.000000000Z }, + hd = RecordHeader { length = 130, rtype = instrument-def, publisher_id = 1, instrument_id = 1, ts_event = 1970-01-01T00:00:00.000000000Z }, ts_recv = 1970-01-01T00:00:00.000000000Z, min_price_increment = 0.000000001, display_factor = 0.000000002, @@ -276,7 +273,7 @@ TEST(RecordTests, TestImbalanceMsgToString) { {}}; const auto res = ToString(target); ASSERT_EQ(res, R"(ImbalanceMsg { - hd = RecordHeader { length = 28, rtype = Imbalance, publisher_id = 1, instrument_id = 1, ts_event = 1970-01-01T00:00:00.000000000Z }, + hd = RecordHeader { length = 28, rtype = imbalance, publisher_id = 1, instrument_id = 1, ts_event = 1970-01-01T00:00:00.000000000Z }, ts_recv = 1970-01-01T00:00:00.000000000Z, ref_price = 0.000000001, auction_time = UNDEF_TIMESTAMP, diff --git a/tests/src/stream_op_helper_tests.cpp b/tests/src/stream_op_helper_tests.cpp index 86bc95d..02a55a0 100644 --- a/tests/src/stream_op_helper_tests.cpp +++ b/tests/src/stream_op_helper_tests.cpp @@ -19,8 +19,7 @@ TEST(StreamOpHelperTests, TestEmpty) { TEST(StreamOpHelperTests, TestSingleLine) { std::ostringstream stream; - auto target = - StreamOpBuilder{stream}.SetTypeName("TestClass").SetSpacer(" ").Build(); + auto target = StreamOpBuilder{stream}.SetTypeName("TestClass").SetSpacer(" ").Build(); target.AddField("schema", Schema::Ohlcv1D) .AddField("dataset", std::string{dataset::kXnasItch}) .AddField("size", 10) @@ -34,10 +33,8 @@ TEST(StreamOpHelperTests, TestSingleLine) { TEST(StreamOpHelperTests, TestMultiLine) { std::ostringstream stream; - auto target = StreamOpBuilder{stream} - .SetTypeName("TestClass") - .SetSpacer("\n ") - .Build(); + auto target = + StreamOpBuilder{stream}.SetTypeName("TestClass").SetSpacer("\n ").Build(); target.AddField("schema", Schema::Ohlcv1D) .AddField("dataset", std::string{dataset::kXnasItch}) .AddField("size", 10) @@ -55,8 +52,7 @@ TEST(StreamOpHelperTests, TestMultiLine) { } TEST(StreamOpHelperTests, TestWithVector) { - const std::vector test_data{Schema::Ohlcv1D, Schema::Mbp10, - Schema::Ohlcv1M}; + const std::vector test_data{Schema::Ohlcv1D, Schema::Mbp10, Schema::Ohlcv1M}; std::ostringstream stream; auto target = StreamOpBuilder{stream}.SetSpacer(" ").Build(); @@ -68,12 +64,10 @@ TEST(StreamOpHelperTests, TestWithVector) { } TEST(StreamOpHelperTests, TestIndent) { - const std::vector test_data{Encoding::Csv, Encoding::Dbn, - Encoding::Json}; + const std::vector test_data{Encoding::Csv, Encoding::Dbn, Encoding::Json}; std::ostringstream stream; - auto target = - StreamOpBuilder{stream}.SetSpacer("\n ").SetIndent(" ").Build(); + auto target = StreamOpBuilder{stream}.SetSpacer("\n ").SetIndent(" ").Build(); for (const auto schema : test_data) { target.AddItem(schema); } diff --git a/tests/src/symbol_map_tests.cpp b/tests/src/symbol_map_tests.cpp index 8ab68a8..458c3fe 100644 --- a/tests/src/symbol_map_tests.cpp +++ b/tests/src/symbol_map_tests.cpp @@ -181,8 +181,7 @@ TEST(TsSymbolMapTests, TestBasic) { {}, {}, {}, - UnixNanos{date::sys_days{date::year{2023} / 7 / 25}} + - std::chrono::minutes{155}, + UnixNanos{date::sys_days{date::year{2023} / 7 / 25}} + std::chrono::minutes{155}, {}, {}}; EXPECT_EQ(target.At(record), "TSLA"); @@ -223,8 +222,7 @@ TEST(PitSymbolMapTests, TestFromMetadata) { EXPECT_EQ(target.Find(7298), target.Map().end()); EXPECT_EQ(target[10163], "TSLA"); EXPECT_EQ(target[6803], "MSFT"); - auto inverse_target = - GenMetadata().CreateSymbolMapForDate(date::year{2023} / 7 / 31); + auto inverse_target = GenMetadata().CreateSymbolMapForDate(date::year{2023} / 7 / 31); EXPECT_EQ(inverse_target.Map(), target.Map()); } @@ -232,19 +230,15 @@ TEST(PitSymbolMapTests, TestFromMetadataOutOfRange) { auto metadata = GenMetadata(); ASSERT_EQ(metadata.start, UnixNanos{std::chrono::seconds{1688169600}}); ASSERT_EQ(metadata.end, UnixNanos{std::chrono::seconds{1690848000}}); - ASSERT_THROW(PitSymbolMap(metadata, date::year{2023} / 8 / 1), - InvalidArgumentError); - ASSERT_THROW(PitSymbolMap(metadata, date::year{2023} / 6 / 30), - InvalidArgumentError); - metadata.end = UnixNanos{date::sys_days{date::year{2023} / 7 / 1}} + - std::chrono::hours{8}; + ASSERT_THROW(PitSymbolMap(metadata, date::year{2023} / 8 / 1), InvalidArgumentError); + ASSERT_THROW(PitSymbolMap(metadata, date::year{2023} / 6 / 30), InvalidArgumentError); + metadata.end = + UnixNanos{date::sys_days{date::year{2023} / 7 / 1}} + std::chrono::hours{8}; ASSERT_NE(metadata.end, UnixNanos{date::sys_days{date::year{2023} / 7 / 1}}); ASSERT_NO_THROW(PitSymbolMap(metadata, date::year{2023} / 7 / 1)); - ASSERT_THROW(PitSymbolMap(metadata, date::year{2023} / 7 / 2), - InvalidArgumentError); + ASSERT_THROW(PitSymbolMap(metadata, date::year{2023} / 7 / 2), InvalidArgumentError); metadata.end = UnixNanos{date::sys_days{date::year{2023} / 7 / 2}}; - ASSERT_THROW(PitSymbolMap(metadata, date::year{2023} / 7 / 2), - InvalidArgumentError); + ASSERT_THROW(PitSymbolMap(metadata, date::year{2023} / 7 / 2), InvalidArgumentError); metadata.end += std::chrono::nanoseconds{1}; ASSERT_NO_THROW(PitSymbolMap(metadata, date::year{2023} / 7 / 2)); } diff --git a/tests/src/symbology_tests.cpp b/tests/src/symbology_tests.cpp index 740813d..682a75b 100644 --- a/tests/src/symbology_tests.cpp +++ b/tests/src/symbology_tests.cpp @@ -8,10 +8,8 @@ namespace databento::tests { TEST(SymbologyTests, TestSymbologyResolutionToString) { const SymbologyResolution target{ { - {"ESM2", - {{date::year{2022} / 6 / 1, date::year{2022} / 6 / 17, "12344"}}}, - {"ESU2", - {{date::year{2022} / 6 / 1, date::year{2022} / 7 / 1, "12345"}}}, + {"ESM2", {{date::year{2022} / 6 / 1, date::year{2022} / 6 / 17, "12344"}}}, + {"ESU2", {{date::year{2022} / 6 / 1, date::year{2022} / 7 / 1, "12345"}}}, }, {"ESM2"}, {"EEES"}, diff --git a/tests/src/tcp_client_tests.cpp b/tests/src/tcp_client_tests.cpp index b74b1dc..ffbc993 100644 --- a/tests/src/tcp_client_tests.cpp +++ b/tests/src/tcp_client_tests.cpp @@ -15,9 +15,7 @@ namespace databento::tests { class TcpClientTests : public testing::Test { protected: TcpClientTests() - : testing::Test(), - mock_server_{}, - target_{"127.0.0.1", mock_server_.Port()} {} + : testing::Test(), mock_server_{}, target_{"127.0.0.1", mock_server_.Port()} {} mock::MockTcpServer mock_server_; detail::TcpClient target_; @@ -91,26 +89,26 @@ TEST_F(TcpClientTests, TestReadSomeTimeout) { bool has_timed_out{}; std::mutex has_timed_out_mutex; std::condition_variable has_timed_out_cv; - const mock::MockTcpServer mock_server{[&has_timed_out, &has_timed_out_mutex, - &has_timed_out_cv]( - mock::MockTcpServer& server) { - // simulate slow or delayed send - server.Accept(); - server.SetSend("hello"); - // wait for timeout - { - std::unique_lock lock{has_timed_out_mutex}; - has_timed_out_cv.wait(lock, [&has_timed_out] { return has_timed_out; }); - } - // then send - server.Send(); - server.Close(); - }}; + const mock::MockTcpServer mock_server{ + [&has_timed_out, &has_timed_out_mutex, + &has_timed_out_cv](mock::MockTcpServer& server) { + // simulate slow or delayed send + server.Accept(); + server.SetSend("hello"); + // wait for timeout + { + std::unique_lock lock{has_timed_out_mutex}; + has_timed_out_cv.wait(lock, [&has_timed_out] { return has_timed_out; }); + } + // then send + server.Send(); + server.Close(); + }}; target_ = {"127.0.0.1", mock_server.Port()}; std::array buffer{}; - const auto res = target_.ReadSome(buffer.data(), buffer.size(), - std::chrono::milliseconds{5}); + const auto res = + target_.ReadSome(buffer.data(), buffer.size(), std::chrono::milliseconds{5}); { const std::lock_guard lock{has_timed_out_mutex}; has_timed_out = true; @@ -151,7 +149,6 @@ TEST_F(TcpClientTests, ReadAfterClose) { EXPECT_EQ(res.status, detail::TcpClient::Status::Ok); EXPECT_GT(res.read_size, 0); target_.Close(); - ASSERT_THROW(target_.ReadSome(buffer.data(), buffer.size()), - databento::TcpError); + ASSERT_THROW(target_.ReadSome(buffer.data(), buffer.size()), databento::TcpError); } } // namespace databento::tests diff --git a/tests/src/zstd_stream_tests.cpp b/tests/src/zstd_stream_tests.cpp index bff6f76..1d807e2 100644 --- a/tests/src/zstd_stream_tests.cpp +++ b/tests/src/zstd_stream_tests.cpp @@ -14,15 +14,14 @@ namespace databento::detail::tests { TEST(ZstdStreamTests, TestMultiFrameFiles) { constexpr auto kRecordCount = 8; - const std::string file_path = - TEST_DATA_DIR "/multi-frame.definition.v1.dbn.frag.zst"; + const std::string file_path = TEST_DATA_DIR "/multi-frame.definition.v1.dbn.frag.zst"; databento::detail::ZstdDecodeStream target{ std::make_unique(file_path)}; for (std::size_t i = 0; i < kRecordCount; ++i) { databento::InstrumentDefMsgV1 def_msg; target.ReadExact(reinterpret_cast(&def_msg), sizeof(def_msg)); - EXPECT_EQ(def_msg.hd.rtype, databento::rtype::InstrumentDef); + EXPECT_EQ(def_msg.hd.rtype, databento::RType::InstrumentDef); } }