19 uint8_t* data = (uint8_t*)buffer;
25 size_t remaining = size - index;
28 if (((_cache.size() == 0) && (remaining < 3)) || (_cache.size() == 1))
30 _cache.push_back(data[index++]);
35 uint16_t message_size;
39 index += CppCommon::Endian::ReadBigEndian(&data[index], message_size);
44 CppCommon::Endian::ReadBigEndian(_cache.data(), message_size);
55 size_t remaining = size - index;
60 size_t tail = _size - _cache.size();
63 _cache.insert(_cache.end(), &data[index], &data[index + tail]);
65 if (_cache.size() < _size)
68 else if (_size > remaining)
70 _cache.reserve(_size);
71 _cache.insert(_cache.end(), &data[index], &data[index + remaining]);
108 uint8_t* data = (uint8_t*)buffer;
113 return ProcessSystemEventMessage(data, size);
115 return ProcessStockDirectoryMessage(data, size);
117 return ProcessStockTradingActionMessage(data, size);
119 return ProcessRegSHOMessage(data, size);
121 return ProcessMarketParticipantPositionMessage(data, size);
123 return ProcessMWCBDeclineMessage(data, size);
125 return ProcessMWCBStatusMessage(data, size);
127 return ProcessIPOQuotingMessage(data, size);
129 return ProcessAddOrderMessage(data, size);
131 return ProcessAddOrderMPIDMessage(data, size);
133 return ProcessOrderExecutedMessage(data, size);
135 return ProcessOrderExecutedWithPriceMessage(data, size);
137 return ProcessOrderCancelMessage(data, size);
139 return ProcessOrderDeleteMessage(data, size);
141 return ProcessOrderReplaceMessage(data, size);
143 return ProcessTradeMessage(data, size);
145 return ProcessCrossTradeMessage(data, size);
147 return ProcessBrokenTradeMessage(data, size);
149 return ProcessNOIIMessage(data, size);
151 return ProcessRPIIMessage(data, size);
153 return ProcessLULDAuctionCollarMessage(data, size);
155 return ProcessUnknownMessage(data, size);
165 bool ITCHHandler::ProcessSystemEventMessage(
void* buffer,
size_t size)
167 assert((size == 12) &&
"Invalid size of the ITCH message type 'S'");
171 uint8_t* data = (uint8_t*)buffer;
174 message.
Type = *data++;
175 data += CppCommon::Endian::ReadBigEndian(data, message.
StockLocate);
176 data += CppCommon::Endian::ReadBigEndian(data, message.
TrackingNumber);
177 data += ReadTimestamp(data, message.
Timestamp);
183 bool ITCHHandler::ProcessStockDirectoryMessage(
void* buffer,
size_t size)
185 assert((size == 39) &&
"Invalid size of the ITCH message type 'R'");
189 uint8_t* data = (uint8_t*)buffer;
191 StockDirectoryMessage message;
192 message.Type = *data++;
193 data += CppCommon::Endian::ReadBigEndian(data, message.StockLocate);
194 data += CppCommon::Endian::ReadBigEndian(data, message.TrackingNumber);
195 data += ReadTimestamp(data, message.Timestamp);
196 data += ReadString(data, message.Stock);
197 message.MarketCategory = *data++;
198 message.FinancialStatusIndicator = *data++;
199 data += CppCommon::Endian::ReadBigEndian(data, message.RoundLotSize);
200 message.RoundLotsOnly = *data++;
201 message.IssueClassification = *data++;
202 data += ReadString(data, message.IssueSubType);
203 message.Authenticity = *data++;
204 message.ShortSaleThresholdIndicator = *data++;
205 message.IPOFlag = *data++;
206 message.LULDReferencePriceTier = *data++;
207 message.ETPFlag = *data++;
208 data += CppCommon::Endian::ReadBigEndian(data, message.ETPLeverageFactor);
209 message.InverseIndicator = *data++;
214 bool ITCHHandler::ProcessStockTradingActionMessage(
void* buffer,
size_t size)
216 assert((size == 25) &&
"Invalid size of the ITCH message type 'H'");
220 uint8_t* data = (uint8_t*)buffer;
222 StockTradingActionMessage message;
223 message.Type = *data++;
224 data += CppCommon::Endian::ReadBigEndian(data, message.StockLocate);
225 data += CppCommon::Endian::ReadBigEndian(data, message.TrackingNumber);
226 data += ReadTimestamp(data, message.Timestamp);
227 data += ReadString(data, message.Stock);
228 message.TradingState = *data++;
229 message.Reserved = *data++;
230 message.Reason = *data++;
235 bool ITCHHandler::ProcessRegSHOMessage(
void* buffer,
size_t size)
237 assert((size == 20) &&
"Invalid size of the ITCH message type 'Y'");
241 uint8_t* data = (uint8_t*)buffer;
243 RegSHOMessage message;
244 message.Type = *data++;
245 data += CppCommon::Endian::ReadBigEndian(data, message.StockLocate);
246 data += CppCommon::Endian::ReadBigEndian(data, message.TrackingNumber);
247 data += ReadTimestamp(data, message.Timestamp);
248 data += ReadString(data, message.Stock);
249 message.RegSHOAction = *data++;
254 bool ITCHHandler::ProcessMarketParticipantPositionMessage(
void* buffer,
size_t size)
256 assert((size == 26) &&
"Invalid size of the ITCH message type 'L'");
260 uint8_t* data = (uint8_t*)buffer;
262 MarketParticipantPositionMessage message;
263 message.Type = *data++;
264 data += CppCommon::Endian::ReadBigEndian(data, message.StockLocate);
265 data += CppCommon::Endian::ReadBigEndian(data, message.TrackingNumber);
266 data += ReadTimestamp(data, message.Timestamp);
267 data += ReadString(data, message.MPID);
268 data += ReadString(data, message.Stock);
269 message.PrimaryMarketMaker = *data++;
270 message.MarketMakerMode = *data++;
271 message.MarketParticipantState = *data++;
276 bool ITCHHandler::ProcessMWCBDeclineMessage(
void* buffer,
size_t size)
278 assert((size == 35) &&
"Invalid size of the ITCH message type 'V'");
282 uint8_t* data = (uint8_t*)buffer;
284 MWCBDeclineMessage message;
285 message.Type = *data++;
286 data += CppCommon::Endian::ReadBigEndian(data, message.StockLocate);
287 data += CppCommon::Endian::ReadBigEndian(data, message.TrackingNumber);
288 data += ReadTimestamp(data, message.Timestamp);
289 data += CppCommon::Endian::ReadBigEndian(data, message.Level1);
290 data += CppCommon::Endian::ReadBigEndian(data, message.Level2);
291 data += CppCommon::Endian::ReadBigEndian(data, message.Level3);
296 bool ITCHHandler::ProcessMWCBStatusMessage(
void* buffer,
size_t size)
298 assert((size == 12) &&
"Invalid size of the ITCH message type 'W'");
302 uint8_t* data = (uint8_t*)buffer;
304 MWCBStatusMessage message;
305 message.Type = *data++;
306 data += CppCommon::Endian::ReadBigEndian(data, message.StockLocate);
307 data += CppCommon::Endian::ReadBigEndian(data, message.TrackingNumber);
308 data += ReadTimestamp(data, message.Timestamp);
309 message.BreachedLevel = *data++;
314 bool ITCHHandler::ProcessIPOQuotingMessage(
void* buffer,
size_t size)
316 assert((size == 28) &&
"Invalid size of the ITCH message type 'W'");
320 uint8_t* data = (uint8_t*)buffer;
322 IPOQuotingMessage message;
323 message.Type = *data++;
324 data += CppCommon::Endian::ReadBigEndian(data, message.StockLocate);
325 data += CppCommon::Endian::ReadBigEndian(data, message.TrackingNumber);
326 data += ReadTimestamp(data, message.Timestamp);
327 data += ReadString(data, message.Stock);
328 data += CppCommon::Endian::ReadBigEndian(data, message.IPOReleaseTime);
329 message.IPOReleaseQualifier = *data++;
330 data += CppCommon::Endian::ReadBigEndian(data, message.IPOPrice);
335 bool ITCHHandler::ProcessAddOrderMessage(
void* buffer,
size_t size)
337 assert((size == 36) &&
"Invalid size of the ITCH message type 'A'");
341 uint8_t* data = (uint8_t*)buffer;
343 AddOrderMessage message;
344 message.Type = *data++;
345 data += CppCommon::Endian::ReadBigEndian(data, message.StockLocate);
346 data += CppCommon::Endian::ReadBigEndian(data, message.TrackingNumber);
347 data += ReadTimestamp(data, message.Timestamp);
348 data += CppCommon::Endian::ReadBigEndian(data, message.OrderReferenceNumber);
349 message.BuySellIndicator = *data++;
350 data += CppCommon::Endian::ReadBigEndian(data, message.Shares);
351 data += ReadString(data, message.Stock);
352 data += CppCommon::Endian::ReadBigEndian(data, message.Price);
357 bool ITCHHandler::ProcessAddOrderMPIDMessage(
void* buffer,
size_t size)
359 assert((size == 40) &&
"Invalid size of the ITCH message type 'F'");
363 uint8_t* data = (uint8_t*)buffer;
365 AddOrderMPIDMessage message;
366 message.Type = *data++;
367 data += CppCommon::Endian::ReadBigEndian(data, message.StockLocate);
368 data += CppCommon::Endian::ReadBigEndian(data, message.TrackingNumber);
369 data += ReadTimestamp(data, message.Timestamp);
370 data += CppCommon::Endian::ReadBigEndian(data, message.OrderReferenceNumber);
371 message.BuySellIndicator = *data++;
372 data += CppCommon::Endian::ReadBigEndian(data, message.Shares);
373 data += ReadString(data, message.Stock);
374 data += CppCommon::Endian::ReadBigEndian(data, message.Price);
375 message.Attribution = *data++;
380 bool ITCHHandler::ProcessOrderExecutedMessage(
void* buffer,
size_t size)
382 assert((size == 31) &&
"Invalid size of the ITCH message type 'E'");
386 uint8_t* data = (uint8_t*)buffer;
388 OrderExecutedMessage message;
389 message.Type = *data++;
390 data += CppCommon::Endian::ReadBigEndian(data, message.StockLocate);
391 data += CppCommon::Endian::ReadBigEndian(data, message.TrackingNumber);
392 data += ReadTimestamp(data, message.Timestamp);
393 data += CppCommon::Endian::ReadBigEndian(data, message.OrderReferenceNumber);
394 data += CppCommon::Endian::ReadBigEndian(data, message.ExecutedShares);
395 data += CppCommon::Endian::ReadBigEndian(data, message.MatchNumber);
400 bool ITCHHandler::ProcessOrderExecutedWithPriceMessage(
void* buffer,
size_t size)
402 assert((size == 36) &&
"Invalid size of the ITCH message type 'C'");
406 uint8_t* data = (uint8_t*)buffer;
408 OrderExecutedWithPriceMessage message;
409 message.Type = *data++;
410 data += CppCommon::Endian::ReadBigEndian(data, message.StockLocate);
411 data += CppCommon::Endian::ReadBigEndian(data, message.TrackingNumber);
412 data += ReadTimestamp(data, message.Timestamp);
413 data += CppCommon::Endian::ReadBigEndian(data, message.OrderReferenceNumber);
414 data += CppCommon::Endian::ReadBigEndian(data, message.ExecutedShares);
415 data += CppCommon::Endian::ReadBigEndian(data, message.MatchNumber);
416 message.Printable = *data++;
417 data += CppCommon::Endian::ReadBigEndian(data, message.ExecutionPrice);
422 bool ITCHHandler::ProcessOrderCancelMessage(
void* buffer,
size_t size)
424 assert((size == 23) &&
"Invalid size of the ITCH message type 'X'");
428 uint8_t* data = (uint8_t*)buffer;
430 OrderCancelMessage message;
431 message.Type = *data++;
432 data += CppCommon::Endian::ReadBigEndian(data, message.StockLocate);
433 data += CppCommon::Endian::ReadBigEndian(data, message.TrackingNumber);
434 data += ReadTimestamp(data, message.Timestamp);
435 data += CppCommon::Endian::ReadBigEndian(data, message.OrderReferenceNumber);
436 data += CppCommon::Endian::ReadBigEndian(data, message.CanceledShares);
441 bool ITCHHandler::ProcessOrderDeleteMessage(
void* buffer,
size_t size)
443 assert((size == 19) &&
"Invalid size of the ITCH message type 'D'");
447 uint8_t* data = (uint8_t*)buffer;
449 OrderDeleteMessage message;
450 message.Type = *data++;
451 data += CppCommon::Endian::ReadBigEndian(data, message.StockLocate);
452 data += CppCommon::Endian::ReadBigEndian(data, message.TrackingNumber);
453 data += ReadTimestamp(data, message.Timestamp);
454 data += CppCommon::Endian::ReadBigEndian(data, message.OrderReferenceNumber);
459 bool ITCHHandler::ProcessOrderReplaceMessage(
void* buffer,
size_t size)
461 assert((size == 35) &&
"Invalid size of the ITCH message type 'U'");
465 uint8_t* data = (uint8_t*)buffer;
467 OrderReplaceMessage message;
468 message.Type = *data++;
469 data += CppCommon::Endian::ReadBigEndian(data, message.StockLocate);
470 data += CppCommon::Endian::ReadBigEndian(data, message.TrackingNumber);
471 data += ReadTimestamp(data, message.Timestamp);
472 data += CppCommon::Endian::ReadBigEndian(data, message.OriginalOrderReferenceNumber);
473 data += CppCommon::Endian::ReadBigEndian(data, message.NewOrderReferenceNumber);
474 data += CppCommon::Endian::ReadBigEndian(data, message.Shares);
475 data += CppCommon::Endian::ReadBigEndian(data, message.Price);
480 bool ITCHHandler::ProcessTradeMessage(
void* buffer,
size_t size)
482 assert((size == 44) &&
"Invalid size of the ITCH message type 'P'");
486 uint8_t* data = (uint8_t*)buffer;
488 TradeMessage message;
489 message.Type = *data++;
490 data += CppCommon::Endian::ReadBigEndian(data, message.StockLocate);
491 data += CppCommon::Endian::ReadBigEndian(data, message.TrackingNumber);
492 data += ReadTimestamp(data, message.Timestamp);
493 data += CppCommon::Endian::ReadBigEndian(data, message.OrderReferenceNumber);
494 message.BuySellIndicator = *data++;
495 data += CppCommon::Endian::ReadBigEndian(data, message.Shares);
496 data += ReadString(data, message.Stock);
497 data += CppCommon::Endian::ReadBigEndian(data, message.Price);
498 data += CppCommon::Endian::ReadBigEndian(data, message.MatchNumber);
503 bool ITCHHandler::ProcessCrossTradeMessage(
void* buffer,
size_t size)
505 assert((size == 40) &&
"Invalid size of the ITCH message type 'Q'");
509 uint8_t* data = (uint8_t*)buffer;
511 CrossTradeMessage message;
512 message.Type = *data++;
513 data += CppCommon::Endian::ReadBigEndian(data, message.StockLocate);
514 data += CppCommon::Endian::ReadBigEndian(data, message.TrackingNumber);
515 data += ReadTimestamp(data, message.Timestamp);
516 data += CppCommon::Endian::ReadBigEndian(data, message.Shares);
517 data += ReadString(data, message.Stock);
518 data += CppCommon::Endian::ReadBigEndian(data, message.CrossPrice);
519 data += CppCommon::Endian::ReadBigEndian(data, message.MatchNumber);
520 message.CrossType = *data++;
525 bool ITCHHandler::ProcessBrokenTradeMessage(
void* buffer,
size_t size)
527 assert((size == 19) &&
"Invalid size of the ITCH message type 'B'");
531 uint8_t* data = (uint8_t*)buffer;
533 BrokenTradeMessage message;
534 message.Type = *data++;
535 data += CppCommon::Endian::ReadBigEndian(data, message.StockLocate);
536 data += CppCommon::Endian::ReadBigEndian(data, message.TrackingNumber);
537 data += ReadTimestamp(data, message.Timestamp);
538 data += CppCommon::Endian::ReadBigEndian(data, message.MatchNumber);
543 bool ITCHHandler::ProcessNOIIMessage(
void* buffer,
size_t size)
545 assert((size == 50) &&
"Invalid size of the ITCH message type 'I'");
549 uint8_t* data = (uint8_t*)buffer;
552 message.Type = *data++;
553 data += CppCommon::Endian::ReadBigEndian(data, message.StockLocate);
554 data += CppCommon::Endian::ReadBigEndian(data, message.TrackingNumber);
555 data += ReadTimestamp(data, message.Timestamp);
556 data += CppCommon::Endian::ReadBigEndian(data, message.PairedShares);
557 data += CppCommon::Endian::ReadBigEndian(data, message.ImbalanceShares);
558 message.ImbalanceDirection = *data++;
559 data += ReadString(data, message.Stock);
560 data += CppCommon::Endian::ReadBigEndian(data, message.FarPrice);
561 data += CppCommon::Endian::ReadBigEndian(data, message.NearPrice);
562 data += CppCommon::Endian::ReadBigEndian(data, message.CurrentReferencePrice);
563 message.CrossType = *data++;
564 message.PriceVariationIndicator = *data++;
569 bool ITCHHandler::ProcessRPIIMessage(
void* buffer,
size_t size)
571 assert((size == 20) &&
"Invalid size of the ITCH message type 'N'");
575 uint8_t* data = (uint8_t*)buffer;
578 message.Type = *data++;
579 data += CppCommon::Endian::ReadBigEndian(data, message.StockLocate);
580 data += CppCommon::Endian::ReadBigEndian(data, message.TrackingNumber);
581 data += ReadTimestamp(data, message.Timestamp);
582 data += ReadString(data, message.Stock);
583 message.InterestFlag = *data++;
588 bool ITCHHandler::ProcessLULDAuctionCollarMessage(
void* buffer,
size_t size)
590 assert((size == 35) &&
"Invalid size of the ITCH message type 'J'");
594 uint8_t* data = (uint8_t*)buffer;
596 LULDAuctionCollarMessage message;
597 message.Type = *data++;
598 data += CppCommon::Endian::ReadBigEndian(data, message.StockLocate);
599 data += CppCommon::Endian::ReadBigEndian(data, message.TrackingNumber);
600 data += ReadTimestamp(data, message.Timestamp);
601 data += ReadString(data, message.Stock);
602 data += CppCommon::Endian::ReadBigEndian(data, message.AuctionCollarReferencePrice);
603 data += CppCommon::Endian::ReadBigEndian(data, message.UpperAuctionCollarPrice);
604 data += CppCommon::Endian::ReadBigEndian(data, message.LowerAuctionCollarPrice);
605 data += CppCommon::Endian::ReadBigEndian(data, message.AuctionCollarExtension);
610 bool ITCHHandler::ProcessUnknownMessage(
void* buffer,
size_t size)
612 assert((size > 0) &&
"Invalid size of the unknown ITCH message!");
616 uint8_t* data = (uint8_t*)buffer;
618 UnknownMessage message;
619 message.Type = *data;
virtual bool onMessage(const SystemEventMessage &message)
bool ProcessMessage(void *buffer, size_t size)
Process a single message from the given buffer in ITCH format and call corresponding handlers.
bool Process(void *buffer, size_t size)
Process all messages from the given buffer in ITCH format and call corresponding handlers.
void Reset()
Reset ITCH handler.
NASDAQ ITCH handler definition.
C++ Trader project definitions.