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_OSLO_MESSAGES_HPP
2 #define ISIMUD_EXCHANGES_MIT_OSLO_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  See:
46  -# <a href="https://www.oslobors.no/ob_eng/Oslo-Boers/Trading/Trading-systems/Millennium-Exchange/Technical-documentation"/>
47  -# <a href="https://www.oslobors.no/obnewsletter/download/084172908123a0c01db388950fd0ecd3/file/file/OSLMIT%20203%20Native%20Trading%20Gateway%20-%20issue%205.2.pdf">"OSLMIT 203 Native Trading Gateway", Issue 5.2, 27 October 2016</a>.
48  -# <a href="https://www.oslobors.no/ob_eng/obnewsletter/download/af04d9d4a7aff5dd1d2f1bf402618b4f/file/file/OSLMIT%20203%20Native%20Trading%20Gateway%20-%20issue%204.2.pdf">"Millennium Exchange - Oslo Børs cash equities and fixed income markets", OSLMIT 801 Reject Codes, Issue 4.2, 28 April 2015</a>.
49 
50  "OSLMIT 203 Native Trading Gateway", Issue 4.1, 12 January 2015
51 
52 */
53 namespace OSLO {
54 
55 /**
56  Section: "5.6.1 New Order"
57 */
59  common::SecurityID_t instrumentID_;
60  const std::int8_t reservedField1=0;
61  const std::int8_t reservedField2=0;
62 
63  explicit constexpr NewOrderSpecific1(common::SecurityID_t instID) noexcept(true) FORCE_INLINE
64  : instrumentID_(instID) {
65  }
66  common::SecurityID_t instrumentID() const noexcept(true) {
67  return instrumentID_;
68  }
69  void instrumentID(common::SecurityID_t i) noexcept(true) {
70  instrumentID_=i;
71  }
72 } __attribute__((packed));
74  using order_qty_t=std::uint64_t;
75 
76  order_qty_t orderQty_;
77  order_qty_t displayQty;
78 
79  explicit constexpr NewOrderSpecific2(order_qty_t ordQty) noexcept(true) FORCE_INLINE
80  : orderQty_(ordQty), displayQty(ordQty) {
81  }
82  order_qty_t orderQty() const noexcept(true) {
83  return orderQty_;
84  }
85  void orderQty(order_qty_t i) noexcept(true) {
86  orderQty_=i;
87  }
88 } __attribute__((packed));
93  int32_t minimumQuantity=0;
95  common::ReservedField12_t reservedField;
96 
98  return passiveOnlyOrder_;
99  }
101  passiveOnlyOrder_=poo;
102  }
103  static constexpr common::OrderSource FORCE_INLINE orderSource() noexcept(true) {
105  }
106  static void FORCE_INLINE orderSource(common::OrderSource) noexcept(true) {
107  }
108 } __attribute__((packed));
109 
110 /**
111  Section: "5.6.4 Order Modification Request"
112 */
117  const int16_t reservedField1=0;
118  common::ReservedField10_t reservedField2;
120 
122  return passiveOnlyOrder_;
123  }
125  passiveOnlyOrder_=poo;
126  }
127 } __attribute__((packed));
128 
129 /**
130  Section: "5.7.1 Execution Report"
131 */
133  using RejectCode_t=mit_oslo::reject_codes_enum;
135  using order_qty_t=std::uint64_t;
136 
137  order_qty_t executedQty;
138  order_qty_t leavesQty;
140  order_qty_t displayQty;
141 } __attribute__((packed));
145  const std::int8_t reservedField1=0;
146  common::ReservedField4_t reservedField2;
147  const uint8_t reservedField3=0;
148  common::Price_t avgPx;
149  const common::Price_t reservedField4=0;
150  common::ReservedField20_t reservedField5;
152  common::ReservedField20_t reservedField6;
155  common::OrderID_t publicOrderID;
156 } __attribute__((packed));
157 
159  common::SecurityID_t instrumentID_;
160  const std::int8_t reservedField1=0;
161  const std::int8_t reservedField2=0;
162  common::Segment_t segment{};
163 
164  explicit constexpr OrderMassCancelRequestSpecific1(common::SecurityID_t instID) noexcept(true) FORCE_INLINE
165  : instrumentID_(instID) {
166  }
167  common::SecurityID_t instrumentID() const noexcept(true) {
168  return instrumentID_;
169  }
170  void instrumentID(common::SecurityID_t i) noexcept(true) {
171  instrumentID_=i;
172  }
173 } __attribute__((packed));
174 
176  using base_t=common::LogonReply<mit_oslo::reject_codes_enum>;
179  using base_t::base_t;
180 
184 };
185 
188  using base_t::base_t;
189  using order_qty_t=NewOrderSpecific2::order_qty_t;
190  using ref_data=common::ref_data;
191 
192  /// Create a message from the source message.
193  /**
194  If a linker error is generated, then this function will need to be specialised for the particular Msg-type.
195 
196  \param msg The source message from which the target message should be created.
197  */
198  template<class SrcMsg> explicit __stdcall
199  NewOrder(SrcMsg const &msg, ref_data const &rd) noexcept(true) FORCE_INLINE;
200 } __attribute__((packed));
201 
204  using base_t::base_t;
205  using order_qty_t=NewOrderSpecific2::order_qty_t;
206  using ref_data=common::ref_data;
207 
208  /// Create a message from the source message.
209  /**
210  If a linker error is generated, then this function will need to be specialised for the particular Msg-type.
211 
212  \param msg The source message from which the target message should be created.
213  */
214  template<class SrcMsg> explicit __stdcall
215  OrderCancelReplaceRequest(SrcMsg const &msg, ref_data const &rd) noexcept(true);
216 } __attribute__((packed));
217 
220  using base_t::base_t;
221  using ref_data=common::ref_data;
222 
223  /// Create a message from the source message.
224  /**
225  If a linker error is generated, then this function will need to be specialised for the particular Msg-type.
226 
227  \param msg The source message from which the target message should be created.
228  */
229  template<class SrcMsg> explicit __stdcall
230  OrderCancelRequest(SrcMsg const &msg, ref_data const &rd) noexcept(true);
231 } __attribute__((packed));
232 
233 struct MsgTypes {
234 
235  static inline constexpr const exchanges::common::mic_codes::ISO_10383_MIC_Codes MIC_code=exchanges::common::mic_codes::ISO_10383_MIC_Codes::ISO_10383_NORWAY_XOSL;
236 
237  using ref_data=common::ref_data;
238 
239  using MsgTypes_t=common::MsgType_t;
240  using UserName_t=common::UserName_t;
241  using Password_t=common::Password_t;
242  using SecurityID_t=common::SecurityID_t;
243  using SeqNum_t=common::SeqNum_t;
244  using Price_t=common::Price_t;
245  using Quantity_t=NewOrderSpecific2::order_qty_t;
246  using ClientOrderID_t=common::ClientOrderID_t;
247  using OrderType=common::OrderType;
248  using Side=common::Side;
249  using TIF=common::TIF;
250  using ExecType=common::ExecType;
251  using AppID=common::AppID;
252  using OrderStatus=common::OrderStatus;
253  using logon_args_t=common::logon_args_t;
254 
255  using Header_t=common::Header;
256  using NewOrder_t=OSLO::NewOrder;
257  using OrderCancelRequest=OSLO::OrderCancelRequest;
259  using OrderCancelReplaceRequest=OSLO::OrderCancelReplaceRequest;
260  typedef common::LogonRequest LogonRequest;
261  typedef common::LogoutRequest LogoutRequest;
262  using ClientHeartbeat=common::Heartbeat;
263  using ServerHeartbeat=common::Heartbeat;
264  typedef common::MissedMessageRequest MissedMessageRequest;
266  using OrderCancelReject=common::OrderCancelReject<common::OrderCancelRejectSpecific<mit_oslo::reject_codes_enum>>;
267  using OrderMassCancelReport=common::OrderMassCancelReport<common::OrderMassCancelReportSpecific<mit_oslo::reject_codes_enum>>;
269  using LogonReply=OSLO::LogonReply;
270  typedef common::MissedMessageRequestAck MissedMessageRequestAck;
271  typedef common::MissedMessageReport MissedMessageReport;
273  typedef common::SystemStatus SystemStatus;
274 
275  using Logout=LogoutRequest;
276 
277  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.
278  static inline constexpr MsgTypes_t Exit=std::numeric_limits<MsgTypes_t>::max(); ///< For the meta-state machine: the exit state to exit the msm.
279 
281  NewOrder_t,
285  LogonRequest,
289  >;
290 
296  LogonReply,
297  Logout,
301  Reject,
303  >;
304 
305  enum : std::size_t {
307  boost::mpl::deref<
308  boost::mpl::min_element<
309  boost::mpl::transform_view<client_to_exchange_messages_t, boost::mpl::sizeof_<boost::mpl::_1> >
310  >::type::base
311  >::type
312  ),
314  boost::mpl::deref<
315  boost::mpl::max_element<
316  boost::mpl::transform_view<client_to_exchange_messages_t, boost::mpl::sizeof_<boost::mpl::_1> >
317  >::type::base
318  >::type
319  ),
321  boost::mpl::deref<
322  boost::mpl::min_element<
323  boost::mpl::transform_view<exchange_to_client_messages_t, boost::mpl::sizeof_<boost::mpl::_1> >
324  >::type::base
325  >::type
326  ),
328  boost::mpl::deref<
329  boost::mpl::max_element<
330  boost::mpl::transform_view<exchange_to_client_messages_t, boost::mpl::sizeof_<boost::mpl::_1> >
331  >::type::base
332  >::type
333  ),
334  min_msg_size=libjmmcg::min<std::size_t, min_size_client_to_exchange_msg, min_size_exchange_to_client_msg>::value,
335  max_msg_size=libjmmcg::max<std::size_t, max_size_client_to_exchange_msg, max_size_exchange_to_client_msg>::value,
336  header_t_size=sizeof(typename LogonRequest::Header_t)
337  };
338  BOOST_MPL_ASSERT_RELATION(max_msg_size, >=, header_t_size);
339 
340  using msg_buffer_t=std::array<std::uint8_t, max_msg_size>;
343 
345 
346  static std::ostream &to_stream(std::ostream &) noexcept(false);
347 };
348 
349 /**
350  \test MIT OSLO size tests.
351 */
352 namespace tests {
353 
354 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::Header_t), <=, MsgTypes::max_size_client_to_exchange_msg);
355 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::Header_t), <=, MsgTypes::max_size_exchange_to_client_msg);
356 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::Header_t), <=, MsgTypes::max_msg_size);
357 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::LogonRequest), ==, 80);
358 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::LogonReply), ==, 38);
359 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::Logout), ==, 24);
360 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::ClientHeartbeat), ==, 4);
361 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::ServerHeartbeat), ==, 4);
362 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::MissedMessageRequest), ==, 9);
363 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::MissedMessageRequestAck), ==, 5);
364 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::MissedMessageReport), ==, 5);
365 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::Reject), ==, 59);
366 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::SystemStatus), ==, 6);
367 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::NewOrder_t), ==, 106);
368 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::OrderCancelReplaceRequest), ==, 129);
369 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::OrderCancelRequest), ==, 73);
370 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::OrderMassCancelRequest), ==, 46);
371 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::ExecutionReport), ==, 229);
372 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::OrderCancelReject), ==, 73);
373 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::OrderMassCancelReport), ==, 56);
374 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::BusinessReject), ==, 63);
375 
376 }
377 
378 } } } } }
379 
380 #include "messages_impl.hpp"
381 
382 #endif