libjmmcg  release_579_6_g8cffd
A C++ library containing an eclectic mix of useful, advanced components.
messages.hpp
Go to the documentation of this file.
1 #ifndef ISIMUD_EXCHANGES_MIT_BIT_MESSAGES_HPP
2 #define ISIMUD_EXCHANGES_MIT_BIT_MESSAGES_HPP
3 
4 /******************************************************************************
5 ** Copyright © 2015 by J.M.McGuiness, isimud@hussar.me.uk
6 **
7 ** This library is free software; you can redistribute it and/or
8 ** modify it under the terms of the GNU Lesser General Public
9 ** License as published by the Free Software Foundation; either
10 ** version 2.1 of the License, or (at your option) any later version.
11 **
12 ** This library is distributed in the hope that it will be useful,
13 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 ** Lesser General Public License for more details.
16 **
17 ** You should have received a copy of the GNU Lesser General Public
18 ** License along with this library; if not, write to the Free Software
19 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21 
22 #include "config.h"
23 #include "reject_codes.hpp"
24 
25 #include "../common/messages.hpp"
26 #include "../common/ref_data.hpp"
27 
28 #include "core/max_min.hpp"
29 
30 #include <boost/mpl/assert.hpp>
31 #include <boost/mpl/deref.hpp>
32 #include <boost/mpl/max_element.hpp>
33 #include <boost/mpl/min_element.hpp>
34 #include <boost/mpl/placeholders.hpp>
35 #include <boost/mpl/sizeof.hpp>
36 #include <boost/mpl/transform_view.hpp>
37 #include <boost/mpl/vector.hpp>
38 #include <boost/variant/variant.hpp>
39 
40 #include <iostream>
41 
42 namespace isimud { namespace ISIMUD_VER_NAMESPACE { namespace exchanges { namespace MIT {
43 
44 /**
45  From <a href="http://www.borsaitaliana.it/borsaitaliana/gestione-mercati/migrazionemillenniumit-mit/mit203nativetradinggatewayspecification.en_pdf.htm">"MIT203 - BIT - MILLENNIUM EXCHANGE Native Trading Gateway", Issue 6.4, October 2014</a>.
46 */
47 namespace BIT {
48 
49 /**
50  Section: "7.4.1 New Order"
51 */
53  common::SecurityID_t instrumentID_;
54  const std::int8_t reservedField1=0;
55  const std::int8_t reservedField2=0;
56 
57  explicit constexpr NewOrderSpecific1(common::SecurityID_t instID) noexcept(true) FORCE_INLINE
58  : instrumentID_(instID) {
59  }
60  common::SecurityID_t instrumentID() const noexcept(true) {
61  return instrumentID_;
62  }
63  void instrumentID(common::SecurityID_t i) noexcept(true) {
64  instrumentID_=i;
65  }
66 } __attribute__((packed));
68  using order_qty_t=std::uint64_t;
69 
70  order_qty_t orderQty_;
71  order_qty_t displayQty;
72 
73  explicit constexpr NewOrderSpecific2(order_qty_t ordQty) noexcept(true) FORCE_INLINE
74  : orderQty_(ordQty), displayQty(ordQty) {
75  }
76  order_qty_t orderQty() const noexcept(true) {
77  return orderQty_;
78  }
79  void orderQty(order_qty_t i) noexcept(true) {
80  orderQty_=i;
81  }
82 } __attribute__((packed));
85  common::Price_t stoppedPrice=0;
86  common::ReservedField10_t reservedField;
88 
89  static constexpr common::PassiveOnlyOrder FORCE_INLINE passiveOnlyOrder() noexcept(true) {
91  }
92  static void FORCE_INLINE passiveOnlyOrder(common::PassiveOnlyOrder) noexcept(true) {
93  }
94  common::OrderSource FORCE_INLINE orderSource() const noexcept(true) {
95  return orderSource_;
96  }
97  void FORCE_INLINE orderSource(common::OrderSource os) noexcept(true) {
98  orderSource_=os;
99  }
100 } __attribute__((packed));
101 
102 /**
103  Section: "7.4.2 New Quote"
104 */
106  common::Price_t bidPrice;
107  uint64_t bidSize;
108  common::Price_t askPrice;
109  uint64_t askSize;
110 } __attribute__((packed));
112  common::ReservedField10_t reservedField;
115 } __attribute__((packed));
116 
117 /**
118  Section: "7.4.5 Order Modification Request"
119 */
121  common::ReservedField10_t reservedField;
122 
123  static constexpr common::PassiveOnlyOrder FORCE_INLINE passiveOnlyOrder() noexcept(true) {
125  }
126  static void FORCE_INLINE passiveOnlyOrder(common::PassiveOnlyOrder) noexcept(true) {
127  }
128 } __attribute__((packed));
129 
130 /**
131  Section: "7.4.8 Execution Report"
132 */
134  using RejectCode_t=mit_bit::reject_codes_enum;
136  using order_qty_t=std::uint64_t;
137 
138  order_qty_t executedQty;
139  order_qty_t leavesQty;
141  uint64_t displayQty;
142 } __attribute__((packed));
144  common::ReservedField10_t reservedField1;
146  common::Price_t avgPx;
148  common::CrossID_t crossID;
149  uint8_t crossType;
152  common::OrderID_t publicOrderID;
154 } __attribute__((packed));
155 
157  common::SecurityID_t instrumentID_;
158  const std::int8_t reservedField1=0;
159  const std::int8_t reservedField2=0;
160  common::Segment_t segment{};
161 
162  explicit constexpr OrderMassCancelRequestSpecific1(common::SecurityID_t instID) noexcept(true) FORCE_INLINE
163  : instrumentID_(instID) {
164  }
165  common::SecurityID_t instrumentID() const noexcept(true) {
166  return instrumentID_;
167  }
168  void instrumentID(common::SecurityID_t i) noexcept(true) {
169  instrumentID_=i;
170  }
171 } __attribute__((packed));
172 
174  using base_t=common::LogonReply<mit_bit::reject_codes_enum>;
177  using base_t::base_t;
178 
182 };
183 
186  using base_t::base_t;
187  using order_qty_t=NewOrderSpecific2::order_qty_t;
188 
189  /// Create a message from the source message.
190  /**
191  If a linker error is generated, then this function will need to be specialised for the particular Msg-type.
192 
193  \param msg The source message from which the target message should be created.
194  */
195  template<class SrcMsg> __stdcall
196  NewOrder(SrcMsg const &msg, common::ref_data const &rd) noexcept(true) FORCE_INLINE;
197 } __attribute__((packed));
198 
201  using base_t::base_t;
202  using order_qty_t=NewOrderSpecific2::order_qty_t;
203 
204  /// Create a message from the source message.
205  /**
206  If a linker error is generated, then this function will need to be specialised for the particular Msg-type.
207 
208  \param msg The source message from which the target message should be created.
209  */
210  template<class SrcMsg> __stdcall
211  OrderCancelReplaceRequest(SrcMsg const &msg, common::ref_data const &rd) noexcept(true);
212 };
213 
216  using base_t::base_t;
217 
218  /// Create a message from the source message.
219  /**
220  If a linker error is generated, then this function will need to be specialised for the particular Msg-type.
221 
222  \param msg The source message from which the target message should be created.
223  */
224  template<class SrcMsg> __stdcall
225  OrderCancelRequest(SrcMsg const &msg, common::ref_data const &rd) noexcept(true);
226 };
227 
228 struct MsgTypes {
229 
230  static inline constexpr const exchanges::common::mic_codes::ISO_10383_MIC_Codes MIC_code=exchanges::common::mic_codes::ISO_10383_MIC_Codes::ISO_10383_ITALY_MTAA;
231 
232  using ref_data=common::ref_data;
233 
234  using MsgTypes_t=common::MsgType_t;
235  using UserName_t=common::UserName_t;
236  using Password_t=common::Password_t;
237  using SecurityID_t=common::SecurityID_t;
238  using SeqNum_t=common::SeqNum_t;
239  using Price_t=common::Price_t;
240  using Quantity_t=NewOrderSpecific2::order_qty_t;
241  using ClientOrderID_t=common::ClientOrderID_t;
242  using OrderType=common::OrderType;
243  using Side=common::Side;
244  using TIF=common::TIF;
245  using ExecType=common::ExecType;
246  using AppID=common::AppID;
247  using OrderStatus=common::OrderStatus;
248  using logon_args_t=common::logon_args_t;
249 
250  using Header_t=common::Header;
251  using NewOrder_t=BIT::NewOrder;
252  using OrderCancelRequest=BIT::OrderCancelRequest;
254  using OrderCancelReplaceRequest=BIT::OrderCancelReplaceRequest;
256  typedef common::LogonRequest LogonRequest;
257  typedef common::LogoutRequest LogoutRequest;
258  using ClientHeartbeat=common::Heartbeat;
259  using ServerHeartbeat=common::Heartbeat;
260  typedef common::MissedMessageRequest MissedMessageRequest;
262  using OrderCancelReject=common::OrderCancelReject<common::OrderCancelRejectSpecific<mit_bit::reject_codes_enum>>;
263  using OrderMassCancelReport=common::OrderMassCancelReport<common::OrderMassCancelReportSpecific<mit_bit::reject_codes_enum>>;
265  using LogonReply=BIT::LogonReply;
266  typedef common::MissedMessageRequestAck MissedMessageRequestAck;
267  typedef common::MissedMessageReport MissedMessageReport;
269  typedef common::SystemStatus SystemStatus;
270 
271  using Logout=LogoutRequest;
272 
273  static inline constexpr MsgTypes_t MatchAll=std::numeric_limits<MsgTypes_t>::max()-1; ///< For the meta-state machine to allow a catch-all rule to reject anything unhandled.
274  static inline constexpr MsgTypes_t Exit=std::numeric_limits<MsgTypes_t>::max(); ///< For the meta-state machine: the exit state to exit the msm.
275 
277  NewOrder_t,
281  NewQuote,
282  LogonRequest,
286  >;
287 
293  LogonReply,
294  Logout,
298  Reject,
300  >;
301 
302  enum : std::size_t {
304  boost::mpl::deref<
305  boost::mpl::min_element<
306  boost::mpl::transform_view<client_to_exchange_messages_t, boost::mpl::sizeof_<boost::mpl::_1> >
307  >::type::base
308  >::type
309  ),
311  boost::mpl::deref<
312  boost::mpl::max_element<
313  boost::mpl::transform_view<client_to_exchange_messages_t, boost::mpl::sizeof_<boost::mpl::_1> >
314  >::type::base
315  >::type
316  ),
318  boost::mpl::deref<
319  boost::mpl::min_element<
320  boost::mpl::transform_view<exchange_to_client_messages_t, boost::mpl::sizeof_<boost::mpl::_1> >
321  >::type::base
322  >::type
323  ),
325  boost::mpl::deref<
326  boost::mpl::max_element<
327  boost::mpl::transform_view<exchange_to_client_messages_t, boost::mpl::sizeof_<boost::mpl::_1> >
328  >::type::base
329  >::type
330  ),
331  min_msg_size=libjmmcg::min<std::size_t, min_size_client_to_exchange_msg, min_size_exchange_to_client_msg>::value,
332  max_msg_size=libjmmcg::max<std::size_t, max_size_client_to_exchange_msg, max_size_exchange_to_client_msg>::value,
333  header_t_size=LogonRequest::header_t_size
334  };
335 
336  using msg_buffer_t=std::array<std::uint8_t, max_msg_size>;
339 
341 
342  static std::ostream &to_stream(std::ostream &) noexcept(false);
343 };
344 
345 /**
346  \test MIT BIT size tests.
347 */
348 namespace tests {
349 
350 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::Header_t), <=, MsgTypes::max_size_client_to_exchange_msg);
351 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::Header_t), <=, MsgTypes::max_size_exchange_to_client_msg);
352 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::Header_t), <=, MsgTypes::max_msg_size);
353 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::LogonRequest), ==, 80);
354 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::LogonReply), ==, 38);
355 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::LogoutRequest), ==, 24);
356 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::ClientHeartbeat), ==, 4);
357 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::ServerHeartbeat), ==, 4);
358 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::MissedMessageRequest), ==, 9);
359 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::MissedMessageRequestAck), ==, 5);
360 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::MissedMessageReport), ==, 5);
361 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::Reject), ==, 59);
362 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::SystemStatus), ==, 6);
363 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::NewOrder_t), ==, 106);
364 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::NewQuote), ==, 86);
365 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::OrderCancelReplaceRequest), ==, 120);
366 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::OrderCancelRequest), ==, 73);
367 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::OrderMassCancelRequest), ==, 46);
368 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::ExecutionReport), ==, 229);
369 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::OrderCancelReject), ==, 73);
370 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::OrderMassCancelReport), ==, 56);
371 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::BusinessReject), ==, 63);
372 
373 }
374 
375 } } } } }
376 
377 #include "messages_impl.hpp"
378 
379 #endif