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_TRQ_MESSAGES_HPP
2 #define ISIMUD_EXCHANGES_MIT_TRQ_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/lexical_cast.hpp>
31 #include <boost/mpl/assert.hpp>
32 #include <boost/mpl/deref.hpp>
33 #include <boost/mpl/max_element.hpp>
34 #include <boost/mpl/min_element.hpp>
35 #include <boost/mpl/placeholders.hpp>
36 #include <boost/mpl/sizeof.hpp>
37 #include <boost/mpl/transform_view.hpp>
38 #include <boost/mpl/vector.hpp>
39 #include <boost/variant/variant.hpp>
40 
41 #include <iostream>
42 
43 namespace isimud { namespace ISIMUD_VER_NAMESPACE { namespace exchanges { namespace MIT {
44 
45 /**
46  From <a href="https://www.lseg.com/sites/default/files/content/documents/TQ301%20-%20Issue%203.2%20-%20Trading%20Gateway%20%28Native%29%20Customer_0.pdf">"TQ301 - Native Trading Gateway", Issue 3.2, 16 January 2015</a>.
47 */
48 namespace TRQ {
49 
50 /**
51  Section: "7.4.1 New Order"
52 */
54  common::CommonSymbol_t commonSymbol;
55 
56  explicit NewOrderSpecific1(common::SecurityID_t instID) noexcept(true) FORCE_INLINE {
57  libjmmcg::memcpy_opt(boost::lexical_cast<common::CommonSymbol_t>(instID), commonSymbol);
58  }
59  explicit NewOrderSpecific1(common::CommonSymbol_t const &instID) noexcept(true) FORCE_INLINE {
60  libjmmcg::memcpy_opt(instID, commonSymbol);
61  }
62  common::SecurityID_t instrumentID() const noexcept(true) {
63  return boost::lexical_cast<common::SecurityID_t>(commonSymbol);
64  }
65  void instrumentID(common::SecurityID_t instID) noexcept(true) {
66  libjmmcg::memcpy_opt(boost::lexical_cast<common::CommonSymbol_t>(instID), commonSymbol);
67  }
68 } __attribute__((packed));
70  using order_qty_t=std::int32_t;
71 
72  order_qty_t orderQty_;
73  order_qty_t displayQty;
74 
75  explicit constexpr NewOrderSpecific2(order_qty_t ordQty) noexcept(true) FORCE_INLINE
76  : orderQty_(ordQty), displayQty(ordQty) {
77  }
78  order_qty_t orderQty() const noexcept(true) {
79  return orderQty_;
80  }
81  void orderQty(order_qty_t i) noexcept(true) {
82  orderQty_=i;
83  }
84 } __attribute__((packed));
85 
87  const std::int8_t reservedField1=0;
88  const common::Price_t reservedField2=0;
91  int32_t minimumQuantity=0;
92  const std::int8_t reservedField3=0;
93  const std::int8_t reservedField4=0;
94  const std::int8_t reservedField5=0;
96  common::OrderID_t clOrdLinkID;
97 
99  return passiveOnlyOrder_;
100  }
102  passiveOnlyOrder_=poo;
103  }
104  static constexpr common::OrderSource FORCE_INLINE orderSource() noexcept(true) {
106  }
107  static void FORCE_INLINE orderSource(common::OrderSource) noexcept(true) {
108  }
109 } __attribute__((packed));
110 
111 /**
112  Section: "7.4.2 Order Cancel/Replace Request"
113 */
119  common::ReservedField3_t reservedField;
120 
122  return passiveOnlyOrder_;
123  }
125  passiveOnlyOrder_=poo;
126  }
127 } __attribute__((packed));
128 
129 /**
130  Section: "7.4.6 Execution Report"
131 */
133  using RejectCode_t=mit_trq::reject_codes_enum;
135  using order_qty_t=std::int32_t;
136 
137  order_qty_t executedQty;
138  order_qty_t leavesQty;
140  order_qty_t displayQty;
141 } __attribute__((packed));
147  common::OrderID_t publicOrderID;
150 } __attribute__((packed));
151 
153  common::CommonSymbol_t commonSymbol;
154  common::Segment_t segment;
155 
156  explicit OrderMassCancelRequestSpecific1(common::SecurityID_t instID) noexcept(true) FORCE_INLINE {
157  libjmmcg::memcpy_opt(boost::lexical_cast<common::CommonSymbol_t>(instID), commonSymbol);
158  }
159  explicit OrderMassCancelRequestSpecific1(common::CommonSymbol_t const &instID) noexcept(true) FORCE_INLINE {
160  libjmmcg::memcpy_opt(instID, commonSymbol);
161  }
162  common::SecurityID_t instrumentID() const noexcept(true) {
163  return boost::lexical_cast<common::SecurityID_t>(commonSymbol);
164  }
165  void instrumentID(common::SecurityID_t instID) noexcept(true) {
166  libjmmcg::memcpy_opt(boost::lexical_cast<common::CommonSymbol_t>(instID), commonSymbol);
167  }
168 } __attribute__((packed));
169 
171  using base_t=common::LogonReply<mit_trq::reject_codes_enum>;
174  using base_t::base_t;
175 
179 };
180 
183  using base_t::base_t;
184  using order_qty_t=NewOrderSpecific2::order_qty_t;
185  using ref_data=common::ref_data;
186 
187  /// Create a message from the source message.
188  /**
189  If a linker error is generated, then this function will need to be specialised for the particular Msg-type.
190 
191  \param msg The source message from which the target message should be created.
192  */
193  template<class SrcMsg> explicit __stdcall
194  NewOrder(SrcMsg const &msg, ref_data const &rd) noexcept(true) FORCE_INLINE;
195 } __attribute__((packed));
196 
199  using base_t::base_t;
200  using order_qty_t=NewOrderSpecific2::order_qty_t;
201  using ref_data=common::ref_data;
202 
203  /// Create a message from the source message.
204  /**
205  If a linker error is generated, then this function will need to be specialised for the particular Msg-type.
206 
207  \param msg The source message from which the target message should be created.
208  */
209  template<class SrcMsg> explicit __stdcall
210  OrderCancelReplaceRequest(SrcMsg const &msg, ref_data const &rd) noexcept(true);
211 } __attribute__((packed));
212 
215  using base_t::base_t;
216  using ref_data=common::ref_data;
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> explicit __stdcall
225  OrderCancelRequest(SrcMsg const &msg, ref_data const &rd) noexcept(true);
226 } __attribute__((packed));
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_UNITED_KINGDOM_TRQX;
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=TRQ::NewOrder;
252  using OrderCancelRequest=TRQ::OrderCancelRequest;
254  using OrderCancelReplaceRequest=TRQ::OrderCancelReplaceRequest;
255  typedef common::LogonRequest LogonRequest;
256  typedef common::LogoutRequest LogoutRequest;
257  using ClientHeartbeat=common::Heartbeat;
258  using ServerHeartbeat=common::Heartbeat;
259  typedef common::MissedMessageRequest MissedMessageRequest;
261  using OrderCancelReject=common::OrderCancelReject<common::OrderCancelRejectSpecific<mit_trq::reject_codes_enum>>;
262  using OrderMassCancelReport=common::OrderMassCancelReport<common::OrderMassCancelReportSpecific<mit_trq::reject_codes_enum>>;
264  using LogonReply=TRQ::LogonReply;
265  typedef common::MissedMessageRequestAck MissedMessageRequestAck;
266  typedef common::MissedMessageReport MissedMessageReport;
268  typedef common::SystemStatus SystemStatus;
269 
270  using Logout=LogoutRequest;
271 
272  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.
273  static inline constexpr MsgTypes_t Exit=std::numeric_limits<MsgTypes_t>::max(); ///< For the meta-state machine: the exit state to exit the msm.
274 
276  NewOrder_t,
280  LogonRequest,
284  >;
285 
291  LogonReply,
292  Logout,
296  Reject,
298  >;
299 
300  enum : std::size_t {
302  boost::mpl::deref<
303  boost::mpl::min_element<
304  boost::mpl::transform_view<client_to_exchange_messages_t, boost::mpl::sizeof_<boost::mpl::_1> >
305  >::type::base
306  >::type
307  ),
309  boost::mpl::deref<
310  boost::mpl::max_element<
311  boost::mpl::transform_view<client_to_exchange_messages_t, boost::mpl::sizeof_<boost::mpl::_1> >
312  >::type::base
313  >::type
314  ),
316  boost::mpl::deref<
317  boost::mpl::min_element<
318  boost::mpl::transform_view<exchange_to_client_messages_t, boost::mpl::sizeof_<boost::mpl::_1> >
319  >::type::base
320  >::type
321  ),
323  boost::mpl::deref<
324  boost::mpl::max_element<
325  boost::mpl::transform_view<exchange_to_client_messages_t, boost::mpl::sizeof_<boost::mpl::_1> >
326  >::type::base
327  >::type
328  ),
329  min_msg_size=libjmmcg::min<std::size_t, min_size_client_to_exchange_msg, min_size_exchange_to_client_msg>::value,
330  max_msg_size=libjmmcg::max<std::size_t, max_size_client_to_exchange_msg, max_size_exchange_to_client_msg>::value,
331  header_t_size=sizeof(typename LogonRequest::Header_t)
332  };
333  BOOST_MPL_ASSERT_RELATION(max_msg_size, >=, header_t_size);
334 
335  using msg_buffer_t=std::array<std::uint8_t, max_msg_size>;
338 
340 
341  static std::ostream &to_stream(std::ostream &) noexcept(false);
342 };
343 
344 /**
345  \test MIT TRQ size tests.
346 */
347 namespace tests {
348 
349 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::Header_t), <=, MsgTypes::max_size_client_to_exchange_msg);
350 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::Header_t), <=, MsgTypes::max_size_exchange_to_client_msg);
351 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::Header_t), <=, MsgTypes::max_msg_size);
352 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::LogonRequest), ==, 80);
353 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::LogonReply), ==, 38);
354 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::Logout), ==, 24);
355 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::ClientHeartbeat), ==, 4);
356 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::ServerHeartbeat), ==, 4);
357 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::MissedMessageRequest), ==, 9);
358 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::MissedMessageRequestAck), ==, 5);
359 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::MissedMessageReport), ==, 5);
360 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::Reject), ==, 59);
361 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::SystemStatus), ==, 6);
362 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::NewOrder_t), ==, 111);
363 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::OrderCancelReplaceRequest), ==, 114);
364 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::OrderCancelRequest), ==, 75);
365 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::OrderMassCancelRequest), ==, 48);
366 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::ExecutionReport), ==, 156);
367 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::OrderCancelReject), ==, 73);
368 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::OrderMassCancelReport), ==, 56);
369 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::BusinessReject), ==, 63);
370 
371 }
372 
373 } } } } }
374 
375 #include "messages_impl.hpp"
376 
377 #endif