root/isimud/exchanges/MIT/BIT/messages.hpp

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


   1 #ifndef libjmmcg_isimud_exchanges_MIT_BIT_messages_hpp
   2 #define libjmmcg_isimud_exchanges_MIT_BIT_messages_hpp
   3 
   4 /******************************************************************************
   5 ** $Header: svn+ssh://jmmcg@svn.code.sf.net/p/libjmmcg/code/trunk/libjmmcg/isimud/exchanges/MIT/BIT/messages.hpp 2330 2018-09-26 03:49:30Z jmmcg $
   6 **
   7 ** Copyright (c) 2015 by J.M.McGuiness, isimud@hussar.me.uk
   8 **
   9 ** This library is free software; you can redistribute it and/or
  10 ** modify it under the terms of the GNU Lesser General Public
  11 ** License as published by the Free Software Foundation; either
  12 ** version 2.1 of the License, or (at your option) any later version.
  13 **
  14 ** This library is distributed in the hope that it will be useful,
  15 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17 ** Lesser General Public License for more details.
  18 **
  19 ** You should have received a copy of the GNU Lesser General Public
  20 ** License along with this library; if not, write to the Free Software
  21 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  22 */
  23 
  24 #include "config.h"
  25 #include "reject_codes.hpp"
  26 
  27 #include "../common/messages.hpp"
  28 #include "../common/ref_data.hpp"
  29 
  30 #include "core/max_min.hpp"
  31 
  32 #include <boost/mpl/assert.hpp>
  33 #include <boost/mpl/deref.hpp>
  34 #include <boost/mpl/max_element.hpp>
  35 #include <boost/mpl/min_element.hpp>
  36 #include <boost/mpl/placeholders.hpp>
  37 #include <boost/mpl/sizeof.hpp>
  38 #include <boost/mpl/transform_view.hpp>
  39 #include <boost/mpl/vector.hpp>
  40 #include <boost/variant/variant.hpp>
  41 
  42 #include <iostream>
  43 
  44 namespace isimud { namespace exchanges { namespace MIT {
  45 
  46 /**
  47         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>.
  48 */
  49 namespace BIT {
  50 
  51 /**
  52         Section: "7.4.1 New Order"
  53 */
  54 struct NewOrderSpecific1 {
  55         common::SecurityID_t instrumentID_;
  56         const std::int8_t reservedField1=0;
  57         const std::int8_t reservedField2=0;
  58 
  59         explicit constexpr NewOrderSpecific1(common::SecurityID_t instID) noexcept(true) FORCE_INLINE
  60         : instrumentID_(instID) {
  61         }
  62         common::SecurityID_t instrumentID() const noexcept(true) {
  63                 return instrumentID_;
  64         }
  65         void instrumentID(common::SecurityID_t i) noexcept(true) {
  66                 instrumentID_=i;
  67         }
  68 } __attribute__((packed));
  69 struct NewOrderSpecific2 {
  70         using order_qty_t=std::uint64_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 struct NewOrderSpecific3 {
  86         common::Anonymity anonymity=common::Anonymity::Anonymous;
  87         common::Price_t stoppedPrice=0;
  88         common::ReservedField10_t reservedField;
  89         common::OrderSource orderSource_=common::OrderSource::MarketParticipantDealsOnOwnAccount;
  90 
  91         static constexpr common::PassiveOnlyOrder FORCE_INLINE passiveOnlyOrder() noexcept(true) {
  92                 return common::PassiveOnlyOrder::NoConstraint;
  93         }
  94         static void FORCE_INLINE passiveOnlyOrder(common::PassiveOnlyOrder) noexcept(true) {
  95         }
  96         common::OrderSource FORCE_INLINE orderSource() const noexcept(true) {
  97                 return orderSource_;
  98         }
  99         void FORCE_INLINE orderSource(common::OrderSource os) noexcept(true) {
 100                 orderSource_=os;
 101         }
 102 } __attribute__((packed));
 103 
 104 /**
 105         Section: "7.4.2 New Quote"
 106 */
 107 struct NewQuoteSpecific1 {
 108         common::Price_t bidPrice;
 109         uint64_t bidSize;
 110         common::Price_t askPrice;
 111         uint64_t askSize;
 112 } __attribute__((packed));
 113 struct NewQuoteSpecific2 {
 114         common::ReservedField10_t reservedField;
 115         common::TIF tif;
 116         common::Anonymity anonymity;
 117 } __attribute__((packed));
 118 
 119 /**
 120         Section: "7.4.5 Order Modification Request"
 121 */
 122 struct OrderCancelReplaceRequestSpecific {
 123         common::ReservedField10_t reservedField;
 124 
 125         static constexpr common::PassiveOnlyOrder FORCE_INLINE passiveOnlyOrder() noexcept(true) {
 126                 return common::PassiveOnlyOrder::NoConstraint;
 127         }
 128         static void FORCE_INLINE passiveOnlyOrder(common::PassiveOnlyOrder) noexcept(true) {
 129         }
 130 } __attribute__((packed));
 131 
 132 /**
 133         Section: "7.4.8 Execution Report"
 134 */
 135 struct ExecutionReportSpecific1 {
 136         using RejectCode_t=mit_bit::reject_codes_enum;
 137         using RejectCodes_t=std::underlying_type<RejectCode_t>::type;
 138 
 139         uint64_t executedQty;
 140         uint64_t leavesQty;
 141         common::Container container;
 142         uint64_t displayQty;
 143 } __attribute__((packed));
 144 struct ExecutionReportSpecific2 {
 145         common::ReservedField10_t reservedField1;
 146         common::OrderSource orderSource;
 147         common::Price_t avgPx;
 148         common::Price_t impliedPrice;
 149         common::CrossID_t crossID;
 150         uint8_t crossType;
 151         common::CrossID_t originalCrossID;
 152         common::RestatementReason restatementReason;
 153         common::OrderID_t publicOrderID;
 154         common::TypeOfTrade typeOfTrade;
 155 } __attribute__((packed));
 156 
 157 struct OrderMassCancelRequestSpecific1 {
 158         common::SecurityID_t instrumentID_;
 159         const std::int8_t reservedField1=0;
 160         const std::int8_t reservedField2=0;
 161         common::Segment_t segment{};
 162 
 163         explicit constexpr OrderMassCancelRequestSpecific1(common::SecurityID_t instID) noexcept(true) FORCE_INLINE
 164         : instrumentID_(instID) {
 165         }
 166         common::SecurityID_t instrumentID() const noexcept(true) {
 167                 return instrumentID_;
 168         }
 169         void instrumentID(common::SecurityID_t i) noexcept(true) {
 170                 instrumentID_=i;
 171         }
 172 } __attribute__((packed));
 173 
 174 struct LogonReply : public common::LogonReply<mit_bit::reject_codes_enum> {
 175         using base_t=common::LogonReply<mit_bit::reject_codes_enum>;
 176         using RejectCode_t=base_t::RejectCode_t;
 177         using RejectCodes_t=std::underlying_type<RejectCode_t>::type;
 178         using base_t::base_t;
 179 
 180         static constexpr const RejectCode_t logon_success=mit_bit::reject_codes_enum::tag_SUCCESS;
 181         static constexpr const RejectCode_t invalid_logon_details=mit_bit::reject_codes_enum::AuthServer_INVALID_USERID_PWD______1;
 182         static constexpr const RejectCode_t unknown_user=mit_bit::reject_codes_enum::AuthServer_USER_NOT_FOUND_4;
 183 };
 184 
 185 struct NewOrder : public common::NewOrder<NewOrderSpecific1, NewOrderSpecific2, NewOrderSpecific3> {
 186         using base_t=common::NewOrder<NewOrderSpecific1, NewOrderSpecific2, NewOrderSpecific3>;
 187         using base_t::base_t;
 188         using order_qty_t=NewOrderSpecific2::order_qty_t;
 189         using ref_data_t=common::ref_data_t;
 190 
 191         /// Create a message from the source message.
 192         /**
 193                 If a linker error is generated, then this function will need to be specialised for the particular Msg-type.
 194 
 195                 \param  msg     The source message from which the target message should be created.
 196         */
 197         template<class SrcMsg> __stdcall
 198         NewOrder(SrcMsg const &msg, ref_data_t rd) noexcept(true) FORCE_INLINE;
 199 } __attribute__((packed));
 200 
 201 struct OrderCancelReplaceRequest : public common::OrderCancelReplaceRequest<NewOrderSpecific1, NewOrderSpecific2, OrderCancelReplaceRequestSpecific> {
 202         using base_t=common::OrderCancelReplaceRequest<NewOrderSpecific1, NewOrderSpecific2, OrderCancelReplaceRequestSpecific>;
 203         using base_t::base_t;
 204         using order_qty_t=NewOrderSpecific2::order_qty_t;
 205         using ref_data_t=common::ref_data_t;
 206 
 207         /// Create a message from the source message.
 208         /**
 209                 If a linker error is generated, then this function will need to be specialised for the particular Msg-type.
 210 
 211                 \param  msg     The source message from which the target message should be created.
 212         */
 213         template<class SrcMsg> __stdcall
 214         OrderCancelReplaceRequest(SrcMsg const &msg, ref_data_t rd) noexcept(true);
 215 };
 216 
 217 struct OrderCancelRequest : public common::OrderCancelRequest<NewOrderSpecific1> {
 218         using base_t=common::OrderCancelRequest<NewOrderSpecific1>;
 219         using base_t::base_t;
 220         using ref_data_t=common::ref_data_t;
 221 
 222         /// Create a message from the source message.
 223         /**
 224                 If a linker error is generated, then this function will need to be specialised for the particular Msg-type.
 225 
 226                 \param  msg     The source message from which the target message should be created.
 227         */
 228         template<class SrcMsg> __stdcall
 229         OrderCancelRequest(SrcMsg const &msg, ref_data_t rd) noexcept(true);
 230 };
 231 
 232 struct MsgTypes {
 233 
 234         static inline constexpr const isimud::exchanges::common::mic_codes::ISO_10383_MIC_Codes MIC_code=isimud::exchanges::common::mic_codes::ISO_10383_MIC_Codes::ISO_10383_ITALY_MTAA;
 235 
 236         using ref_data=common::ref_data;
 237         using ref_data_t=common::ref_data_t;
 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 Price_t=common::Price_t;
 244         using ClientOrderID_t=common::ClientOrderID_t;
 245         using OrderType=common::OrderType;
 246         using Side=common::Side;
 247         using ExecType=common::ExecType;
 248         using AppID=common::AppID;
 249         using OrderStatus=common::OrderStatus;
 250         using logon_args_t=common::logon_args_t;
 251 
 252         using Header_t=common::Header;
 253         using NewOrder=BIT::NewOrder;
 254         using OrderCancelRequest=BIT::OrderCancelRequest;
 255         typedef common::OrderMassCancelRequest<OrderMassCancelRequestSpecific1> OrderMassCancelRequest;
 256         using OrderCancelReplaceRequest=BIT::OrderCancelReplaceRequest;
 257         typedef common::NewQuote<NewQuoteSpecific1, NewQuoteSpecific2> NewQuote;
 258         typedef common::LogonRequest LogonRequest;
 259         typedef common::LogoutRequest LogoutRequest;
 260         using ClientHeartbeat=common::Heartbeat;
 261         using ServerHeartbeat=common::Heartbeat;
 262         typedef common::MissedMessageRequest MissedMessageRequest;
 263         typedef common::ExecutionReport<ExecutionReportSpecific1, ExecutionReportSpecific2> ExecutionReport;
 264         using OrderCancelReject=common::OrderCancelReject<common::OrderCancelRejectSpecific<mit_bit::reject_codes_enum>>;
 265         using OrderMassCancelReport=common::OrderMassCancelReport<common::OrderMassCancelReportSpecific<mit_bit::reject_codes_enum>>;
 266         using BusinessReject=common::BusinessReject<common::BusinessRejectSpecific<mit_bit::reject_codes_enum, mit_bit::reject_codes_enum::MatchingEngine_Unknown_instrument_9000>>;
 267         using LogonReply=BIT::LogonReply;
 268         typedef common::MissedMessageRequestAck MissedMessageRequestAck;
 269         typedef common::MissedMessageReport MissedMessageReport;
 270         using Reject=common::Reject<mit_bit::reject_codes_enum, mit_bit::reject_codes_enum::NativeGateway_Message_not_supported_102>;
 271         typedef common::SystemStatus SystemStatus;
 272 
 273         using Logout=LogoutRequest;
 274 
 275         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.
 276         static inline constexpr MsgTypes_t Exit=std::numeric_limits<MsgTypes_t>::max(); ///< For the meta-state machine: the exit state to exit the msm.
 277 
 278         using client_to_exchange_messages_t=boost::mpl::vector<
 279                 NewOrder,
 280                 OrderCancelRequest,
 281                 OrderMassCancelRequest,
 282                 OrderCancelReplaceRequest,
 283                 NewQuote,
 284                 LogonRequest,
 285                 LogoutRequest,
 286                 ClientHeartbeat,
 287                 MissedMessageRequest
 288         >;
 289 
 290         using exchange_to_client_messages_t=boost::mpl::vector<
 291                 ExecutionReport,
 292                 OrderCancelReject,
 293                 OrderMassCancelReport,
 294                 BusinessReject,
 295                 LogonReply,
 296                 Logout,
 297                 ServerHeartbeat,
 298                 MissedMessageRequestAck,
 299                 MissedMessageReport,
 300                 Reject,
 301                 SystemStatus
 302         >;
 303 
 304         enum : std::size_t {
 305                 min_size_client_to_exchange_msg=sizeof(
 306                         boost::mpl::deref<
 307                                 boost::mpl::min_element<
 308                                         boost::mpl::transform_view<client_to_exchange_messages_t, boost::mpl::sizeof_<boost::mpl::_1> >
 309                                 >::type::base
 310                         >::type
 311                 ),
 312                 max_size_client_to_exchange_msg=sizeof(
 313                         boost::mpl::deref<
 314                                 boost::mpl::max_element<
 315                                         boost::mpl::transform_view<client_to_exchange_messages_t, boost::mpl::sizeof_<boost::mpl::_1> >
 316                                 >::type::base
 317                         >::type
 318                 ),
 319                 min_size_exchange_to_client_msg=sizeof(
 320                         boost::mpl::deref<
 321                                 boost::mpl::min_element<
 322                                         boost::mpl::transform_view<exchange_to_client_messages_t, boost::mpl::sizeof_<boost::mpl::_1> >
 323                                 >::type::base
 324                         >::type
 325                 ),
 326                 max_size_exchange_to_client_msg=sizeof(
 327                         boost::mpl::deref<
 328                                 boost::mpl::max_element<
 329                                         boost::mpl::transform_view<exchange_to_client_messages_t, boost::mpl::sizeof_<boost::mpl::_1> >
 330                                 >::type::base
 331                         >::type
 332                 ),
 333                 min_msg_size=jmmcg::min<std::size_t, min_size_client_to_exchange_msg, min_size_exchange_to_client_msg>::value,
 334                 max_msg_size=jmmcg::max<std::size_t, max_size_client_to_exchange_msg, max_size_exchange_to_client_msg>::value,
 335                 header_t_size=LogonRequest::header_t_size
 336         };
 337 
 338         using msg_buffer_t=std::array<std::uint8_t, max_msg_size>;
 339         using client_to_exchange_messages_container=boost::make_variant_over<client_to_exchange_messages_t>::type;
 340         using exchange_to_client_messages_container=boost::make_variant_over<exchange_to_client_messages_t>::type;
 341 
 342         static inline constexpr Price_t implied_decimal_places=common::implied_decimal_places;
 343 
 344         static std::ostream &to_stream(std::ostream &) noexcept(false);
 345 };
 346 
 347 /**
 348         \test MIT BIT size tests.
 349 */
 350 namespace tests {
 351 
 352 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::Header_t), <=, MsgTypes::max_size_client_to_exchange_msg);
 353 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::Header_t), <=, MsgTypes::max_size_exchange_to_client_msg);
 354 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::Header_t), <=, MsgTypes::max_msg_size);
 355 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::LogonRequest), ==, 80);
 356 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::LogonReply), ==, 38);
 357 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::LogoutRequest), ==, 24);
 358 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::ClientHeartbeat), ==, 4);
 359 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::ServerHeartbeat), ==, 4);
 360 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::MissedMessageRequest), ==, 9);
 361 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::MissedMessageRequestAck), ==, 5);
 362 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::MissedMessageReport), ==, 5);
 363 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::Reject), ==, 59);
 364 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::SystemStatus), ==, 6);
 365 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::NewOrder), ==, 106);
 366 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::NewQuote), ==, 86);
 367 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::OrderCancelReplaceRequest), ==, 120);
 368 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::OrderCancelRequest), ==, 73);
 369 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::OrderMassCancelRequest), ==, 46);
 370 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::ExecutionReport), ==, 229);
 371 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::OrderCancelReject), ==, 73);
 372 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::OrderMassCancelReport), ==, 56);
 373 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::BusinessReject), ==, 63);
 374 
 375 }
 376 
 377 } } } }
 378 
 379 #include "messages_impl.hpp"
 380 
 381 #endif

/* [<][>][^][v][top][bottom][index][help] */