18 template <
typename IntType>
19 auto put(IntType value) ->
void {
20 const auto big = utils::from_big_endian(value);
21 std::array<std::byte,
sizeof(IntType)> bytes {};
22 std::memcpy(bytes.data(), &big,
sizeof(IntType));
23 m_bytes.insert(m_bytes.end(), bytes.begin(), bytes.end());
26 auto put_char(
char value) ->
void { m_bytes.push_back(
static_cast<std::byte
>(value)); }
29 auto put_chars(
const char* source, std::size_t size) ->
void {
30 for (std::size_t index = 0; index < size; ++index) {
31 m_bytes.push_back(
static_cast<std::byte
>(source[index]));
36 auto put_timestamp(std::uint64_t
timestamp) ->
void {
37 constexpr int LOWER_SHIFT = 32;
38 put<std::uint16_t>(
static_cast<std::uint16_t
>(
timestamp >> LOWER_SHIFT));
39 put<std::uint32_t>(
static_cast<std::uint32_t
>(
timestamp & 0xFFFFFFFFULL));
42 [[nodiscard]]
auto take() -> std::vector<std::byte> {
return std::move(m_bytes); }
45 std::vector<std::byte> m_bytes;
49template <
typename MsgType>
50auto write_header(ByteWriter& writer,
const MsgType& msg) ->
void {
51 writer.put_char(msg.message_type);
52 writer.put<std::uint16_t>(msg.stock_locate);
53 writer.put<std::uint16_t>(msg.tracking_number);
54 writer.put_timestamp(msg.timestamp);
57auto write_body(ByteWriter& writer,
const SystemEventMessage& msg) ->
void {
58 writer.put_char(msg.event_code);
61auto write_body(ByteWriter& writer,
const StockDirectoryMessage& msg) ->
void {
63 writer.put_char(msg.market_category);
64 writer.put_char(msg.financial_status_indicator);
65 writer.put<std::uint32_t>(msg.round_lot_size);
66 writer.put_char(msg.round_lots_only);
67 writer.put_char(msg.issue_classification);
68 writer.put_chars(msg.issue_sub_type, 2);
69 writer.put_char(msg.authenticity);
70 writer.put_char(msg.short_sale_threshold_indicator);
71 writer.put_char(msg.ipo_flag);
72 writer.put_char(msg.luld_ref);
73 writer.put_char(msg.etp_flag);
74 writer.put<std::uint32_t>(msg.etp_leverage_factor);
75 writer.put_char(msg.inverse_indicator);
78auto write_body(ByteWriter& writer,
const StockTradingActionMessage& msg) ->
void {
80 writer.put_char(msg.trading_state);
81 writer.put_char(msg.reserved);
82 writer.put_chars(msg.reason, 4);
85auto write_body(ByteWriter& writer,
const RegSHOMessage& msg) ->
void {
87 writer.put_char(msg.reg_sho_action);
90auto write_body(ByteWriter& writer,
const MarketParticipantPositionMessage& msg) ->
void {
91 writer.put_chars(msg.mpid, 4);
93 writer.put_char(msg.primary_market_maker);
94 writer.put_char(msg.market_maker_mode);
95 writer.put_char(msg.market_participant_state);
98auto write_body(ByteWriter& writer,
const MWCBDeclineLevelMessage& msg) ->
void {
99 writer.put<std::uint64_t>(msg.level1);
100 writer.put<std::uint64_t>(msg.level2);
101 writer.put<std::uint64_t>(msg.level3);
104auto write_body(ByteWriter& writer,
const MWCBStatusMessage& msg) ->
void {
105 writer.put_char(msg.breached_level);
108auto write_body(ByteWriter& writer,
const IPOQuotingPeriodUpdateMessage& msg) ->
void {
110 writer.put<std::uint32_t>(msg.ipo_quotation_release_time);
111 writer.put_char(msg.ipo_quotation_release_qualifier);
112 writer.put<std::uint32_t>(msg.ipo_price);
115auto write_body(ByteWriter& writer,
const LULDAuctionCollarMessage& msg) ->
void {
117 writer.put<std::uint32_t>(msg.auction_collar_reference_price);
118 writer.put<std::uint32_t>(msg.upper_auction_collar_price);
119 writer.put<std::uint32_t>(msg.lower_auction_collar_price);
120 writer.put<std::uint32_t>(msg.auction_collar_extension);
123auto write_body(ByteWriter& writer,
const OperationalHaltMessage& msg) ->
void {
125 writer.put_char(msg.market_code);
126 writer.put_char(msg.operational_halt_action);
129auto write_body(ByteWriter& writer,
const AddOrderMessage& msg) ->
void {
130 writer.put<std::uint64_t>(msg.order_reference_number);
131 writer.put_char(msg.buy_sell_indicator);
132 writer.put<std::uint32_t>(msg.shares);
134 writer.put<std::uint32_t>(msg.price);
137auto write_body(ByteWriter& writer,
const AddOrderMPIDAttributionMessage& msg) ->
void {
138 writer.put<std::uint64_t>(msg.order_reference_number);
139 writer.put_char(msg.buy_sell_indicator);
140 writer.put<std::uint32_t>(msg.shares);
142 writer.put<std::uint32_t>(msg.price);
143 writer.put_chars(msg.attribution, 4);
146auto write_body(ByteWriter& writer,
const OrderExecutedMessage& msg) ->
void {
147 writer.put<std::uint64_t>(msg.order_reference_number);
148 writer.put<std::uint32_t>(msg.executed_shares);
149 writer.put<std::uint64_t>(msg.match_number);
152auto write_body(ByteWriter& writer,
const OrderExecutedWithPriceMessage& msg) ->
void {
153 writer.put<std::uint64_t>(msg.order_reference_number);
154 writer.put<std::uint32_t>(msg.executed_shares);
155 writer.put<std::uint64_t>(msg.match_number);
156 writer.put_char(msg.printable);
157 writer.put<std::uint32_t>(msg.execution_price);
160auto write_body(ByteWriter& writer,
const OrderCancelMessage& msg) ->
void {
161 writer.put<std::uint64_t>(msg.order_reference_number);
162 writer.put<std::uint32_t>(msg.cancelled_shares);
165auto write_body(ByteWriter& writer,
const OrderDeleteMessage& msg) ->
void {
166 writer.put<std::uint64_t>(msg.order_reference_number);
169auto write_body(ByteWriter& writer,
const OrderReplaceMessage& msg) ->
void {
170 writer.put<std::uint64_t>(msg.original_order_reference_number);
171 writer.put<std::uint64_t>(msg.new_order_reference_number);
172 writer.put<std::uint32_t>(msg.shares);
173 writer.put<std::uint32_t>(msg.price);
176auto write_body(ByteWriter& writer,
const NonCrossTradeMessage& msg) ->
void {
177 writer.put<std::uint64_t>(msg.order_reference_number);
178 writer.put_char(msg.buy_sell_indicator);
179 writer.put<std::uint32_t>(msg.shares);
181 writer.put<std::uint32_t>(msg.price);
182 writer.put<std::uint64_t>(msg.match_number);
185auto write_body(ByteWriter& writer,
const CrossTradeMessage& msg) ->
void {
186 writer.put<std::uint64_t>(msg.shares);
188 writer.put<std::uint32_t>(msg.cross_price);
189 writer.put<std::uint64_t>(msg.match_number);
190 writer.put_char(msg.cross_type);
193auto write_body(ByteWriter& writer,
const BrokenTradeMessage& msg) ->
void {
194 writer.put<std::uint64_t>(msg.match_number);
197auto write_body(ByteWriter& writer,
const NOIIMessage& msg) ->
void {
198 writer.put<std::uint64_t>(msg.paired_shares);
199 writer.put<std::uint64_t>(msg.imbalance_shares);
200 writer.put_char(msg.imbalance_direction);
202 writer.put<std::uint32_t>(msg.far_price);
203 writer.put<std::uint32_t>(msg.near_price);
204 writer.put<std::uint32_t>(msg.current_reference_price);
205 writer.put_char(msg.cross_type);
206 writer.put_char(msg.price_variation_indicator);
209auto write_body(ByteWriter& writer,
const RetailPriceImprovementIndicatorMessage& msg) ->
void {
211 writer.put_char(msg.interest_flag);
214auto write_body(ByteWriter& writer,
const DLCRMessage& msg) ->
void {
216 writer.put_char(msg.open_eligibility_status);
217 writer.put<std::uint32_t>(msg.minimum_allowable_price);
218 writer.put<std::uint32_t>(msg.maximum_allowable_price);
219 writer.put<std::uint32_t>(msg.near_execution_price);
220 writer.put<std::uint64_t>(msg.near_execution_time);
221 writer.put<std::uint32_t>(msg.lower_price_range_collar);
222 writer.put<std::uint32_t>(msg.upper_price_range_collar);
230 [&writer](
const auto& concrete) {
231 write_header(writer, concrete);
232 write_body(writer, concrete);
236 return writer.take();
242 writer.put<std::uint16_t>(
static_cast<std::uint16_t
>(body.size()));
243 std::vector<std::byte> frame = writer.take();
244 frame.insert(frame.end(), body.begin(), body.end());
Serializes parsed ITCH messages back to valid wire bytes.
std::variant< SystemEventMessage, StockDirectoryMessage, StockTradingActionMessage, RegSHOMessage, MarketParticipantPositionMessage, MWCBDeclineLevelMessage, MWCBStatusMessage, IPOQuotingPeriodUpdateMessage, LULDAuctionCollarMessage, OperationalHaltMessage, AddOrderMessage, AddOrderMPIDAttributionMessage, OrderExecutedMessage, OrderExecutedWithPriceMessage, OrderCancelMessage, OrderDeleteMessage, OrderReplaceMessage, NonCrossTradeMessage, CrossTradeMessage, BrokenTradeMessage, NOIIMessage, RetailPriceImprovementIndicatorMessage, DLCRMessage > Message
A variant able to hold any one of the ITCH 5.0 message structs.
auto encode_message(const Message &message) -> std::vector< std::byte >
Encodes a message body and header without the 2-byte length prefix.
auto encode_frame(const Message &message) -> std::vector< std::byte >
Encodes a complete length-prefixed frame (2-byte big-endian length followed by the message bytes),...
Public parsing interface for NASDAQ TotalView-ITCH 5.0 feeds, plus the low-level byte-unpacking utili...