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_FIX_5_0sp2_MESSAGES_HPP
2 #define ISIMUD_EXCHANGES_FIX_5_0sp2_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 "types.hpp"
24 #include "../common/messages.hpp"
25 
26 #include "core/max_min.hpp"
27 
28 #include <boost/mpl/assert.hpp>
29 #include <boost/mpl/deref.hpp>
30 #include <boost/mpl/max_element.hpp>
31 #include <boost/mpl/min_element.hpp>
32 #include <boost/mpl/placeholders.hpp>
33 #include <boost/mpl/sizeof.hpp>
34 #include <boost/mpl/transform_view.hpp>
35 #include <boost/mpl/vector.hpp>
36 #include <boost/variant/variant.hpp>
37 
38 #include <iosfwd>
39 
40 /**
41  FIX documentation:
42  -# <a href="https://www.fixtrading.org/standards/fix-5-0-sp-2/">"FIX 5.0 Specification Service Pack 2"</a>..
43  -# <a href="https://github.com/jamesdbrock/hffix/commit/d2539d5602672e596c0bb34e1fe642918df7b14f">Usge of the XML specification to generate code</a>.
44 
45  Note that Wireshark has a built-in FIX protocol: see the "Analyze/Enabled Protocols..." dialog in Wireshark. See <a href="https://www.wireshark.org/docs/dfref/f/fix.html"/> also.
46 */
47 namespace isimud { namespace ISIMUD_VER_NAMESPACE { namespace exchanges { namespace FIX { namespace v5_0sp2 {
48 
51  enum : std::size_t {
52  fix_template_body_length_offset=sizeof(JMMCG_FIX_v5_0sp2_MSG_VER)-1+libjmmcg::enum_tags::mpl::to_array<common::FieldsFast, common::FieldsFast::BodyLength>::size,
53  fix_template_msg_type_offset=sizeof(fix_template_to_msg_type)-1
54  };
55  static inline constexpr const char MsgVer[]=JMMCG_FIX_v5_0sp2_MSG_VER;
56 
57  /// Verify that the referenced FIX message is valid.
58  /**
59  \param m A wrapper for the FIX message,
60  \return True is the referenced FIX message is valid, false otherwise.
61  */
62  template<class Msg>
63  static constexpr bool is_valid(Msg const &m) noexcept(true);
64 };
65 
66 struct LogonSpecific : public VersionSpecific {
68 
69  /// Verify that the referenced FIX message is valid.
70  /**
71  \param m A wrapper for the FIX message,
72  \return True is the referenced FIX message is valid, false otherwise.
73  */
74  template<class Msg>
75  static bool is_valid(Msg const &m) noexcept(true);
76 };
77 
80 
81  /// Verify that the referenced FIX message is valid.
82  /**
83  \param m A wrapper for the FIX message,
84  \return True is the referenced FIX message is valid, false otherwise.
85  */
86  template<class Msg>
87  static bool is_valid(Msg const &m) noexcept(true);
88 };
89 
92 
93  /// Verify that the referenced FIX message is valid.
94  /**
95  \param m A wrapper for the FIX message,
96  \return True is the referenced FIX message is valid, false otherwise.
97  */
98  template<class Msg>
99  static bool is_valid(Msg const &m) noexcept(true) __attribute__((pure));
100 };
101 
104 
106  : base_t() {
107  pointer data=this->set_header<common::MsgTypes::Heartbeat>();
108  this->finalise_msg(data);
109  }
110 };
111 
114 
115  /// Verify that the referenced FIX message is valid.
116  /**
117  \param m A wrapper for the FIX message,
118  \return True is the referenced FIX message is valid, false otherwise.
119  */
120  template<class Msg>
121  static bool is_valid(Msg const &m) noexcept(true);
122 };
123 
126 
127  /// Verify that the referenced FIX message is valid.
128  /**
129  \param m A wrapper for the FIX message,
130  \return True is the referenced FIX message is valid, false otherwise.
131  */
132  template<class Msg>
133  static bool is_valid(Msg const &m) noexcept(true);
134 };
135 
138 
139  /// Verify that the referenced FIX message is valid.
140  /**
141  \param m A wrapper for the FIX message,
142  \return True is the referenced FIX message is valid, false otherwise.
143  */
144  template<class Msg>
145  static bool is_valid(Msg const &m) noexcept(true);
146 };
147 
150 
151  /// Verify that the referenced FIX message is valid.
152  /**
153  \param m A wrapper for the FIX message,
154  \return True is the referenced FIX message is valid, false otherwise.
155  */
156  template<class Msg>
157  static bool is_valid(Msg const &m) noexcept(true);
158 };
159 
162 
163  /// Verify that the referenced FIX message is valid.
164  /**
165  \param m A wrapper for the FIX message,
166  \return True is the referenced FIX message is valid, false otherwise.
167  */
168  template<class Msg>
169  static bool is_valid(Msg const &m) noexcept(true);
170 };
171 
174 
175  /// Verify that the referenced FIX message is valid.
176  /**
177  \param m A wrapper for the FIX message,
178  \return True is the referenced FIX message is valid, false otherwise.
179  */
180  template<class Msg>
181  static bool is_valid(Msg const &m) noexcept(true);
182 };
183 
186 
187  /// Verify that the referenced FIX message is valid.
188  /**
189  \param m A wrapper for the FIX message,
190  \return True is the referenced FIX message is valid, false otherwise.
191  */
192  template<class Msg>
193  static bool is_valid(Msg const &m) noexcept(true);
194 };
195 
198 
199  /// Verify that the referenced FIX message is valid.
200  /**
201  \param m A wrapper for the FIX message,
202  \return True is the referenced FIX message is valid, false otherwise.
203  */
204  template<class Msg>
205  static bool is_valid(Msg const &m) noexcept(true);
206 };
207 
210 
211  /// Verify that the referenced FIX message is valid.
212  /**
213  \param m A wrapper for the FIX message,
214  \return True is the referenced FIX message is valid, false otherwise.
215  */
216  template<class Msg>
217  static bool is_valid(Msg const &m) noexcept(true);
218 };
219 
222 
223  /// Verify that the referenced FIX message is valid.
224  /**
225  \param m A wrapper for the FIX message,
226  \return True is the referenced FIX message is valid, false otherwise.
227  */
228  template<class Msg>
229  static bool is_valid(Msg const &m) noexcept(true);
230 };
231 
234 
235  /// Verify that the referenced FIX message is valid.
236  /**
237  \param m A wrapper for the FIX message,
238  \return True is the referenced FIX message is valid, false otherwise.
239  */
240  template<class Msg>
241  static bool is_valid(Msg const &m) noexcept(true);
242 };
243 
246 
247  /// Verify that the referenced FIX message is valid.
248  /**
249  \param m A wrapper for the FIX message,
250  \return True is the referenced FIX message is valid, false otherwise.
251  */
252  template<class Msg>
253  static bool is_valid(Msg const &m) noexcept(true);
254 };
255 
258 
259  /// Verify that the referenced FIX message is valid.
260  /**
261  \param m A wrapper for the FIX message,
262  \return True is the referenced FIX message is valid, false otherwise.
263  */
264  template<class Msg>
265  static bool is_valid(Msg const &m) noexcept(true);
266 };
267 
270 
271  /// Verify that the referenced FIX message is valid.
272  /**
273  \param m A wrapper for the FIX message,
274  \return True is the referenced FIX message is valid, false otherwise.
275  */
276  template<class Msg>
277  static bool is_valid(Msg const &m) noexcept(true);
278 };
279 
282 
283  /// Verify that the referenced FIX message is valid.
284  /**
285  \param m A wrapper for the FIX message,
286  \return True is the referenced FIX message is valid, false otherwise.
287  */
288  template<class Msg>
289  static bool is_valid(Msg const &m) noexcept(true);
290 };
291 
294 
295  /// Verify that the referenced FIX message is valid.
296  /**
297  \param m A wrapper for the FIX message,
298  \return True is the referenced FIX message is valid, false otherwise.
299  */
300  template<class Msg>
301  static bool is_valid(Msg const &m) noexcept(true);
302 };
303 
306 
307  /// Verify that the referenced FIX message is valid.
308  /**
309  \param m A wrapper for the FIX message,
310  \return True is the referenced FIX message is valid, false otherwise.
311  */
312  template<class Msg>
313  static bool is_valid(Msg const &m) noexcept(true);
314 };
315 
318 
319  /// Verify that the referenced FIX message is valid.
320  /**
321  \param m A wrapper for the FIX message,
322  \return True is the referenced FIX message is valid, false otherwise.
323  */
324  template<class Msg>
325  static bool is_valid(Msg const &m) noexcept(true);
326 };
327 
330 
331  /// Verify that the referenced FIX message is valid.
332  /**
333  \param m A wrapper for the FIX message,
334  \return True is the referenced FIX message is valid, false otherwise.
335  */
336  template<class Msg>
337  static bool is_valid(Msg const &m) noexcept(true);
338 };
339 
342 
343  /// Verify that the referenced FIX message is valid.
344  /**
345  \param m A wrapper for the FIX message,
346  \return True is the referenced FIX message is valid, false otherwise.
347  */
348  template<class Msg>
349  static bool is_valid(Msg const &m) noexcept(true);
350 };
351 
354 
355  /// Verify that the referenced FIX message is valid.
356  /**
357  \param m A wrapper for the FIX message,
358  \return True is the referenced FIX message is valid, false otherwise.
359  */
360  template<class Msg>
361  static bool is_valid(Msg const &m) noexcept(true);
362 };
363 
366 
367  /// Verify that the referenced FIX message is valid.
368  /**
369  \param m A wrapper for the FIX message,
370  \return True is the referenced FIX message is valid, false otherwise.
371  */
372  template<class Msg>
373  static bool is_valid(Msg const &m) noexcept(true);
374 };
375 
376 /**
377  I expect that the FIX message will be constructible using accessors, but also via placement-new or a reference to the data-block. I also expect that a FIX message can be constructed from BATS or MIT messages. Also BATS & MIT messages will be constructible from FIX messages.
378 */
379 struct MsgTypes {
380 
381  struct ref_data {};
382  using FieldsFast=common::FieldsFast;
383  using field_str_const_range_t=common::field_str_const_range_t;
384 
386  using MsgType_t=common::MsgTypes;
387  using UserName_t=common::UserName_t;
388  using Password_t=common::Password_t;
389  using SeqNum_t=common::SeqNum_t;
390  using Price_t=common::Price_t;
391  using Quantity_t=common::Quantity_t;
392  using Side=common::Side;
393  using ClientOrderID_t=common::ClientOrderID_t;
394  using SecurityID_t=common::SecurityID_t;
395  using ExecType=common::ExecType;
396  using TIF=common::TIF;
397  using OrderType=common::OrderType;
398  struct logon_args_t {};
399 
400  using LogonRequest=common::Message<LogonSpecific>;
402  using LogoutRequest=common::Message<LogoutRequestSpecific>;
403  using ClientHeartbeat=common::Message<HeartbeatSpecific>;
404  using ServerHeartbeat=v5_0sp2::ServerHeartbeat;
405  using NewOrderSingle=common::Message<NewOrderSingleSpecific>;
406  using OrderCancelRequest=common::Message<OrderCancelRequestSpecific>;
407  using OrderCancelReplace=common::Message<OrderCancelReplaceSpecific>;
408  using ExecutionReport=common::Message<ExecutionReportSpecific>;
409  using LogonReply=common::Message<LogonReplySpecific>;
410  using Logout=common::Message<LogoutSpecific>;
411  using CancelOrder=common::Message<CancelOrderSpecific>;
412  using ModifyOrder=common::Message<ModifyOrderSpecific>;
413  using TradeCaptureReport=common::Message<TradeCaptureReportSpecific>;
414  using TradeCaptureReportRequest=common::Message<TradeCaptureReportRequestSpecific>;
415  using OrderAcknowledgement=common::Message<OrderAcknowledgementSpecific>;
416  using OrderRejected=common::Message<OrderRejectedSpecific>;
417  using BusinessMessageReject=common::Message<BusinessMessageRejectSpecific>;
418  using OrderModified=common::Message<OrderModifiedSpecific>;
419  using OrderRestated=common::Message<OrderRestatedSpecific>;
420  using UserModifyRejected=common::Message<UserModifyRejectedSpecific>;
421  using OrderCancelled=common::Message<OrderCancelledSpecific>;
422  using CancelRejected=common::Message<CancelRejectedSpecific>;
423  using OrderExecution=common::Message<OrderExecutionSpecific>;
424  using TradeCaptureReportAck=common::Message<TradeCaptureReportAckSpecific>;
425  using TradeCaptureReportRequestAck=common::Message<TradeCaptureReportRequestAckSpecific>;
426  using Reject=common::Message<RejectSpecific>;
427 
428  using NewOrder_t=NewOrderSingle;
429 
430  static inline constexpr MsgType_t MatchAll=MsgType_t::MatchAll; ///< For the meta-state machine to allow a catch-all rule to reject anything unhandled.
431  static inline constexpr MsgType_t Exit=MsgType_t::Exit; ///< For the meta-state machine: the exit state to exit the msm.
432 
434  LogonRequest,
437  NewOrder_t,
440  ModifyOrder,
443  >;
445  LogonReply,
446  Logout,
460  Reject
461  >;
462  enum : std::size_t {
464  boost::mpl::deref<
465  boost::mpl::min_element<
466  boost::mpl::transform_view<client_to_exchange_messages_t, boost::mpl::sizeof_<boost::mpl::_1> >
467  >::type::base
468  >::type
469  ),
471  boost::mpl::deref<
472  boost::mpl::max_element<
473  boost::mpl::transform_view<client_to_exchange_messages_t, boost::mpl::sizeof_<boost::mpl::_1> >
474  >::type::base
475  >::type
476  ),
478  boost::mpl::deref<
479  boost::mpl::min_element<
480  boost::mpl::transform_view<exchange_to_client_messages_t, boost::mpl::sizeof_<boost::mpl::_1> >
481  >::type::base
482  >::type
483  ),
485  boost::mpl::deref<
486  boost::mpl::max_element<
487  boost::mpl::transform_view<exchange_to_client_messages_t, boost::mpl::sizeof_<boost::mpl::_1> >
488  >::type::base
489  >::type
490  ),
491  min_msg_size=libjmmcg::min<std::size_t, min_size_client_to_exchange_msg, min_size_exchange_to_client_msg>::value,
492  max_msg_size=libjmmcg::max<std::size_t, max_size_client_to_exchange_msg, max_size_exchange_to_client_msg>::value,
493  header_t_size=Header_t::header_t_size
494  };
495  BOOST_MPL_ASSERT_RELATION(max_msg_size, >=, header_t_size);
496 
497  using underlying_fix_data_buffer=common::underlying_fix_data_buffer;
501 
502 
503  static inline constexpr std::uint64_t implied_decimal_places=common::implied_decimal_places;
504 
505  static std::ostream &to_stream(std::ostream &) noexcept(false);
506 };
507 
508 /**
509  \test FIX v5.0sp2 size tests.
510 */
511 namespace tests {
512 
513 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::Header_t), ==, 576);
514 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::LogonRequest), ==, 576);
515 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::LogoutRequest), ==, 576);
516 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::ClientHeartbeat), ==, 576);
517 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::ServerHeartbeat), ==, 576);
518 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::NewOrder_t), ==, 576);
519 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::OrderCancelRequest), ==, 576);
520 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::OrderCancelReplace), ==, 576);
521 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::ExecutionReport), ==, 576);
522 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::ModifyOrder), ==, 576);
523 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::TradeCaptureReport), ==, 576);
524 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::TradeCaptureReportRequest), ==, 576);
525 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::LogonReply), ==, 576);
526 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::Logout), ==, 576);
527 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::OrderAcknowledgement), ==, 576);
528 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::OrderRejected), ==, 576);
529 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::BusinessMessageReject), ==, 576);
530 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::OrderModified), ==, 576);
531 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::OrderRestated), ==, 576);
532 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::UserModifyRejected), ==, 576);
533 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::OrderCancelled), ==, 576);
534 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::CancelRejected), ==, 576);
535 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::OrderExecution), ==, 576);
536 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::TradeCaptureReportAck), ==, 576);
537 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::TradeCaptureReportRequestAck), ==, 576);
538 
539 }
540 
541 } } } } }
542 
543 #include "messages_impl.hpp"
544 
545 #endif