The SDK API hides protocol details and provides direct access to high-level entities like security definitions, trading information, and books. Events are exposed by the handler to allow the users to build books by themselves using atomic update information.
The handler provides access to network packets as the handler captures them.
The OnixS::CME::MDH::MarketDataListener class represents a collection of events related to the network packet and message processing. An instance of the listener can be associated with the handler using the OnixS::CME::MDH::HandlerListeners::marketData member and the handler.settings().listeners().marketData(&listener) path in the handler's settings.
The handler notifies the client code when it begins and finishes the processing of various logical parts of market data. The handler calls the OnixS::CME::MDH::MarketDataListener::onPacket member when it starts processing a received packet. The handler invokes the OnixS::CME::MDH::MarketDataListener::onEndOfPacket member when it finishes the processing of the received packet.
The handler invokes similar callbacks when it processes each message belonging to a received packet.
This feature requires an SDK configured for C++20 or later (ONIXS_CMEMDH_CXX20 defined). SbeGroupRange, the Range aliases, and asRange() are unavailable in SDKs configured for earlier standards, even when the application is compiled with C++20 or later.
Call asRange() on an SBE repeating group or its entries wrapper to use standard input-iterator algorithms and C++20 forward-range algorithms. Include the standard algorithm and ranges headers:
The IncrementalRefreshBook46 message callback below counts bid entries, selects the first five bid instrument IDs with C++20 views, and groups adjacent equal IDs with C++23 chunk_by when the standard library provides it. The last pipeline skips the first group and preserves message order.
Dereferencing returns an entry view by value. A copy of that view refers to the same message bytes, and its field setters modify those bytes. Iterator copies advance independently; retain an entry with auto entry = *iterator or const auto& entry = *iterator. Read fields with iterator->securityId(); the arrow proxy holds a temporary entry view for the expression. Pointers to that view must not outlive the proxy. There is no stable Entry&.
The adapter's legacy iterator category is input; its C++20 iterator concept is forward. Use entries.size() for a constant-time total count. std::distance and positive std::advance traverse the adapter linearly. Adapter iterators support forward traversal; backward std::advance/std::prev are unsupported.
Existing group Iterator types, typedefs, and begin()/end() retain their original behavior for source compatibility, including explicit decrement and offset arithmetic. Their historical traits do not describe a conforming random-access iterator. Opt into standard algorithms through asRange().
Group wrappers, adapters, iterators, and entry views borrow the message storage. The adapter copies iterator positions and the entry count, so it may outlive the group wrapper that created it. The adapter models std::ranges::view; standard view adaptors copy it even when it is named. A pipeline may therefore outlive the source adapter while the message storage remains alive and valid. The adapter also models std::ranges::borrowed_range, so algorithms such as std::ranges::find_if(group.asRange(), predicate) return a usable iterator instead of std::ranges::dangling. Iterators may outlive the adapter while the message storage remains alive and valid. Reacquire affected views after group resizing, relocation, reconstruction, or buffer reuse. Ordinary field changes preserve iterator positions. Views must not outlive the storage, which may be reused after a handler callback returns.
Packets obtained from different feeds (e.g., Market Recovery Feeds and Instrument) have uncorrelated sequence numbers. Therefore, the user code must not rely on that packets are lined up into a single sequence.