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

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

INCLUDED FROM


   1 #ifndef libjmmcg_isimud_exchanges_MIT_OSLO_messages_hpp
   2 #define libjmmcg_isimud_exchanges_MIT_OSLO_messages_hpp
   3 
   4 /******************************************************************************
   5 ** $Header: svn+ssh://jmmcg@svn.code.sf.net/p/libjmmcg/code/trunk/libjmmcg/isimud/exchanges/MIT/OSLO/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.oslobors.no/ob_eng/obnewsletter/download/af04d9d4a7aff5dd1d2f1bf402618b4f/file/file/OSLMIT%20203%20Native%20Trading%20Gateway%20-%20issue%204.2.pdf">"OSLMIT 203 Native Trading Gateway", Issue 4.1, 12 January 2015</a>.
  48         
  49 */
  50 namespace OSLO {
  51 
  52 /**
  53         Section: "5.6.1 New Order"
  54 */
  55 struct NewOrderSpecific1 {
  56         common::SecurityID_t instrumentID_;
  57         const std::int8_t reservedField1=0;
  58         const std::int8_t reservedField2=0;
  59 
  60         explicit constexpr NewOrderSpecific1(common::SecurityID_t instID) noexcept(true) FORCE_INLINE
  61         : instrumentID_(instID) {
  62         }
  63         common::SecurityID_t instrumentID() const noexcept(true) {
  64                 return instrumentID_;
  65         }
  66         void instrumentID(common::SecurityID_t i) noexcept(true) {
  67                 instrumentID_=i;
  68         }
  69 } __attribute__((packed));
  70 struct NewOrderSpecific2 {
  71         using order_qty_t=std::uint64_t;
  72 
  73         order_qty_t orderQty_;
  74         order_qty_t displayQty;
  75 
  76         explicit constexpr NewOrderSpecific2(order_qty_t ordQty) noexcept(true) FORCE_INLINE
  77         : orderQty_(ordQty), displayQty(ordQty) {
  78         }
  79         order_qty_t orderQty() const noexcept(true) {
  80                 return orderQty_;
  81         }
  82         void orderQty(order_qty_t i) noexcept(true) {
  83                 orderQty_=i;
  84         }
  85 } __attribute__((packed));
  86 struct NewOrderSpecific3 {
  87         common::PassiveOnlyOrder passiveOnlyOrder_=common::PassiveOnlyOrder::NoConstraint;
  88         common::TargetBook targetBook=common::TargetBook::LitOrderBook;
  89         common::ExecInstruction execInstruction=common::ExecInstruction::Default;
  90         int32_t minimumQuantity=0;
  91         const common::PegPriceType pegPriceType=common::PegPriceType::MidPoint;
  92         common::ReservedField12_t reservedField;
  93 
  94         common::PassiveOnlyOrder FORCE_INLINE passiveOnlyOrder() const noexcept(true) {
  95                 return passiveOnlyOrder_;
  96         }
  97         void FORCE_INLINE passiveOnlyOrder(common::PassiveOnlyOrder poo) noexcept(true) {
  98                 passiveOnlyOrder_=poo;
  99         }
 100         static constexpr common::OrderSource FORCE_INLINE orderSource() noexcept(true) {
 101                 return common::OrderSource::MarketParticipantDealsOnOwnAccount;
 102         }
 103         static void FORCE_INLINE orderSource(common::OrderSource) noexcept(true) {
 104         }
 105 } __attribute__((packed));
 106 
 107 /**
 108         Section: "5.6.4 Order Modification Request"
 109 */
 110 struct OrderCancelReplaceRequestSpecific {
 111         common::TargetBook targetBook;
 112         common::ExecInstruction execInstruction;
 113         int32_t minimumQuantity;
 114         const int16_t reservedField1=0;
 115         common::ReservedField10_t reservedField2;
 116         common::PassiveOnlyOrder passiveOnlyOrder_;
 117 
 118         common::PassiveOnlyOrder FORCE_INLINE passiveOnlyOrder() const noexcept(true) {
 119                 return passiveOnlyOrder_;
 120         }
 121         void FORCE_INLINE passiveOnlyOrder(common::PassiveOnlyOrder poo) noexcept(true) {
 122                 passiveOnlyOrder_=poo;
 123         }       
 124 } __attribute__((packed));
 125 
 126 /**
 127         Section: "5.7.1 Execution Report"
 128 */
 129 struct ExecutionReportSpecific1 {
 130         using RejectCode_t=mit_oslo::reject_codes_enum;
 131         using RejectCodes_t=std::underlying_type<RejectCode_t>::type;
 132 
 133         uint64_t executedQty;
 134         uint64_t leavesQty;
 135         common::Container container;
 136         uint64_t displayQty;
 137 } __attribute__((packed));
 138 struct ExecutionReportSpecific2 {
 139         common::TargetBook targetBook;
 140         int32_t minimumQuantity;
 141         const std::int8_t reservedField1=0;
 142         common::ReservedField4_t reservedField2;
 143         const uint8_t reservedField3=0;
 144         common::Price_t avgPx;
 145         const common::Price_t reservedField4=0;
 146         common::ReservedField20_t reservedField5;
 147         common::TypeOfTrade typeOfTrade;
 148         common::ReservedField20_t reservedField6;
 149         common::RestatementReason restatementReason;
 150         common::PriceDifferential priceDifferential;
 151         common::OrderID_t publicOrderID;
 152 } __attribute__((packed));
 153 
 154 struct OrderMassCancelRequestSpecific1 {
 155         common::SecurityID_t instrumentID_;
 156         const std::int8_t reservedField1=0;
 157         const std::int8_t reservedField2=0;
 158         common::Segment_t segment{};
 159 
 160         explicit constexpr OrderMassCancelRequestSpecific1(common::SecurityID_t instID) noexcept(true) FORCE_INLINE
 161         : instrumentID_(instID) {
 162         }
 163         common::SecurityID_t instrumentID() const noexcept(true) {
 164                 return instrumentID_;
 165         }
 166         void instrumentID(common::SecurityID_t i) noexcept(true) {
 167                 instrumentID_=i;
 168         }
 169 } __attribute__((packed));
 170 
 171 struct LogonReply : public common::LogonReply<mit_oslo::reject_codes_enum> {
 172         using base_t=common::LogonReply<mit_oslo::reject_codes_enum>;
 173         using RejectCode_t=base_t::RejectCode_t;
 174         using RejectCodes_t=std::underlying_type<RejectCode_t>::type;
 175         using base_t::base_t;
 176 
 177         static constexpr const RejectCode_t logon_success=mit_oslo::reject_codes_enum::tag_SUCCESS;
 178         static constexpr const RejectCode_t invalid_logon_details=mit_oslo::reject_codes_enum::Native_Trading_Gateway__Invalid_User_ID_or_password_1;
 179         static constexpr const RejectCode_t unknown_user=mit_oslo::reject_codes_enum::Native_Trading_Gateway__Invalid_User_ID_or_password_1;
 180 };
 181 
 182 struct NewOrder : public common::NewOrder<NewOrderSpecific1, NewOrderSpecific2, NewOrderSpecific3> {
 183         using base_t=common::NewOrder<NewOrderSpecific1, NewOrderSpecific2, NewOrderSpecific3>;
 184         using base_t::base_t;
 185         using order_qty_t=NewOrderSpecific2::order_qty_t;
 186         using ref_data_t=common::ref_data_t;
 187 
 188         /// Create a message from the source message.
 189         /**
 190                 If a linker error is generated, then this function will need to be specialised for the particular Msg-type.
 191 
 192                 \param  msg     The source message from which the target message should be created.
 193         */
 194         template<class SrcMsg> explicit __stdcall
 195         NewOrder(SrcMsg const &msg, ref_data_t rd) noexcept(true) FORCE_INLINE;
 196 } __attribute__((packed));
 197 
 198 struct OrderCancelReplaceRequest : public common::OrderCancelReplaceRequest<NewOrderSpecific1, NewOrderSpecific2, OrderCancelReplaceRequestSpecific> {
 199         using base_t=common::OrderCancelReplaceRequest<NewOrderSpecific1, NewOrderSpecific2, OrderCancelReplaceRequestSpecific>;
 200         using base_t::base_t;
 201         using order_qty_t=NewOrderSpecific2::order_qty_t;
 202         using ref_data_t=common::ref_data_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> explicit __stdcall
 211         OrderCancelReplaceRequest(SrcMsg const &msg, ref_data_t rd) noexcept(true);
 212 } __attribute__((packed));
 213 
 214 struct OrderCancelRequest : public common::OrderCancelRequest<NewOrderSpecific1> {
 215         using base_t=common::OrderCancelRequest<NewOrderSpecific1>;
 216         using base_t::base_t;
 217         using ref_data_t=common::ref_data_t;
 218 
 219         /// Create a message from the source message.
 220         /**
 221                 If a linker error is generated, then this function will need to be specialised for the particular Msg-type.
 222 
 223                 \param  msg     The source message from which the target message should be created.
 224         */
 225         template<class SrcMsg> explicit __stdcall
 226         OrderCancelRequest(SrcMsg const &msg, ref_data_t rd) noexcept(true);
 227 } __attribute__((packed));
 228 
 229 struct MsgTypes {
 230 
 231         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_NORWAY_XOSL;
 232 
 233         using ref_data=common::ref_data;
 234         using ref_data_t=common::ref_data_t;
 235 
 236         using MsgTypes_t=common::MsgType_t;
 237         using UserName_t=common::UserName_t;
 238         using Password_t=common::Password_t;
 239         using SecurityID_t=common::SecurityID_t;
 240         using Price_t=common::Price_t;
 241         using ClientOrderID_t=common::ClientOrderID_t;
 242         using OrderType=common::OrderType;
 243         using Side=common::Side;
 244         using ExecType=common::ExecType;
 245         using AppID=common::AppID;
 246         using OrderStatus=common::OrderStatus;
 247         using logon_args_t=common::logon_args_t;
 248 
 249         using Header_t=common::Header;
 250         using NewOrder=OSLO::NewOrder;
 251         using OrderCancelRequest=OSLO::OrderCancelRequest;
 252         typedef common::OrderMassCancelRequest<OrderMassCancelRequestSpecific1> OrderMassCancelRequest;
 253         using OrderCancelReplaceRequest=OSLO::OrderCancelReplaceRequest;
 254         typedef common::LogonRequest LogonRequest;
 255         typedef common::LogoutRequest LogoutRequest;
 256         using ClientHeartbeat=common::Heartbeat;
 257         using ServerHeartbeat=common::Heartbeat;
 258         typedef common::MissedMessageRequest MissedMessageRequest;
 259         typedef common::ExecutionReport<ExecutionReportSpecific1, ExecutionReportSpecific2> ExecutionReport;
 260         using OrderCancelReject=common::OrderCancelReject<common::OrderCancelRejectSpecific<mit_oslo::reject_codes_enum>>;
 261         using OrderMassCancelReport=common::OrderMassCancelReport<common::OrderMassCancelReportSpecific<mit_oslo::reject_codes_enum>>;
 262         using BusinessReject=common::BusinessReject<common::BusinessRejectSpecific<mit_oslo::reject_codes_enum, mit_oslo::reject_codes_enum::Matching_Engine__Unknown_instrument_9000>>;
 263         using LogonReply=OSLO::LogonReply;
 264         typedef common::MissedMessageRequestAck MissedMessageRequestAck;
 265         typedef common::MissedMessageReport MissedMessageReport;
 266         using Reject=common::Reject<mit_oslo::reject_codes_enum, mit_oslo::reject_codes_enum::Native_Trading_Gateway__Message_not_supported_102>;
 267         typedef common::SystemStatus SystemStatus;
 268 
 269         using Logout=LogoutRequest;
 270 
 271         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.
 272         static inline constexpr MsgTypes_t Exit=std::numeric_limits<MsgTypes_t>::max(); ///< For the meta-state machine: the exit state to exit the msm.
 273 
 274         using client_to_exchange_messages_t=boost::mpl::vector<
 275                 NewOrder,
 276                 OrderCancelRequest,
 277                 OrderMassCancelRequest,
 278                 OrderCancelReplaceRequest,
 279                 LogonRequest,
 280                 LogoutRequest,
 281                 ClientHeartbeat,
 282                 MissedMessageRequest
 283         >;
 284 
 285         using exchange_to_client_messages_t=boost::mpl::vector<
 286                 ExecutionReport,
 287                 OrderCancelReject,
 288                 OrderMassCancelReport,
 289                 BusinessReject,
 290                 LogonReply,
 291                 Logout,
 292                 ServerHeartbeat,
 293                 MissedMessageRequestAck,
 294                 MissedMessageReport,
 295                 Reject,
 296                 SystemStatus
 297         >;
 298 
 299         enum : std::size_t {
 300                 min_size_client_to_exchange_msg=sizeof(
 301                         boost::mpl::deref<
 302                                 boost::mpl::min_element<
 303                                         boost::mpl::transform_view<client_to_exchange_messages_t, boost::mpl::sizeof_<boost::mpl::_1> >
 304                                 >::type::base
 305                         >::type
 306                 ),
 307                 max_size_client_to_exchange_msg=sizeof(
 308                         boost::mpl::deref<
 309                                 boost::mpl::max_element<
 310                                         boost::mpl::transform_view<client_to_exchange_messages_t, boost::mpl::sizeof_<boost::mpl::_1> >
 311                                 >::type::base
 312                         >::type
 313                 ),
 314                 min_size_exchange_to_client_msg=sizeof(
 315                         boost::mpl::deref<
 316                                 boost::mpl::min_element<
 317                                         boost::mpl::transform_view<exchange_to_client_messages_t, boost::mpl::sizeof_<boost::mpl::_1> >
 318                                 >::type::base
 319                         >::type
 320                 ),
 321                 max_size_exchange_to_client_msg=sizeof(
 322                         boost::mpl::deref<
 323                                 boost::mpl::max_element<
 324                                         boost::mpl::transform_view<exchange_to_client_messages_t, boost::mpl::sizeof_<boost::mpl::_1> >
 325                                 >::type::base
 326                         >::type
 327                 ),
 328                 min_msg_size=jmmcg::min<std::size_t, min_size_client_to_exchange_msg, min_size_exchange_to_client_msg>::value,
 329                 max_msg_size=jmmcg::max<std::size_t, max_size_client_to_exchange_msg, max_size_exchange_to_client_msg>::value,
 330                 header_t_size=sizeof(typename LogonRequest::Header_t)
 331         };
 332         BOOST_MPL_ASSERT_RELATION(max_msg_size, >=, header_t_size);
 333 
 334         using msg_buffer_t=std::array<std::uint8_t, max_msg_size>;
 335         using client_to_exchange_messages_container=boost::make_variant_over<client_to_exchange_messages_t>::type;
 336         using exchange_to_client_messages_container=boost::make_variant_over<exchange_to_client_messages_t>::type;
 337 
 338         static inline constexpr Price_t implied_decimal_places=common::implied_decimal_places;
 339 
 340         static std::ostream &to_stream(std::ostream &) noexcept(false);
 341 };
 342 
 343 /**
 344         \test MIT OSLO size tests.
 345 */
 346 namespace tests {
 347 
 348 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::Header_t), <=, MsgTypes::max_size_client_to_exchange_msg);
 349 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::Header_t), <=, MsgTypes::max_size_exchange_to_client_msg);
 350 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::Header_t), <=, MsgTypes::max_msg_size);
 351 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::LogonRequest), ==, 80);
 352 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::LogonReply), ==, 38);
 353 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::Logout), ==, 24);
 354 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::ClientHeartbeat), ==, 4);
 355 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::ServerHeartbeat), ==, 4);
 356 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::MissedMessageRequest), ==, 9);
 357 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::MissedMessageRequestAck), ==, 5);
 358 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::MissedMessageReport), ==, 5);
 359 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::Reject), ==, 59);
 360 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::SystemStatus), ==, 6);
 361 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::NewOrder), ==, 106);
 362 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::OrderCancelReplaceRequest), ==, 129);
 363 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::OrderCancelRequest), ==, 73);
 364 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::OrderMassCancelRequest), ==, 46);
 365 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::ExecutionReport), ==, 229);
 366 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::OrderCancelReject), ==, 73);
 367 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::OrderMassCancelReport), ==, 56);
 368 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::BusinessReject), ==, 63);
 369 
 370 }
 371 
 372 } } } }
 373 
 374 #include "messages_impl.hpp"
 375 
 376 #endif

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