Repository: roq-trading/roq-api Branch: master Commit: c24b86492980 Files: 284 Total size: 299.9 KB Directory structure: gitextract_kyd8hy5r/ ├── .clang-format ├── .clang-tidy ├── .cmake-format.yaml ├── .gitattributes ├── .gitignore ├── .gitmodules ├── CHANGELOG.md ├── CMakeLists.txt ├── LICENSE ├── README.md ├── conda/ │ ├── bld.bat │ └── meta.yaml ├── doxygen/ │ ├── .gitignore │ ├── CMakeLists.txt │ └── Doxyfile.in ├── include/ │ └── roq/ │ ├── CMakeLists.txt │ ├── action.hpp │ ├── add_market.hpp │ ├── add_routes.hpp │ ├── api.hpp │ ├── api.hpp.in │ ├── args/ │ │ └── parser.hpp │ ├── bar.hpp │ ├── batch_begin.hpp │ ├── batch_end.hpp │ ├── buffer_capacity.hpp │ ├── cancel_all_orders.hpp │ ├── cancel_all_orders_ack.hpp │ ├── cancel_order.hpp │ ├── cancel_quotes.hpp │ ├── cancel_quotes_ack.hpp │ ├── category.hpp │ ├── client/ │ │ └── custom_message.hpp │ ├── clock.hpp │ ├── compat.hpp │ ├── connected.hpp │ ├── connection_status.hpp │ ├── control.hpp │ ├── control_ack.hpp │ ├── create_order.hpp │ ├── custom_matrix.hpp │ ├── custom_matrix_update.hpp │ ├── custom_metrics.hpp │ ├── custom_metrics_update.hpp │ ├── data_source.hpp │ ├── decimal.hpp │ ├── disconnected.hpp │ ├── download_begin.hpp │ ├── download_end.hpp │ ├── encoding.hpp │ ├── error.hpp │ ├── event.hpp │ ├── exceptions.hpp │ ├── execution_instruction.hpp │ ├── external_latency.hpp │ ├── fill.hpp │ ├── filter.hpp │ ├── format_str.hpp │ ├── funds_update.hpp │ ├── gateway_settings.hpp │ ├── gateway_status.hpp │ ├── interval.hpp │ ├── layer.hpp │ ├── leg.hpp │ ├── legs_update.hpp │ ├── limits.hpp │ ├── liquidity.hpp │ ├── map.hpp │ ├── margin_mode.hpp │ ├── market_by_order_update.hpp │ ├── market_by_price_update.hpp │ ├── market_status.hpp │ ├── mask.hpp │ ├── mass_quote.hpp │ ├── mass_quote_ack.hpp │ ├── mbo_update.hpp │ ├── mbp_update.hpp │ ├── measurement.hpp │ ├── message_info.hpp │ ├── modify_order.hpp │ ├── name.hpp │ ├── option_type.hpp │ ├── order_ack.hpp │ ├── order_cancel_policy.hpp │ ├── order_management.hpp │ ├── order_status.hpp │ ├── order_type.hpp │ ├── order_update.hpp │ ├── origin.hpp │ ├── parameter.hpp │ ├── parameters_update.hpp │ ├── portfolio.hpp │ ├── portfolio_update.hpp │ ├── position.hpp │ ├── position_effect.hpp │ ├── position_update.hpp │ ├── precision.hpp │ ├── precision_2.hpp │ ├── priority.hpp │ ├── protocol.hpp │ ├── quality_of_service.hpp │ ├── quantity_type.hpp │ ├── quote.hpp │ ├── rate_limit.hpp │ ├── rate_limit_trigger.hpp │ ├── rate_limit_type.hpp │ ├── rate_limits_update.hpp │ ├── ready.hpp │ ├── reference_data.hpp │ ├── remove_routes.hpp │ ├── request_id_type.hpp │ ├── request_status.hpp │ ├── request_type.hpp │ ├── risk_limit.hpp │ ├── risk_limits.hpp │ ├── risk_limits_update.hpp │ ├── route.hpp │ ├── route_ack.hpp │ ├── route_request_status.hpp │ ├── routing.hpp │ ├── security_type.hpp │ ├── service_update.hpp │ ├── side.hpp │ ├── start.hpp │ ├── state.hpp │ ├── statistics.hpp │ ├── statistics_type.hpp │ ├── statistics_update.hpp │ ├── stop.hpp │ ├── strategy_update.hpp │ ├── stream_status.hpp │ ├── string.hpp │ ├── string_types.hpp │ ├── subscribe.hpp │ ├── support_type.hpp │ ├── tick_size_step.hpp │ ├── time_in_force.hpp │ ├── time_series_update.hpp │ ├── timer.hpp │ ├── top_of_book.hpp │ ├── trace.hpp │ ├── trace_info.hpp │ ├── trade.hpp │ ├── trade_summary.hpp │ ├── trade_update.hpp │ ├── trading_status.hpp │ ├── transport.hpp │ ├── update_action.hpp │ ├── update_reason.hpp │ ├── update_type.hpp │ ├── uuid.hpp │ ├── variant_type.hpp │ └── version.hpp ├── schema/ │ └── roq/ │ ├── CMakeLists.txt │ ├── action.json │ ├── add_market.json │ ├── add_routes.json │ ├── bar.json │ ├── batch_begin.json │ ├── batch_end.json │ ├── buffer_capacity.json │ ├── cancel_all_orders.json │ ├── cancel_all_orders_ack.json │ ├── cancel_order.json │ ├── cancel_quotes.json │ ├── cancel_quotes_ack.json │ ├── category.json │ ├── connected.json │ ├── connection_status.json │ ├── control.json │ ├── control_ack.json │ ├── create_order.json │ ├── custom_matrix.json │ ├── custom_matrix_update.json │ ├── custom_metrics.json │ ├── custom_metrics_update.json │ ├── data_source.json │ ├── disconnected.json │ ├── download_begin.json │ ├── download_end.json │ ├── encoding.json │ ├── error.json │ ├── execution_instruction.json │ ├── external_latency.json │ ├── fill.json │ ├── filter.json │ ├── funds_update.json │ ├── gateway_settings.json │ ├── gateway_status.json │ ├── interval.json │ ├── layer.json │ ├── leg.json │ ├── legs_update.json │ ├── liquidity.json │ ├── margin_mode.json │ ├── market_by_order_update.json │ ├── market_by_price_update.json │ ├── market_status.json │ ├── mass_quote.json │ ├── mass_quote_ack.json │ ├── mbo_update.json │ ├── mbp_update.json │ ├── measurement.json │ ├── message_info.json │ ├── modify_order.json │ ├── option_type.json │ ├── order_ack.json │ ├── order_cancel_policy.json │ ├── order_management.json │ ├── order_status.json │ ├── order_type.json │ ├── order_update.json │ ├── origin.json │ ├── parameter.json │ ├── parameters_update.json │ ├── portfolio.json │ ├── portfolio_update.json │ ├── position.json │ ├── position_effect.json │ ├── position_update.json │ ├── precision.json │ ├── priority.json │ ├── protocol.json │ ├── quality_of_service.json │ ├── quantity_type.json │ ├── quote.json │ ├── rate_limit.json │ ├── rate_limit_trigger.json │ ├── rate_limit_type.json │ ├── rate_limits_update.json │ ├── ready.json │ ├── reference_data.json │ ├── remove_routes.json │ ├── request_id_type.json │ ├── request_status.json │ ├── request_type.json │ ├── risk_limit.json │ ├── risk_limits.json │ ├── risk_limits_update.json │ ├── route.json │ ├── route_ack.json │ ├── route_request_status.json │ ├── routing.json │ ├── security_type.json │ ├── service_update.json │ ├── side.json │ ├── start.json │ ├── state.json │ ├── statistics.json │ ├── statistics_type.json │ ├── statistics_update.json │ ├── stop.json │ ├── strategy_update.json │ ├── stream_status.json │ ├── subscribe.json │ ├── support_type.json │ ├── tick_size_step.json │ ├── time_in_force.json │ ├── time_series_update.json │ ├── timer.json │ ├── top_of_book.json │ ├── trade.json │ ├── trade_summary.json │ ├── trade_update.json │ ├── trading_status.json │ ├── transport.json │ ├── update_action.json │ ├── update_reason.json │ ├── update_type.json │ └── variant_type.json └── test/ ├── .clang-tidy ├── .gitignore ├── CMakeLists.txt ├── alignment.cpp ├── compat.cpp ├── exceptions.cpp ├── format.cpp ├── main.cpp ├── mask.cpp ├── side.cpp ├── span.cpp ├── string.cpp ├── support_type.cpp └── version.cpp ================================================ FILE CONTENTS ================================================ ================================================ FILE: .clang-format ================================================ --- BasedOnStyle: Google AlignAfterOpenBracket: AlwaysBreak AllowAllParametersOfDeclarationOnNextLine: true AllowShortCaseLabelsOnASingleLine: false AllowShortFunctionsOnASingleLine: InlineOnly AllowShortIfStatementsOnASingleLine: Never AllowShortLoopsOnASingleLine: false BinPackArguments: false BinPackParameters: false BreakBeforeBraces: Attach BreakConstructorInitializers: BeforeColon BreakInheritanceList: BeforeColon ColumnLimit: 160 ConstructorInitializerAllOnOneLineOrOnePerLine: false DerivePointerAlignment: false ExperimentalAutoDetectBinPacking: false IncludeBlocks: Preserve IndentCaseLabels: true InsertBraces: true PointerAlignment: Right QualifierAlignment: Right Standard: c++20 # note! clang20 does not support c++23 ================================================ FILE: .clang-tidy ================================================ --- Checks: bugprone-*, modernize-*, performance-*, readability-*, -bugprone-branch-clone, -bugprone-easily-swappable-parameters, -bugprone-inc-dec-in-conditions, -bugprone-macro-parentheses, -bugprone-switch-missing-default-case, -clang-analyzer-optin.performance.Padding, -clang-diagnostic-unused-command-line-argument, -modernize-concat-nested-namespaces, -modernize-use-nodiscard, -modernize-use-trailing-return-type, -performance-enum-size, -performance-move-const-arg, -readability-duplicate-include, -readability-convert-member-functions-to-static, -readability-enum-initial-value, -readability-isolate-declaration, -readability-named-parameter, -readability-qualified-auto, -readability-redundant-member-init, -readability-uppercase-literal-suffix, CheckOptions: - key: readability-magic-numbers.IgnoredIntegerValues value: 1;2;3;4;5;10;100;1000;10000;100000;1000000 - key: readability-magic-numbers.IgnorePowersOf2IntegerValues value: 'true' - key: readability-magic-numbers.IgnoreAllFloatingPointValues value: 'true' - key: cppcoreguidelines-avoid-magic-numbers.IgnoredIntegerValues value: 1;2;3;4;5;10;100;1000;10000;100000;1000000 - key: cppcoreguidelines-avoid-magic-numbers.IgnorePowersOf2IntegerValues value: 'true' - key: cppcoreguidelines-avoid-magic-numbers.IgnoreAllFloatingPointValues value: 'true' - key: readability-identifier-length.IgnoredVariableNames value: e|i|j|k|m|n|fd|id|io|ok|wd|_ - key: readability-identifier-length.IgnoredParameterNames value: fd|id|wd - key: readability-function-cognitive-complexity.IgnoreMacros value: 'true' WarningsAsErrors: '' HeaderFilterRegex: '' FormatStyle: none ================================================ FILE: .cmake-format.yaml ================================================ --- format: line_width: 160 tab_size: 2 ================================================ FILE: .gitattributes ================================================ cmake/* linguist-vendored doxygen/Doxyfile.in linguist-vendored *.hpp.in linguist-language=C++ ================================================ FILE: .gitignore ================================================ # vim *.sw[po] # cmake *.[ao] *.cmake *.so *.dylib CMake*.in CMakeCache.txt CMakeFiles/ DartConfiguration.tcl Makefile Testing/ build/ compile_commands.json* install_manifest.txt lib/ external/ external-prefix/ # cpack _CPack_Packages/ # debian *.deb # conda opt/ ================================================ FILE: .gitmodules ================================================ [submodule "roq-cmake"] path = cmake url = https://github.com/roq-trading/roq-cmake.git ignore = dirty [submodule "roq-scripts"] path = scripts url = https://github.com/roq-trading/roq-scripts.git ignore = dirty ================================================ FILE: CHANGELOG.md ================================================ # Change Log All notable changes will be documented in this file. ## Head ## 1.1.3 – 2026-03-12 ### Changed * Add `FundsUpdate.unrealized_pnl` (#571) ## 1.1.2 – 2026-02-08 ## 1.1.1 – 2025-12-14 ## 1.1.0 – 2025-11-22 ### Changed * Support leverage (CreateOrder, OrderAck, OrderUpdate) (#529) ## 1.0.9 – 2025-09-26 ### Changed * Workaround for fmt 11.2 and clang 21.x (#521) ## 1.0.8 – 2025-08-16 ### Changed * Increase max-length of `symbol` to 64 (#516) * Auto-generate time-series from history of event-logs and live data (#515) * Better support for estimating P&L and funds (#514) ## 1.0.7 – 2025-07-02 ### Changed * Extend FundsUpdate with borrowed amount (#502) ## 1.0.6 – 2025-05-16 ## 1.0.5 – 2025-03-26 ### Changed * Upgrade the `format_str` helper class to work with `fmt 11.1` (#488) ### Added * Control enabled/disabled state (#484) * Support MassQuote (#483) ## 1.0.4 – 2024-12-30 ## 1.0.3 – 2024-11-26 ### Changed * Add quantity type to order management (#469) * Add settlement currency to reference data (#468) ## 1.0.2 – 2024-07-14 ### Changed * `cache::MarketByPrice::impact_price` to accept an optional number of orders (#462) * `Fill` to support quote quantity and commission (#458) ## 1.0.1 – 2024-04-14 ### Changed * Issues with create limited depth updates (#453) ## 1.0.0 – 2024-03-16 ### Fixed * `utils::compare` could incorrectly compare values in the [0;1] range (#446) ### Added * `RateLimitsUpdate` to support exchange rate-limit updates ### Changed * Renamed `{price|quantity}_precision` (from `{price_quantity}_decimals` * Moved several header files to the roq-server library (from the roq::oms namespace here) * UUID now using C++23 features * Moved several header files to the roq-cache library (from the roq::cache namespace here) * Moved several header files to the roq-utils library (from the roq::utils namespace here) * Promote Decimal to API (from utils::Number) and rename Precision (from Decimals) (#439) ## 0.9.9 – 2024-01-28 ### Added * Adding exchange time, exchange sequence and sending time to ReferenceData and MarketStatus ### Changed * Adding `PositionEffect` to `OrderAck` * Adding `MarginMode` to `CreateOrder`, `OrderAck`, `OrderUpdate`, `TradeUpdate` * OMS validate quantity and price against reference data (#432) * Added `MarginMode` to `FundsUpdate` and `PositionUpdate` (#430) ## 0.9.8 – 2023-11-20 ### Fixed * The position cache would treat zero as a missing value and therefore not update (#419) ### Changed * `exchange_sequence` is now `uint64_t` (was `int64_t`) * `RoutingId` now 64 bytes * `GatewaySettings.oms_cancel_all_orders` has been added (#414) * `CancelAllOrders` now includes some filters (#414) * `oms::OrderUpdate` now includes the max request/response/accepted versions ### Added * `Fill.exchange_time_utc` * `CancelAllOrdersAck` (#414) * EXPERIMENTAL: messages for managing dynamic routes ### Removed * The FlatBuffers schema and auto-generated is no longer needed (replaced by the roq-codec library) ## 0.9.7 – 2023-09-18 ### Added * `oms::OrderUpdate::routing_id` to support FIX ### Changed * `order_id` must be `uint64_t` (#377) ### Added * `OrderAck.client_order_id` and `TradeUpdate.client_order_id` (#389) * `CancelAllOrders.strategy_id` * `CreateOrder.strategy_id`, `OrderAck.strategy_id`, `OrderUpdate.strategy_id`, `TradeUpdate.strategy_id` (#375) * `OrderAck.user` to support drop-copy and risk management ## 0.9.6 – 2023-07-22 ### Changed * Using `std::source_location` (clang16) * Using fmt10 ### Added * `Error.RISK_LIMIT_REACHED` * New `Ready` event to indicate the completion of the intial download phase * Risk exposure and change added to `OrderAck` and `OrderUpdate` (EXPERIMENTAL) * `cache::MarketByPrice::impact_price()` (#372) * `RiskLimits` and `RiskLimitsUpdate` (EXPERIMENTAL) * `client::Dispatcher.broadcast(CancelAllOrders)` ## 0.9.5 – 2023-06-12 ### Changed * The `Mask` template had to be changed to work with magic_enum 0.9.0 ### Added * `OrderUpdate.client_order_id` (#366) * `OrderAck.traded_quantity` (#359) ### Removed * `oms::TradeUpdate` was unnecessary (`TradeUpdate` is sufficient for the gateways) ## 0.9.4 – 2023-05-04 ### Changed * Review `PositionUpdate` and `FundsUpdate` to better correlate with `OrderUpdate` and `TradeUpdate` (#340) * `cache::MarketByOrder::OrderUpdate` now includes the final update action * `StreamStatus` should include connection details (#337) * [BREAKING CHANGE] `CreateOrder::request_template` (renamed from `order_template`) * All order requests must support `request_template` (#329) ### Removed * Drop `OrderUpdate.order_template` (#330) ### Added * `CustomMatrix` (#344) * `PortfolioUpdate` and `Position` to support a position manager (#343) ## 0.9.3 – 2023-03-20 ### Added * `sending_time_utc` to market data messages (#326) * `oms::TradeUpdate` (#254) * `client::Settings.drop_copy` (#254) ### Changed * [BREAKING CHANGE] `MarketByOrderUpdate` and `MBOUpdate` has been changed to support CME's TradeSummary (#322) ### Fixed * utils::invert(side)` didn't work for `side == UNDEFINED` (#325) ## 0.9.2 – 2023-02-22 ### Added * `MBOUpdate.reason` + `UpdateReason` * `cache::MarketByOrder` ### Changed * `fbs::MarketByOrderUpdate.max_depth` was inserted (should not be an issue since it was never used before) * `MBOUpdate`: `priority` now `uint64_t`, `order_id` length 36 (UUID), re-ordering ## 0.9.1 – 2023-01-12 ## 0.9.0 – 2022-12-22 ### Changed * New `Protocol` and `Encoding` to support Roq's UDP transport (#307) ## 0.8.9 – 2022-11-14 ### Added * Move `Category` (from the core and adapter libraries) (#297) ### Changed * `Parameter` now includes the `account`, `exchange`, `symbol` tuple * `ParametersUpdate` was renamed (from `ParameterUpdate`) * `TraceInfo` now default initializing to current time * `clock` promoted (from core library) ## 0.8.8 – 2022-10-04 ### Added * `RequestStatus.ERROR` (#292) * `TradeSummary` to include exchange sequence and taker/maker order id's (#279) * `CustomMetrics.update_type` and `CustomMetricsUpdate.update_type` * `GatewaySettings.mbp_checksum` ### Changed * Preparing to drop C++17 compatibility * `cache::MarketByPrice::max_depth` now returns `uint16_t` ### Removed * `MarketByPriceUpdate.checksum` from the FlatBuffers schema * Optimize the `cache::MarketByPrice` interface (#267) ## 0.8.7 – 2022-08-22 ### Added * `client::EventLogMultiplexer` (#266) * Cache objects for Create/Modify/CancelOrder (#26) * `ParameterUpdate` (#258) ### Changed * Optimize the `cache::MarketByPrice` interface (#267) * An optional `is_last` field has been added to `client::Dispatcher::send` (#26) * Move `RateLimiter` (from roq-server) (#259) * API changes needed to support drop-copy (#254) * Add notional fields to `ReferenceData` (#252) * Add new fields to `RateLimitTrigger` (#251) ### Removed * `OrderUpdateAction` (replaced with `UpdateAction`) ### Fixed * `utils::safe_cast` now using `std::numeric_limist::lowest()` (instead of `min()`) ## 0.8.6 – 2022-07-18 ### Fixed * fmt v9 requires custom formatters to be const ### Changed * Prevent copy/move of `Event<>` and `Trace<>` (#247) * return `span` from `cache::MarketByPrice` (#241) * Flatbuffers auto-generated code now using C++17 * `client::EventLogReader` now expose more metadata * `MBPUpdate` now supports `UpdateAction` (#236) ## 0.8.5 – 2022-06-06 ### Added * `cache::Manager::get_market_with_id` and `cache::Manager::get_market_id` * `ReferenceData::discard` (#225) ### Changed * Promote `utils::DateTime_iso8601` formatter to API (from core) * Make `cache::Manager` a non-template (#230) * `cache::MarketByPrice::stream_id()` ## 0.8.4 – 2022-05-14 ### Added * `cache::MarketByPrice::find_index` * `cache::MarketByPrice::compute_vwap` * RequestIdType added to GatewaySettings (from server) ### Changed * Increase `Symbol` fixed-length size to 48 (#214) * `Event<>` and `Trace<>` formatting has move the value to the front * C++17 compatibility (std::span and "using enum" workarounds) * `Trace` now supports non-const (and retains const-safety when const) * `TopOfBook` now includes an exhange sequence number (to correlate with MbP updates) * `StreamStatus` now provides more detailed information * Promote `debug::hex::Message` and `debug::fix::Message` (from core library) * Comparisons now use (or return) `std::strong_ordering` (instead of `int`) * Simplify enums (#199) * Proper bit-mask support (#198) * Promote Trace and TraceInfo to API (from server) ## 0.8.3 – 2022-03-22 ### Changed * Enforce fixed-length strings for standard use-cases (account, exchange, symbol, ...) * Rename `string` (from `string_buffer`) * Promote Mask to API (from utils) * Rename headers to .hpp (#195) * Conda packaging should pin versions to match x.x.x (#189) * Added `update_type` to `OrderUpdate` and `TradeUpdate` (#39) ## 0.8.2 – 2022-02-18 ### Changed * Added account to ExternalLatency (#170) * Source file name are now evaluated and stored at compile time (#160) ## 0.8.1 – 2022-01-16 ### Changed * Upgrade to C++20 (#158) ## 0.8.0 – 2022-01-12 ### Added * `cache::MarketByPrice::exists` (#153) * `SecurityType::SWAP` * Capture `origin_create_time` for externally triggered events (#140) ### Changed * Increase `MAX_LENGTH_CURRENCY` * `ReferenceData::margin_currency` (#150) * Support macOS/ARM64 (#149) ### Removed * `client::DepthBuilder` (#152) ## 0.7.9 – 2021-12-08 ### Changed * Align oms with new use of Decimals enum * `MarketByPriceUpdate` now include max-depth (#123) * `MarketByPriceUpdate` and `MarketByOrderUpdate` now include checksum (#74) * `MarketByPriceUpdate` and `MarketByOrderUpdate` now include price/quantity decimals (#119) ### Added * Capture request round-trip latency (#130) * Starting to move object cache logic into API (#128) ## 0.7.8 – 2021-11-02 ### Added * Move cache utilities to API (#111) * Promoted `server::TraceInfo` to API * Add exchange sequence number to `MarketByPrice` and `MarketByOrder` (#101) * Add `max_trade_vol` and `trade_vol_step_size` to ReferenceData (#100) * New method to update `market::MarketByPrice` (#17) * Price/quantity decimal digits added to `oms::Order` (#46) * Conversion to/from internal price used by `market::MarketByPrice` (#21) * Interface to extract bid/ask `MBPUpdate` from `market::MarketByPrice` * New `UpdateType` (will eventually be used with `MarketByPriceUpdate`) (#93) * Add `StatisticsType::TRADE_VOLUME` (#88) ### Changed * Remove custom literals (#110) * ReferenceData currencies should follow FX conventions (#99) * Replace `snapshot` (bool) with `update_type` (UpdateType) (#97) * Align type used to represent decimal digits (#46) * Adding more `MAX_LENGTH` constants (#91) * Align `PositionUpdate` with the FIX protocol (#89) ### Fixed * Utility functions did not correctly handle `RequestStatus::FAILED` (#82) ## 0.7.7 – 2021-09-20 ### Added * New `market::MarketByPrice` interface (#56) ### Changed * `RequestStatus::TIMEOUT` should not be a final order request state (#59) * `GatewaySettings` has changed structure and new fields (#56) * `client::DepthBuilder` now derives from `market::MarketByPrice` (#56) * `string_buffer` did not have O(1) `length()` (#53) * Move OMS interfaces to API (#51) * `RateLimitTrigger` must support const members (#34) ### Fixed * API exceptions should compile with C++14 (#69) ## 0.7.6 – 2021-09-02 ### Added * `Error::INSUFFICIENT_FUNDS` (#32) * `RateLimitTrigger` replaces `RateLimitUsage` (#34) * Promoting `RateLimitType` to API (#34) * `NotSupported` exception (clean-up) * `CustomMetrics` (publish) and `CustomMetricsUpdate` (receive) (#8) * `NotImplemented` exception (clean-up) * `Error::CONDITIONAL_REQUEST_HAS_FAILED` and `Error::UNKNOWN_ORDER_ID` (#25) * `utils::was_order_received` and `utils::to_request_status` (#25) * `OrderAck::side` (#11) * `client::EventLogReader` interface (#10) ### Changed * The various interfaces used for simulation has been updated (#7) ### Removed * `Subscribe` has been removed from API (#14) ## 0.7.5 – 2021-08-08 ### Changes * `Error` has been extended to communicate certain exchange errors * `RequestStatus` now includes `DISCONNECTED`, `TIMEOUT`, and `FAILED` * `OrderAck` now includes `exchange` and `symbol` * `CustomMessage` now uses `span` to represent the message ### Fixed * `DepthBuilder` was unsafe because the constructor cached a pointer to a span of `Layer`s, aka. the depth. This has been changed and applying a `MarketByPriceUpdate` will now require you to also pass a reference to the depth. ### Added * `Error::REQUEST_RATE_LIMIT_REACHED` * `StatisticsType::FUNDING_RATE_PREDICTION` ### Removed * Dropped all wrappers for fmt. (Reason: `fmt::format_string` is now a template solution -- previously it was a macro). ## 0.7.4 – 2021-07-20 ### Changed * The exception hierarchy no longer tries to mirror `std`. ## 0.7.3 – 2021-07-06 ### Added * `OrderManagement` used to instruct a gateway of the order management style * `MAX_ORDER_ID` and `MAX_REQUEST_VERSION` to reflect 24 bit limits ### Changed * `OrderAck`, `OrderUpdate`, `ModifyOrder` and `CancelOrder` now use `uint32_t` for all version fields * The format functions no longer require use of the `_fmt` literal * Reduced `MAX_LENGTH_ROUTING_ID` to 16 * `GatewaySettings` now includes `oms_download_has_state` and `oms_download_has_routing_id` ### Removed * The `_fmt` literal * The `format_str` wrapper class has been moved to the roq-logging library ## 0.7.2 – 2021-06-20 ### Changed * `Error` has been updated * `OrderAck` has been updated and extended with `version` * `OrderUpdate` has been updated and extended with `max_request_version`, `max_response_version` and `max_accepted_version` * `ModifyOrder` and `CancelOrder` has been updated with `version` and `conditional_on_version` * `CreateOrder` and `OrderUpdate` has changed field ordering to better group constant vs. possibly changing fields * `TradeUpdate` and `Fill` has changed field ordering and `Fill` has dropped artificially generated `trade_id`'s * `MBPUpdate` has been updated with `implied_quantity`, `price_level` and `number_of_orders` ## 0.7.1 – 2021-05-30 ### Added * `RateLimitUsage` to allow strategy to back off when it high-water mark on rate-limiting has been detected * `CancelAllOrders` when all orders must be cancelled immediately * `GatewaySettings.mbp_allow_remove_non_existing` to indicate if an exchange could possibly send updates to unknown price levels * `StatisticsType::FUNDING_RATE` and `StatisticsType::DAILY_FUNDING_RATE` * `routing_id` to `ModifyOrder` and `CancelOrder` * `SupportType.ORDER_STATE` to indicate if gateway supports FIX 4.4 style order state management (through ClOrdId/OrigClOrdId transitions) * `GatewaySettings.supports` to allow users to detect what is supported * Added `Liquidity` to indicate if last fill was as maker or taker * Extend `OrderUpdate` with more fields (required for FIX bridge and download) * `TradingStatus` has been completely reviewed to match the trading session state changes which can occur on most exchanges * `ExecutionInstruction` will now support bit-masks (future change) * The layout of many structs have changed ### Changed * `client::Config::Handler` now includes a method to configur * `client::Settings`. This makes it possible to override `cancel_policy` (on disconnect) * `Disconnected` now adds a flag useful to detect if disconnect could trigger an order cancellation request * `OrderStatus` better aligned with FIX enum, but excluding state transitions * `TimeInForce` better aligned with FIX enum ## 0.7.0 – 2021-04-15 ### Added * Promoted a number of generic utilities to the `roq::utils` namespace. Although these are useful, they should not be considered "API". * The `routing_id` field has been added to the relevant order management structures. ### Changed * All server (gateway) originated structs now include `stream_id` to indicate the origin of a message. `MarketDataStatus` and `OrderManagerStatus` have been replaced with `StreamUpdate`. Clients must use the `supports` bit-mask from `StreamUpdate` to maintain availability of cached objects. This change was done to allow gateways to manage load balance e.g. by maintaining multiple connections. * Replaced `Connection` with `Connected` and `Disconnected` * Renamed `GatewayStatus` to `ConnectionStatus` ### Removed * Python API (this is not the right place) * Removed `name` from `ExternalLatency` * Removed `MarketDataStatus` and `OrderManagerStatus` ## 0.6.1 – 2021-02-19 ### Added * Convenience functions making it easy to encode Flatbuffers objects ### Changed * Consistent use string literals * Enforce usage of the `_fmt` literal when formatting ### Removed * Enumerations no longer include `MAX` ## 0.6.0 – 2021-02-02 ### Changed * Repo now includes the auto-generated header files (for better discoverability) * Miniforge (instead of Miniconda) * `MessageInfo.source_session_id` now using a more efficient UUID representation * Now using span-lite (instead of own implementation, C++20 preparation) ### Added * `Settings` * `ExternalLatency` ### Removed * `User` and `Account` removed (not public interfaces) ## 0.5.0 – 2020-12-04 ### Changed * Time management has been changed * `std::chrono::nanoseconds` used for all precision timestamps * `std::chrono::seconds` used for all date-times * `std::chrono::days` (using `roq::chrono::days` until C++20 is supported) used for all dates ### Added * `ReferenceData` * `description`, `underlying`, `time_zone`, `issue_date`, `settlement_date`, `expiry_datetime`, `expiry_datetime_utc ### Removed * `ReferenceData::limit_{up|down}` * Upper and lower trading limits belongs to daily session statistics, not reference data. These fields were anyway already managed by `StatisticsUpdate`. ## 0.4.5 – 2020-11-09 ## 0.4.4 – 2020-09-20 ## 0.4.3 – 2020-09-02 ### Changed * `client::Collector` interface now implements default handlers instead of having pure virtual functions. * `is_{order|request}_completed` replacing `is_completed`. ### Removed * `client::Collector::{extract|write}` were too specific. ## 0.4.2 – 2020-07-27 ### Removed * Automake support ## 0.4.1 – 2020-07-17 **Note!** *CMake is now the default build system for all Roq solutions. This makes it significantly easier to integrate with other CMake based solutions*. ### Changed * CMake is now the default build system for all Roq solutions * Replace ROQ\_PREDICT\_{TRUE,FALSE} with ROQ\_LIKELY and ROQ\_UNLIKLEY to better match c++20 naming * Removed (again) the use of FMT\_STRING since it will not be compatible with c++20 ### Removed * `roq/format.h` ## 0.4.0 – 2020-06-30 **Note!** *FlatBuffers has been introduced to compliment the C++ interface for non-latency sensitive use-cases. Event-logs are now using FlatBuffers for all encoding. This allows for backwards compatibility and thereby dropping the requirement for decoding to be binary compatible with encoding. An upcoming release will introduce a FlatBuffers interface into the gateways thereby allowing other languages than C++ languages to communicate with the gateway*. ### Added * FlatBuffers schema (experimental!) * `StatisticsUpdate` (to replace `DailyStatistics` and `SessionStatistics`) ### Changed * Events are now wrapped with the `Event` template * Replaced `MarketByPrice` and `MarketByOrder` with `MarketByPriceUpdate` and `MarketByOrderUpdate` to more clearly reflect changes being communicated ## 0.3.9 – 2020-06-09 ### Fixed * `roq::event_value` was broken in release 0.3.8 ### Changed * Metrics interfaces and utilities have been moved into the `roq::metrics` namespace * Metric collectors now using std::atomic variables ### Removed * Logging has been moved into a separate library `roq-logging` ## 0.3.8 – 2020-06-06 ### Changed * Auto-generate enums, structs, classes, formatting, etc. * Major parts of the client API have been moved here ## 0.3.7 – 2020-05-27 ### Added * Dependency on FlatBuffers * `SessionsStatistics::index_value` and `SessionsStatistics::margin_rate` ### Changed * Inherit all network-related exceptions from `NetworkError` ## 0.3.6 – 2020-05-02 ### Added * `TimedOut` (exception) ## 0.3.5 – 2020-04-22 ## 0.3.4 – 2020-04-08 ### Added * `ExecutionInstruction` (enum) similar to FIX `ExecInst` * `Error::EXECUTION_INSTRUCTION_NOT_SUPPORTED` * `Account::user` * `OrderUpdate::execution_instruction`, `OrderUpdate::stop_price` and `OrderUpdate::max_show_quantity` * Ensure all enums have an `UNDEFINED` ### Removed * `OrderUpdate::commissions` ### Changed * Log non-zero application exit codes as warning * Prefer C++ raw strings ## 0.3.3 – 2020-03-04 ### Added * `Fill` (struct) * `TopOfBook` (struct) * `price_from_side` (function) * `span` (struct) ### Removed * `MBOUpdate::side` ### Changed * `TradeUpdate` (struct) now containing an array of `Fill`'s (struct) * Logging now requires `FMT_STRING` to better formatting errors at compile time * `MarketByPrice` (struct) now maintaining `bids` and `asks` separately * `MBOUpdate::order_id` (string) replaces `order_id_ext` (integer) * Use `roq::span` everywhere ================================================ FILE: CMakeLists.txt ================================================ cmake_minimum_required(VERSION 4.0) set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH}) # config include(RoqConfig) # version (using git tag) include(GetGitRepoVersion) message("Using GIT_REPO_VERSION=${GIT_REPO_VERSION}") # project project(roq-api VERSION ${GIT_REPO_VERSION}) # language enable_language(CXX) # filesystem include(GNUInstallDirs) # dependencies find_package(fmt REQUIRED) find_package(magic_enum REQUIRED) find_package(nameof REQUIRED) if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME) include(CTest) endif() if(BUILD_TESTING) find_package(Catch2 REQUIRED) endif() # autogen find_program(ROQ_AUTOGEN roq-autogen REQUIRED) set(TEMPLATE_DIR ${CMAKE_SOURCE_DIR}/scripts/templates) set(SCHEMA_LINK_DIR ${CMAKE_SOURCE_DIR}/schema) # clang-format find_program(CLANG_FORMAT clang-format REQUIRED) # includes include_directories(${CMAKE_SOURCE_DIR}/include ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_INCLUDEDIR}) # sub-projects add_subdirectory(${CMAKE_SOURCE_DIR}/schema/roq) add_subdirectory(${CMAKE_SOURCE_DIR}/include/roq) if(BUILD_TESTING) add_subdirectory(${CMAKE_SOURCE_DIR}/test) endif() # project add_library(${PROJECT_NAME} INTERFACE) add_dependencies(${PROJECT_NAME} ${PROJECT_NAME}-include-cpp) # install (public headers) install( DIRECTORY ${CMAKE_SOURCE_DIR}/include/roq/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/roq FILES_MATCHING PATTERN "*.h*" PATTERN "CMakeFiles" EXCLUDE) # doxygen option(BUILD_DOCS "Enable doxygen" OFF) if(BUILD_DOCS) find_package(Doxygen) add_subdirectory(${CMAKE_SOURCE_DIR}/doxygen) add_dependencies(${PROJECT_NAME} ${PROJECT_NAME}-doxygen) add_dependencies(${PROJECT_NAME}-doxygen ${PROJECT_NAME}-include-cpp) endif() # install (cmake) install(TARGETS ${PROJECT_NAME} EXPORT ${PROJECT_NAME}-config) install(FILES ${CMAKE_SOURCE_DIR}/CHANGELOG.md DESTINATION ${CMAKE_INSTALL_DATADIR}/doc/${PROJECT_NAME}) set(CMAKE_LIB_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}) export( TARGETS ${PROJECT_NAME} NAMESPACE ${PROJECT_NAME}:: FILE ${CMAKE_LIB_DIR}/${PROJECT_NAME}-config.cmake) install( EXPORT ${PROJECT_NAME}-config NAMESPACE ${PROJECT_NAME}:: DESTINATION ${CMAKE_LIB_DIR}) ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2017-2026, Hans Erik Thrane Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # roq-api API for algorithmic and high-frequency trading (HFT). > This project does **not** contain the closed source implementation of the > C++ interfaces. ## Links * [Roq GmbH (website)](https://roq-trading.com/) * [Contact (email)](mailto:info@roq-trading.com) * [Documentation](https://roq-trading.com/docs/) * [Releases](https://roq-trading.com/docs/releases/) * [Gateways](https://roq-trading.com/docs/introduction/gateways/) * [Samples](https://github.com/roq-trading/roq-cpp-samples/) * [Roadmap](https://roq-trading.com/docs/introduction/roadmap/) * [Pricing](https://roq-trading.com/#pricing) * [LinkedIn](https://www.linkedin.com/company/35447832/) * [Telegram](https://t.me/roq_trading/) ## Design * Modular. * Predictable low latency. * Support all aspects required by a production environment. * Aim to reduce "glue" code and offer standard solutions for data capture, monitoring, bridge solutions, etc. ![Design](/static/images/architecture_reference.svg) * The **C++ API** enables clients (e.g. trading strategies) to * communicate with gateways using a unified interface, or * replay event-logs (exactly, for simulation and back-testing purposes). * The **FIX bridge** supports third-party solutions. * The **adapters** support third-party database solutions, e.g. ClickHouse. * The **metrics** interface supports third-party monitoring solutions, e.g. Prometheus, Alertmanager and Grafana. ## Features * Open source interface (no need to sign an NDA to access or use). * Permissive license (anyone is free to copy and use for whatever purpose). * Free to download and try (no need to contact or register). * Unified client interface to access any market. * Design is strongly inspired by standards and specific implementations used by major exchanges. * Strong preference for allocation-free message encoding/decoding. * Extensive use of auto-generated code based on schemas. * Strongly typed messages (events). * Asynchronous interfaces and implementations. * C++ and shared memory for low latency. * Automatic capture of all events. * Free to download tools and database adapters. ## Support and Maintenance A SLA is required for production support. More information can be found [here](https://roq-trading.com/#pricing). Feel free to [contact us](mailto:info@roq-trading.com) with any questions you may have. ## Gateways Currently supported traditional exchanges include * CME Currently supported Cryptocurrency exchanges include * Binance * BitMEX * Bitstamp * Bybit * Coinbase PRO * Deribit * Gate * Gemini * HitBTC * Huobi * Kraken * KuCoin * OKX The full list can be found [here](https://roq-trading.com/docs/introduction/gateways/). > Instructions on how to install, configure and use the gateways can either > be found in the [samples](https://github.com/roq-trading/roq-cpp-samples) or > by consulting the [documentation](https://roq-trading.com/docs/tutorials/gateways/). ## Operating Systems * Linux (x86-64, AArch64) * macOS (x86-64, Arm64) > All listed combinations are regularly compiled but only Linux/x86-64 is continuously being tested. > If you require a specific combination, please [contact us](mailto:info@roq-trading.com) before using. > We plan to drop support for macOS/x86-64. ## Library/Package Dependencies * [fmt](https://github.com/fmtlib/fmt) (MIT License) * [magic_enum](https://github.com/Neargye/magic_enum) (MIT License) * [jinja2](https://github.com/pallets/jinja) (BSD 3-Clause License) Optional * [Catch2](https://github.com/catchorg/Catch2) (Boost Software License 1.0 License) ## Prerequisites > It is not very interesting to follow the instructions shown here due to this > project only containing interfaces. > The actual client implementation is closed source as mentioned elsewhere in > this document. The project is primarily designed to be compatible with the conda package manager. > Use `stable` for (the approx. monthly) release build. > Use `unstable` for the more regularly updated development builds. ### Initialize sub-modules ```bash git submodule update --init --recursive ``` ### Create development environment ```bash scripts/create_conda_env unstable debug ``` ### Activate environment ```bash source opt/conda/bin/activate dev ``` ## Build the project > Sometimes you may have to delete CMakeCache.txt if CMake has already cached an incorrect configuration. ```bash cmake . && make -j4 ``` ### Using You can download the closed source client implementation like this ```bash conda install -y --channel https://roq-trading.com/conda/stable \ roq-client ``` Samples can be found [here](https://github.com/roq-trading/roq-cpp-samples). ## License The project is released under the terms of the MIT license. ================================================ FILE: conda/bld.bat ================================================ #xyz ================================================ FILE: conda/meta.yaml ================================================ package: name: roq-api version: {{ GIT_DESCRIBE_TAG }} source: git_url: .. build: skip: true # [not unix] number: {{ ROQ_BUILD_NUMBER if ROQ_BUILD_NUMBER is defined else GIT_DESCRIBE_NUMBER }} requirements: build: - {{ compiler('cxx') }} - clang-format - cmake - coreutils - doxygen - git - make - roq-autogen host: - catch2 - fmt - magic_enum - roq-oss-nameof about: home: https://roq-trading.com doc_url: https://roq-trading.com/docs dev_url: https://github.com/roq-trading license: MIT license_family: MIT license_file: LICENSE summary: Roq API ================================================ FILE: doxygen/.gitignore ================================================ Doxyfile doxygen-build.stamp html xml ================================================ FILE: doxygen/CMakeLists.txt ================================================ set(TARGET_NAME ${PROJECT_NAME}-doxygen) set(TARGET_DIR ${CMAKE_INSTALL_DATADIR}/doc/${PROJECT_NAME}) # doxyfile set(DOXYFILE ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in ${DOXYFILE} @ONLY) # target set(INDEX_HTML ${CMAKE_CURRENT_BINARY_DIR}/html/index.html) add_custom_command( OUTPUT ${INDEX_HTML} COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYFILE} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} VERBATIM DEPENDS ${DOXYGEN_EXECUTABLE} ${DOXYFILE}) add_custom_target(${TARGET_NAME} ALL DEPENDS ${INDEX_HTML}) # install install( DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/xml/ DESTINATION ${TARGET_DIR}/xml FILES_MATCHING PATTERN "*.xml") install( DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html/ DESTINATION ${TARGET_DIR}/html FILES_MATCHING PATTERN "*.html") ================================================ FILE: doxygen/Doxyfile.in ================================================ PROJECT_NAME = "roq-api" PROJECT_NUMBER = "@ROQ_VERSION@" EXTRACT_ALL = YES EXTRACT_PRIVATE = YES EXTRACT_STATIC = YES CASE_SENSE_NAMES = NO INPUT = @CMAKE_SOURCE_DIR@/include \ @CMAKE_BINARY_DIR@/@CMAKE_INSTALL_INCLUDEDIR@ RECURSIVE = YES EXCLUDE = @CMAKE_SOURCE_DIR@/include/roq/fbs GENERATE_LATEX = NO GENERATE_XML = YES HIDE_UNDOC_RELATIONS = NO HAVE_DOT = NO COLLABORATION_GRAPH = NO GROUP_GRAPHS = NO GRAPHICAL_HIERARCHY = NO ================================================ FILE: include/roq/CMakeLists.txt ================================================ set(TARGET_NAME ${PROJECT_NAME}-include-cpp) include(RoqAutogen) set(TARGET_DIR ${CMAKE_INSTALL_INCLUDEDIR}/roq) # schema set(SCHEMA_ROQ action.json add_market.json add_routes.json bar.json batch_begin.json batch_end.json buffer_capacity.json cancel_all_orders_ack.json cancel_all_orders.json cancel_order.json cancel_quotes_ack.json cancel_quotes.json category.json connected.json connection_status.json control_ack.json control.json create_order.json custom_matrix.json custom_matrix_update.json custom_metrics.json custom_metrics_update.json data_source.json disconnected.json download_begin.json download_end.json encoding.json error.json execution_instruction.json external_latency.json fill.json filter.json funds_update.json gateway_settings.json gateway_status.json interval.json layer.json leg.json legs_update.json liquidity.json margin_mode.json market_by_order_update.json market_by_price_update.json market_status.json mass_quote_ack.json mass_quote.json mbo_update.json mbp_update.json measurement.json message_info.json modify_order.json option_type.json order_ack.json order_cancel_policy.json order_management.json order_status.json order_type.json order_update.json origin.json parameter.json parameters_update.json portfolio.json portfolio_update.json position_effect.json position.json position_update.json precision.json priority.json protocol.json quality_of_service.json quantity_type.json quote.json rate_limit.json rate_limits_update.json rate_limit_trigger.json rate_limit_type.json ready.json reference_data.json remove_routes.json request_id_type.json request_status.json request_type.json risk_limit.json risk_limits.json risk_limits_update.json route_ack.json route.json route_request_status.json routing.json security_type.json service_update.json side.json start.json state.json statistics.json statistics_type.json statistics_update.json stop.json strategy_update.json stream_status.json subscribe.json support_type.json tick_size_step.json time_in_force.json timer.json time_series_update.json top_of_book.json trade.json trade_summary.json trade_update.json trading_status.json transport.json update_action.json update_reason.json update_type.json variant_type.json) set(SOURCES ${SCHEMA_ROQ}) # configure set(API_HPP ${CMAKE_BINARY_DIR}/${TARGET_DIR}/api.hpp) configure_file("api.hpp.in" ${API_HPP} @ONLY) # auto-generate roq_autogen_hpp( OUTPUT AUTOGEN_HEADERS SOURCES ${SOURCES} NAMESPACE "roq" SCHEMA_LINK_DIR ${SCHEMA_LINK_DIR} TEMPLATE_DIR ${TEMPLATE_DIR} TEMPLATE_TYPE "api") # target add_custom_target(${TARGET_NAME} ALL DEPENDS ${AUTOGEN_HEADERS} ${GITIGNORE}) # install install(FILES ${AUTOGEN_HEADERS} ${API_HPP} DESTINATION ${TARGET_DIR}) ================================================ FILE: include/roq/action.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include namespace roq { //! Enumeration of control action enum class Action : uint8_t { UNDEFINED = 0, ENABLE, //!< Enable DISABLE, //!< Disable }; } // namespace roq ================================================ FILE: include/roq/add_market.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include "roq/event.hpp" #include "roq/name.hpp" #include "roq/trace.hpp" namespace roq { //! Emitted when a new market is being created by the framework struct ROQ_PUBLIC AddMarket final { std::string_view exchange; //!< Exchange std::string_view symbol; //!< Symbol }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "add_market"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::AddMarket const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(exchange="{}", )" R"(symbol="{}")" R"(}})"sv, value.exchange, value.symbol); } }; ================================================ FILE: include/roq/add_routes.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include #include "roq/event.hpp" #include "roq/name.hpp" #include "roq/trace.hpp" namespace roq { //! Add route(s) struct ROQ_PUBLIC AddRoutes final { std::span strategy_ids; //!< List of strategy_id's to add }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "add_routes"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::AddRoutes const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(strategy_ids=[{}])" R"(}})"sv, fmt::join(value.strategy_ids, ", "sv)); } }; ================================================ FILE: include/roq/api.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ #pragma once #include "roq/compat.hpp" // convenience #include "roq/limits.hpp" // enums #include "roq/action.hpp" #include "roq/buffer_capacity.hpp" #include "roq/category.hpp" #include "roq/connection_status.hpp" #include "roq/data_source.hpp" #include "roq/encoding.hpp" #include "roq/error.hpp" #include "roq/execution_instruction.hpp" #include "roq/filter.hpp" #include "roq/interval.hpp" #include "roq/liquidity.hpp" #include "roq/margin_mode.hpp" #include "roq/option_type.hpp" #include "roq/order_cancel_policy.hpp" #include "roq/order_management.hpp" #include "roq/order_status.hpp" #include "roq/order_type.hpp" #include "roq/origin.hpp" #include "roq/position_effect.hpp" #include "roq/precision.hpp" #include "roq/priority.hpp" #include "roq/protocol.hpp" #include "roq/quantity_type.hpp" #include "roq/rate_limit_type.hpp" #include "roq/request_id_type.hpp" #include "roq/request_status.hpp" #include "roq/request_type.hpp" #include "roq/route_request_status.hpp" #include "roq/security_type.hpp" #include "roq/side.hpp" #include "roq/state.hpp" #include "roq/statistics_type.hpp" #include "roq/support_type.hpp" #include "roq/time_in_force.hpp" #include "roq/trading_status.hpp" #include "roq/transport.hpp" #include "roq/update_action.hpp" #include "roq/update_reason.hpp" #include "roq/update_type.hpp" // helpers #include "roq/bar.hpp" #include "roq/fill.hpp" #include "roq/layer.hpp" #include "roq/leg.hpp" #include "roq/mbo_update.hpp" #include "roq/mbp_update.hpp" #include "roq/measurement.hpp" #include "roq/parameter.hpp" #include "roq/position.hpp" #include "roq/quote.hpp" #include "roq/rate_limit.hpp" #include "roq/risk_limit.hpp" #include "roq/route.hpp" #include "roq/statistics.hpp" #include "roq/tick_size_step.hpp" #include "roq/trade.hpp" // transport #include "roq/message_info.hpp" // control (autogen) #include "roq/connected.hpp" #include "roq/control.hpp" #include "roq/control_ack.hpp" #include "roq/disconnected.hpp" #include "roq/legs_update.hpp" #include "roq/service_update.hpp" #include "roq/start.hpp" #include "roq/stop.hpp" #include "roq/strategy_update.hpp" #include "roq/timer.hpp" // messages (autogen) #include "roq/add_market.hpp" #include "roq/add_routes.hpp" #include "roq/batch_begin.hpp" #include "roq/batch_end.hpp" #include "roq/cancel_all_orders.hpp" #include "roq/cancel_all_orders_ack.hpp" #include "roq/cancel_order.hpp" #include "roq/cancel_quotes.hpp" #include "roq/cancel_quotes_ack.hpp" #include "roq/create_order.hpp" #include "roq/custom_matrix.hpp" #include "roq/custom_matrix_update.hpp" #include "roq/custom_metrics.hpp" #include "roq/custom_metrics_update.hpp" #include "roq/download_begin.hpp" #include "roq/download_end.hpp" #include "roq/external_latency.hpp" #include "roq/funds_update.hpp" #include "roq/gateway_settings.hpp" #include "roq/gateway_status.hpp" #include "roq/market_by_order_update.hpp" #include "roq/market_by_price_update.hpp" #include "roq/market_status.hpp" #include "roq/mass_quote.hpp" #include "roq/mass_quote_ack.hpp" #include "roq/modify_order.hpp" #include "roq/order_ack.hpp" #include "roq/order_update.hpp" #include "roq/parameters_update.hpp" #include "roq/portfolio.hpp" #include "roq/portfolio_update.hpp" #include "roq/position_update.hpp" #include "roq/rate_limit_trigger.hpp" #include "roq/rate_limits_update.hpp" #include "roq/ready.hpp" #include "roq/reference_data.hpp" #include "roq/remove_routes.hpp" #include "roq/risk_limits.hpp" #include "roq/risk_limits_update.hpp" #include "roq/route_ack.hpp" #include "roq/statistics_update.hpp" #include "roq/stream_status.hpp" #include "roq/subscribe.hpp" #include "roq/time_series_update.hpp" #include "roq/top_of_book.hpp" #include "roq/trade_summary.hpp" #include "roq/trade_update.hpp" // misc #include "roq/exceptions.hpp" // version #define ROQ_VERSION "1.1.3" namespace roq { // NOLINTBEGIN(readability-magic-numbers) // user id (8 bits) static constexpr uint8_t const SOURCE_MIN = 0; static constexpr uint8_t const SOURCE_MAX = 255; static constexpr auto const SOURCE_NONE = SOURCE_MIN; static constexpr auto const SOURCE_SELF = SOURCE_MAX; // stream id (16 bits) static constexpr uint16_t const STREAM_ID_MIN = 0; static constexpr uint16_t const STREAM_ID_MAX = 65535; static constexpr auto const STREAM_ID_NONE = STREAM_ID_MIN; // order id (48 bits) static constexpr uint64_t const ORDER_ID_MIN = 0; static constexpr uint64_t const ORDER_ID_MAX = (uint64_t{1} << 48) - 1; static constexpr auto const ORDER_ID_NONE = ORDER_ID_MIN; // request version (24 bits) static constexpr uint32_t const REQUEST_VERSION_MIN = 0; static constexpr uint32_t const REQUEST_VERSION_MAX = (uint32_t{1} << 24) - 1; static constexpr auto const REQUEST_VERSION_NONE = REQUEST_VERSION_MIN; // strategy id (24 bits) static constexpr uint32_t const STRATEGY_ID_MIN = 0; static constexpr uint32_t const STRATEGY_ID_MAX = (uint32_t{1} << 24) - 1; static constexpr auto const STRATEGY_ID_NONE = STRATEGY_ID_MIN; // account id (8 bits) static constexpr uint8_t const ACCOUNT_MIN = 0; static constexpr uint8_t const ACCOUNT_MAX = 255; static constexpr auto const ACCOUNT_NONE = ACCOUNT_MIN; // symbol id (24 bits) static constexpr uint32_t const SYMBOL_ID_MIN = 0; static constexpr uint32_t const SYMBOL_ID_MAX = (uint32_t{1} << 24) - 1; static constexpr auto const SYMBOL_ID_NONE = SYMBOL_ID_MIN; // instance id (4 bits) static constexpr uint8_t const INSTANCE_MIN = 0; static constexpr uint8_t const INSTANCE_MAX = (uint8_t{1} << 4) - 1; static constexpr auto const INSTANCE_NONE = INSTANCE_MIN; // validate auto-generated code static_assert(sizeof(decltype(RateLimitTrigger::users)::value_type) == sizeof(User)); static_assert(sizeof(decltype(RateLimitTrigger::accounts)::value_type) == sizeof(Account)); static_assert(sizeof(decltype(Measurement::name)) == sizeof(MeasurementKey)); // check size of certain array items // - frequent -- should be (reasonably) cache aligned static_assert(sizeof(Layer) == 32); static_assert(sizeof(MBPUpdate) == 32); static_assert(sizeof(MBOUpdate) == 64); static_assert(sizeof(Trade) == 192); static_assert(sizeof(Statistics) == 32); static_assert(sizeof(Measurement) == 16); static_assert(sizeof(Route) == 8); static_assert(sizeof(TickSizeStep) == 16); // - not frequent -- not so important static_assert(sizeof(Fill) == 136); static_assert(sizeof(Parameter) == 196); static_assert(sizeof(Position) == 144); static_assert(sizeof(RiskLimit) == 152); // NOLINTEND(readability-magic-numbers) } // namespace roq ================================================ FILE: include/roq/api.hpp.in ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ #pragma once #include "roq/compat.hpp" // convenience #include "roq/limits.hpp" // enums #include "roq/action.hpp" #include "roq/buffer_capacity.hpp" #include "roq/category.hpp" #include "roq/connection_status.hpp" #include "roq/data_source.hpp" #include "roq/encoding.hpp" #include "roq/error.hpp" #include "roq/execution_instruction.hpp" #include "roq/filter.hpp" #include "roq/interval.hpp" #include "roq/liquidity.hpp" #include "roq/margin_mode.hpp" #include "roq/option_type.hpp" #include "roq/order_cancel_policy.hpp" #include "roq/order_management.hpp" #include "roq/order_status.hpp" #include "roq/order_type.hpp" #include "roq/origin.hpp" #include "roq/position_effect.hpp" #include "roq/precision.hpp" #include "roq/priority.hpp" #include "roq/protocol.hpp" #include "roq/quantity_type.hpp" #include "roq/rate_limit_type.hpp" #include "roq/request_id_type.hpp" #include "roq/request_status.hpp" #include "roq/request_type.hpp" #include "roq/route_request_status.hpp" #include "roq/security_type.hpp" #include "roq/side.hpp" #include "roq/state.hpp" #include "roq/statistics_type.hpp" #include "roq/support_type.hpp" #include "roq/time_in_force.hpp" #include "roq/trading_status.hpp" #include "roq/transport.hpp" #include "roq/update_action.hpp" #include "roq/update_reason.hpp" #include "roq/update_type.hpp" // helpers #include "roq/bar.hpp" #include "roq/fill.hpp" #include "roq/layer.hpp" #include "roq/leg.hpp" #include "roq/mbo_update.hpp" #include "roq/mbp_update.hpp" #include "roq/measurement.hpp" #include "roq/parameter.hpp" #include "roq/position.hpp" #include "roq/quote.hpp" #include "roq/rate_limit.hpp" #include "roq/risk_limit.hpp" #include "roq/route.hpp" #include "roq/statistics.hpp" #include "roq/tick_size_step.hpp" #include "roq/trade.hpp" // transport #include "roq/message_info.hpp" // control (autogen) #include "roq/connected.hpp" #include "roq/control.hpp" #include "roq/control_ack.hpp" #include "roq/disconnected.hpp" #include "roq/legs_update.hpp" #include "roq/service_update.hpp" #include "roq/start.hpp" #include "roq/stop.hpp" #include "roq/strategy_update.hpp" #include "roq/timer.hpp" // messages (autogen) #include "roq/add_market.hpp" #include "roq/add_routes.hpp" #include "roq/batch_begin.hpp" #include "roq/batch_end.hpp" #include "roq/cancel_all_orders.hpp" #include "roq/cancel_all_orders_ack.hpp" #include "roq/cancel_order.hpp" #include "roq/cancel_quotes.hpp" #include "roq/cancel_quotes_ack.hpp" #include "roq/create_order.hpp" #include "roq/custom_matrix.hpp" #include "roq/custom_matrix_update.hpp" #include "roq/custom_metrics.hpp" #include "roq/custom_metrics_update.hpp" #include "roq/download_begin.hpp" #include "roq/download_end.hpp" #include "roq/external_latency.hpp" #include "roq/funds_update.hpp" #include "roq/gateway_settings.hpp" #include "roq/gateway_status.hpp" #include "roq/market_by_order_update.hpp" #include "roq/market_by_price_update.hpp" #include "roq/market_status.hpp" #include "roq/mass_quote.hpp" #include "roq/mass_quote_ack.hpp" #include "roq/modify_order.hpp" #include "roq/order_ack.hpp" #include "roq/order_update.hpp" #include "roq/parameters_update.hpp" #include "roq/portfolio.hpp" #include "roq/portfolio_update.hpp" #include "roq/position_update.hpp" #include "roq/rate_limit_trigger.hpp" #include "roq/rate_limits_update.hpp" #include "roq/ready.hpp" #include "roq/reference_data.hpp" #include "roq/remove_routes.hpp" #include "roq/risk_limits.hpp" #include "roq/risk_limits_update.hpp" #include "roq/route_ack.hpp" #include "roq/statistics_update.hpp" #include "roq/stream_status.hpp" #include "roq/subscribe.hpp" #include "roq/time_series_update.hpp" #include "roq/top_of_book.hpp" #include "roq/trade_summary.hpp" #include "roq/trade_update.hpp" // misc #include "roq/exceptions.hpp" // version #define ROQ_VERSION "@ROQ_VERSION_MAJOR@.@ROQ_VERSION_MINOR@.@ROQ_VERSION_PATCH@" namespace roq { // NOLINTBEGIN(readability-magic-numbers) // user id (8 bits) static constexpr uint8_t const SOURCE_MIN = 0; static constexpr uint8_t const SOURCE_MAX = 255; static constexpr auto const SOURCE_NONE = SOURCE_MIN; static constexpr auto const SOURCE_SELF = SOURCE_MAX; // stream id (16 bits) static constexpr uint16_t const STREAM_ID_MIN = 0; static constexpr uint16_t const STREAM_ID_MAX = 65535; static constexpr auto const STREAM_ID_NONE = STREAM_ID_MIN; // order id (48 bits) static constexpr uint64_t const ORDER_ID_MIN = 0; static constexpr uint64_t const ORDER_ID_MAX = (uint64_t{1} << 48) - 1; static constexpr auto const ORDER_ID_NONE = ORDER_ID_MIN; // request version (24 bits) static constexpr uint32_t const REQUEST_VERSION_MIN = 0; static constexpr uint32_t const REQUEST_VERSION_MAX = (uint32_t{1} << 24) - 1; static constexpr auto const REQUEST_VERSION_NONE = REQUEST_VERSION_MIN; // strategy id (24 bits) static constexpr uint32_t const STRATEGY_ID_MIN = 0; static constexpr uint32_t const STRATEGY_ID_MAX = (uint32_t{1} << 24) - 1; static constexpr auto const STRATEGY_ID_NONE = STRATEGY_ID_MIN; // account id (8 bits) static constexpr uint8_t const ACCOUNT_MIN = 0; static constexpr uint8_t const ACCOUNT_MAX = 255; static constexpr auto const ACCOUNT_NONE = ACCOUNT_MIN; // symbol id (24 bits) static constexpr uint32_t const SYMBOL_ID_MIN = 0; static constexpr uint32_t const SYMBOL_ID_MAX = (uint32_t{1} << 24) - 1; static constexpr auto const SYMBOL_ID_NONE = SYMBOL_ID_MIN; // instance id (4 bits) static constexpr uint8_t const INSTANCE_MIN = 0; static constexpr uint8_t const INSTANCE_MAX = (uint8_t{1} << 4) - 1; static constexpr auto const INSTANCE_NONE = INSTANCE_MIN; // validate auto-generated code static_assert(sizeof(decltype(RateLimitTrigger::users)::value_type) == sizeof(User)); static_assert(sizeof(decltype(RateLimitTrigger::accounts)::value_type) == sizeof(Account)); static_assert(sizeof(decltype(Measurement::name)) == sizeof(MeasurementKey)); // check size of certain array items // - frequent -- should be (reasonably) cache aligned static_assert(sizeof(Layer) == 32); static_assert(sizeof(MBPUpdate) == 32); static_assert(sizeof(MBOUpdate) == 64); static_assert(sizeof(Trade) == 192); static_assert(sizeof(Statistics) == 32); static_assert(sizeof(Measurement) == 16); static_assert(sizeof(Route) == 8); static_assert(sizeof(TickSizeStep) == 16); // - not frequent -- not so important static_assert(sizeof(Fill) == 136); static_assert(sizeof(Parameter) == 196); static_assert(sizeof(Position) == 144); static_assert(sizeof(RiskLimit) == 152); // NOLINTEND(readability-magic-numbers) } // namespace roq ================================================ FILE: include/roq/args/parser.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ #pragma once #include "roq/compat.hpp" #include #include namespace roq { namespace args { struct ROQ_PUBLIC Parser { virtual ~Parser() = default; // note! c-style with first element being the program name virtual operator std::span() const = 0; auto program_name() const { return static_cast>(*this)[0]; } auto params() const { return static_cast>(*this).subspan(1); } }; } // namespace args } // namespace roq ================================================ FILE: include/roq/bar.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include #include "roq/limits.hpp" namespace roq { //! Represents a single bar of a time-series struct ROQ_PUBLIC Bar final { std::chrono::seconds begin_time_utc = {}; //!< Begin-of-period time-stamp (UTC) bool confirmed = false; //!< Confirmed? double open_price = roq::NaN; //!< Open price double high_price = roq::NaN; //!< High price double low_price = roq::NaN; //!< Low price double close_price = roq::NaN; //!< Close price double quantity = roq::NaN; //!< Total quantity (contracts or base currency) double base_amount = roq::NaN; //!< Total amount (base currency) double quote_amount = roq::NaN; //!< Total amount (quote currency) uint32_t number_of_trades = {}; //!< Number of trades (count) double vwap = roq::NaN; //!< VWAP }; } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::Bar const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(begin_time_utc={}, )" R"(confirmed={}, )" R"(open_price={}, )" R"(high_price={}, )" R"(low_price={}, )" R"(close_price={}, )" R"(quantity={}, )" R"(base_amount={}, )" R"(quote_amount={}, )" R"(number_of_trades={}, )" R"(vwap={})" R"(}})"sv, value.begin_time_utc, value.confirmed, value.open_price, value.high_price, value.low_price, value.close_price, value.quantity, value.base_amount, value.quote_amount, value.number_of_trades, value.vwap); } }; ================================================ FILE: include/roq/batch_begin.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include "roq/event.hpp" #include "roq/name.hpp" #include "roq/trace.hpp" namespace roq { //! Identifies the beginning of a sequence of related messages struct ROQ_PUBLIC BatchBegin final {}; template <> constexpr std::string_view get_name() { using namespace std::literals; return "batch_begin"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::BatchBegin const &, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), R"({{}})"sv); } }; ================================================ FILE: include/roq/batch_end.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include "roq/event.hpp" #include "roq/name.hpp" #include "roq/trace.hpp" namespace roq { //! Identifies the end of a sequence of related messages struct ROQ_PUBLIC BatchEnd final {}; template <> constexpr std::string_view get_name() { using namespace std::literals; return "batch_end"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::BatchEnd const &, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), R"({{}})"sv); } }; ================================================ FILE: include/roq/buffer_capacity.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include namespace roq { //! Buffer capacity enum class BufferCapacity : uint8_t { UNDEFINED = 0, EMPTY, //!< Buffer is empty LOW_WATER_MARK, //!< Buffer has reached the low water mark (from above) HIGH_WATER_MARK, //!< Buffer has reached the high water mark (from below) FULL, //!< Buffer is full }; } // namespace roq ================================================ FILE: include/roq/cancel_all_orders.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include "roq/event.hpp" #include "roq/name.hpp" #include "roq/side.hpp" #include "roq/trace.hpp" namespace roq { //! Cancel all orders (best effort) struct ROQ_PUBLIC CancelAllOrders final { std::string_view account; //!< Account name uint64_t order_id = {}; //!< Order identifier std::string_view exchange; //!< Exchange std::string_view symbol; //!< Symbol uint32_t strategy_id = {}; //!< Strategy identifier (optional) roq::Side side = {}; //!< Side }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "cancel_all_orders"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::CancelAllOrders const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(account="{}", )" R"(order_id={}, )" R"(exchange="{}", )" R"(symbol="{}", )" R"(strategy_id={}, )" R"(side={})" R"(}})"sv, value.account, value.order_id, value.exchange, value.symbol, value.strategy_id, value.side); } }; ================================================ FILE: include/roq/cancel_all_orders_ack.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include #include #include "roq/error.hpp" #include "roq/event.hpp" #include "roq/name.hpp" #include "roq/origin.hpp" #include "roq/request_status.hpp" #include "roq/side.hpp" #include "roq/trace.hpp" namespace roq { //! Acknowledgement that a cancel all orders request has been seen by gateway/exchange struct ROQ_PUBLIC CancelAllOrdersAck final { uint16_t stream_id = {}; //!< Stream identifier std::string_view account; //!< Account name uint64_t order_id = {}; //!< Order identifier std::string_view exchange; //!< Exchange std::string_view symbol; //!< Symbol roq::Side side = {}; //!< Side roq::Origin origin = {}; //!< Origin of ack roq::RequestStatus request_status = {}; //!< Request status roq::Error error = {}; //!< Error code std::string_view text; //!< Descriptive text std::string_view request_id; //!< Request identifier std::string_view external_account; //!< External account name uint32_t number_of_affected_orders = {}; //!< Number of affected orders (optional, indicative) std::chrono::nanoseconds round_trip_latency = {}; //!< Round-trip latency between gateway and exchange std::string_view user; //!< User name (optional, only relevant for drop-copy) uint32_t strategy_id = {}; //!< Strategy identifier (optional) }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "cancel_all_orders_ack"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::CancelAllOrdersAck const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(stream_id={}, )" R"(account="{}", )" R"(order_id={}, )" R"(exchange="{}", )" R"(symbol="{}", )" R"(side={}, )" R"(origin={}, )" R"(request_status={}, )" R"(error={}, )" R"(text="{}", )" R"(request_id="{}", )" R"(external_account="{}", )" R"(number_of_affected_orders={}, )" R"(round_trip_latency={}, )" R"(user="{}", )" R"(strategy_id={})" R"(}})"sv, value.stream_id, value.account, value.order_id, value.exchange, value.symbol, value.side, value.origin, value.request_status, value.error, value.text, value.request_id, value.external_account, value.number_of_affected_orders, value.round_trip_latency, value.user, value.strategy_id); } }; ================================================ FILE: include/roq/cancel_order.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include #include #include "roq/event.hpp" #include "roq/name.hpp" #include "roq/trace.hpp" namespace roq { //! Fields required to cancel an existing order struct ROQ_PUBLIC CancelOrder final { std::string_view account; //!< Account name uint64_t order_id = {}; //!< Order identifier std::string_view request_template; //!< Request template (gateway configured) std::string_view routing_id; //!< Routing identifier uint32_t version = {}; //!< Version number (strictly increasing, optional) uint32_t conditional_on_version = {}; //!< Auto-reject if this version has positively failed (optional) std::chrono::nanoseconds release_time_utc = {}; //!< Request release time (optional) }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "cancel_order"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::CancelOrder const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(account="{}", )" R"(order_id={}, )" R"(request_template="{}", )" R"(routing_id="{}", )" R"(version={}, )" R"(conditional_on_version={}, )" R"(release_time_utc={})" R"(}})"sv, value.account, value.order_id, value.request_template, value.routing_id, value.version, value.conditional_on_version, value.release_time_utc); } }; ================================================ FILE: include/roq/cancel_quotes.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include "roq/event.hpp" #include "roq/name.hpp" #include "roq/trace.hpp" namespace roq { //! Cancel quotes struct ROQ_PUBLIC CancelQuotes final { std::string_view account; //!< Account name uint16_t quote_set_id = {}; //!< Quote Request ID }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "cancel_quotes"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::CancelQuotes const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(account="{}", )" R"(quote_set_id={})" R"(}})"sv, value.account, value.quote_set_id); } }; ================================================ FILE: include/roq/cancel_quotes_ack.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include "roq/error.hpp" #include "roq/event.hpp" #include "roq/name.hpp" #include "roq/origin.hpp" #include "roq/request_status.hpp" #include "roq/trace.hpp" namespace roq { //! Acknowledgement that a cancel quotes request has been seen by gateway/exchange struct ROQ_PUBLIC CancelQuotesAck final { uint16_t stream_id = {}; //!< Stream identifier std::string_view account; //!< Account name roq::Origin origin = {}; //!< Origin of ack roq::RequestStatus request_status = {}; //!< Request status roq::Error error = {}; //!< Error code std::string_view text; //!< Descriptive text std::string_view request_id; //!< Request identifier std::string_view external_account; //!< External account name uint32_t number_of_affected_quotes = {}; //!< Number of affected quotes (optional, indicative) }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "cancel_quotes_ack"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::CancelQuotesAck const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(stream_id={}, )" R"(account="{}", )" R"(origin={}, )" R"(request_status={}, )" R"(error={}, )" R"(text="{}", )" R"(request_id="{}", )" R"(external_account="{}", )" R"(number_of_affected_quotes={})" R"(}})"sv, value.stream_id, value.account, value.origin, value.request_status, value.error, value.text, value.request_id, value.external_account, value.number_of_affected_quotes); } }; ================================================ FILE: include/roq/category.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include namespace roq { //! Category (of data) enum class Category : uint8_t { UNDEFINED = 0, PUBLIC, //!< Public data PRIVATE, //!< Private data }; } // namespace roq ================================================ FILE: include/roq/client/custom_message.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ #pragma once #include "roq/compat.hpp" #include #include #include "roq/event.hpp" namespace roq { namespace client { struct ROQ_PUBLIC CustomMessage final { std::span message; }; } // namespace client } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::client::CustomMessage const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(length={})" R"(}})"sv, std::size(value.message)); } }; template <> struct fmt::formatter> { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::Event const &event, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(message_info={}, )" R"(custom_message={})" R"(}})"sv, event.message_info, event.value); } }; ================================================ FILE: include/roq/clock.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ #pragma once #include #include #include #include "roq/exceptions.hpp" namespace roq { namespace detail { template inline auto get_time_helper() { struct timespec time; auto res = ::clock_gettime(clock, &time); if (res != 0) [[unlikely]] { using namespace std::literals; throw SystemError{std::error_code{errno, std::system_category()}, "clock_gettime"sv}; } return std::chrono::nanoseconds{(static_cast(time.tv_sec) * INT64_C(1000000000)) + static_cast(time.tv_nsec)}; } } // namespace detail namespace clock { template inline T get_system() { return std::chrono::duration_cast(detail::get_time_helper()); } template inline T get_realtime() { return std::chrono::duration_cast(detail::get_time_helper()); } } // namespace clock } // namespace roq ================================================ FILE: include/roq/compat.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ #pragma once #include #if defined(__GNUC__) #define ROQ_PUBLIC __attribute__((visibility("default"))) #define ROQ_HOT __attribute__((hot)) #define ROQ_PACKED __attribute__((packed)) #else // not gnuc #if defined(__clang__) #error "expected __clang__ to also define __GNUC__" #endif #error "unsupported compiler" #endif #if defined(__APPLE__) // sysctl -a | grep -e vm.pagesize -e hw.cachelinesize #if defined(__arm64__) static constexpr size_t const ROQ_CACHELINE_SIZE = 128; static constexpr size_t const ROQ_PAGE_SIZE = 16384; #else // not __arm64__ static constexpr size_t const ROQ_CACHELINE_SIZE = 64; static constexpr size_t const ROQ_PAGE_SIZE = 4096; #endif #else // not __APPLE__ // getconf -a | grep -e PAGE_SIZE -e LEVEL1_DCACHE_LINESIZE static constexpr size_t const ROQ_CACHELINE_SIZE = 64; static constexpr size_t const ROQ_PAGE_SIZE = 4096; #endif ================================================ FILE: include/roq/connected.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include "roq/event.hpp" #include "roq/name.hpp" #include "roq/trace.hpp" namespace roq { //! Connected to gateway struct ROQ_PUBLIC Connected final {}; template <> constexpr std::string_view get_name() { using namespace std::literals; return "connected"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::Connected const &, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), R"({{}})"sv); } }; ================================================ FILE: include/roq/connection_status.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include namespace roq { //! Enumeration of exchange connectivity status as seen from a gateway enum class ConnectionStatus : uint8_t { UNDEFINED = 0, DISCONNECTED, //!< Disconnected CONNECTING, //!< Connecting LOGIN_SENT, //!< Login sent DOWNLOADING, //!< Downloading READY, //!< Ready LOGGED_OUT, //!< Logged out }; } // namespace roq ================================================ FILE: include/roq/control.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include "roq/action.hpp" #include "roq/event.hpp" #include "roq/name.hpp" #include "roq/trace.hpp" namespace roq { //! Service control struct ROQ_PUBLIC Control final { std::string_view request_id; //!< Request identifier std::string_view user; //!< User name (client routing, optional) roq::Action action = {}; //!< Action uint32_t strategy_id = {}; //!< Strategy filter (optional) uint16_t leg_id = {}; //!< Leg index filter (optional) std::string_view account; //!< Account filter (optional) std::string_view exchange; //!< Exchange filter (optional) std::string_view symbol; //!< Symbol filter (optional) }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "control"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::Control const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(request_id="{}", )" R"(user="{}", )" R"(action={}, )" R"(strategy_id={}, )" R"(leg_id={}, )" R"(account="{}", )" R"(exchange="{}", )" R"(symbol="{}")" R"(}})"sv, value.request_id, value.user, value.action, value.strategy_id, value.leg_id, value.account, value.exchange, value.symbol); } }; ================================================ FILE: include/roq/control_ack.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include "roq/error.hpp" #include "roq/event.hpp" #include "roq/name.hpp" #include "roq/origin.hpp" #include "roq/request_status.hpp" #include "roq/trace.hpp" namespace roq { //! Control ack struct ROQ_PUBLIC ControlAck final { std::string_view request_id; //!< Request identifier std::string_view user; //!< User name (client routing, optional) roq::Origin origin = {}; //!< Origin of ack roq::RequestStatus request_status = {}; //!< Request status roq::Error error = {}; //!< Error code std::string_view text; //!< Descriptive text }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "control_ack"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::ControlAck const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(request_id="{}", )" R"(user="{}", )" R"(origin={}, )" R"(request_status={}, )" R"(error={}, )" R"(text="{}")" R"(}})"sv, value.request_id, value.user, value.origin, value.request_status, value.error, value.text); } }; ================================================ FILE: include/roq/create_order.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include #include #include "roq/event.hpp" #include "roq/execution_instruction.hpp" #include "roq/limits.hpp" #include "roq/margin_mode.hpp" #include "roq/mask.hpp" #include "roq/name.hpp" #include "roq/order_type.hpp" #include "roq/position_effect.hpp" #include "roq/quantity_type.hpp" #include "roq/side.hpp" #include "roq/time_in_force.hpp" #include "roq/trace.hpp" namespace roq { //! Fields required to create an order struct ROQ_PUBLIC CreateOrder final { std::string_view account; //!< Account name uint64_t order_id = {}; //!< Order identifier std::string_view exchange; //!< Exchange std::string_view symbol; //!< Symbol roq::Side side = {}; //!< Order side roq::PositionEffect position_effect = {}; //!< Position effect roq::MarginMode margin_mode = {}; //!< Margin mode roq::QuantityType quantity_type = {}; //!< Type of quantity (requires ecxhange support) double max_show_quantity = roq::NaN; //!< Quantity visible to market (requires exchange support) roq::OrderType order_type = {}; //!< Order type roq::TimeInForce time_in_force = {}; //!< Time in force roq::Mask execution_instructions; //!< Execution instructions std::string_view request_template; //!< Request template (gateway configured) double quantity = roq::NaN; //!< Order quantity double price = roq::NaN; //!< Limit price (depends on order_type) double stop_price = roq::NaN; //!< Stop price (depends on order_type and time_in_force) double leverage = roq::NaN; //!< Leverage (requires exchange support) std::string_view routing_id; //!< Routing identifier uint32_t strategy_id = {}; //!< Strategy identifier (optional) std::chrono::nanoseconds release_time_utc = {}; //!< Request release time (optional) }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "create_order"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::CreateOrder const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(account="{}", )" R"(order_id={}, )" R"(exchange="{}", )" R"(symbol="{}", )" R"(side={}, )" R"(position_effect={}, )" R"(margin_mode={}, )" R"(quantity_type={}, )" R"(max_show_quantity={}, )" R"(order_type={}, )" R"(time_in_force={}, )" R"(execution_instructions={}, )" R"(request_template="{}", )" R"(quantity={}, )" R"(price={}, )" R"(stop_price={}, )" R"(leverage={}, )" R"(routing_id="{}", )" R"(strategy_id={}, )" R"(release_time_utc={})" R"(}})"sv, value.account, value.order_id, value.exchange, value.symbol, value.side, value.position_effect, value.margin_mode, value.quantity_type, value.max_show_quantity, value.order_type, value.time_in_force, value.execution_instructions, value.request_template, value.quantity, value.price, value.stop_price, value.leverage, value.routing_id, value.strategy_id, value.release_time_utc); } }; ================================================ FILE: include/roq/custom_matrix.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include #include #include "roq/event.hpp" #include "roq/limits.hpp" #include "roq/name.hpp" #include "roq/string_types.hpp" #include "roq/trace.hpp" #include "roq/update_type.hpp" namespace roq { //! Custom matrix (publish) struct ROQ_PUBLIC CustomMatrix final { std::string_view label; //!< Label std::string_view account; //!< Account name std::string_view exchange; //!< Exchange std::string_view symbol; //!< Symbol std::span rows; //!< row labels std::span columns; //!< column labels std::span data; //!< matrix roq::UpdateType update_type = {}; //!< Update type uint32_t version = {}; //!< Version number (does not have to be sequential) }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "custom_matrix"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::CustomMatrix const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(label="{}", )" R"(account="{}", )" R"(exchange="{}", )" R"(symbol="{}", )" R"(rows=[{}], )" R"(columns=[{}], )" R"(data=[{}], )" R"(update_type={}, )" R"(version={})" R"(}})"sv, value.label, value.account, value.exchange, value.symbol, fmt::join(value.rows, ", "sv), fmt::join(value.columns, ", "sv), fmt::join(value.data, ", "sv), value.update_type, value.version); } }; ================================================ FILE: include/roq/custom_matrix_update.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include #include #include #include #include "roq/event.hpp" #include "roq/limits.hpp" #include "roq/name.hpp" #include "roq/string_types.hpp" #include "roq/trace.hpp" #include "roq/update_type.hpp" namespace roq { //! Custom matrix (receive) struct ROQ_PUBLIC CustomMatrixUpdate final { std::string_view label; //!< Label std::string_view account; //!< Account name std::string_view exchange; //!< Exchange std::string_view symbol; //!< Symbol std::span rows; //!< row labels std::span columns; //!< column labels std::span data; //!< matrix roq::UpdateType update_type = {}; //!< Update type uint32_t version = {}; //!< Version number (does not have to be sequential) std::chrono::nanoseconds sending_time_utc = {}; //!< Exchange sending timestamp (UTC) std::string_view user; //!< User name (origin) }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "custom_matrix_update"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::CustomMatrixUpdate const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(label="{}", )" R"(account="{}", )" R"(exchange="{}", )" R"(symbol="{}", )" R"(rows=[{}], )" R"(columns=[{}], )" R"(data=[{}], )" R"(update_type={}, )" R"(version={}, )" R"(sending_time_utc={}, )" R"(user="{}")" R"(}})"sv, value.label, value.account, value.exchange, value.symbol, fmt::join(value.rows, ", "sv), fmt::join(value.columns, ", "sv), fmt::join(value.data, ", "sv), value.update_type, value.version, value.sending_time_utc, value.user); } }; ================================================ FILE: include/roq/custom_metrics.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include #include #include "roq/event.hpp" #include "roq/measurement.hpp" #include "roq/name.hpp" #include "roq/trace.hpp" #include "roq/update_type.hpp" namespace roq { //! Custom metrics (publish) struct ROQ_PUBLIC CustomMetrics final { std::string_view label; //!< Label std::string_view account; //!< Account name std::string_view exchange; //!< Exchange std::string_view symbol; //!< Symbol std::span measurements; //!< List of measurements roq::UpdateType update_type = {}; //!< Update type }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "custom_metrics"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::CustomMetrics const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(label="{}", )" R"(account="{}", )" R"(exchange="{}", )" R"(symbol="{}", )" R"(measurements=[{}], )" R"(update_type={})" R"(}})"sv, value.label, value.account, value.exchange, value.symbol, fmt::join(value.measurements, ", "sv), value.update_type); } }; ================================================ FILE: include/roq/custom_metrics_update.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include #include #include #include #include "roq/event.hpp" #include "roq/measurement.hpp" #include "roq/name.hpp" #include "roq/trace.hpp" #include "roq/update_type.hpp" namespace roq { //! Custom metrics (receive) struct ROQ_PUBLIC CustomMetricsUpdate final { std::string_view label; //!< Label std::string_view account; //!< Account name std::string_view exchange; //!< Exchange std::string_view symbol; //!< Symbol std::span measurements; //!< List of measurements roq::UpdateType update_type = {}; //!< Update type std::chrono::nanoseconds sending_time_utc = {}; //!< Exchange sending timestamp (UTC) std::string_view user; //!< User name (origin) }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "custom_metrics_update"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::CustomMetricsUpdate const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(label="{}", )" R"(account="{}", )" R"(exchange="{}", )" R"(symbol="{}", )" R"(measurements=[{}], )" R"(update_type={}, )" R"(sending_time_utc={}, )" R"(user="{}")" R"(}})"sv, value.label, value.account, value.exchange, value.symbol, fmt::join(value.measurements, ", "sv), value.update_type, value.sending_time_utc, value.user); } }; ================================================ FILE: include/roq/data_source.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include namespace roq { //! Enumeration of time-series data sources enum class DataSource : uint8_t { UNDEFINED = 0, TRADE_SUMMARY, //!< Trades }; } // namespace roq ================================================ FILE: include/roq/decimal.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ #pragma once #include #include "roq/limits.hpp" #include "roq/precision.hpp" namespace roq { struct Decimal final { Decimal() = default; Decimal(double value, Precision precision) : value_{value}, precision_{precision} {} bool empty() const { return std::isnan(value_); } operator double() const { return value_; } operator Precision() const { return precision_; } private: double value_ = NaN; Precision precision_ = {}; }; } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::Decimal const &value, format_context &context) const { constexpr auto helper = [](auto precision) { using result_type = int8_t; if (precision >= roq::Precision::_0 && precision <= roq::Precision::_15) { return static_cast(precision) - static_cast(roq::Precision::_0); } return -1; }; // NOLINTBEGIN(readability-magic-numbers) static_assert(helper(roq::Precision::UNDEFINED) == -1); static_assert(helper(roq::Precision::_0) == 0); static_assert(helper(roq::Precision::_15) == 15); // NOLINTEND(readability-magic-numbers) using namespace std::literals; auto decimal_digits = helper(static_cast(value)); if (decimal_digits >= 0) { return fmt::format_to(context.out(), "{:.{}f}"sv, static_cast(value), decimal_digits); } return fmt::format_to(context.out(), "{}"sv, static_cast(value)); } }; ================================================ FILE: include/roq/disconnected.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include "roq/event.hpp" #include "roq/name.hpp" #include "roq/order_cancel_policy.hpp" #include "roq/trace.hpp" namespace roq { //! Disconnected struct ROQ_PUBLIC Disconnected final { roq::OrderCancelPolicy order_cancel_policy = {}; //!< Cancel orders on disconnect? }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "disconnected"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::Disconnected const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(order_cancel_policy={})" R"(}})"sv, value.order_cancel_policy); } }; ================================================ FILE: include/roq/download_begin.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include "roq/event.hpp" #include "roq/name.hpp" #include "roq/trace.hpp" namespace roq { //! Identifies the beginning of a download sequence struct ROQ_PUBLIC DownloadBegin final { std::string_view account; //!< Account name }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "download_begin"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::DownloadBegin const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(account="{}")" R"(}})"sv, value.account); } }; ================================================ FILE: include/roq/download_end.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include "roq/event.hpp" #include "roq/name.hpp" #include "roq/trace.hpp" namespace roq { //! Identifies the end of a download sequence struct ROQ_PUBLIC DownloadEnd final { std::string_view account; //!< Account name uint64_t max_order_id = {}; //!< Highest previous order identifier (as seen by gateway) }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "download_end"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::DownloadEnd const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(account="{}", )" R"(max_order_id={})" R"(}})"sv, value.account, value.max_order_id); } }; ================================================ FILE: include/roq/encoding.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include #include #include namespace roq { //! Enumeration of message encoding types (informational, only) enum class Encoding : uint32_t { // NOLINT(performance-enum-size) UNDEFINED = 0, FIX = 0x1, //!< FIX JSON = 0x2, //!< JSON SBE = 0x4, //!< SBE FBS = 0x8, //!< FlatBuffers }; } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::Encoding const &value, format_context &context) const { using namespace std::literals; auto name = [&]() -> std::string_view { switch (value) { using enum roq::Encoding; case UNDEFINED: return "UNDEFINED"sv; case FIX: return "FIX"sv; case JSON: return "JSON"sv; case SBE: return "SBE"sv; case FBS: return "FBS"sv; } std::abort(); }(); return fmt::format_to(context.out(), "{}"sv, name); } }; ================================================ FILE: include/roq/error.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include namespace roq { //! Enumeration of error types enum class Error : uint8_t { UNDEFINED = 0, UNKNOWN, NOT_SUPPORTED, //!< Request type not supported INVALID_ACCOUNT, //!< Invalid account INVALID_ORDER_ID, //!< Invalid order ID INVALID_EXCHANGE, //!< Invalid exchange INVALID_SYMBOL, //!< Invalid symbol INVALID_SIDE, //!< Invalid side INVALID_POSITION_EFFECT, //!< Invalid position effect INVALID_QUANTITY, //!< Invalid quantity INVALID_MAX_SHOW_QUANTITY, //!< Invalid max show quantity INVALID_ORDER_TYPE, //!< Invalid order type INVALID_TIME_IN_FORCE, //!< Invalid time in force INVALID_EXECUTION_INSTRUCTION, //!< Invalid execution instruction INVALID_REQUEST_TEMPLATE, //!< Invalid request template INVALID_PRICE, //!< Invalid price INVALID_STOP_PRICE, //!< Invalid stop price INVALID_ROUTING_ID, //!< Invalid routing ID INVALID_REQUEST_VERSION, //!< Invalid request version INVALID_REQUEST_ID, //!< Invalid request ID INVALID_REQUEST_TYPE, //!< Invalid request type INVALID_REQUEST_STATUS, //!< Invalid request status INVALID_REQUEST_ARGS, //!< Request arguments did not meet validation rules UNKNOWN_EXTERNAL_ORDER_ID, //!< An external order identifier has not yet been received NOT_AUTHORIZED, //!< User is not authorized REQUEST_RATE_LIMIT_REACHED, //!< Request rate limit has been reached GATEWAY_NOT_READY, //!< Gateway not ready (could be disconnected or currently downloading) NETWORK_ERROR, //!< Network disconnect event (unknown request/order status) TIMEOUT, //!< Response has not been received (unknown request/order status) PARSE_ERROR, //!< Message parse error (unknown request/order status) MODIFY_HAS_NO_EFFECT, //!< Modify request has no effect on order TOO_LATE_TO_MODIFY_OR_CANCEL, //!< Too late to modify or cancel (order has been filled or is already canceled) CONDITIONAL_REQUEST_HAS_FAILED, //!< Happens when gateway detects chain failure UNKNOWN_ORDER_ID, //!< Unknown order ID INSUFFICIENT_FUNDS, //!< Insufficient funds for order action RISK_LIMIT_REACHED, //!< Risk limit reached INVALID_FILTER, //!< Invalid filter INVALID_MARGIN_MODE, //!< Invalid margin mode INVALID_QUANTITY_TYPE, //!< Invalid quantity type INVALID_RELEASE_TIME, //!< Invalid release time }; } // namespace roq ================================================ FILE: include/roq/event.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ #pragma once #include #include #include #include "roq/message_info.hpp" #include "roq/name.hpp" namespace roq { //! Event template struct Event final { using value_type = std::remove_cvref_t; Event(MessageInfo const &message_info, T const &value) : message_info{message_info}, value{value} {} Event(Event &&) = delete; Event(Event const &) = delete; void operator=(Event &&) = delete; void operator=(Event const &) = delete; //! Dispatch to handler template Result dispatch(Handler &&handler, Args &&...args) const { return handler(*this, std::forward(args)...); } //! Access MessageInfo operator MessageInfo const &() const { return message_info; } //! Access Message operator value_type const &() const { return value; } //! Structured binding operator std::pair() const { return {message_info, value}; } MessageInfo const &message_info; //!< MessageInfo value_type const &value; //!< Message //! Create event and dispatch to handler template static void create_and_dispatch(auto &handler, MessageInfo const &message_info, T const &value, Args &&...args) { Event const event{message_info, value}; return event.template dispatch(handler, std::forward(args)...); } }; //! Create event and dispatch to handler template inline void create_event_and_dispatch(auto &handler, MessageInfo const &message_info, T const &value, Args &&...args) { return Event::create_and_dispatch(handler, message_info, value, std::forward(args)...); } } // namespace roq template struct fmt::formatter> { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::Event const &event, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"({}={}, )" R"(message_info={})" R"(}})"sv, roq::get_name(), event.value, event.message_info); } }; ================================================ FILE: include/roq/exceptions.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ #pragma once #include "roq/compat.hpp" #include #include #include #include #include #include #include #include "roq/error.hpp" #include "roq/format_str.hpp" #include "roq/request_status.hpp" namespace roq { namespace detail { template constexpr auto create_what(fmt::string_view const &str, Args &&...args) -> std::string { if (std::size(str) == 0) { return {}; } if constexpr (sizeof...(args) == 0) { return {std::data(str), std::size(str)}; } else { // XXX FIXME TODO fmt::format_string return fmt::vformat(str, fmt::make_format_args(args...)); } } } // namespace detail // This class hierarchy is *similar to* that of std::exception, // but not trying to be a mirror! // The reason is that a mirrored exception hierarchy would require multiple // inheritance and then cause issues with catch handlers. // The implication is that you must implement two exception handlers, // e.g. // try { // ... // } catch (std::overflow_error&) { // ... // } catch (roq::OverflowError&) { // ... // } //! Base struct ROQ_PUBLIC Exception : public std::exception { template explicit Exception(format_str const &str, Args &&...args) : file_name_{str.file_name}, line_{str.line}, what_{detail::create_what(str.str, std::forward(args)...)} {} char const *what() const noexcept override { return what_.c_str(); } virtual std::string_view file() const noexcept { return file_name_; } virtual int line() const noexcept { return static_cast(line_); } template auto format_to(Context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(type="{}", )" R"(what="{}", )" R"(file="{}", )" R"(line={})" R"(}})"sv, typeid(*this).name(), what_, file_name_, line_); } protected: detail::static_string<32> const file_name_; uint32_t const line_; std::string const what_; }; //! Runtime error struct ROQ_PUBLIC RuntimeError : public Exception { using Exception::Exception; }; //! SystemError struct ROQ_PUBLIC SystemError : public RuntimeError { public: std::error_code const &code() const noexcept { return error_; } template SystemError(std::error_code error, format_str const &fmt, Args &&...args) : RuntimeError{fmt, std::forward(args)...}, error_{error} {} template auto format_to(Context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(type="{}", )" R"(what="{}", )" R"(file="{}", )" R"(line={}, )" R"(error_code={{)" R"(message="{}", )" R"(value={})" R"(}})" R"(}})"sv, typeid(*this).name(), what_, file_name_, line_, error_.message(), error_.value()); } private: std::error_code const error_; }; //! RangeError struct ROQ_PUBLIC RangeError : public RuntimeError { using RuntimeError::RuntimeError; }; //! OverflowError struct ROQ_PUBLIC OverflowError : public RuntimeError { using RuntimeError::RuntimeError; }; //! LogicError struct ROQ_PUBLIC LogicError : public Exception { using Exception::Exception; }; //! InvalidArgument struct ROQ_PUBLIC InvalidArgument : public LogicError { using LogicError::LogicError; }; //! OutOfRange struct ROQ_PUBLIC OutOfRange : public LogicError { using LogicError::LogicError; }; //! LengthError struct ROQ_PUBLIC LengthError : public LogicError { using LogicError::LogicError; }; // ROQ SPECIFIC //! Fatal struct ROQ_PUBLIC Fatal : public RuntimeError { using RuntimeError::RuntimeError; }; //! File does not exist struct ROQ_PUBLIC FileDoesNotExist : public RuntimeError { using RuntimeError::RuntimeError; }; //! Not ready struct ROQ_PUBLIC NotReady : public RuntimeError { using RuntimeError::RuntimeError; }; //! Not implemented struct ROQ_PUBLIC NotImplemented : public RuntimeError { using RuntimeError::RuntimeError; }; //! Not supported struct ROQ_PUBLIC NotSupported : public RuntimeError { using RuntimeError::RuntimeError; }; //! Bad state struct ROQ_PUBLIC BadState : public RuntimeError { using RuntimeError::RuntimeError; }; // network errors //! Base class for network errors struct ROQ_PUBLIC NetworkError : public RuntimeError { template NetworkError(RequestStatus request_status, Error error, format_str const &fmt, Args &&...args) : RuntimeError{fmt, std::forward(args)...}, request_status_{request_status}, error_{error} {} RequestStatus request_status() const noexcept { return request_status_; } Error error() const noexcept { return error_; } private: RequestStatus const request_status_; Error const error_; }; // transport errors //! Base class for transport errors struct ROQ_PUBLIC TransportError : public NetworkError { using NetworkError::NetworkError; }; //! Not connected struct ROQ_PUBLIC NotConnected : public TransportError { template explicit NotConnected(format_str const &fmt, Args &&...args) : TransportError{RequestStatus::REJECTED, Error::GATEWAY_NOT_READY, fmt, std::forward(args)...} {} }; //! Connection refused struct ROQ_PUBLIC ConnectionRefused : public TransportError { template explicit ConnectionRefused(format_str const &fmt, Args &&...args) : TransportError{RequestStatus::REJECTED, Error::GATEWAY_NOT_READY, fmt, std::forward(args)...} {} }; //! Timed out struct ROQ_PUBLIC TimedOut : public TransportError { template explicit TimedOut(format_str const &fmt, Args &&...args) : TransportError{RequestStatus::TIMEOUT, Error::TIMEOUT, fmt, std::forward(args)...} {} }; // session errors //! Base class for session errors struct ROQ_PUBLIC SessionError : public NetworkError { using NetworkError::NetworkError; }; //! Permissions denied (operating system) struct ROQ_PUBLIC PermissionDenied : public SessionError { template explicit PermissionDenied(format_str const &fmt, Args &&...args) : SessionError{RequestStatus::UNDEFINED, Error::UNDEFINED, fmt, std::forward(args)...} {} }; //! Order not live struct ROQ_PUBLIC OrderNotLive : public SessionError { template explicit OrderNotLive(format_str const &fmt, Args &&...args) : SessionError{RequestStatus::REJECTED, Error::TOO_LATE_TO_MODIFY_OR_CANCEL, fmt, std::forward(args)...} {} }; } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::Exception const &value, format_context &context) const { return value.format_to(context); } }; template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::RuntimeError const &value, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), "{}"sv, static_cast(value)); } }; template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::SystemError const &value, format_context &context) const { return value.format_to(context); } }; template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::RangeError const &value, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), "{}"sv, static_cast(value)); } }; template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::OverflowError const &value, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), "{}"sv, static_cast(value)); } }; template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::LogicError const &value, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), "{}"sv, static_cast(value)); } }; template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::InvalidArgument const &value, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), "{}"sv, static_cast(value)); } }; template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::OutOfRange const &value, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), "{}"sv, static_cast(value)); } }; template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::LengthError const &value, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), "{}"sv, static_cast(value)); } }; template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::Fatal const &value, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), "{}"sv, static_cast(value)); } }; template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::FileDoesNotExist const &value, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), "{}"sv, static_cast(value)); } }; template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::NotReady const &value, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), "{}"sv, static_cast(value)); } }; template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::BadState const &value, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), "{}"sv, static_cast(value)); } }; template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::NetworkError const &value, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), "{}"sv, static_cast(value)); } }; template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::TransportError const &value, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), "{}"sv, static_cast(value)); } }; template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::NotConnected const &value, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), "{}"sv, static_cast(value)); } }; template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::ConnectionRefused const &value, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), "{}"sv, static_cast(value)); } }; template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::TimedOut const &value, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), "{}"sv, static_cast(value)); } }; template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::SessionError const &value, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), "{}"sv, static_cast(value)); } }; template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::PermissionDenied const &value, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), "{}"sv, static_cast(value)); } }; template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::OrderNotLive const &value, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), "{}"sv, static_cast(value)); } }; ================================================ FILE: include/roq/execution_instruction.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include #include #include namespace roq { //! Enumeration of execution types enum class ExecutionInstruction : uint32_t { // NOLINT(performance-enum-size) UNDEFINED = 0, PARTICIPATE_DO_NOT_INITIATE = 0x1, //!< Cancel if order would have executed on placement (i.e. not as maker) CANCEL_IF_NOT_BEST = 0x2, //!< Cancel if order can not be placed at best price DO_NOT_INCREASE = 0x4, //!< Order may only reduce net position, order quantity can automatically be reduced by exchange DO_NOT_REDUCE = 0x8, //!< Order can not be partially filled, aka. all-or-none (AON) orders }; } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::ExecutionInstruction const &value, format_context &context) const { using namespace std::literals; auto name = [&]() -> std::string_view { switch (value) { using enum roq::ExecutionInstruction; case UNDEFINED: return "UNDEFINED"sv; case PARTICIPATE_DO_NOT_INITIATE: return "PARTICIPATE_DO_NOT_INITIATE"sv; case CANCEL_IF_NOT_BEST: return "CANCEL_IF_NOT_BEST"sv; case DO_NOT_INCREASE: return "DO_NOT_INCREASE"sv; case DO_NOT_REDUCE: return "DO_NOT_REDUCE"sv; } std::abort(); }(); return fmt::format_to(context.out(), "{}"sv, name); } }; ================================================ FILE: include/roq/external_latency.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include #include #include "roq/event.hpp" #include "roq/name.hpp" #include "roq/trace.hpp" namespace roq { //! Update relating to external latency struct ROQ_PUBLIC ExternalLatency final { uint16_t stream_id = {}; //!< Stream identifier std::string_view account; //!< Account name std::chrono::nanoseconds latency = {}; //!< latency measurement (1-way) }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "external_latency"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::ExternalLatency const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(stream_id={}, )" R"(account="{}", )" R"(latency={})" R"(}})"sv, value.stream_id, value.account, value.latency); } }; ================================================ FILE: include/roq/fill.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include #include "roq/limits.hpp" #include "roq/liquidity.hpp" #include "roq/string_types.hpp" namespace roq { //! Represents a single fill (match) when an order is being partially or fully filled struct ROQ_PUBLIC Fill final { std::chrono::nanoseconds exchange_time_utc = {}; //!< Exchange timestamp, possibly from matching engine (UTC) roq::ExternalTradeId external_trade_id; //!< External trade identifier double quantity = roq::NaN; //!< Quantity double price = roq::NaN; //!< Price roq::Liquidity liquidity = {}; //!< Liquidity indicator double commission_amount = roq::NaN; //!< Funds (commission currency, optional) roq::Currency commission_currency; //!< Commission currency double base_amount = roq::NaN; //!< Funds (base currency, internal) double quote_amount = roq::NaN; //!< Funds (quote currency, internal) double profit_loss_amount = roq::NaN; //!< P&L (settlement currency, internal) }; } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::Fill const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(exchange_time_utc={}, )" R"(external_trade_id="{}", )" R"(quantity={}, )" R"(price={}, )" R"(liquidity={}, )" R"(commission_amount={}, )" R"(commission_currency="{}", )" R"(base_amount={}, )" R"(quote_amount={}, )" R"(profit_loss_amount={})" R"(}})"sv, value.exchange_time_utc, value.external_trade_id, value.quantity, value.price, value.liquidity, value.commission_amount, value.commission_currency, value.base_amount, value.quote_amount, value.profit_loss_amount); } }; ================================================ FILE: include/roq/filter.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include #include #include namespace roq { //! Enumeration of filter fields enum class Filter : uint64_t { // NOLINT(performance-enum-size) UNDEFINED = 0, ACCOUNT = 0x1, //!< By account EXCHANGE = 0x2, //!< By exchange SYMBOL = 0x4, //!< By symbol STRATEGY_ID = 0x8, //!< By strategy_id SIDE = 0x10, //!< By side }; } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::Filter const &value, format_context &context) const { using namespace std::literals; auto name = [&]() -> std::string_view { switch (value) { using enum roq::Filter; case UNDEFINED: return "UNDEFINED"sv; case ACCOUNT: return "ACCOUNT"sv; case EXCHANGE: return "EXCHANGE"sv; case SYMBOL: return "SYMBOL"sv; case STRATEGY_ID: return "STRATEGY_ID"sv; case SIDE: return "SIDE"sv; } std::abort(); }(); return fmt::format_to(context.out(), "{}"sv, name); } }; ================================================ FILE: include/roq/format_str.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ #pragma once #include #include #include #include // capture source location namespace roq { namespace detail { // compile-time evaluated string template struct static_string final { consteval static_string(std::string_view const &str) : length_{std::min(N, std::size(str))}, buffer_{create(str, length_)} {} static_string(static_string &&) = delete; static_string(static_string const &) = default; constexpr operator std::string_view() const { return {std::data(buffer_), length_}; } protected: static consteval auto create(std::string_view const &str, std::size_t length) { static_assert(N > 0); std::array buffer; for (std::size_t i = 0; i < length; ++i) { buffer[i] = str[i]; } for (std::size_t i = length; i < N; ++i) { buffer[i] = '\0'; } return buffer; } private: std::size_t const length_; std::array const buffer_; }; } // namespace detail struct format_str final { template consteval format_str(T const &str, std::source_location const loc = std::source_location::current()) : str{str}, file_name{extract_basename(loc.file_name())}, line{loc.line()} {} // note! string could be truncated using file_name_type = detail::static_string<32>; // NOLINT(readability-magic-numbers) std::string_view const str; file_name_type const file_name; std::uint32_t const line; private: static consteval std::string_view extract_basename(char const *path) { if (path == nullptr) { return {}; } std::string_view tmp{path}; if (std::empty(tmp)) { return tmp; } auto pos = tmp.find_last_of('/'); if (pos == std::string_view::npos || pos == (std::size(tmp) - 1)) { return tmp; } return tmp.substr(++pos); } }; } // namespace roq template struct fmt::formatter> { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::detail::static_string const &value, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), "{}"sv, static_cast(value)); } }; ================================================ FILE: include/roq/funds_update.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include #include #include "roq/event.hpp" #include "roq/limits.hpp" #include "roq/margin_mode.hpp" #include "roq/name.hpp" #include "roq/trace.hpp" #include "roq/update_type.hpp" namespace roq { //! Update relating to available funds struct ROQ_PUBLIC FundsUpdate final { uint16_t stream_id = {}; //!< Stream identifier std::string_view account; //!< Account name std::string_view currency; //!< Currency roq::MarginMode margin_mode = {}; //!< Margin mode double balance = roq::NaN; //!< Total funds double hold = roq::NaN; //!< Funds on hold (aka locked) double borrowed = roq::NaN; //!< Borrowed funds (margin trading) double unrealized_pnl = roq::NaN; //!< Unrealized P&L std::string_view external_account; //!< External account name roq::UpdateType update_type = {}; //!< Update type std::chrono::nanoseconds exchange_time_utc = {}; //!< Exchange timestamp, possibly from matching engine (UTC) uint64_t exchange_sequence = {}; //!< Exchange message sequence number std::chrono::nanoseconds sending_time_utc = {}; //!< Exchange sending timestamp (UTC) }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "funds_update"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::FundsUpdate const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(stream_id={}, )" R"(account="{}", )" R"(currency="{}", )" R"(margin_mode={}, )" R"(balance={}, )" R"(hold={}, )" R"(borrowed={}, )" R"(unrealized_pnl={}, )" R"(external_account="{}", )" R"(update_type={}, )" R"(exchange_time_utc={}, )" R"(exchange_sequence={}, )" R"(sending_time_utc={})" R"(}})"sv, value.stream_id, value.account, value.currency, value.margin_mode, value.balance, value.hold, value.borrowed, value.unrealized_pnl, value.external_account, value.update_type, value.exchange_time_utc, value.exchange_sequence, value.sending_time_utc); } }; ================================================ FILE: include/roq/gateway_settings.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include "roq/event.hpp" #include "roq/filter.hpp" #include "roq/interval.hpp" #include "roq/limits.hpp" #include "roq/mask.hpp" #include "roq/name.hpp" #include "roq/request_id_type.hpp" #include "roq/support_type.hpp" #include "roq/trace.hpp" namespace roq { //! Gateway settings struct ROQ_PUBLIC GatewaySettings final { roq::Mask supports; //!< Supported update types uint16_t mbp_max_depth = {}; //!< MBP max depth double mbp_tick_size_multiplier = roq::NaN; //!< MBP multiplier used to manage prices as integer double mbp_min_trade_vol_multiplier = roq::NaN; //!< MBP multiplier used to manage quantities as integer bool mbp_allow_remove_non_existing = false; //!< MBP allow remove operation on non-existing level? bool mbp_allow_price_inversion = false; //!< MBP allow price inversion? bool mbp_checksum = false; //!< MBP compute checksum? bool oms_download_has_state = false; //!< OMS download includes state information? bool oms_download_has_routing_id = false; //!< OMS download includes routing_id? roq::RequestIdType oms_request_id_type = {}; //!< OMS request identifier type roq::Mask oms_cancel_all_orders; //!< Supported filters for CancelAllOrders roq::Interval ts_interval = {}; //!< Time-series interval uint16_t ts_max_history = {}; //!< Time-series max history (bars) }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "gateway_settings"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::GatewaySettings const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(supports={}, )" R"(mbp_max_depth={}, )" R"(mbp_tick_size_multiplier={}, )" R"(mbp_min_trade_vol_multiplier={}, )" R"(mbp_allow_remove_non_existing={}, )" R"(mbp_allow_price_inversion={}, )" R"(mbp_checksum={}, )" R"(oms_download_has_state={}, )" R"(oms_download_has_routing_id={}, )" R"(oms_request_id_type={}, )" R"(oms_cancel_all_orders={}, )" R"(ts_interval={}, )" R"(ts_max_history={})" R"(}})"sv, value.supports, value.mbp_max_depth, value.mbp_tick_size_multiplier, value.mbp_min_trade_vol_multiplier, value.mbp_allow_remove_non_existing, value.mbp_allow_price_inversion, value.mbp_checksum, value.oms_download_has_state, value.oms_download_has_routing_id, value.oms_request_id_type, value.oms_cancel_all_orders, value.ts_interval, value.ts_max_history); } }; ================================================ FILE: include/roq/gateway_status.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include "roq/event.hpp" #include "roq/mask.hpp" #include "roq/name.hpp" #include "roq/support_type.hpp" #include "roq/trace.hpp" namespace roq { //! Update relating to current gateway service status struct ROQ_PUBLIC GatewayStatus final { std::string_view account; //!< Account name roq::Mask supported; //!< Supported update types roq::Mask available; //!< Available update types (union of all streams, one or more available) roq::Mask unavailable; //!< Unavailable update types (union of all streams, one or more unavailable) }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "gateway_status"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::GatewayStatus const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(account="{}", )" R"(supported={}, )" R"(available={}, )" R"(unavailable={})" R"(}})"sv, value.account, value.supported, value.available, value.unavailable); } }; ================================================ FILE: include/roq/interval.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include namespace roq { //! Enumeration of time-series update frequencies enum class Interval : uint8_t { UNDEFINED = 0, _1, //!< 1 second _5, //!< 5 seconds _10, //!< 10 seconds _15, //!< 15 seconds _30, //!< 30 seconds _60, //!< 1 minute _300, //!< 5 minutes _600, //!< 10 minutes _900, //!< 15 minutes _1800, //!< 30 minutes }; } // namespace roq ================================================ FILE: include/roq/layer.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include "roq/limits.hpp" namespace roq { //! Represents aggregate order book bid/ask information at a given depth struct ROQ_PUBLIC Layer final { double bid_price = roq::NaN; //!< Bid price level double bid_quantity = {}; //!< Total quantity available at bid double ask_price = roq::NaN; //!< Ask price level double ask_quantity = {}; //!< Total quantity available at ask }; } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::Layer const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(bid_price={}, )" R"(bid_quantity={}, )" R"(ask_price={}, )" R"(ask_quantity={})" R"(}})"sv, value.bid_price, value.bid_quantity, value.ask_price, value.ask_quantity); } }; ================================================ FILE: include/roq/leg.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include "roq/state.hpp" #include "roq/string_types.hpp" namespace roq { //! Represents current state of a strategy leg struct ROQ_PUBLIC Leg final { uint16_t leg_id = {}; //!< Index roq::Account account; //!< Account (optional) roq::Exchange exchange; //!< Exchange (optional) roq::Symbol symbol; //!< Symbol (optional) roq::State state = {}; //!< Strategy state }; } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::Leg const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(leg_id={}, )" R"(account="{}", )" R"(exchange="{}", )" R"(symbol="{}", )" R"(state={})" R"(}})"sv, value.leg_id, value.account, value.exchange, value.symbol, value.state); } }; ================================================ FILE: include/roq/legs_update.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include #include #include "roq/event.hpp" #include "roq/leg.hpp" #include "roq/name.hpp" #include "roq/trace.hpp" #include "roq/update_type.hpp" namespace roq { //! Legs update struct ROQ_PUBLIC LegsUpdate final { std::string_view user; //!< Service name uint32_t strategy_id = {}; //!< Strategy ID std::span legs; //!< List of leg updates roq::UpdateType update_type = {}; //!< Update type }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "legs_update"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::LegsUpdate const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(user="{}", )" R"(strategy_id={}, )" R"(legs=[{}], )" R"(update_type={})" R"(}})"sv, value.user, value.strategy_id, fmt::join(value.legs, ", "sv), value.update_type); } }; ================================================ FILE: include/roq/limits.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ #pragma once #include namespace roq { constexpr auto const NaN = std::numeric_limits::quiet_NaN(); } // namespace roq ================================================ FILE: include/roq/liquidity.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include namespace roq { //! Enumeration of liquidity type enum class Liquidity : uint8_t { UNDEFINED = 0, MAKER, //!< Maker TAKER, //!< Taker }; } // namespace roq ================================================ FILE: include/roq/map.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ #pragma once #include #include namespace roq { namespace detail { // note! constexpr helper for static testing template struct MapHelper final { constexpr explicit MapHelper(std::tuple const &args) : args_{args} {} constexpr explicit MapHelper(Args &&...args_) : args_{std::forward(args_)...} {} template constexpr operator std::optional() const; template constexpr bool operator==(R rhs) const { auto tmp = (*this).operator std::optional(); if (tmp.has_value()) { return tmp.value() == rhs; } return false; } private: std::tuple const args_; }; } // namespace detail template struct Map final { explicit Map(Args &&...args) : args_{std::forward(args)...} {} explicit Map(Args const &...args) : args_{args...} {} Map(Map const &) = delete; template operator R() const { return helper().value(); } template R get() const { return helper().value(); } protected: template std::optional helper() const { static_assert(false, "mapping has not been declared"); } private: std::tuple const args_; }; template inline auto map(Args &&...args) { return Map{std::forward(args)...}; } } // namespace roq ================================================ FILE: include/roq/margin_mode.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include namespace roq { //! Enumeration of margin modes enum class MarginMode : uint8_t { UNDEFINED = 0, ISOLATED, //!< Isolated CROSS, //!< Cross PORTFOLIO, //!< Portfolio }; } // namespace roq ================================================ FILE: include/roq/market_by_order_update.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include #include #include #include #include "roq/event.hpp" #include "roq/mbo_update.hpp" #include "roq/name.hpp" #include "roq/precision.hpp" #include "roq/trace.hpp" #include "roq/update_type.hpp" namespace roq { //! Update relating to market by order struct ROQ_PUBLIC MarketByOrderUpdate final { uint16_t stream_id = {}; //!< Stream identifier std::string_view exchange; //!< Exchange std::string_view symbol; //!< Symbol std::span orders; //!< List of order updates roq::UpdateType update_type = {}; //!< Update type std::chrono::nanoseconds exchange_time_utc = {}; //!< Exchange timestamp, possibly from matching engine (UTC) uint64_t exchange_sequence = {}; //!< Exchange message sequence number std::chrono::nanoseconds sending_time_utc = {}; //!< Exchange sending timestamp (UTC) roq::Precision price_precision = {}; //!< Precision (decimal digits) required to represent prices (dynamic) roq::Precision quantity_precision = {}; //!< Precision (decimal digits) required to represent quantities (dynamic) uint16_t max_depth = {}; //!< Maximum depth (zero means unlimited) uint32_t checksum = {}; //!< Checksum (internal) }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "market_by_order_update"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::MarketByOrderUpdate const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(stream_id={}, )" R"(exchange="{}", )" R"(symbol="{}", )" R"(orders=[{}], )" R"(update_type={}, )" R"(exchange_time_utc={}, )" R"(exchange_sequence={}, )" R"(sending_time_utc={}, )" R"(price_precision={}, )" R"(quantity_precision={}, )" R"(max_depth={}, )" R"(checksum={})" R"(}})"sv, value.stream_id, value.exchange, value.symbol, fmt::join(value.orders, ", "sv), value.update_type, value.exchange_time_utc, value.exchange_sequence, value.sending_time_utc, value.price_precision, value.quantity_precision, value.max_depth, value.checksum); } }; ================================================ FILE: include/roq/market_by_price_update.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include #include #include #include #include "roq/event.hpp" #include "roq/mbp_update.hpp" #include "roq/name.hpp" #include "roq/precision.hpp" #include "roq/trace.hpp" #include "roq/update_type.hpp" namespace roq { //! Update relating to market by price struct ROQ_PUBLIC MarketByPriceUpdate final { uint16_t stream_id = {}; //!< Stream identifier std::string_view exchange; //!< Exchange std::string_view symbol; //!< Symbol std::span bids; //!< List of bids std::span asks; //!< List of asks roq::UpdateType update_type = {}; //!< Update type std::chrono::nanoseconds exchange_time_utc = {}; //!< Exchange timestamp, possibly from matching engine (UTC) uint64_t exchange_sequence = {}; //!< Exchange message sequence number std::chrono::nanoseconds sending_time_utc = {}; //!< Exchange sending timestamp (UTC) roq::Precision price_precision = {}; //!< Precision (decimal digits) required to represent prices (dynamic) roq::Precision quantity_precision = {}; //!< Precision (decimal digits) required to represent quantities (dynamic) uint16_t max_depth = {}; //!< Maximum depth (zero means unlimited) uint32_t checksum = {}; //!< Checksum (internal) }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "market_by_price_update"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::MarketByPriceUpdate const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(stream_id={}, )" R"(exchange="{}", )" R"(symbol="{}", )" R"(bids=[{}], )" R"(asks=[{}], )" R"(update_type={}, )" R"(exchange_time_utc={}, )" R"(exchange_sequence={}, )" R"(sending_time_utc={}, )" R"(price_precision={}, )" R"(quantity_precision={}, )" R"(max_depth={}, )" R"(checksum={})" R"(}})"sv, value.stream_id, value.exchange, value.symbol, fmt::join(value.bids, ", "sv), fmt::join(value.asks, ", "sv), value.update_type, value.exchange_time_utc, value.exchange_sequence, value.sending_time_utc, value.price_precision, value.quantity_precision, value.max_depth, value.checksum); } }; ================================================ FILE: include/roq/market_status.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include #include #include "roq/event.hpp" #include "roq/name.hpp" #include "roq/trace.hpp" #include "roq/trading_status.hpp" namespace roq { //! Update relating to current trading status of a symbol struct ROQ_PUBLIC MarketStatus final { uint16_t stream_id = {}; //!< Stream identifier std::string_view exchange; //!< Exchange std::string_view symbol; //!< Symbol roq::TradingStatus trading_status = {}; //!< Trading status std::chrono::nanoseconds exchange_time_utc = {}; //!< Exchange timestamp, possibly from matching engine (UTC) uint64_t exchange_sequence = {}; //!< Exchange message sequence number std::chrono::nanoseconds sending_time_utc = {}; //!< Exchange sending timestamp (UTC) }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "market_status"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::MarketStatus const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(stream_id={}, )" R"(exchange="{}", )" R"(symbol="{}", )" R"(trading_status={}, )" R"(exchange_time_utc={}, )" R"(exchange_sequence={}, )" R"(sending_time_utc={})" R"(}})"sv, value.stream_id, value.exchange, value.symbol, value.trading_status, value.exchange_time_utc, value.exchange_sequence, value.sending_time_utc); } }; ================================================ FILE: include/roq/mask.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ #pragma once #include #include #include #include #include #include #include #include namespace roq { // implements a bitmap mask using an underlying enumeration // some limitations: // - flag (enum value) should not be 0 -- we don't currently check // - flag (enum value) should be powers of two, or combinations -- we don't currently check template requires std::is_enum_v struct Mask final { using value_type = typename std::underlying_type_t; struct sentinel final {}; struct iterator final { // std::iterator_traits using difference_type = std::ptrdiff_t; using value_type = T const; using pointer = T const *; using reference = T const; using iterator_category = std::forward_iterator_tag; using underlying_type = std::underlying_type_t; iterator(Mask value) : value_{value.get()} {} bool operator==(sentinel const &) const { for (; bit_ < std::numeric_limits::digits; ++bit_) { auto mask = static_cast(size_t{1} << bit_); if (value_ < mask) { break; } if (value_ & mask) { return false; } } return true; } reference operator*() const { auto mask = static_cast(size_t{1} << bit_++); return static_cast(mask); } iterator &operator++() { return *this; } void operator++(int) { ++(*this); } private: underlying_type value_; mutable size_t bit_ = 0; // skip undefined }; constexpr Mask() = default; constexpr explicit Mask(value_type mask) : value_{mask} {} constexpr explicit Mask(T flag) : value_{static_cast(flag)} {} constexpr Mask(std::initializer_list flags) { for (auto &flag : flags) { value_ |= static_cast(flag); } } template constexpr Mask(Mask const &other, Args &&...args) : value_{other.value_ | Mask{std::forward(args)...}.get()} {} constexpr auto operator<=>(Mask const &) const = default; constexpr bool empty() const { return value_ == value_type{}; } constexpr void reset() { value_ = value_type{}; } constexpr value_type get() const { return value_; } constexpr bool is_same(T flag) const { return value_ == static_cast(flag); } constexpr bool has(T flag) const { return value_ & static_cast(flag); } constexpr bool has_any(T flag) const { return (value_ & static_cast(flag)) != value_type{}; } constexpr bool has_any(std::initializer_list flags) const { value_type value = {}; for (auto &flag : flags) { value |= static_cast(flag); } return value_ & value; } constexpr bool has_any(Mask rhs) const { return (value_ & rhs.value_) != value_type{}; } constexpr bool has_all(T flag) const { return (value_ & static_cast(flag)) == static_cast(flag); } constexpr bool has_all(std::initializer_list flags) const { value_type value = {}; for (auto &flag : flags) { value |= static_cast(flag); } return (value_ & value) == value; } constexpr bool has_all(Mask rhs) const { return (value_ & rhs.value_) == rhs.value_; } constexpr Mask &set(T flag) { value_ |= static_cast(flag); return *this; } constexpr Mask &set(Mask rhs) { value_ |= rhs.value_; return *this; } constexpr Mask &remove(T flag) { value_ &= ~static_cast(flag); return *this; } constexpr Mask &remove(Mask rhs) { value_ &= ~rhs.value_; return *this; } constexpr bool has_none(T flag) const { return !has_any(flag); } constexpr bool has_none(std::initializer_list flags) const { return !has_any(flags); } constexpr bool has_none(Mask rhs) const { return !has_any(rhs); } constexpr Mask negate() const { return Mask{~value_}; } constexpr Mask logical_and(Mask rhs) const { return Mask{value_ & rhs.value_}; } constexpr Mask &set(std::initializer_list flags) { for (auto &flag : flags) { value_ |= static_cast(flag); } return *this; } constexpr Mask operator~() const { return negate(); } constexpr Mask operator&(Mask rhs) const { return logical_and(rhs); } constexpr Mask &operator|=(T flag) { set(flag); return *this; } constexpr Mask &operator|=(Mask rhs) { set(rhs); return *this; } private: value_type value_ = {}; }; } // namespace roq template struct fmt::formatter> { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::Mask const &value, format_context &context) const { using namespace std::literals; using iterator = typename roq::Mask::iterator; using sentinel = typename roq::Mask::sentinel; return fmt::format_to(context.out(), "{}"sv, fmt::join(iterator{value}, sentinel{}, "|"sv)); } }; ================================================ FILE: include/roq/mass_quote.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include #include #include #include #include "roq/event.hpp" #include "roq/name.hpp" #include "roq/quote.hpp" #include "roq/trace.hpp" namespace roq { //! Quotes struct ROQ_PUBLIC MassQuote final { std::string_view account; //!< Account name uint32_t quote_id = {}; //!< Quote ID std::span quotes; //!< Quotes bool mmp_reset = false; //!< Market Maker Protection reset? (when supported by exchange) std::string_view mmp_group; //!< Market Maker Protection group name (when supported by exchange) std::chrono::nanoseconds valid_until_utc = {}; //!< Quote valid until UTC timestamp (when supported by exchange) }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "mass_quote"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::MassQuote const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(account="{}", )" R"(quote_id={}, )" R"(quotes=[{}], )" R"(mmp_reset={}, )" R"(mmp_group="{}", )" R"(valid_until_utc={})" R"(}})"sv, value.account, value.quote_id, fmt::join(value.quotes, ", "sv), value.mmp_reset, value.mmp_group, value.valid_until_utc); } }; ================================================ FILE: include/roq/mass_quote_ack.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include "roq/error.hpp" #include "roq/event.hpp" #include "roq/name.hpp" #include "roq/origin.hpp" #include "roq/request_status.hpp" #include "roq/trace.hpp" namespace roq { //! Acknowledgement that a mass quote request has been seen by gateway/exchange struct ROQ_PUBLIC MassQuoteAck final { uint16_t stream_id = {}; //!< Stream identifier std::string_view account; //!< Account name uint32_t quote_id = {}; //!< Quote ID roq::Origin origin = {}; //!< Origin of ack roq::RequestStatus request_status = {}; //!< Request status roq::Error error = {}; //!< Error code std::string_view text; //!< Descriptive text std::string_view request_id; //!< Request identifier std::string_view external_account; //!< External account name }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "mass_quote_ack"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::MassQuoteAck const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(stream_id={}, )" R"(account="{}", )" R"(quote_id={}, )" R"(origin={}, )" R"(request_status={}, )" R"(error={}, )" R"(text="{}", )" R"(request_id="{}", )" R"(external_account="{}")" R"(}})"sv, value.stream_id, value.account, value.quote_id, value.origin, value.request_status, value.error, value.text, value.request_id, value.external_account); } }; ================================================ FILE: include/roq/mbo_update.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include "roq/limits.hpp" #include "roq/side.hpp" #include "roq/string_types.hpp" #include "roq/update_action.hpp" #include "roq/update_reason.hpp" namespace roq { //! Represents an update to be applied to an order book struct ROQ_PUBLIC MBOUpdate final { double price = roq::NaN; //!< Price level double quantity = {}; //!< Order quantity (remaining unless update action is fill) uint64_t priority = {}; //!< Queue priority (optional) roq::MBOOrderId order_id; //!< Order identifier (optional when deleting) roq::Side side = {}; //!< Order side (optional when updating an existing order) roq::UpdateAction action = {}; //!< Update action roq::UpdateReason reason = {}; //!< Update reason (optional) }; } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::MBOUpdate const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(price={}, )" R"(quantity={}, )" R"(priority={}, )" R"(order_id="{}", )" R"(side={}, )" R"(action={}, )" R"(reason={})" R"(}})"sv, value.price, value.quantity, value.priority, value.order_id, value.side, value.action, value.reason); } }; ================================================ FILE: include/roq/mbp_update.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include "roq/limits.hpp" #include "roq/update_action.hpp" namespace roq { //! Represents the update status of a single aggregate price level in the order book struct ROQ_PUBLIC MBPUpdate final { double price = roq::NaN; //!< Price double quantity = {}; //!< Total quantity available at price (zero means remove price level) double implied_quantity = roq::NaN; //!< Total implied quantity at price (optional) uint16_t number_of_orders = {}; //!< Number of orders at price (optional) roq::UpdateAction update_action = {}; //!< Type of update action uint32_t price_level = {}; //!< Price level (0-based indexing) }; } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::MBPUpdate const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(price={}, )" R"(quantity={}, )" R"(implied_quantity={}, )" R"(number_of_orders={}, )" R"(update_action={}, )" R"(price_level={})" R"(}})"sv, value.price, value.quantity, value.implied_quantity, value.number_of_orders, value.update_action, value.price_level); } }; ================================================ FILE: include/roq/measurement.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include "roq/limits.hpp" #include "roq/string_types.hpp" namespace roq { //! A single measurement point struct ROQ_PUBLIC Measurement final { roq::MeasurementKey name; //!< Key double value = roq::NaN; //!< Value }; } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::Measurement const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(name="{}", )" R"(value={})" R"(}})"sv, value.name, value.value); } }; ================================================ FILE: include/roq/message_info.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include #include #include "roq/uuid.hpp" namespace roq { //! Trace information relating to the current message struct ROQ_PUBLIC MessageInfo final { uint8_t source = {}; //!< Source identifier (index into the list of connections) std::string_view source_name; //!< Source name roq::UUID source_session_id = {}; //!< Session identifier (UUID) uint64_t source_seqno = {}; //!< Sequence number (strictly increasing) std::chrono::nanoseconds receive_time_utc = {}; //!< Client receive time (realtime clock) std::chrono::nanoseconds receive_time = {}; //!< Client receive time (monotonic clock) std::chrono::nanoseconds source_send_time = {}; //!< Source send time (monotonic clock) std::chrono::nanoseconds source_receive_time = {}; //!< Source receive time (monotonic clock) std::chrono::nanoseconds origin_create_time = {}; //!< Origin create time (monotonic clock) std::chrono::nanoseconds origin_create_time_utc = {}; //!< Origin create time (realtime clock) bool is_last = false; //!< Is last in batch? uint64_t opaque = {}; //!< Opaque value (internal) }; } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::MessageInfo const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(source={}, )" R"(source_name="{}", )" R"(source_session_id={}, )" R"(source_seqno={}, )" R"(receive_time_utc={}, )" R"(receive_time={}, )" R"(source_send_time={}, )" R"(source_receive_time={}, )" R"(origin_create_time={}, )" R"(origin_create_time_utc={}, )" R"(is_last={}, )" R"(opaque={})" R"(}})"sv, value.source, value.source_name, value.source_session_id, value.source_seqno, value.receive_time_utc, value.receive_time, value.source_send_time, value.source_receive_time, value.origin_create_time, value.origin_create_time_utc, value.is_last, value.opaque); } }; ================================================ FILE: include/roq/modify_order.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include #include #include "roq/event.hpp" #include "roq/limits.hpp" #include "roq/name.hpp" #include "roq/trace.hpp" namespace roq { //! Fields required to modify an existing order struct ROQ_PUBLIC ModifyOrder final { std::string_view account; //!< Account name uint64_t order_id = {}; //!< Order identifier std::string_view request_template; //!< Request template (gateway configured) double quantity = roq::NaN; //!< New (total) quantity double price = roq::NaN; //!< New limit price std::string_view routing_id; //!< Routing identifier uint32_t version = {}; //!< Version number (strictly increasing, optional) uint32_t conditional_on_version = {}; //!< Auto-reject if this version has positively failed (optional) std::chrono::nanoseconds release_time_utc = {}; //!< Request release time (optional) }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "modify_order"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::ModifyOrder const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(account="{}", )" R"(order_id={}, )" R"(request_template="{}", )" R"(quantity={}, )" R"(price={}, )" R"(routing_id="{}", )" R"(version={}, )" R"(conditional_on_version={}, )" R"(release_time_utc={})" R"(}})"sv, value.account, value.order_id, value.request_template, value.quantity, value.price, value.routing_id, value.version, value.conditional_on_version, value.release_time_utc); } }; ================================================ FILE: include/roq/name.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ #pragma once #include namespace roq { template constexpr std::string_view get_name(); } // namespace roq ================================================ FILE: include/roq/option_type.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include namespace roq { //! Enumeration of option types enum class OptionType : uint8_t { UNDEFINED = 0, CALL, //!< Call PUT, //!< Put }; } // namespace roq ================================================ FILE: include/roq/order_ack.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include #include #include "roq/error.hpp" #include "roq/event.hpp" #include "roq/limits.hpp" #include "roq/margin_mode.hpp" #include "roq/name.hpp" #include "roq/origin.hpp" #include "roq/position_effect.hpp" #include "roq/quantity_type.hpp" #include "roq/request_status.hpp" #include "roq/request_type.hpp" #include "roq/side.hpp" #include "roq/trace.hpp" namespace roq { //! Acknowledgement that a create/modify/cancel order request has been seen by gateway/exchange struct ROQ_PUBLIC OrderAck final { uint16_t stream_id = {}; //!< Stream identifier std::string_view account; //!< Account name uint64_t order_id = {}; //!< Order identifier std::string_view exchange; //!< Exchange std::string_view symbol; //!< Symbol roq::Side side = {}; //!< Side roq::PositionEffect position_effect = {}; //!< Position effect roq::MarginMode margin_mode = {}; //!< Margin mode roq::QuantityType quantity_type = {}; //!< Type of quantity (requires ecxhange support) roq::RequestType request_type = {}; //!< Request type roq::Origin origin = {}; //!< Origin of ack roq::RequestStatus request_status = {}; //!< Request status roq::Error error = {}; //!< Error code std::string_view text; //!< Descriptive text std::string_view request_id; //!< Request identifier std::string_view external_account; //!< External account name std::string_view external_order_id; //!< External order identifier std::string_view client_order_id; //!< Client order identifier double quantity = roq::NaN; //!< Quantity (total, indicative) double price = roq::NaN; //!< Price double stop_price = roq::NaN; //!< Stop price (depends on order_type and time_in_force) double leverage = roq::NaN; //!< Leverage (requires exchange support) std::string_view routing_id; //!< Routing identifier uint32_t version = {}; //!< Version number (strictly increasing, optional) double risk_exposure = roq::NaN; //!< Risk exposure double risk_exposure_change = roq::NaN; //!< Risk exposure change double traded_quantity = roq::NaN; //!< Quantity (total traded) std::chrono::nanoseconds round_trip_latency = {}; //!< Round-trip latency (interpretation depends on origin) std::string_view user; //!< User name (optional, only relevant for drop-copy) uint32_t strategy_id = {}; //!< Strategy identifier (optional) }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "order_ack"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::OrderAck const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(stream_id={}, )" R"(account="{}", )" R"(order_id={}, )" R"(exchange="{}", )" R"(symbol="{}", )" R"(side={}, )" R"(position_effect={}, )" R"(margin_mode={}, )" R"(quantity_type={}, )" R"(request_type={}, )" R"(origin={}, )" R"(request_status={}, )" R"(error={}, )" R"(text="{}", )" R"(request_id="{}", )" R"(external_account="{}", )" R"(external_order_id="{}", )" R"(client_order_id="{}", )" R"(quantity={}, )" R"(price={}, )" R"(stop_price={}, )" R"(leverage={}, )" R"(routing_id="{}", )" R"(version={}, )" R"(risk_exposure={}, )" R"(risk_exposure_change={}, )" R"(traded_quantity={}, )" R"(round_trip_latency={}, )" R"(user="{}", )" R"(strategy_id={})" R"(}})"sv, value.stream_id, value.account, value.order_id, value.exchange, value.symbol, value.side, value.position_effect, value.margin_mode, value.quantity_type, value.request_type, value.origin, value.request_status, value.error, value.text, value.request_id, value.external_account, value.external_order_id, value.client_order_id, value.quantity, value.price, value.stop_price, value.leverage, value.routing_id, value.version, value.risk_exposure, value.risk_exposure_change, value.traded_quantity, value.round_trip_latency, value.user, value.strategy_id); } }; ================================================ FILE: include/roq/order_cancel_policy.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include namespace roq { //! Enumeration of order cancel policies enum class OrderCancelPolicy : uint8_t { UNDEFINED = 0, MANAGED_ORDERS, //!< Cancel managed orders BY_ACCOUNT, //!< Cancel by account BY_STRATEGY, //!< Cancel by strategy }; } // namespace roq ================================================ FILE: include/roq/order_management.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include namespace roq { //! Enumeration of a specific order management style enum class OrderManagement : uint8_t { UNDEFINED = 0, FIX, //!< Client provides a globally unique routing_id }; } // namespace roq ================================================ FILE: include/roq/order_status.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include namespace roq { //! Last known order status received from exchange enum class OrderStatus : uint8_t { UNDEFINED = 0, SENT, //!< Order has been sent to exchange (no response has been received yet) ACCEPTED, //!< Order has been accepted by exchange and is not yet been activated SUSPENDED, //!< Order has been suspended and requires external action to re-activate WORKING, //!< Order is working and has not yet been completely filled STOPPED, //!< Order has guaranteed fill at as of yet unknown price COMPLETED, //!< Order has been completely filled EXPIRED, //!< Order has expired CANCELED, //!< Order has been canceled REJECTED, //!< Order has been rejected }; } // namespace roq ================================================ FILE: include/roq/order_type.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include namespace roq { //! Enumeration of order types enum class OrderType : uint8_t { UNDEFINED = 0, MARKET, //!< Market order LIMIT, //!< Limit order }; } // namespace roq ================================================ FILE: include/roq/order_update.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include #include #include "roq/event.hpp" #include "roq/execution_instruction.hpp" #include "roq/limits.hpp" #include "roq/liquidity.hpp" #include "roq/margin_mode.hpp" #include "roq/mask.hpp" #include "roq/name.hpp" #include "roq/order_status.hpp" #include "roq/order_type.hpp" #include "roq/position_effect.hpp" #include "roq/quantity_type.hpp" #include "roq/side.hpp" #include "roq/time_in_force.hpp" #include "roq/trace.hpp" #include "roq/update_type.hpp" namespace roq { //! Update relating to current status of an order struct ROQ_PUBLIC OrderUpdate final { uint16_t stream_id = {}; //!< Stream identifier std::string_view account; //!< Account name uint64_t order_id = {}; //!< Order identifier std::string_view exchange; //!< Exchange std::string_view symbol; //!< Symbol roq::Side side = {}; //!< Side roq::PositionEffect position_effect = {}; //!< Position effect roq::MarginMode margin_mode = {}; //!< Margin mode roq::QuantityType quantity_type = {}; //!< Type of quantity (requires ecxhange support) double max_show_quantity = roq::NaN; //!< Quantity visible to market (base currency, requires exchange support) roq::OrderType order_type = {}; //!< Order type roq::TimeInForce time_in_force = {}; //!< Time in force roq::Mask execution_instructions; //!< Execution instructions std::chrono::nanoseconds create_time_utc = {}; //!< Created timestamp (UTC) std::chrono::nanoseconds update_time_utc = {}; //!< Updated timestamp (UTC) std::string_view external_account; //!< External account name std::string_view external_order_id; //!< External order identifier std::string_view client_order_id; //!< Client order identifier roq::OrderStatus order_status = {}; //!< Order status double quantity = roq::NaN; //!< Quantity (base currency, total, indicative) double price = roq::NaN; //!< Price double stop_price = roq::NaN; //!< Stop price (depends on order_type and time_in_force) double leverage = roq::NaN; //!< Leverage (requires exchange support) double risk_exposure = roq::NaN; //!< Risk exposure double risk_exposure_change = roq::NaN; //!< Risk exposure change double remaining_quantity = roq::NaN; //!< Quantity (base currency, remaining) double traded_quantity = roq::NaN; //!< Quantity (base currency, total traded) double average_traded_price = roq::NaN; //!< Average price (total traded) double last_traded_quantity = roq::NaN; //!< Traded quantity (base currency, last trade) double last_traded_price = roq::NaN; //!< Traded price (last trade) roq::Liquidity last_liquidity = {}; //!< Liquidity indicator (last trade) std::string_view routing_id; //!< Routing identifier uint32_t max_request_version = {}; //!< Last request version uint32_t max_response_version = {}; //!< Last response version uint32_t max_accepted_version = {}; //!< Last accepted version roq::UpdateType update_type = {}; //!< Update type std::chrono::nanoseconds exchange_time_utc = {}; //!< Exchange timestamp, possibly from matching engine (UTC) uint64_t exchange_sequence = {}; //!< Exchange message sequence number std::chrono::nanoseconds sending_time_utc = {}; //!< Exchange sending timestamp (UTC) std::string_view user; //!< User name (optional, only relevant for drop-copy) uint32_t strategy_id = {}; //!< Strategy identifier (optional) }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "order_update"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::OrderUpdate const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(stream_id={}, )" R"(account="{}", )" R"(order_id={}, )" R"(exchange="{}", )" R"(symbol="{}", )" R"(side={}, )" R"(position_effect={}, )" R"(margin_mode={}, )" R"(quantity_type={}, )" R"(max_show_quantity={}, )" R"(order_type={}, )" R"(time_in_force={}, )" R"(execution_instructions={}, )" R"(create_time_utc={}, )" R"(update_time_utc={}, )" R"(external_account="{}", )" R"(external_order_id="{}", )" R"(client_order_id="{}", )" R"(order_status={}, )" R"(quantity={}, )" R"(price={}, )" R"(stop_price={}, )" R"(leverage={}, )" R"(risk_exposure={}, )" R"(risk_exposure_change={}, )" R"(remaining_quantity={}, )" R"(traded_quantity={}, )" R"(average_traded_price={}, )" R"(last_traded_quantity={}, )" R"(last_traded_price={}, )" R"(last_liquidity={}, )" R"(routing_id="{}", )" R"(max_request_version={}, )" R"(max_response_version={}, )" R"(max_accepted_version={}, )" R"(update_type={}, )" R"(exchange_time_utc={}, )" R"(exchange_sequence={}, )" R"(sending_time_utc={}, )" R"(user="{}", )" R"(strategy_id={})" R"(}})"sv, value.stream_id, value.account, value.order_id, value.exchange, value.symbol, value.side, value.position_effect, value.margin_mode, value.quantity_type, value.max_show_quantity, value.order_type, value.time_in_force, value.execution_instructions, value.create_time_utc, value.update_time_utc, value.external_account, value.external_order_id, value.client_order_id, value.order_status, value.quantity, value.price, value.stop_price, value.leverage, value.risk_exposure, value.risk_exposure_change, value.remaining_quantity, value.traded_quantity, value.average_traded_price, value.last_traded_quantity, value.last_traded_price, value.last_liquidity, value.routing_id, value.max_request_version, value.max_response_version, value.max_accepted_version, value.update_type, value.exchange_time_utc, value.exchange_sequence, value.sending_time_utc, value.user, value.strategy_id); } }; ================================================ FILE: include/roq/origin.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include namespace roq { //! Enumeration of origin types enum class Origin : uint8_t { UNDEFINED = 0, CLIENT, //!< Client GATEWAY, //!< Gateway BROKER, //!< Broker EXCHANGE, //!< Exchange }; } // namespace roq ================================================ FILE: include/roq/parameter.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include "roq/string_types.hpp" namespace roq { //! Represents a single parameter struct ROQ_PUBLIC Parameter final { roq::ParameterKey label; //!< Label uint32_t strategy_id = {}; //!< Strategy identifier (optional) roq::Account account; //!< Account name roq::Exchange exchange; //!< Exchange roq::Symbol symbol; //!< Symbol roq::ParameterValue value; //!< Value }; } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::Parameter const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(label="{}", )" R"(strategy_id={}, )" R"(account="{}", )" R"(exchange="{}", )" R"(symbol="{}", )" R"(value="{}")" R"(}})"sv, value.label, value.strategy_id, value.account, value.exchange, value.symbol, value.value); } }; ================================================ FILE: include/roq/parameters_update.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include #include #include "roq/event.hpp" #include "roq/name.hpp" #include "roq/parameter.hpp" #include "roq/trace.hpp" #include "roq/update_type.hpp" namespace roq { //! Update relating to parameters struct ROQ_PUBLIC ParametersUpdate final { std::span parameters; //!< List of parameters roq::UpdateType update_type = {}; //!< Update type std::string_view user; //!< User name (optional, only relevant for drop-copy) }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "parameters_update"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::ParametersUpdate const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(parameters=[{}], )" R"(update_type={}, )" R"(user="{}")" R"(}})"sv, fmt::join(value.parameters, ", "sv), value.update_type, value.user); } }; ================================================ FILE: include/roq/portfolio.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include #include #include #include #include "roq/event.hpp" #include "roq/name.hpp" #include "roq/position.hpp" #include "roq/trace.hpp" #include "roq/update_type.hpp" #include "roq/uuid.hpp" namespace roq { //! Portfolio struct ROQ_PUBLIC Portfolio final { std::string_view user; //!< User (optional) uint32_t strategy_id = {}; //!< Strategy identifier (optional) std::string_view account; //!< Account name std::span positions; //!< Position updates roq::UpdateType update_type = {}; //!< Update type std::chrono::nanoseconds exchange_time_utc = {}; //!< Exchange timestamp, possibly from matching engine (UTC) roq::UUID session_id = {}; //!< Reference (UUID) uint64_t seqno = {}; //!< Reference (sequencing) }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "portfolio"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::Portfolio const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(user="{}", )" R"(strategy_id={}, )" R"(account="{}", )" R"(positions=[{}], )" R"(update_type={}, )" R"(exchange_time_utc={}, )" R"(session_id={}, )" R"(seqno={})" R"(}})"sv, value.user, value.strategy_id, value.account, fmt::join(value.positions, ", "sv), value.update_type, value.exchange_time_utc, value.session_id, value.seqno); } }; ================================================ FILE: include/roq/portfolio_update.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include #include #include #include #include "roq/event.hpp" #include "roq/name.hpp" #include "roq/position.hpp" #include "roq/trace.hpp" #include "roq/update_type.hpp" namespace roq { //! Portfolio update struct ROQ_PUBLIC PortfolioUpdate final { std::string_view user; //!< User (optional) uint32_t strategy_id = {}; //!< Strategy identifier (optional) std::string_view account; //!< Account name std::span positions; //!< Position updates roq::UpdateType update_type = {}; //!< Update type std::chrono::nanoseconds exchange_time_utc = {}; //!< Exchange timestamp, possibly from matching engine (UTC) }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "portfolio_update"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::PortfolioUpdate const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(user="{}", )" R"(strategy_id={}, )" R"(account="{}", )" R"(positions=[{}], )" R"(update_type={}, )" R"(exchange_time_utc={})" R"(}})"sv, value.user, value.strategy_id, value.account, fmt::join(value.positions, ", "sv), value.update_type, value.exchange_time_utc); } }; ================================================ FILE: include/roq/position.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include "roq/limits.hpp" #include "roq/string_types.hpp" namespace roq { //! Position struct ROQ_PUBLIC Position final { roq::Exchange exchange; //!< Exchange roq::Symbol symbol; //!< Symbol double position = 0.0; //!< Position (quantity) double profit_loss_amount = 0.0; //!< P&L (internal) roq::Currency profit_loss_currency; //!< P&L currency }; } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::Position const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(exchange="{}", )" R"(symbol="{}", )" R"(position={}, )" R"(profit_loss_amount={}, )" R"(profit_loss_currency="{}")" R"(}})"sv, value.exchange, value.symbol, value.position, value.profit_loss_amount, value.profit_loss_currency); } }; ================================================ FILE: include/roq/position_effect.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include namespace roq { //! Enumeration of position effect types enum class PositionEffect : uint8_t { UNDEFINED = 0, OPEN, //!< Open position CLOSE, //!< Close position }; } // namespace roq ================================================ FILE: include/roq/position_update.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include #include #include "roq/event.hpp" #include "roq/limits.hpp" #include "roq/margin_mode.hpp" #include "roq/name.hpp" #include "roq/trace.hpp" #include "roq/update_type.hpp" namespace roq { //! Update relating to current position for a symbol/side/account struct ROQ_PUBLIC PositionUpdate final { uint16_t stream_id = {}; //!< Stream identifier std::string_view account; //!< Account name std::string_view exchange; //!< Exchange std::string_view symbol; //!< Symbol roq::MarginMode margin_mode = {}; //!< Margin mode std::string_view external_account; //!< External account name double long_quantity = roq::NaN; //!< Current long position (absolute) double short_quantity = roq::NaN; //!< Current short position (absolute) roq::UpdateType update_type = {}; //!< Update type std::chrono::nanoseconds exchange_time_utc = {}; //!< Exchange timestamp, possibly from matching engine (UTC) uint64_t exchange_sequence = {}; //!< Exchange message sequence number std::chrono::nanoseconds sending_time_utc = {}; //!< Exchange sending timestamp (UTC) }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "position_update"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::PositionUpdate const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(stream_id={}, )" R"(account="{}", )" R"(exchange="{}", )" R"(symbol="{}", )" R"(margin_mode={}, )" R"(external_account="{}", )" R"(long_quantity={}, )" R"(short_quantity={}, )" R"(update_type={}, )" R"(exchange_time_utc={}, )" R"(exchange_sequence={}, )" R"(sending_time_utc={})" R"(}})"sv, value.stream_id, value.account, value.exchange, value.symbol, value.margin_mode, value.external_account, value.long_quantity, value.short_quantity, value.update_type, value.exchange_time_utc, value.exchange_sequence, value.sending_time_utc); } }; ================================================ FILE: include/roq/precision.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include namespace roq { //! Enumeration of decimal precision (digits) enum class Precision : uint8_t { UNDEFINED = 0, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, }; } // namespace roq ================================================ FILE: include/roq/precision_2.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ #pragma once #include "roq/compat.hpp" #include #include #include "roq/limits.hpp" #include "roq/precision.hpp" namespace roq { //! Numerical precision // XXX TODO rename struct ROQ_PUBLIC Precision2 final { double increment = NaN; Precision precision = {}; }; } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::Precision2 const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(increment={}, )" R"(precision={})" R"(}})"sv, value.increment, value.precision); } }; ================================================ FILE: include/roq/priority.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include namespace roq { //! Enumeration of priority enum class Priority : uint8_t { UNDEFINED = 0, PRIMARY, //!< Primary SECONDARY, //!< Secondary }; } // namespace roq ================================================ FILE: include/roq/protocol.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include namespace roq { //! Enumeration of protocol types (layer 7) enum class Protocol : uint8_t { UNDEFINED = 0, FIX, //!< FIX WS, //!< Web-Socket HTTP, //!< HTTP (REST) SBE, //!< Simple Binary Encoding ROQ, //!< UDP messaging }; } // namespace roq ================================================ FILE: include/roq/quality_of_service.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include namespace roq { //! Enumeration of quality of service enum class QualityOfService : uint8_t { UNDEFINED = 0, IMMEDIATE, //!< Immediate CRITICAL, //!< Critical }; } // namespace roq ================================================ FILE: include/roq/quantity_type.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include namespace roq { //! Enumeration of the type of quantity enum class QuantityType : uint8_t { UNDEFINED = 0, UNITS, //!< Units CONTRACTS, //!< Contracts }; } // namespace roq ================================================ FILE: include/roq/quote.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include "roq/execution_instruction.hpp" #include "roq/limits.hpp" #include "roq/mask.hpp" #include "roq/string_types.hpp" namespace roq { //! Quote struct ROQ_PUBLIC Quote final { uint32_t quote_entry_id = {}; //!< Quote Entry ID roq::Exchange exchange; //!< Exchange roq::Symbol symbol; //!< Symbol double bid_price = roq::NaN; //!< Bid price level double bid_quantity = {}; //!< Total quantity available at bid double ask_price = roq::NaN; //!< Ask price level double ask_quantity = {}; //!< Total quantity available at ask uint16_t quote_set_id = {}; //!< Quote Set ID (can be used to group and cancel quotes) roq::Mask execution_instructions; //!< Execution instructions }; } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::Quote const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(quote_entry_id={}, )" R"(exchange="{}", )" R"(symbol="{}", )" R"(bid_price={}, )" R"(bid_quantity={}, )" R"(ask_price={}, )" R"(ask_quantity={}, )" R"(quote_set_id={}, )" R"(execution_instructions={})" R"(}})"sv, value.quote_entry_id, value.exchange, value.symbol, value.bid_price, value.bid_quantity, value.ask_price, value.ask_quantity, value.quote_set_id, value.execution_instructions); } }; ================================================ FILE: include/roq/rate_limit.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include #include "roq/rate_limit_type.hpp" namespace roq { //! Rate-limit struct ROQ_PUBLIC RateLimit final { roq::RateLimitType type = {}; //!< Type std::chrono::seconds period = {}; //!< Monitor period std::chrono::seconds end_time_utc = {}; //!< End of current period uint32_t limit = {}; //!< Limit uint32_t value = {}; //!< Value }; } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::RateLimit const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(type={}, )" R"(period={}, )" R"(end_time_utc={}, )" R"(limit={}, )" R"(value={})" R"(}})"sv, value.type, value.period, value.end_time_utc, value.limit, value.value); } }; ================================================ FILE: include/roq/rate_limit_trigger.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include #include #include #include #include "roq/buffer_capacity.hpp" #include "roq/event.hpp" #include "roq/name.hpp" #include "roq/origin.hpp" #include "roq/rate_limit_type.hpp" #include "roq/string_types.hpp" #include "roq/trace.hpp" namespace roq { //! Rate-limit trigger struct ROQ_PUBLIC RateLimitTrigger final { std::string_view name; //!< Configuration name roq::Origin origin = {}; //!< Origin roq::RateLimitType type = {}; //!< Rate-limit type std::span users; //!< Sorted list of users being affected (empty list means: all) std::span accounts; //!< Sorted list of accounts being affected (empty list means: all) std::chrono::nanoseconds ban_expires = {}; //!< System time when ban expires (zero means: ban is no longer effective) std::string_view triggered_by; //!< Trigger activated by this user roq::BufferCapacity buffer_capacity = {}; //!< Buffer capacity (indicator for how full or empty the buffer is) uint32_t remaining_requests = {}; //!< The buffer becomes full if this many requests are sent instantly }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "rate_limit_trigger"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::RateLimitTrigger const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(name="{}", )" R"(origin={}, )" R"(type={}, )" R"(users=[{}], )" R"(accounts=[{}], )" R"(ban_expires={}, )" R"(triggered_by="{}", )" R"(buffer_capacity={}, )" R"(remaining_requests={})" R"(}})"sv, value.name, value.origin, value.type, fmt::join(value.users, ", "sv), fmt::join(value.accounts, ", "sv), value.ban_expires, value.triggered_by, value.buffer_capacity, value.remaining_requests); } }; ================================================ FILE: include/roq/rate_limit_type.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include namespace roq { //! Rate limit type enum class RateLimitType : uint8_t { UNDEFINED = 0, ORDER_ACTION, //!< Any order action: create, modify, cancel, etc. CREATE_ORDER, //!< Only create order REQUEST, //!< Requests (count) REQUEST_WEIGHT, //!< Requests (weighted) }; } // namespace roq ================================================ FILE: include/roq/rate_limits_update.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include #include #include "roq/event.hpp" #include "roq/name.hpp" #include "roq/origin.hpp" #include "roq/rate_limit.hpp" #include "roq/trace.hpp" namespace roq { //! Rate-limits update struct ROQ_PUBLIC RateLimitsUpdate final { uint16_t stream_id = {}; //!< Stream identifier std::string_view account; //!< Account name roq::Origin origin = {}; //!< Origin std::span rate_limits; //!< Rate-limits updates }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "rate_limits_update"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::RateLimitsUpdate const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(stream_id={}, )" R"(account="{}", )" R"(origin={}, )" R"(rate_limits=[{}])" R"(}})"sv, value.stream_id, value.account, value.origin, fmt::join(value.rate_limits, ", "sv)); } }; ================================================ FILE: include/roq/ready.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include "roq/event.hpp" #include "roq/name.hpp" #include "roq/trace.hpp" namespace roq { //! Marks the end of the initial download phase struct ROQ_PUBLIC Ready final {}; template <> constexpr std::string_view get_name() { using namespace std::literals; return "ready"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::Ready const &, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), R"({{}})"sv); } }; ================================================ FILE: include/roq/reference_data.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include #include #include #include #include "roq/event.hpp" #include "roq/limits.hpp" #include "roq/name.hpp" #include "roq/option_type.hpp" #include "roq/security_type.hpp" #include "roq/tick_size_step.hpp" #include "roq/trace.hpp" namespace roq { //! Update relating to the reference data for a symbol struct ROQ_PUBLIC ReferenceData final { uint16_t stream_id = {}; //!< Stream identifier std::string_view exchange; //!< Exchange std::string_view symbol; //!< Symbol std::string_view description; //!< Description roq::SecurityType security_type = {}; //!< Security type int32_t external_security_id = {}; //!< Security ID std::string_view cfi_code; //!< CFI code std::string_view base_currency; //!< Base currency std::string_view quote_currency; //!< Quote currency std::string_view settlement_currency; //!< Settlement currency std::string_view margin_currency; //!< Margin currency std::string_view commission_currency; //!< Commission currency double tick_size = roq::NaN; //!< Minimum price increment std::span tick_size_steps; //!< List of tick size steps double multiplier = roq::NaN; //!< Multiplier (notional) double min_notional = roq::NaN; //!< Minimum notional (price * quantity) double min_trade_vol = roq::NaN; //!< Minimum trade volume double max_trade_vol = roq::NaN; //!< Maximum trade volume double trade_vol_step_size = roq::NaN; //!< Trade volume step size roq::OptionType option_type = {}; //!< Option type std::string_view strike_currency; //!< Strike currency double strike_price = roq::NaN; //!< Strike price std::string_view underlying; //!< Underlying instrument std::string_view time_zone; //!< Time-zone std::chrono::days issue_date = {}; //!< Issue date std::chrono::days settlement_date = {}; //!< Settlement date std::chrono::seconds expiry_datetime = {}; //!< Expiry datetime std::chrono::seconds expiry_datetime_utc = {}; //!< Expiry datetime std::chrono::nanoseconds exchange_time_utc = {}; //!< Exchange timestamp, possibly from matching engine (UTC) uint64_t exchange_sequence = {}; //!< Exchange message sequence number std::chrono::nanoseconds sending_time_utc = {}; //!< Exchange sending timestamp (UTC) bool discard = false; //!< Discard market data updates? }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "reference_data"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::ReferenceData const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(stream_id={}, )" R"(exchange="{}", )" R"(symbol="{}", )" R"(description="{}", )" R"(security_type={}, )" R"(external_security_id={}, )" R"(cfi_code="{}", )" R"(base_currency="{}", )" R"(quote_currency="{}", )" R"(settlement_currency="{}", )" R"(margin_currency="{}", )" R"(commission_currency="{}", )" R"(tick_size={}, )" R"(tick_size_steps=[{}], )" R"(multiplier={}, )" R"(min_notional={}, )" R"(min_trade_vol={}, )" R"(max_trade_vol={}, )" R"(trade_vol_step_size={}, )" R"(option_type={}, )" R"(strike_currency="{}", )" R"(strike_price={}, )" R"(underlying="{}", )" R"(time_zone="{}", )" R"(issue_date={}, )" R"(settlement_date={}, )" R"(expiry_datetime={}, )" R"(expiry_datetime_utc={}, )" R"(exchange_time_utc={}, )" R"(exchange_sequence={}, )" R"(sending_time_utc={}, )" R"(discard={})" R"(}})"sv, value.stream_id, value.exchange, value.symbol, value.description, value.security_type, value.external_security_id, value.cfi_code, value.base_currency, value.quote_currency, value.settlement_currency, value.margin_currency, value.commission_currency, value.tick_size, fmt::join(value.tick_size_steps, ", "sv), value.multiplier, value.min_notional, value.min_trade_vol, value.max_trade_vol, value.trade_vol_step_size, value.option_type, value.strike_currency, value.strike_price, value.underlying, value.time_zone, value.issue_date, value.settlement_date, value.expiry_datetime, value.expiry_datetime_utc, value.exchange_time_utc, value.exchange_sequence, value.sending_time_utc, value.discard); } }; ================================================ FILE: include/roq/remove_routes.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include #include "roq/event.hpp" #include "roq/name.hpp" #include "roq/trace.hpp" namespace roq { //! Remove route(s) struct ROQ_PUBLIC RemoveRoutes final { std::span strategy_ids; //!< List of strategy_id's to remove }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "remove_routes"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::RemoveRoutes const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(strategy_ids=[{}])" R"(}})"sv, fmt::join(value.strategy_ids, ", "sv)); } }; ================================================ FILE: include/roq/request_id_type.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include namespace roq { //! Request identifier enum class RequestIdType : uint8_t { UNDEFINED = 0, BASE64, //!< Base64 encoded BASE32, //!< Base32 encoded SIMPLE, //!< Simple encoded UUID, //!< UUID encoded HEX16, //!< Hex encoded (len=16) HEX32, //!< Hex encoded (len=32) }; } // namespace roq ================================================ FILE: include/roq/request_status.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include namespace roq { //! Enumeration of request status types enum class RequestStatus : uint8_t { UNDEFINED = 0, FORWARDED, //!< Forwarded to broker/exchange ACCEPTED, //!< Accepted by broker/exchange REJECTED, //!< Rejected by broker/exchange DISCONNECTED, //!< Disconnected TIMEOUT, //!< Timed out FAILED, //!< Generic failure ERROR, //!< Generic error, possibly parse error ENQUEUED, //!< Enqueued for later release time to broker/exchange }; } // namespace roq ================================================ FILE: include/roq/request_type.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include namespace roq { //! Enumeration of request types enum class RequestType : uint8_t { UNDEFINED = 0, CREATE_ORDER, //!< Create order MODIFY_ORDER, //!< Modify order CANCEL_ORDER, //!< Cancel order }; } // namespace roq ================================================ FILE: include/roq/risk_limit.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include "roq/limits.hpp" #include "roq/string_types.hpp" namespace roq { //! Risk limit for {exchange, symbol} struct ROQ_PUBLIC RiskLimit final { roq::Exchange exchange; //!< Exchange roq::Symbol symbol; //!< Symbol double long_position = 0.0; //!< Position (long) double short_position = 0.0; //!< Position (short) double long_position_limit = roq::NaN; //!< Position limit (long) double short_position_limit = roq::NaN; //!< Position limit (short) double long_risk_exposure_limit = roq::NaN; //!< Risk exposure limit (long) double short_risk_exposure_limit = roq::NaN; //!< Risk exposure limit (short) bool allow_netting = false; //!< Allow netting? }; } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::RiskLimit const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(exchange="{}", )" R"(symbol="{}", )" R"(long_position={}, )" R"(short_position={}, )" R"(long_position_limit={}, )" R"(short_position_limit={}, )" R"(long_risk_exposure_limit={}, )" R"(short_risk_exposure_limit={}, )" R"(allow_netting={})" R"(}})"sv, value.exchange, value.symbol, value.long_position, value.short_position, value.long_position_limit, value.short_position_limit, value.long_risk_exposure_limit, value.short_risk_exposure_limit, value.allow_netting); } }; ================================================ FILE: include/roq/risk_limits.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include #include #include "roq/event.hpp" #include "roq/name.hpp" #include "roq/risk_limit.hpp" #include "roq/trace.hpp" #include "roq/uuid.hpp" namespace roq { //! Risk limits (receive) !!! EXPERIMENTAL !!! struct ROQ_PUBLIC RiskLimits final { std::string_view user; //!< User name (optional) uint32_t strategy_id = {}; //!< Strategy identifier (optional) std::string_view account; //!< Account name (optional) std::span limits; //!< Risk limits per {exchange, symbol} roq::UUID session_id = {}; //!< Reference (UUID) uint64_t seqno = {}; //!< Reference (sequencing) }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "risk_limits"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::RiskLimits const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(user="{}", )" R"(strategy_id={}, )" R"(account="{}", )" R"(limits=[{}], )" R"(session_id={}, )" R"(seqno={})" R"(}})"sv, value.user, value.strategy_id, value.account, fmt::join(value.limits, ", "sv), value.session_id, value.seqno); } }; ================================================ FILE: include/roq/risk_limits_update.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include #include #include "roq/event.hpp" #include "roq/name.hpp" #include "roq/risk_limit.hpp" #include "roq/trace.hpp" #include "roq/update_type.hpp" namespace roq { //! Risk limits (publish) !!! EXPERIMENTAL !!! struct ROQ_PUBLIC RiskLimitsUpdate final { std::string_view user; //!< User name (optional) uint32_t strategy_id = {}; //!< Strategy identifier (optional) std::string_view account; //!< Account name (optional) std::span limits; //!< Risk limits per {exchange, symbol} roq::UpdateType update_type = {}; //!< Update type }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "risk_limits_update"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::RiskLimitsUpdate const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(user="{}", )" R"(strategy_id={}, )" R"(account="{}", )" R"(limits=[{}], )" R"(update_type={})" R"(}})"sv, value.user, value.strategy_id, value.account, fmt::join(value.limits, ", "sv), value.update_type); } }; ================================================ FILE: include/roq/route.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include "roq/route_request_status.hpp" namespace roq { //! Route struct ROQ_PUBLIC Route final { uint32_t strategy_id = {}; //!< Strategy identifier (optional) roq::RouteRequestStatus status = {}; //!< Response to the request }; } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::Route const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(strategy_id={}, )" R"(status={})" R"(}})"sv, value.strategy_id, value.status); } }; ================================================ FILE: include/roq/route_ack.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include #include #include "roq/event.hpp" #include "roq/name.hpp" #include "roq/route.hpp" #include "roq/trace.hpp" namespace roq { //! Response to route request struct ROQ_PUBLIC RouteAck final { std::span routes; //!< Response per strategy_id std::string_view user; //!< User name (optional, only relevant for drop-copy) }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "route_ack"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::RouteAck const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(routes=[{}], )" R"(user="{}")" R"(}})"sv, fmt::join(value.routes, ", "sv), value.user); } }; ================================================ FILE: include/roq/route_request_status.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include namespace roq { //! Route request status enum class RouteRequestStatus : uint8_t { UNDEFINED = 0, CREATED, //!< Created REMOVED, //!< Removed REJECTED, //!< Rejected }; } // namespace roq ================================================ FILE: include/roq/routing.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include "roq/event.hpp" #include "roq/name.hpp" #include "roq/quality_of_service.hpp" #include "roq/trace.hpp" namespace roq { //! Routing struct ROQ_PUBLIC Routing final { uint8_t source = {}; //!< source bool is_last = false; //!< is last? roq::QualityOfService quality_of_service = {}; //!< quality of service }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "routing"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::Routing const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(source={}, )" R"(is_last={}, )" R"(quality_of_service={})" R"(}})"sv, value.source, value.is_last, value.quality_of_service); } }; ================================================ FILE: include/roq/security_type.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include namespace roq { //! Enumeration of security/instrument types enum class SecurityType : uint8_t { UNDEFINED = 0, SPOT, //!< Spot FUTURES, //!< Futures OPTION, //!< Option SWAP, //!< Perpetuals (like a futures contract but without an expiration date) }; } // namespace roq ================================================ FILE: include/roq/service_update.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include "roq/connection_status.hpp" #include "roq/event.hpp" #include "roq/name.hpp" #include "roq/state.hpp" #include "roq/trace.hpp" #include "roq/update_type.hpp" namespace roq { //! Service update struct ROQ_PUBLIC ServiceUpdate final { std::string_view user; //!< Service name (optional) std::string_view description; //!< Service description roq::ConnectionStatus connection_status = {}; //!< Service connection status roq::State state = {}; //!< Service state roq::UpdateType update_type = {}; //!< Update type }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "service_update"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::ServiceUpdate const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(user="{}", )" R"(description="{}", )" R"(connection_status={}, )" R"(state={}, )" R"(update_type={})" R"(}})"sv, value.user, value.description, value.connection_status, value.state, value.update_type); } }; ================================================ FILE: include/roq/side.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include namespace roq { //! Enumeration of the side of a trade enum class Side : uint8_t { UNDEFINED = 0, BUY, //!< Buy SELL, //!< Sell }; } // namespace roq ================================================ FILE: include/roq/start.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include "roq/event.hpp" #include "roq/name.hpp" #include "roq/trace.hpp" namespace roq { //! Signals a start event struct ROQ_PUBLIC Start final {}; template <> constexpr std::string_view get_name() { using namespace std::literals; return "start"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::Start const &, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), R"({{}})"sv); } }; ================================================ FILE: include/roq/state.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include namespace roq { //! Enumeration of target state enum class State : uint8_t { UNDEFINED = 0, ENABLED, //!< Enabled DISABLED, //!< Disabled }; } // namespace roq ================================================ FILE: include/roq/statistics.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include #include "roq/limits.hpp" #include "roq/statistics_type.hpp" namespace roq { //! Represents a single statistic struct ROQ_PUBLIC Statistics final { roq::StatisticsType type = {}; //!< Statistics type double value = roq::NaN; //!< Value std::chrono::seconds begin_time_utc = {}; //!< Sample period begin time std::chrono::seconds end_time_utc = {}; //!< Sample period end time }; } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::Statistics const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(type={}, )" R"(value={}, )" R"(begin_time_utc={}, )" R"(end_time_utc={})" R"(}})"sv, value.type, value.value, value.begin_time_utc, value.end_time_utc); } }; ================================================ FILE: include/roq/statistics_type.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include namespace roq { //! Enumeration of a statistics type enum class StatisticsType : uint8_t { UNDEFINED = 0, OPEN_PRICE, //!< Open price SETTLEMENT_PRICE, //!< Settlement price CLOSE_PRICE, //!< Close price OPEN_INTEREST, //!< Open interest PRE_OPEN_INTEREST, //!< Pre-open interest PRE_SETTLEMENT_PRICE, //!< Pre-settlement price PRE_CLOSE_PRICE, //!< Pre-close price HIGHEST_TRADED_PRICE, //!< Highest traded price LOWEST_TRADED_PRICE, //!< Lowest traded price UPPER_LIMIT_PRICE, //!< Upper limit price LOWER_LIMIT_PRICE, //!< Lower limit price INDEX_VALUE, //!< Index value MARGIN_RATE, //!< Margin rate FUNDING_RATE, //!< Funding rate FUNDING_RATE_PREDICTION, //!< Funding rate prediction TRADE_VOLUME, //!< Trade volume }; } // namespace roq ================================================ FILE: include/roq/statistics_update.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include #include #include #include #include "roq/event.hpp" #include "roq/name.hpp" #include "roq/statistics.hpp" #include "roq/trace.hpp" #include "roq/update_type.hpp" namespace roq { //! Update relating to statistics published by the exchange struct ROQ_PUBLIC StatisticsUpdate final { uint16_t stream_id = {}; //!< Stream identifier std::string_view exchange; //!< Exchange std::string_view symbol; //!< Symbol std::span statistics; //!< List of statistics roq::UpdateType update_type = {}; //!< Update type std::chrono::nanoseconds exchange_time_utc = {}; //!< Exchange timestamp, possibly from matching engine (UTC) uint64_t exchange_sequence = {}; //!< Exchange message sequence number std::chrono::nanoseconds sending_time_utc = {}; //!< Exchange sending timestamp (UTC) }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "statistics_update"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::StatisticsUpdate const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(stream_id={}, )" R"(exchange="{}", )" R"(symbol="{}", )" R"(statistics=[{}], )" R"(update_type={}, )" R"(exchange_time_utc={}, )" R"(exchange_sequence={}, )" R"(sending_time_utc={})" R"(}})"sv, value.stream_id, value.exchange, value.symbol, fmt::join(value.statistics, ", "sv), value.update_type, value.exchange_time_utc, value.exchange_sequence, value.sending_time_utc); } }; ================================================ FILE: include/roq/stop.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include "roq/event.hpp" #include "roq/name.hpp" #include "roq/trace.hpp" namespace roq { //! Signals a stop event struct ROQ_PUBLIC Stop final {}; template <> constexpr std::string_view get_name() { using namespace std::literals; return "stop"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::Stop const &, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), R"({{}})"sv); } }; ================================================ FILE: include/roq/strategy_update.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include "roq/event.hpp" #include "roq/name.hpp" #include "roq/state.hpp" #include "roq/trace.hpp" #include "roq/update_type.hpp" namespace roq { //! Strategy update struct ROQ_PUBLIC StrategyUpdate final { std::string_view user; //!< Service name uint32_t strategy_id = {}; //!< Strategy ID std::string_view description; //!< Strategy description roq::State state = {}; //!< Strategy state roq::UpdateType update_type = {}; //!< Update type }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "strategy_update"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::StrategyUpdate const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(user="{}", )" R"(strategy_id={}, )" R"(description="{}", )" R"(state={}, )" R"(update_type={})" R"(}})"sv, value.user, value.strategy_id, value.description, value.state, value.update_type); } }; ================================================ FILE: include/roq/stream_status.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include "roq/connection_status.hpp" #include "roq/encoding.hpp" #include "roq/event.hpp" #include "roq/mask.hpp" #include "roq/name.hpp" #include "roq/priority.hpp" #include "roq/protocol.hpp" #include "roq/support_type.hpp" #include "roq/trace.hpp" #include "roq/transport.hpp" namespace roq { //! Update relating to current stream status struct ROQ_PUBLIC StreamStatus final { uint16_t stream_id = {}; //!< Stream identifier std::string_view account; //!< Account name roq::Mask supports; //!< Supported update types roq::Transport transport = {}; //!< Transport type (layer 4) roq::Protocol protocol = {}; //!< Communication protocol (layer 7) roq::Mask encoding; //!< Message encoding roq::Priority priority = {}; //!< Priority roq::ConnectionStatus connection_status = {}; //!< Connection status (when applicable) std::string_view reason; //!< Reason (last change) std::string_view interface; //!< Local network interface std::string_view authority; //!< URL authority (network end-point) std::string_view path; //!< URL path std::string_view proxy; //!< Network proxy }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "stream_status"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::StreamStatus const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(stream_id={}, )" R"(account="{}", )" R"(supports={}, )" R"(transport={}, )" R"(protocol={}, )" R"(encoding={}, )" R"(priority={}, )" R"(connection_status={}, )" R"(reason="{}", )" R"(interface="{}", )" R"(authority="{}", )" R"(path="{}", )" R"(proxy="{}")" R"(}})"sv, value.stream_id, value.account, value.supports, value.transport, value.protocol, value.encoding, value.priority, value.connection_status, value.reason, value.interface, value.authority, value.path, value.proxy); } }; ================================================ FILE: include/roq/string.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ #pragma once #include "roq/compat.hpp" #include #include #include #include #include #include #include #include "roq/exceptions.hpp" namespace roq { // fixed length string buffer //! A fixed-length string buffer with automatic conversion to/from //! \ref std::string_view. /*! * This is useful for managing fixed length arrays as if they were string-like. * Typically used to avoid heap allocations, e.g. stack allocated structs used * for messaging. * This is a higher level abstraction than \ref std::array to provide * more * string-specific features. * The interface is a subset of \ref std::string and \ref std::string_view. */ template struct ROQ_PACKED String { using value_type = char; constexpr String() = default; constexpr String(String &&) noexcept = default; constexpr String(String const &) = default; constexpr String &operator=(String &&) noexcept = default; constexpr String &operator=(String const &) = default; constexpr String(std::string_view const &text) { copy(text); } constexpr String(std::string const &text) { copy(text); } constexpr String(value_type const *text) : String{std::string_view{text}} {} constexpr String &operator=(std::string_view const &text) { copy(text); return *this; } constexpr String &operator=(std::string const &text) { copy(text); return *this; } template constexpr auto operator<=>(String const &rhs) const { return static_cast(*this) <=> static_cast(rhs); } template constexpr bool operator==(String const &rhs) const { return (*this) == static_cast(rhs); } constexpr auto operator<=>(std::string_view const &rhs) const { return static_cast(*this) <=> rhs; } constexpr bool operator==(std::string_view const &rhs) const { return static_cast(*this) == rhs; } constexpr value_type &operator[](size_t index) { return buffer_[index]; } constexpr value_type operator[](size_t index) const { return buffer_[index]; } constexpr std::size_t size() const { return N; } constexpr std::size_t length() const { auto tmp = static_cast(static_cast(buffer_[N - 1])); if (buffer_[N - 2]) { return N - (tmp != 0 ? 0 : 1); } return tmp; } constexpr bool empty() const { return length() == 0; } constexpr value_type const *data() const { return std::data(buffer_); } constexpr operator std::string_view() const { return {data(), length()}; } constexpr void clear() { // note! // we prefer to clear the entire buffer (for security reasons) // even though it would be enough to only set the first element std::fill(std::begin(buffer_), std::end(buffer_), '\0'); } constexpr void push_back(value_type value) { using namespace std::literals; auto len = length(); if (N <= len) [[unlikely]] { throw LengthError{"String buffer is full"sv}; } buffer_[len] = value; set_length(++len); } protected: constexpr value_type *data() { return std::data(buffer_); } constexpr void copy(std::string_view const &text) { using namespace std::literals; auto len = std::size(text); if (N < len) [[unlikely]] { throw LengthError{R"(can't copy: len(text="{}")={} exceeds size={})"sv, text, len, N}; } std::copy(std::begin(text), std::end(text), std::begin(buffer_)); set_length(len); } constexpr void set_length(size_t len) { if (len < N) { size_t last; if (len < (N - 1)) { buffer_[N - 2] = {}; last = len; } else { last = {}; } buffer_[N - 1] = static_cast(last); } } private: std::array buffer_ = {}; }; } // namespace roq template struct fmt::formatter> { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::String const &value, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), "{}"sv, static_cast(value)); } }; ================================================ FILE: include/roq/string_types.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ #pragma once #include #include "roq/string.hpp" namespace roq { namespace detail { static constexpr size_t const MAX_LENGTH_SOURCE = 16; static constexpr size_t const MAX_LENGTH_USER = 16; static constexpr size_t const MAX_LENGTH_ACCOUNT = 32; static constexpr size_t const MAX_LENGTH_EXCHANGE = 32; static constexpr size_t const MAX_LENGTH_SYMBOL = 64; static constexpr size_t const MAX_LENGTH_CURRENCY = 32; static constexpr size_t const MAX_LENGTH_CFI_CODE = 6; static constexpr size_t const MAX_LENGTH_MBO_ORDER_ID = 36; // note! UUID static constexpr size_t const MAX_LENGTH_REQUEST_TEMPLATE = 16; static constexpr size_t const MAX_LENGTH_EXTERNAL_ACCOUNT = 64; static constexpr size_t const MAX_LENGTH_EXTERNAL_ORDER_ID = 64; static constexpr size_t const MAX_LENGTH_EXTERNAL_TRADE_ID = 40; static constexpr size_t const MAX_LENGTH_ROUTING_ID = 64; static constexpr size_t const MAX_LENGTH_CL_ORD_ID = 36; static constexpr size_t const MAX_LENGTH_REQUEST_ID = 36; static constexpr size_t const MAX_LENGTH_LABEL = 32; static constexpr size_t const MAX_LENGTH_MEASUREMENT_KEY = 8; static constexpr size_t const MAX_LENGTH_MATRIX_KEY = 8; static constexpr size_t const MAX_LENGTH_DESCRIPTION = 128; static constexpr size_t const MAX_LENGTH_TIME_ZONE = 32; static constexpr size_t const MAX_LENGTH_PARAMETER_KEY = 32; static constexpr size_t const MAX_LENGTH_PARAMETER_VALUE = 32; } // namespace detail struct ROQ_PUBLIC Source final : public String { using String::String; }; struct ROQ_PUBLIC User final : public String { using String::String; }; struct ROQ_PUBLIC Account final : public String { using String::String; }; struct ROQ_PUBLIC Exchange final : public String { using String::String; }; struct ROQ_PUBLIC Symbol final : public String { using String::String; }; struct ROQ_PUBLIC Currency final : public String { using String::String; }; struct ROQ_PUBLIC CFICode final : public String { using String::String; }; struct ROQ_PUBLIC MBOOrderId final : public String { using String::String; }; struct ROQ_PUBLIC RequestTemplate final : public String { using String::String; }; struct ROQ_PUBLIC ExternalAccount final : public String { using String::String; }; struct ROQ_PUBLIC ExternalOrderId final : public String { using String::String; }; struct ROQ_PUBLIC ExternalTradeId final : public String { using String::String; }; struct ROQ_PUBLIC RoutingId final : public String { using String::String; }; struct ROQ_PUBLIC ClOrdId final : public String { using String::String; }; struct ROQ_PUBLIC RequestId final : public String { using String::String; }; struct ROQ_PUBLIC Label final : public String { using String::String; }; struct ROQ_PUBLIC MeasurementKey final : public String { using String::String; }; struct ROQ_PUBLIC MatrixKey final : public String { using String::String; }; struct ROQ_PUBLIC Description final : public String { using String::String; }; struct ROQ_PUBLIC TimeZone final : public String { using String::String; }; struct ROQ_PUBLIC ParameterKey final : public String { using String::String; }; struct ROQ_PUBLIC ParameterValue final : public String { using String::String; }; // validate static_assert(sizeof(Source) == detail::MAX_LENGTH_USER); static_assert(sizeof(User) == detail::MAX_LENGTH_USER); static_assert(sizeof(Account) == detail::MAX_LENGTH_ACCOUNT); static_assert(sizeof(Exchange) == detail::MAX_LENGTH_EXCHANGE); static_assert(sizeof(Symbol) == detail::MAX_LENGTH_SYMBOL); static_assert(sizeof(Currency) == detail::MAX_LENGTH_CURRENCY); static_assert(sizeof(CFICode) == detail::MAX_LENGTH_CFI_CODE); static_assert(sizeof(MBOOrderId) == detail::MAX_LENGTH_MBO_ORDER_ID); static_assert(sizeof(RequestTemplate) == detail::MAX_LENGTH_REQUEST_TEMPLATE); static_assert(sizeof(ExternalAccount) == detail::MAX_LENGTH_EXTERNAL_ACCOUNT); static_assert(sizeof(ExternalOrderId) == detail::MAX_LENGTH_EXTERNAL_ORDER_ID); static_assert(sizeof(ExternalTradeId) == detail::MAX_LENGTH_EXTERNAL_TRADE_ID); static_assert(sizeof(RoutingId) == detail::MAX_LENGTH_ROUTING_ID); static_assert(sizeof(ClOrdId) == detail::MAX_LENGTH_CL_ORD_ID); static_assert(sizeof(RequestId) == detail::MAX_LENGTH_REQUEST_ID); static_assert(sizeof(Label) == detail::MAX_LENGTH_LABEL); static_assert(sizeof(MeasurementKey) == detail::MAX_LENGTH_MEASUREMENT_KEY); static_assert(sizeof(MatrixKey) == detail::MAX_LENGTH_MATRIX_KEY); static_assert(sizeof(Description) == detail::MAX_LENGTH_DESCRIPTION); static_assert(sizeof(TimeZone) == detail::MAX_LENGTH_TIME_ZONE); static_assert(sizeof(ParameterKey) == detail::MAX_LENGTH_PARAMETER_KEY); static_assert(sizeof(ParameterValue) == detail::MAX_LENGTH_PARAMETER_VALUE); } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::Source const &value, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), "{}"sv, static_cast(value)); } }; template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::User const &value, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), "{}"sv, static_cast(value)); } }; template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::Account const &value, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), "{}"sv, static_cast(value)); } }; template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::Exchange const &value, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), "{}"sv, static_cast(value)); } }; template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::Symbol const &value, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), "{}"sv, static_cast(value)); } }; template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::Currency const &value, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), "{}"sv, static_cast(value)); } }; template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::CFICode const &value, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), "{}"sv, static_cast(value)); } }; template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::MBOOrderId const &value, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), "{}"sv, static_cast(value)); } }; template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::RequestTemplate const &value, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), "{}"sv, static_cast(value)); } }; template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::ExternalAccount const &value, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), "{}"sv, static_cast(value)); } }; template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::ExternalOrderId const &value, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), "{}"sv, static_cast(value)); } }; template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::ExternalTradeId const &value, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), "{}"sv, static_cast(value)); } }; template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::RoutingId const &value, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), "{}"sv, static_cast(value)); } }; template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::ClOrdId const &value, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), "{}"sv, static_cast(value)); } }; template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::RequestId const &value, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), "{}"sv, static_cast(value)); } }; template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::Label const &value, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), "{}"sv, static_cast(value)); } }; template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::MeasurementKey const &value, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), "{}"sv, static_cast(value)); } }; template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::MatrixKey const &value, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), "{}"sv, static_cast(value)); } }; template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::Description const &value, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), "{}"sv, static_cast(value)); } }; template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::TimeZone const &value, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), "{}"sv, static_cast(value)); } }; template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::ParameterKey const &value, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), "{}"sv, static_cast(value)); } }; template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::ParameterValue const &value, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), "{}"sv, static_cast(value)); } }; ================================================ FILE: include/roq/subscribe.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include #include #include "roq/event.hpp" #include "roq/name.hpp" #include "roq/string_types.hpp" #include "roq/trace.hpp" namespace roq { //! Dynamic subscription struct ROQ_PUBLIC Subscribe final { std::string_view exchange; //!< Exchange std::span symbols; //!< Symbols }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "subscribe"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::Subscribe const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(exchange="{}", )" R"(symbols=[{}])" R"(}})"sv, value.exchange, fmt::join(value.symbols, ", "sv)); } }; ================================================ FILE: include/roq/support_type.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include #include #include namespace roq { //! Enumeration of support types enum class SupportType : uint64_t { // NOLINT(performance-enum-size) UNDEFINED = 0, REFERENCE_DATA = 0x1, //!< Reference data MARKET_STATUS = 0x2, //!< Market status TOP_OF_BOOK = 0x4, //!< Top of book MARKET_BY_PRICE = 0x8, //!< Market by price MARKET_BY_ORDER = 0x10, //!< Market by order TRADE_SUMMARY = 0x20, //!< Trade summary STATISTICS = 0x40, //!< Statistics TIME_SERIES = 0x80, //!< Time-series CREATE_ORDER = 0x10000, //!< Create order MODIFY_ORDER = 0x20000, //!< Modify order CANCEL_ORDER = 0x40000, //!< Cancel order ORDER_ACK = 0x80000, //!< Order ack ORDER = 0x100000, //!< Order ORDER_STATE = 0x800000, //!< Order TRADE = 0x200000, //!< Trade POSITION = 0x400000, //!< Position FUNDS = 0x10000000, //!< Funds }; } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::SupportType const &value, format_context &context) const { using namespace std::literals; auto name = [&]() -> std::string_view { switch (value) { using enum roq::SupportType; case UNDEFINED: return "UNDEFINED"sv; case REFERENCE_DATA: return "REFERENCE_DATA"sv; case MARKET_STATUS: return "MARKET_STATUS"sv; case TOP_OF_BOOK: return "TOP_OF_BOOK"sv; case MARKET_BY_PRICE: return "MARKET_BY_PRICE"sv; case MARKET_BY_ORDER: return "MARKET_BY_ORDER"sv; case TRADE_SUMMARY: return "TRADE_SUMMARY"sv; case STATISTICS: return "STATISTICS"sv; case TIME_SERIES: return "TIME_SERIES"sv; case CREATE_ORDER: return "CREATE_ORDER"sv; case MODIFY_ORDER: return "MODIFY_ORDER"sv; case CANCEL_ORDER: return "CANCEL_ORDER"sv; case ORDER_ACK: return "ORDER_ACK"sv; case ORDER: return "ORDER"sv; case ORDER_STATE: return "ORDER_STATE"sv; case TRADE: return "TRADE"sv; case POSITION: return "POSITION"sv; case FUNDS: return "FUNDS"sv; } std::abort(); }(); return fmt::format_to(context.out(), "{}"sv, name); } }; ================================================ FILE: include/roq/tick_size_step.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include "roq/limits.hpp" namespace roq { //! Represents tick size for a range starting from a minimum price struct ROQ_PUBLIC TickSizeStep final { double min_price = roq::NaN; //!< Minimum price (of range) double tick_size = roq::NaN; //!< Tick size }; } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::TickSizeStep const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(min_price={}, )" R"(tick_size={})" R"(}})"sv, value.min_price, value.tick_size); } }; ================================================ FILE: include/roq/time_in_force.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include namespace roq { //! Order life-time, aka time in force enum class TimeInForce : uint8_t { UNDEFINED = 0, GFD, //!< Good for day, aka DAY GTC, //!< Good till canceled OPG, //!< At the open IOC, //!< Immediate or cancel FOK, //!< Fill or kill GTX, //!< Good till crossing GTD, //!< Good till date AT_THE_CLOSE, //!< At the close GOOD_THROUGH_CROSSING, //!< Good through crossing AT_CROSSING, //!< At crossing GOOD_FOR_TIME, //!< Good for time GFA, //!< Good for auction GFM, //!< Good for this month }; } // namespace roq ================================================ FILE: include/roq/time_series_update.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include #include #include #include #include "roq/bar.hpp" #include "roq/data_source.hpp" #include "roq/event.hpp" #include "roq/interval.hpp" #include "roq/name.hpp" #include "roq/origin.hpp" #include "roq/trace.hpp" #include "roq/update_type.hpp" namespace roq { //! Update relating to time-series struct ROQ_PUBLIC TimeSeriesUpdate final { uint16_t stream_id = {}; //!< Stream identifier std::string_view exchange; //!< Exchange std::string_view symbol; //!< Symbol roq::DataSource data_source = {}; //!< Data source roq::Interval interval = {}; //!< Update frequency roq::Origin origin = {}; //!< Origin of time-series std::span bars; //!< List of updated bars roq::UpdateType update_type = {}; //!< Update type std::chrono::nanoseconds exchange_time_utc = {}; //!< Exchange timestamp, possibly from matching engine (UTC) }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "time_series_update"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::TimeSeriesUpdate const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(stream_id={}, )" R"(exchange="{}", )" R"(symbol="{}", )" R"(data_source={}, )" R"(interval={}, )" R"(origin={}, )" R"(bars=[{}], )" R"(update_type={}, )" R"(exchange_time_utc={})" R"(}})"sv, value.stream_id, value.exchange, value.symbol, value.data_source, value.interval, value.origin, fmt::join(value.bars, ", "sv), value.update_type, value.exchange_time_utc); } }; ================================================ FILE: include/roq/timer.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include #include "roq/event.hpp" #include "roq/name.hpp" #include "roq/trace.hpp" namespace roq { //! Represents a timer update struct ROQ_PUBLIC Timer final { std::chrono::nanoseconds now = {}; //!< Current time (monotonic clock) }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "timer"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::Timer const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(now={})" R"(}})"sv, value.now); } }; ================================================ FILE: include/roq/top_of_book.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include #include #include "roq/event.hpp" #include "roq/layer.hpp" #include "roq/name.hpp" #include "roq/precision.hpp" #include "roq/trace.hpp" #include "roq/update_type.hpp" namespace roq { //! Update relating to top of book (aggregate price) struct ROQ_PUBLIC TopOfBook final { uint16_t stream_id = {}; //!< Stream identifier std::string_view exchange; //!< Exchange std::string_view symbol; //!< Symbol roq::Layer layer = {}; //!< Top of book roq::UpdateType update_type = {}; //!< Update type std::chrono::nanoseconds exchange_time_utc = {}; //!< Exchange timestamp, possibly from matching engine (UTC) uint64_t exchange_sequence = {}; //!< Exchange message sequence number std::chrono::nanoseconds sending_time_utc = {}; //!< Exchange sending timestamp (UTC) roq::Precision price_precision = {}; //!< Precision (decimal digits) required to represent prices (dynamic) roq::Precision quantity_precision = {}; //!< Precision (decimal digits) required to represent quantities (dynamic) }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "top_of_book"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::TopOfBook const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(stream_id={}, )" R"(exchange="{}", )" R"(symbol="{}", )" R"(layer={}, )" R"(update_type={}, )" R"(exchange_time_utc={}, )" R"(exchange_sequence={}, )" R"(sending_time_utc={}, )" R"(price_precision={}, )" R"(quantity_precision={})" R"(}})"sv, value.stream_id, value.exchange, value.symbol, value.layer, value.update_type, value.exchange_time_utc, value.exchange_sequence, value.sending_time_utc, value.price_precision, value.quantity_precision); } }; ================================================ FILE: include/roq/trace.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ #pragma once #include #include #include #include "roq/name.hpp" #include "roq/trace_info.hpp" namespace roq { template struct Trace final { using value_type = std::remove_cvref_t; Trace(TraceInfo const &trace_info, T const &value) : trace_info{trace_info}, value{value} {} Trace(Trace &&) = delete; Trace(Trace const &) = delete; void operator=(Trace &&) = delete; void operator=(Trace const &) = delete; operator TraceInfo const &() const { return trace_info; } operator value_type const &() const { return value; } operator std::pair() const { return {trace_info, value}; } TraceInfo const &trace_info; value_type const &value; template static void create_and_dispatch(auto &handler, TraceInfo const &trace_info, T const &value, Args &&...args) { Trace const event{trace_info, value}; handler(event, std::forward(args)...); } }; template inline void create_trace_and_dispatch(auto &handler, TraceInfo const &trace_info, T const &value, Args &&...args) { Trace::create_and_dispatch(handler, trace_info, value, std::forward(args)...); } } // namespace roq template struct fmt::formatter> { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::Trace const &event, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"({}={}, )" R"(trace_info={})" R"(}})"sv, roq::get_name(), event.value, event.trace_info); } }; ================================================ FILE: include/roq/trace_info.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ #pragma once #include "roq/compat.hpp" #include #include #include #include #include "roq/clock.hpp" #include "roq/message_info.hpp" namespace roq { // note! // certain use-cases are not allowed, e.g. zero initialization, copy construction and assignment // this is done to prevent specific mistakes from happening struct ROQ_PUBLIC TraceInfo final { // note! default initialization is using *current* time TraceInfo() : source_receive_time{clock::get_system()}, origin_create_time{source_receive_time}, origin_create_time_utc{clock::get_realtime()} {} // note! meant for internal use, only TraceInfo(auto source_receive_time, auto origin_create_time, auto origin_create_time_utc) : source_receive_time{source_receive_time}, origin_create_time{origin_create_time}, origin_create_time_utc{origin_create_time_utc} {} // note! meant for internal use, only TraceInfo(MessageInfo const &message_info) : TraceInfo{ message_info.source_receive_time, message_info.origin_create_time, message_info.origin_create_time_utc, } {} TraceInfo(TraceInfo const &) = delete; void operator=(TraceInfo const &) = delete; std::chrono::nanoseconds const source_receive_time; std::chrono::nanoseconds const origin_create_time; std::chrono::nanoseconds const origin_create_time_utc; }; } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::TraceInfo const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), "{{" "source_receive_time={}, " "origin_create_time={}, " "origin_create_time_utc={}" "}}"sv, value.source_receive_time, value.origin_create_time, value.origin_create_time_utc); } }; ================================================ FILE: include/roq/trade.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include "roq/limits.hpp" #include "roq/side.hpp" #include "roq/string_types.hpp" namespace roq { //! Represents a single trade (a match) as part of trade reporting by the exchange struct ROQ_PUBLIC Trade final { roq::Side side = {}; //!< Side (by convention: side of the taker) double price = roq::NaN; //!< Price double quantity = roq::NaN; //!< Quantity roq::ExternalTradeId trade_id; //!< Trade identifier roq::ExternalOrderId taker_order_id; //!< External order identifier (taker) roq::ExternalOrderId maker_order_id; //!< External order identifier (maker) }; } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::Trade const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(side={}, )" R"(price={}, )" R"(quantity={}, )" R"(trade_id="{}", )" R"(taker_order_id="{}", )" R"(maker_order_id="{}")" R"(}})"sv, value.side, value.price, value.quantity, value.trade_id, value.taker_order_id, value.maker_order_id); } }; ================================================ FILE: include/roq/trade_summary.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include #include #include #include #include "roq/event.hpp" #include "roq/name.hpp" #include "roq/precision.hpp" #include "roq/trace.hpp" #include "roq/trade.hpp" namespace roq { //! Update relating to trade reporting by the exchange struct ROQ_PUBLIC TradeSummary final { uint16_t stream_id = {}; //!< Stream identifier std::string_view exchange; //!< Exchange std::string_view symbol; //!< Symbol std::span trades; //!< List of trades std::chrono::nanoseconds exchange_time_utc = {}; //!< Exchange timestamp, possibly from matching engine (UTC) uint64_t exchange_sequence = {}; //!< Exchange message sequence number std::chrono::nanoseconds sending_time_utc = {}; //!< Exchange sending timestamp (UTC) roq::Precision price_precision = {}; //!< Precision (decimal digits) required to represent prices (dynamic) roq::Precision quantity_precision = {}; //!< Precision (decimal digits) required to represent quantities (dynamic) }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "trade_summary"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::TradeSummary const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(stream_id={}, )" R"(exchange="{}", )" R"(symbol="{}", )" R"(trades=[{}], )" R"(exchange_time_utc={}, )" R"(exchange_sequence={}, )" R"(sending_time_utc={}, )" R"(price_precision={}, )" R"(quantity_precision={})" R"(}})"sv, value.stream_id, value.exchange, value.symbol, fmt::join(value.trades, ", "sv), value.exchange_time_utc, value.exchange_sequence, value.sending_time_utc, value.price_precision, value.quantity_precision); } }; ================================================ FILE: include/roq/trade_update.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include "roq/compat.hpp" #include #include #include #include #include #include #include #include "roq/event.hpp" #include "roq/fill.hpp" #include "roq/margin_mode.hpp" #include "roq/name.hpp" #include "roq/position_effect.hpp" #include "roq/quantity_type.hpp" #include "roq/side.hpp" #include "roq/trace.hpp" #include "roq/update_type.hpp" namespace roq { //! Update relating to order being partially or fully filled struct ROQ_PUBLIC TradeUpdate final { uint16_t stream_id = {}; //!< Stream identifier std::string_view account; //!< Account name uint64_t order_id = {}; //!< Order identifier std::string_view exchange; //!< Exchange std::string_view symbol; //!< Symbol roq::Side side = {}; //!< Side roq::PositionEffect position_effect = {}; //!< Position effect roq::MarginMode margin_mode = {}; //!< Margin mode roq::QuantityType quantity_type = {}; //!< Type of quantity (requires ecxhange support) std::chrono::nanoseconds create_time_utc = {}; //!< Created timestamp (UTC) std::chrono::nanoseconds update_time_utc = {}; //!< Updated timestamp (UTC) std::string_view external_account; //!< External account name std::string_view external_order_id; //!< External order identifier std::string_view client_order_id; //!< Client order identifier std::span fills; //!< List of fills std::string_view routing_id; //!< Routing identifier roq::UpdateType update_type = {}; //!< Update type std::chrono::nanoseconds exchange_time_utc = {}; //!< Exchange timestamp, possibly from matching engine (UTC) uint64_t exchange_sequence = {}; //!< Exchange message sequence number std::chrono::nanoseconds sending_time_utc = {}; //!< Exchange sending timestamp (UTC) std::string_view user; //!< User name (optional, only relevant for drop-copy) uint32_t strategy_id = {}; //!< Strategy identifier (optional) }; template <> constexpr std::string_view get_name() { using namespace std::literals; return "trade_update"sv; } } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::TradeUpdate const &value, format_context &context) const { using namespace std::literals; return fmt::format_to( context.out(), R"({{)" R"(stream_id={}, )" R"(account="{}", )" R"(order_id={}, )" R"(exchange="{}", )" R"(symbol="{}", )" R"(side={}, )" R"(position_effect={}, )" R"(margin_mode={}, )" R"(quantity_type={}, )" R"(create_time_utc={}, )" R"(update_time_utc={}, )" R"(external_account="{}", )" R"(external_order_id="{}", )" R"(client_order_id="{}", )" R"(fills=[{}], )" R"(routing_id="{}", )" R"(update_type={}, )" R"(exchange_time_utc={}, )" R"(exchange_sequence={}, )" R"(sending_time_utc={}, )" R"(user="{}", )" R"(strategy_id={})" R"(}})"sv, value.stream_id, value.account, value.order_id, value.exchange, value.symbol, value.side, value.position_effect, value.margin_mode, value.quantity_type, value.create_time_utc, value.update_time_utc, value.external_account, value.external_order_id, value.client_order_id, fmt::join(value.fills, ", "sv), value.routing_id, value.update_type, value.exchange_time_utc, value.exchange_sequence, value.sending_time_utc, value.user, value.strategy_id); } }; ================================================ FILE: include/roq/trading_status.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include namespace roq { //! Enumeration of the tradig status of a symbol enum class TradingStatus : uint8_t { UNDEFINED = 0, START_OF_DAY, //!< No matching, no order actions PRE_OPEN, //!< No matching, all order actions PRE_OPEN_NO_CANCEL, //!< No matching, only new orders PRE_OPEN_FREEZE, //!< Matching, no order actions OPEN, //!< Matching, all order actions FAST_MARKET, //!< Same as Open, some settings could be relaxed by the exchange HALT, //!< No matching, only order cancellation CLOSE_NOT_FINAL, //!< Same as Close, state required to support mid-session PreOpen PRE_CLOSE, //!< No matching, all order actions PRE_CLOSE_NO_CANCEL, //!< No matching, only new orders PRE_CLOSE_FREEZE, //!< Matching, no order actions CLOSE, //!< No matching, no order actions, good-for-day orders automatically canceled POST_CLOSE, //!< No matching, all order actions (only with next-trading-day validity) END_OF_DAY, //!< No matching, no order actions }; } // namespace roq ================================================ FILE: include/roq/transport.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include namespace roq { //! Enumeration of transport types (layer 4) enum class Transport : uint8_t { UNDEFINED = 0, TCP, //!< TCP UDP, //!< UDP }; } // namespace roq ================================================ FILE: include/roq/update_action.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include namespace roq { //! Enumeration of update actions enum class UpdateAction : uint8_t { UNDEFINED = 0, NEW, //!< New CHANGE, //!< Change DELETE, //!< Delete TRADE, //!< Trade !!! FOR INTERNAL USE !!! }; } // namespace roq ================================================ FILE: include/roq/update_reason.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include namespace roq { //! Enumeration of update reasons enum class UpdateReason : uint8_t { UNDEFINED = 0, CREATED, //!< Created MODIFIED, //!< Modified CANCELED, //!< Canceled FILLED, //!< Filled }; } // namespace roq ================================================ FILE: include/roq/update_type.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include namespace roq { //! Enumeration of update types enum class UpdateType : uint8_t { UNDEFINED = 0, SNAPSHOT, //!< Full snapshot INCREMENTAL, //!< Incremental change STALE, //!< Stale awaiting full snapshot }; } // namespace roq ================================================ FILE: include/roq/uuid.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ #pragma once #include #include namespace roq { // NOLINTBEGIN(readability-magic-numbers) // note! // interface using native byte order // network byte order for internal representation struct alignas(16) UUID final { using value_type = __uint128_t; UUID() = default; UUID(UUID const &) = default; UUID &operator=(UUID const &) = default; explicit UUID(value_type value) : value_{create(value)} {} UUID(uint64_t high, uint64_t low) : value_{create(high, low)} {} constexpr auto operator<=>(UUID const &) const = default; constexpr operator value_type() const { if constexpr (std::endian::native == std::endian::little) { return std::byteswap(value_); } return value_; } constexpr operator std::pair() const { if constexpr (std::endian::native == std::endian::little) { // note! legacy (testing purposes) -- inconsistent with uint128_t constructor auto high = static_cast(value_); auto low = static_cast(value_ >> 64); return {high, low}; } else { auto high = static_cast(value_ >> 64); auto low = static_cast(value_); return {high, low}; } } constexpr value_type *data() { return &value_; } constexpr value_type const *data() const { return &value_; } constexpr size_t size() const { return sizeof(value_); } constexpr bool empty() const { return value_ == value_type{}; } protected: static value_type create(value_type value) { if constexpr (std::endian::native == std::endian::little) { return std::byteswap(value); } return value; } static value_type create(uint64_t high, uint64_t low) { if constexpr (std::endian::native == std::endian::little) { // note! legacy (testing purposes) -- inconsistent with uint128_t constructor return static_cast(low) << 64 | static_cast(high); } return static_cast(high) << 64 | static_cast(low); } private: value_type value_ = {}; }; static_assert(sizeof(UUID) == 16); // NOLINTEND(readability-magic-numbers) } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::UUID const &value, format_context &context) const { using namespace std::literals; auto data = reinterpret_cast(std::data(value)); // NOLINTBEGIN(readability-magic-numbers) return fmt::format_to( context.out(), "{:02x}{:02x}{:02x}{:02x}-" "{:02x}{:02x}-" "{:02x}{:02x}-" "{:02x}{:02x}-" "{:02x}{:02x}{:02x}{:02x}{:02x}{:02x}", data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15]); // NOLINTEND(readability-magic-numbers) } }; ================================================ FILE: include/roq/variant_type.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ /* !!! THIS FILE HAS BEEN AUTO-GENERATED !!! */ #pragma once #include namespace roq { //! Enumeration of variant types enum class VariantType : uint8_t { UNDEFINED = 0, STRING, //!< ASCII string BOOL, //!< Boolean INT8, //!< Signed 8 bit integer UINT8, //!< Unsigned 8 bit integer INT16, //!< Signed 16 bit integer UINT16, //!< Unsigned 16 bit integer INT32, //!< Signed 32 bit integer UINT32, //!< Unsigned 32 bit integer INT64, //!< Signed 64 bit integer UINT64, //!< Unsigned 64 bit integer FLOAT, //!< 32 bit floating point DOUBLE, //!< 64 bit floating point ENUM, //!< Enumeration DATETIME, //!< Nanoseconds relative to Unix epoch }; } // namespace roq ================================================ FILE: include/roq/version.hpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ #pragma once #include #include namespace roq { struct Version final { uint8_t major = {}; uint8_t minor = {}; uint16_t revision = {}; auto operator<=>(Version const &) const = default; }; } // namespace roq template <> struct fmt::formatter { constexpr auto parse(format_parse_context &context) { return std::begin(context); } auto format(roq::Version const &value, format_context &context) const { using namespace std::literals; return fmt::format_to(context.out(), "{}.{}.{}"sv, value.major, value.minor, value.revision); } }; ================================================ FILE: schema/roq/CMakeLists.txt ================================================ set(TARGET_NAME ${PROJECT_NAME}-schema-roq) # XXX FIXME share with other subdirectories set(SCHEMA_ROQ action.json add_routes.json batch_begin.json batch_end.json buffer_capacity.json cancel_all_orders_ack.json cancel_all_orders.json cancel_order.json cancel_quotes_ack.json category.json connected.json connection_status.json control.json control_ack.json create_order.json custom_matrix.json custom_matrix_update.json custom_metrics.json custom_metrics_update.json data_source.json disconnected.json download_begin.json download_end.json encoding.json error.json execution_instruction.json external_latency.json fill.json filter.json funds_update.json gateway_settings.json gateway_status.json interval.json layer.json leg.json legs_update.json liquidity.json margin_mode.json market_by_order_update.json market_by_price_update.json market_status.json mass_quote_ack.json mbo_update.json mbp_update.json measurement.json message_info.json modify_order.json option_type.json order_ack.json order_cancel_policy.json order_management.json order_status.json order_type.json order_update.json origin.json parameter.json parameters_update.json portfolio.json portfolio_update.json position_effect.json position.json position_update.json precision.json priority.json protocol.json quality_of_service.json quantity_type.json rate_limit.json rate_limits_update.json rate_limit_trigger.json rate_limit_type.json ready.json reference_data.json remove_routes.json request_id_type.json request_status.json request_type.json risk_limit.json risk_limits.json risk_limits_update.json route_ack.json route.json route_request_status.json routing.json security_type.json service_update.json side.json start.json state.json statistics.json statistics_type.json statistics_update.json stop.json stream_status.json subscribe.json support_type.json tick_size_step.json time_in_force.json timer.json time_series_update.json top_of_book.json trade.json trade_summary.json trade_update.json trading_status.json transport.json update_action.json update_reason.json update_type.json variant_type.json) ================================================ FILE: schema/roq/action.json ================================================ { "link": "roq/Action" } ================================================ FILE: schema/roq/add_market.json ================================================ { "link": "roq/AddMarket" } ================================================ FILE: schema/roq/add_routes.json ================================================ { "link": "roq/AddRoutes" } ================================================ FILE: schema/roq/bar.json ================================================ { "link": "roq/Bar" } ================================================ FILE: schema/roq/batch_begin.json ================================================ { "link": "roq/BatchBegin" } ================================================ FILE: schema/roq/batch_end.json ================================================ { "link": "roq/BatchEnd" } ================================================ FILE: schema/roq/buffer_capacity.json ================================================ { "link": "roq/BufferCapacity" } ================================================ FILE: schema/roq/cancel_all_orders.json ================================================ { "link": "roq/CancelAllOrders" } ================================================ FILE: schema/roq/cancel_all_orders_ack.json ================================================ { "link": "roq/CancelAllOrdersAck" } ================================================ FILE: schema/roq/cancel_order.json ================================================ { "link": "roq/CancelOrder" } ================================================ FILE: schema/roq/cancel_quotes.json ================================================ { "link": "roq/CancelQuotes" } ================================================ FILE: schema/roq/cancel_quotes_ack.json ================================================ { "link": "roq/CancelQuotesAck" } ================================================ FILE: schema/roq/category.json ================================================ { "link": "roq/Category" } ================================================ FILE: schema/roq/connected.json ================================================ { "link": "roq/Connected" } ================================================ FILE: schema/roq/connection_status.json ================================================ { "link": "roq/ConnectionStatus" } ================================================ FILE: schema/roq/control.json ================================================ { "link": "roq/Control" } ================================================ FILE: schema/roq/control_ack.json ================================================ { "link": "roq/ControlAck" } ================================================ FILE: schema/roq/create_order.json ================================================ { "link": "roq/CreateOrder" } ================================================ FILE: schema/roq/custom_matrix.json ================================================ { "link": "roq/CustomMatrix" } ================================================ FILE: schema/roq/custom_matrix_update.json ================================================ { "link": "roq/CustomMatrixUpdate" } ================================================ FILE: schema/roq/custom_metrics.json ================================================ { "link": "roq/CustomMetrics" } ================================================ FILE: schema/roq/custom_metrics_update.json ================================================ { "link": "roq/CustomMetricsUpdate" } ================================================ FILE: schema/roq/data_source.json ================================================ { "link": "roq/DataSource" } ================================================ FILE: schema/roq/disconnected.json ================================================ { "link": "roq/Disconnected" } ================================================ FILE: schema/roq/download_begin.json ================================================ { "link": "roq/DownloadBegin" } ================================================ FILE: schema/roq/download_end.json ================================================ { "link": "roq/DownloadEnd" } ================================================ FILE: schema/roq/encoding.json ================================================ { "link": "roq/Encoding" } ================================================ FILE: schema/roq/error.json ================================================ { "link": "roq/Error" } ================================================ FILE: schema/roq/execution_instruction.json ================================================ { "link": "roq/ExecutionInstruction" } ================================================ FILE: schema/roq/external_latency.json ================================================ { "link": "roq/ExternalLatency" } ================================================ FILE: schema/roq/fill.json ================================================ { "link": "roq/Fill" } ================================================ FILE: schema/roq/filter.json ================================================ { "link": "roq/Filter" } ================================================ FILE: schema/roq/funds_update.json ================================================ { "link": "roq/FundsUpdate" } ================================================ FILE: schema/roq/gateway_settings.json ================================================ { "link": "roq/GatewaySettings" } ================================================ FILE: schema/roq/gateway_status.json ================================================ { "link": "roq/GatewayStatus" } ================================================ FILE: schema/roq/interval.json ================================================ { "link": "roq/Interval" } ================================================ FILE: schema/roq/layer.json ================================================ { "link": "roq/Layer" } ================================================ FILE: schema/roq/leg.json ================================================ { "link": "roq/Leg" } ================================================ FILE: schema/roq/legs_update.json ================================================ { "link": "roq/LegsUpdate" } ================================================ FILE: schema/roq/liquidity.json ================================================ { "link": "roq/Liquidity" } ================================================ FILE: schema/roq/margin_mode.json ================================================ { "link": "roq/MarginMode" } ================================================ FILE: schema/roq/market_by_order_update.json ================================================ { "link": "roq/MarketByOrderUpdate" } ================================================ FILE: schema/roq/market_by_price_update.json ================================================ { "link": "roq/MarketByPriceUpdate" } ================================================ FILE: schema/roq/market_status.json ================================================ { "link": "roq/MarketStatus" } ================================================ FILE: schema/roq/mass_quote.json ================================================ { "link": "roq/MassQuote" } ================================================ FILE: schema/roq/mass_quote_ack.json ================================================ { "link": "roq/MassQuoteAck" } ================================================ FILE: schema/roq/mbo_update.json ================================================ { "link": "roq/MBOUpdate" } ================================================ FILE: schema/roq/mbp_update.json ================================================ { "link": "roq/MBPUpdate" } ================================================ FILE: schema/roq/measurement.json ================================================ { "link": "roq/Measurement" } ================================================ FILE: schema/roq/message_info.json ================================================ { "link": "roq/MessageInfo" } ================================================ FILE: schema/roq/modify_order.json ================================================ { "link": "roq/ModifyOrder" } ================================================ FILE: schema/roq/option_type.json ================================================ { "link": "roq/OptionType" } ================================================ FILE: schema/roq/order_ack.json ================================================ { "link": "roq/OrderAck" } ================================================ FILE: schema/roq/order_cancel_policy.json ================================================ { "link": "roq/OrderCancelPolicy" } ================================================ FILE: schema/roq/order_management.json ================================================ { "link": "roq/OrderManagement" } ================================================ FILE: schema/roq/order_status.json ================================================ { "link": "roq/OrderStatus" } ================================================ FILE: schema/roq/order_type.json ================================================ { "link": "roq/OrderType" } ================================================ FILE: schema/roq/order_update.json ================================================ { "link": "roq/OrderUpdate" } ================================================ FILE: schema/roq/origin.json ================================================ { "link": "roq/Origin" } ================================================ FILE: schema/roq/parameter.json ================================================ { "link": "roq/Parameter" } ================================================ FILE: schema/roq/parameters_update.json ================================================ { "link": "roq/ParametersUpdate" } ================================================ FILE: schema/roq/portfolio.json ================================================ { "link": "roq/Portfolio" } ================================================ FILE: schema/roq/portfolio_update.json ================================================ { "link": "roq/PortfolioUpdate" } ================================================ FILE: schema/roq/position.json ================================================ { "link": "roq/Position" } ================================================ FILE: schema/roq/position_effect.json ================================================ { "link": "roq/PositionEffect" } ================================================ FILE: schema/roq/position_update.json ================================================ { "link": "roq/PositionUpdate" } ================================================ FILE: schema/roq/precision.json ================================================ { "link": "roq/Precision" } ================================================ FILE: schema/roq/priority.json ================================================ { "link": "roq/Priority" } ================================================ FILE: schema/roq/protocol.json ================================================ { "link": "roq/Protocol" } ================================================ FILE: schema/roq/quality_of_service.json ================================================ { "link": "roq/QualityOfService" } ================================================ FILE: schema/roq/quantity_type.json ================================================ { "link": "roq/QuantityType" } ================================================ FILE: schema/roq/quote.json ================================================ { "link": "roq/Quote" } ================================================ FILE: schema/roq/rate_limit.json ================================================ { "link": "roq/RateLimit" } ================================================ FILE: schema/roq/rate_limit_trigger.json ================================================ { "link": "roq/RateLimitTrigger" } ================================================ FILE: schema/roq/rate_limit_type.json ================================================ { "link": "roq/RateLimitType" } ================================================ FILE: schema/roq/rate_limits_update.json ================================================ { "link": "roq/RateLimitsUpdate" } ================================================ FILE: schema/roq/ready.json ================================================ { "link": "roq/Ready" } ================================================ FILE: schema/roq/reference_data.json ================================================ { "link": "roq/ReferenceData" } ================================================ FILE: schema/roq/remove_routes.json ================================================ { "link": "roq/RemoveRoutes" } ================================================ FILE: schema/roq/request_id_type.json ================================================ { "link": "roq/RequestIdType" } ================================================ FILE: schema/roq/request_status.json ================================================ { "link": "roq/RequestStatus" } ================================================ FILE: schema/roq/request_type.json ================================================ { "link": "roq/RequestType" } ================================================ FILE: schema/roq/risk_limit.json ================================================ { "link": "roq/RiskLimit" } ================================================ FILE: schema/roq/risk_limits.json ================================================ { "link": "roq/RiskLimits" } ================================================ FILE: schema/roq/risk_limits_update.json ================================================ { "link": "roq/RiskLimitsUpdate" } ================================================ FILE: schema/roq/route.json ================================================ { "link": "roq/Route" } ================================================ FILE: schema/roq/route_ack.json ================================================ { "link": "roq/RouteAck" } ================================================ FILE: schema/roq/route_request_status.json ================================================ { "link": "roq/RouteRequestStatus" } ================================================ FILE: schema/roq/routing.json ================================================ { "link": "roq/Routing" } ================================================ FILE: schema/roq/security_type.json ================================================ { "link": "roq/SecurityType" } ================================================ FILE: schema/roq/service_update.json ================================================ { "link": "roq/ServiceUpdate" } ================================================ FILE: schema/roq/side.json ================================================ { "link": "roq/Side" } ================================================ FILE: schema/roq/start.json ================================================ { "link": "roq/Start" } ================================================ FILE: schema/roq/state.json ================================================ { "link": "roq/State" } ================================================ FILE: schema/roq/statistics.json ================================================ { "link": "roq/Statistics" } ================================================ FILE: schema/roq/statistics_type.json ================================================ { "link": "roq/StatisticsType" } ================================================ FILE: schema/roq/statistics_update.json ================================================ { "link": "roq/StatisticsUpdate" } ================================================ FILE: schema/roq/stop.json ================================================ { "link": "roq/Stop" } ================================================ FILE: schema/roq/strategy_update.json ================================================ { "link": "roq/StrategyUpdate" } ================================================ FILE: schema/roq/stream_status.json ================================================ { "link": "roq/StreamStatus" } ================================================ FILE: schema/roq/subscribe.json ================================================ { "link": "roq/Subscribe" } ================================================ FILE: schema/roq/support_type.json ================================================ { "link": "roq/SupportType" } ================================================ FILE: schema/roq/tick_size_step.json ================================================ { "link": "roq/TickSizeStep" } ================================================ FILE: schema/roq/time_in_force.json ================================================ { "link": "roq/TimeInForce" } ================================================ FILE: schema/roq/time_series_update.json ================================================ { "link": "roq/TimeSeriesUpdate" } ================================================ FILE: schema/roq/timer.json ================================================ { "link": "roq/Timer" } ================================================ FILE: schema/roq/top_of_book.json ================================================ { "link": "roq/TopOfBook" } ================================================ FILE: schema/roq/trade.json ================================================ { "link": "roq/Trade" } ================================================ FILE: schema/roq/trade_summary.json ================================================ { "link": "roq/TradeSummary" } ================================================ FILE: schema/roq/trade_update.json ================================================ { "link": "roq/TradeUpdate" } ================================================ FILE: schema/roq/trading_status.json ================================================ { "link": "roq/TradingStatus" } ================================================ FILE: schema/roq/transport.json ================================================ { "link": "roq/Transport" } ================================================ FILE: schema/roq/update_action.json ================================================ { "link": "roq/UpdateAction" } ================================================ FILE: schema/roq/update_reason.json ================================================ { "link": "roq/UpdateReason" } ================================================ FILE: schema/roq/update_type.json ================================================ { "link": "roq/UpdateType" } ================================================ FILE: schema/roq/variant_type.json ================================================ { "link": "roq/VariantType" } ================================================ FILE: test/.clang-tidy ================================================ --- InheritParentConfig: true Checks: -clang-analyzer-security.insecureAPI.rand, -readability-function-cognitive-complexity, -readability-isolate-declaration, -readability-magic-numbers, ================================================ FILE: test/.gitignore ================================================ roq-api-test ================================================ FILE: test/CMakeLists.txt ================================================ set(TARGET_NAME ${PROJECT_NAME}-test) set(SOURCES alignment.cpp compat.cpp exceptions.cpp format.cpp mask.cpp side.cpp span.cpp string.cpp support_type.cpp version.cpp main.cpp) add_executable(${TARGET_NAME} ${SOURCES}) add_dependencies(${TARGET_NAME} ${PROJECT_NAME}-include-cpp) target_link_libraries(${TARGET_NAME} PRIVATE fmt::fmt magic_enum::magic_enum nameof::nameof Catch2::Catch2) if(ROQ_BUILD_TYPE STREQUAL "Release") set_target_properties(${TARGET_NAME} PROPERTIES LINK_FLAGS_RELEASE -s) endif() add_test(NAME ${TARGET_NAME} COMMAND ${TARGET_NAME}) ================================================ FILE: test/alignment.cpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ #include #include "roq/api.hpp" using namespace roq; TEST_CASE("alignment_layer", "[alignment]") { std::array value; auto offset = reinterpret_cast(&value[1]) - reinterpret_cast(std::data(value)); CHECK(offset == std::ptrdiff_t{32}); } TEST_CASE("alignment_mbp_update", "[alignment]") { std::array value; auto offset = reinterpret_cast(&value[1]) - reinterpret_cast(std::data(value)); CHECK(offset == std::ptrdiff_t{32}); } TEST_CASE("alignment_mbo_update", "[alignment]") { std::array value; auto offset = reinterpret_cast(&value[1]) - reinterpret_cast(std::data(value)); CHECK(offset == std::ptrdiff_t{64}); } TEST_CASE("alignment_trade", "[alignment]") { std::array value; auto offset = reinterpret_cast(&value[1]) - reinterpret_cast(std::data(value)); CHECK(offset == std::ptrdiff_t{192}); } TEST_CASE("alignment_fill", "[alignment]") { std::array value; auto offset = reinterpret_cast(&value[1]) - reinterpret_cast(std::data(value)); CHECK(offset == std::ptrdiff_t{136}); } ================================================ FILE: test/compat.cpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ #include #if defined(__APPLE__) #if defined(__arm64__) static_assert(std::hardware_destructive_interference_size == 256); static_assert(std::hardware_constructive_interference_size == 64); #else // not __arm64__ static_assert(std::hardware_destructive_interference_size == 64); static_assert(std::hardware_constructive_interference_size == 64); #endif #else // not __APPLE__ #if defined(__arm64__) static_assert(std::hardware_destructive_interference_size == 256); // note! since gcc12 static_assert(std::hardware_constructive_interference_size == 64); #else // not __arm64__ // static_assert(std::hardware_destructive_interference_size == 64); // static_assert(std::hardware_destructive_interference_size == 256); static_assert(std::hardware_constructive_interference_size == 64); #endif #endif ================================================ FILE: test/exceptions.cpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ #include #include "roq/exceptions.hpp" using namespace std::literals; using namespace roq; TEST_CASE("exceptions_simple_1", "[exceptions]") { auto success = false; try { throw NotReady{"something's not right"sv}; } catch (std::exception &) { success = true; } CHECK(success == true); } TEST_CASE("exceptions_simple_2", "[exceptions]") { auto success = false; try { throw NotReady{"something's not right"sv}; } catch (Exception &) { success = true; } CHECK(success == true); } TEST_CASE("exceptions_simple_3", "[exceptions]") { auto success = false; try { throw NotReady{"something's not right"sv}; } catch (RuntimeError &) { success = true; } CHECK(success == true); } TEST_CASE("exceptions_simple_4", "[exceptions]") { auto success = false; try { throw NotReady{"something's not right"sv}; } catch (NotReady &) { success = true; } CHECK(success == true); } TEST_CASE("exceptions_simple_5", "[exceptions]") { auto success = false; try { throw RuntimeError{"something's not right"sv}; } catch (RuntimeError &) { success = true; } CHECK(success == true); } TEST_CASE("exceptions_what", "[exceptions]") { auto success = false; try { throw NotReady{"{}"sv, 123}; } catch (NotReady &e) { success = true; CHECK(e.what() == "123"sv); } CHECK(success == true); success = false; try { throw NotReady{"123"sv}; } catch (NotReady &e) { success = true; CHECK(e.what() == "123"sv); } CHECK(success == true); } ================================================ FILE: test/format.cpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ #include #include #include "roq/market_by_order_update.hpp" #include "roq/market_by_price_update.hpp" #include "roq/side.hpp" using namespace std::literals; using namespace roq; TEST_CASE("format_side", "[format]") { CHECK(fmt::format("{}"sv, Side{Side::UNDEFINED}) == "UNDEFINED"sv); CHECK(fmt::format("{}"sv, Side{Side::BUY}) == "BUY"sv); CHECK(fmt::format("{}"sv, Side{Side::SELL}) == "SELL"sv); } TEST_CASE("format_string", "[format]") { MBOOrderId order_id = "1234"sv; CHECK(fmt::format("{}"sv, order_id) == "1234"sv); } TEST_CASE("format_market_by_price", "[format]") { std::array bids{{ { .price = 1.0, .quantity = 2.0, .implied_quantity = 3.0, .number_of_orders = 2, .update_action = {}, .price_level = 1, }, { .price = 2.0, .quantity = 4.0, .implied_quantity = 3.0, .number_of_orders = 2, .update_action = {}, .price_level = 1, }, { .price = 3.0, .quantity = 8.0, .implied_quantity = 3.0, .number_of_orders = 2, .update_action = {}, .price_level = 1, }, { .price = 4.0, .quantity = 10.0, .implied_quantity = 3.0, .number_of_orders = 2, .update_action = {}, .price_level = 1, }, { .price = 5.0, .quantity = 12.0, .implied_quantity = 3.0, .number_of_orders = 2, .update_action = {}, .price_level = 1, }, }}; std::array asks{{ { .price = 1.0, .quantity = 2.0, .implied_quantity = 3.0, .number_of_orders = 2, .update_action = {}, .price_level = 1, }, { .price = 2.0, .quantity = 4.0, .implied_quantity = 3.0, .number_of_orders = 2, .update_action = {}, .price_level = 1, }, { .price = 3.0, .quantity = 8.0, .implied_quantity = 3.0, .number_of_orders = 2, .update_action = {}, .price_level = 1, }, { .price = 4.0, .quantity = 10.0, .implied_quantity = 3.0, .number_of_orders = 2, .update_action = {}, .price_level = 1, }, { .price = 5.0, .quantity = 12.0, .implied_quantity = 3.0, .number_of_orders = 2, .update_action = {}, .price_level = 1, }, }}; auto market_by_price = MarketByPriceUpdate{ .stream_id = {}, .exchange = "deribit"sv, .symbol = "BTC-27DEC19"sv, .bids = bids, .asks = asks, .update_type = UpdateType::SNAPSHOT, .exchange_time_utc = {}, .exchange_sequence = 123, .price_precision = Precision::_0, .quantity_precision = Precision::_1, .max_depth = 10, .checksum = 123, }; auto result = fmt::format("{}"sv, market_by_price); CHECK(std::size(result) > 0UZ); auto expected = R"({)" R"(stream_id=0, )" R"(exchange="deribit", )" R"(symbol="BTC-27DEC19", )" R"(bids=[)" R"({price=1, quantity=2, implied_quantity=3, number_of_orders=2, update_action=UNDEFINED, price_level=1}, )" R"({price=2, quantity=4, implied_quantity=3, number_of_orders=2, update_action=UNDEFINED, price_level=1}, )" R"({price=3, quantity=8, implied_quantity=3, number_of_orders=2, update_action=UNDEFINED, price_level=1}, )" R"({price=4, quantity=10, implied_quantity=3, number_of_orders=2, update_action=UNDEFINED, price_level=1}, )" R"({price=5, quantity=12, implied_quantity=3, number_of_orders=2, update_action=UNDEFINED, price_level=1})" R"(], )" R"(asks=[)" R"({price=1, quantity=2, implied_quantity=3, number_of_orders=2, update_action=UNDEFINED, price_level=1}, )" R"({price=2, quantity=4, implied_quantity=3, number_of_orders=2, update_action=UNDEFINED, price_level=1}, )" R"({price=3, quantity=8, implied_quantity=3, number_of_orders=2, update_action=UNDEFINED, price_level=1}, )" R"({price=4, quantity=10, implied_quantity=3, number_of_orders=2, update_action=UNDEFINED, price_level=1}, )" R"({price=5, quantity=12, implied_quantity=3, number_of_orders=2, update_action=UNDEFINED, price_level=1})" R"(], )" R"(update_type=SNAPSHOT, )" R"(exchange_time_utc=0ns, )" R"(exchange_sequence=123, )" R"(sending_time_utc=0ns, )" R"(price_precision=_0, )" R"(quantity_precision=_1, )" R"(max_depth=10, )" R"(checksum=123)" R"(})"sv; CHECK(result == expected); } ================================================ FILE: test/main.cpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ #define CATCH_CONFIG_RUNNER #include int main(int argc, char **argv) { return Catch::Session{}.run(argc, argv); } ================================================ FILE: test/mask.cpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ #include #include #include #include "roq/mask.hpp" using namespace std::literals; using namespace roq; namespace { enum class E : uint32_t { A = 1, B = 2, C = 4, }; // compile-time checks static_assert(Mask{E::A} == Mask{E::A}); static_assert(Mask{E::A} != Mask{}); static_assert(Mask{E::A} != Mask{E::B}); static_assert(Mask{E::A} == Mask{}.set(E::A)); static_assert(Mask{E::A, E::B} == Mask{}.set(E::A).set(E::B)); static_assert(Mask{E::A, E::B, E::C} == Mask{}.set(E::A).set(E::B).set(E::C)); } // namespace // run-time checks TEST_CASE("mask_simple", "[mask]") { auto mask_1 = Mask{ E::A, }; CHECK(mask_1.has(E::A) == true); CHECK(mask_1.has(E::B) == false); auto mask_2 = Mask{mask_1, E::B}; CHECK(mask_2.has(E::A) == true); CHECK(mask_2.has(E::B) == true); CHECK(mask_2.has_any(E::A) == true); CHECK(mask_2.has_any({E::A, E::B}) == true); CHECK(mask_2.has_any({E::A, E::B, E::C}) == true); CHECK(fmt::format("{}"sv, Mask{E::A}) == "A"sv); CHECK(fmt::format("{}"sv, Mask{E::B, E::C}) == "B|C"sv); CHECK(fmt::format("{}"sv, Mask{E::A, E::B, E::C}) == "A|B|C"sv); } namespace { enum class E2 : uint32_t { U = 0, // "undefined" A = 1, B = 2, C = 4, }; } TEST_CASE("mask_with_undefined", "[mask]") { SKIP("format broken with magic_enum 0.9.0"); CHECK(fmt::format("{}"sv, Mask{}) == "U"sv); CHECK(fmt::format("{}"sv, Mask{E2::U}) == "U"sv); CHECK(fmt::format("{}"sv, Mask{E2::A}) == "A"sv); CHECK(fmt::format("{}"sv, Mask{E2::A, E2::C}) == "A|C"sv); CHECK(fmt::format("{}"sv, Mask{E2::A, E2::B, E2::C}) == "A|B|C"sv); } ================================================ FILE: test/side.cpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ #include #include #include #include "roq/side.hpp" using namespace std::literals; using namespace roq; TEST_CASE("side_simple", "[side]") { CHECK(fmt::format("{}"sv, Side::BUY) == "BUY"sv); CHECK(fmt::format("{}"sv, Side::SELL) == "SELL"sv); } ================================================ FILE: test/span.cpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ #include #include #include #include #include #include #include #include using namespace std::literals; using namespace Catch::literals; TEST_CASE("span_simple", "[span]") { // initialize empty std::vector empty; std::span empty_span{empty}; CHECK(std::empty(empty_span) == true); // initialize non-empty std::array raw{{ 0.0, 2.0, 3.0, }}; std::span span{raw}; CHECK(std::empty(span) == false); span[0] = 1.0; CHECK(span[0] == 1.0_a); CHECK(span[1] == 2.0_a); CHECK(span[2] == 3.0_a); // assignment std::span span_2; CHECK(std::empty(span_2) == true); span_2 = span; CHECK(std::empty(span_2) == false); CHECK(span_2[0] == 1.0_a); CHECK(span_2[1] == 2.0_a); CHECK(span_2[2] == 3.0_a); } TEST_CASE("span_string_view", "[span]") { std::vector raw{ "abc"sv, "def"sv, }; std::span span{raw}; CHECK(span[0] == "abc"sv); CHECK(span[1] == "def"sv); } ================================================ FILE: test/string.cpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ #include #include #include "roq/string.hpp" using namespace std::literals; using namespace roq; static_assert(String<4>{"12"sv} < "2"sv); static_assert(String<4>{"12"sv} == "12"sv); static_assert(String<4>{"2"sv} > "12"sv); TEST_CASE("string_empty", "[string]") { String<4> str; CHECK(str.size() == 4); CHECK(str.length() == 0); // NOLINT(readability-container-size-empty) CHECK(std::empty(str)); auto view = static_cast(str); CHECK(std::empty(view) == true); CHECK(std::size(view) == 0); } TEST_CASE("string_partial", "[string]") { constexpr auto text = "12"sv; String<4> str = text; CHECK(str.size() == 4); CHECK(str.length() == 2); auto view = static_cast(str); CHECK(std::empty(view) == false); CHECK(std::size(view) == 2); CHECK(view == text); } TEST_CASE("string_almost_full", "[string]") { constexpr auto text = "123"sv; String<4> str = text; CHECK(str.size() == 4); CHECK(str.length() == 3); auto view = static_cast(str); CHECK(std::empty(view) == false); CHECK(std::size(view) == 3); CHECK(view == text); } TEST_CASE("string_full", "[string]") { constexpr auto text = "1234"sv; String<4> str = text; CHECK(str.size() == 4); CHECK(str.length() == 4); auto view = static_cast(str); CHECK(std::empty(view) == false); CHECK(std::size(view) == 4); CHECK(view == text); } TEST_CASE("string_construct", "[string]") { String<4>{}; String<4>{"1"sv}; String<4>{"12"sv}; String<4>{"123"sv}; String<4>{"1234"sv}; CHECK_THROWS_AS(String<4>{"12345"sv}, LengthError); } TEST_CASE("string_push_back", "[string]") { String<4> str; CHECK(str.length() == 0); // NOLINT(readability-container-size-empty) CHECK(std::empty(str)); CHECK(str == ""sv); // NOLINT(readability-container-size-empty) str.push_back('1'); CHECK(str.length() == 1); CHECK(str == "1"sv); str.push_back('2'); CHECK(str.length() == 2); CHECK(str == "12"sv); str.push_back('3'); CHECK(str.length() == 3); CHECK(str == "123"sv); str.push_back('4'); CHECK(str.length() == 4); CHECK(str == "1234"sv); CHECK_THROWS_AS(str.push_back('5'), LengthError); } TEST_CASE("string_signed_unsigned_issue", "[string]") { constexpr auto text = "01234567890123456789012345678901234567890123456789012345678901234567890123456789" "01234567890123456789012345678901234567890123456789012345678901234567890123456789"sv; String<192> str = text; CHECK(str.size() == 192); CHECK(str.length() == 160); auto view = static_cast(str); CHECK(std::empty(view) == false); CHECK(std::size(view) == 160); CHECK(view == text); } TEST_CASE("string_spaceship", "[string]") { String<8> str = "1234"sv; // String<8> CHECK(str == String<8>{"1234"sv}); CHECK(str != String<8>{"2345"sv}); CHECK(str < String<8>{"2345"sv}); CHECK(str <= String<8>{"2345"sv}); CHECK(str > String<8>{"0123"sv}); CHECK(str >= String<8>{"0123"sv}); CHECK(str != String<8>{}); // NOLINT(readability-container-size-empty) // String<16> CHECK(str == String<16>{"1234"sv}); CHECK(str != String<16>{"2345"sv}); CHECK(str < String<16>{"2345"sv}); CHECK(str <= String<16>{"2345"sv}); CHECK(str > String<16>{"0123"sv}); CHECK(str >= String<16>{"0123"sv}); CHECK(str != String<16>{}); // NOLINT(readability-container-size-empty) // String<4> CHECK(str == String<4>{"1234"sv}); CHECK(str != String<4>{"2345"sv}); CHECK(str < String<4>{"2345"sv}); CHECK(str <= String<4>{"2345"sv}); CHECK(str > String<4>{"0123"sv}); CHECK(str >= String<4>{"0123"sv}); CHECK(str != String<4>{}); // NOLINT(readability-container-size-empty) // std::string_view CHECK(str == "1234"sv); CHECK(str != "2345"sv); CHECK(str < "2345"sv); CHECK(str <= "2345"sv); CHECK(str > "0123"sv); CHECK(str >= "0123"sv); CHECK(str != std::string_view{}); // NOLINT(readability-container-size-empty) } ================================================ FILE: test/support_type.cpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ #include #include "roq/mask.hpp" #include "roq/support_type.hpp" using namespace std::literals; using namespace roq; TEST_CASE("support_type_format", "[support_type]") { CHECK(fmt::format("{}"sv, SupportType::UNDEFINED) == "UNDEFINED"sv); CHECK(fmt::format("{}"sv, SupportType::REFERENCE_DATA) == "REFERENCE_DATA"sv); // ... CHECK(fmt::format("{}"sv, SupportType::FUNDS) == "FUNDS"sv); } TEST_CASE("support_type_mask_empty", "[support_type]") { auto supports = Mask{}; CHECK(fmt::format("{}"sv, supports) == ""sv); // NOLINT(readability-container-size-empty) } TEST_CASE("support_type_mask_lower_bits", "[support_type]") { auto supports = Mask{ SupportType::REFERENCE_DATA, SupportType::TOP_OF_BOOK, }; REQUIRE(supports.has(SupportType::REFERENCE_DATA)); REQUIRE(supports.has(SupportType::TOP_OF_BOOK)); CHECK(fmt::format("{}"sv, supports) == "REFERENCE_DATA|TOP_OF_BOOK"sv); } TEST_CASE("support_type_mask_higher_bits", "[support_type]") { auto supports = Mask{ SupportType::ORDER_ACK, SupportType::ORDER, SupportType::FUNDS, }; REQUIRE(supports.has(SupportType::ORDER_ACK)); REQUIRE(supports.has(SupportType::ORDER)); REQUIRE(supports.has(SupportType::FUNDS)); CHECK(fmt::format("{}"sv, supports) == "ORDER_ACK|ORDER|FUNDS"sv); } ================================================ FILE: test/version.cpp ================================================ /* Copyright (c) 2017-2026, Hans Erik Thrane */ #include #include "roq/version.hpp" using namespace std::literals; using namespace roq; TEST_CASE("simple", "[version]") { CHECK(Version{1, 2, 3} == Version{1, 2, 3}); CHECK(Version{1, 2, 3} <= Version{1, 2, 3}); CHECK(Version{1, 2, 3} >= Version{1, 2, 3}); CHECK(Version{} < Version{1, 2, 3}); CHECK(Version{} <= Version{1, 2, 3}); CHECK(Version{} != Version{1, 2, 3}); CHECK(Version{1, 2, 3} > Version{}); CHECK(Version{1, 2, 3} >= Version{}); CHECK(Version{1, 2, 3} != Version{}); }