1 #ifndef libjmmcg_isimud_exchanges_MIT_LSE_messages_hpp
2 #define libjmmcg_isimud_exchanges_MIT_LSE_messages_hpp
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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
48
49
50 namespace LSE {
51
52
53
54
55 struct NewOrderSpecific1 {
56 common::SecurityID_t instrumentID_;
57 common::MESQualifier mesQualifier_=common::MESQualifier::NonMES;
58 const std::int8_t reservedField1=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 common::MESQualifier mesQualifier() const noexcept(true) {
70 return mesQualifier_;
71 }
72 void mesQualifier(common::MESQualifier m) noexcept(true) {
73 mesQualifier_=m;
74 }
75 } __attribute__((packed));
76 struct NewOrderSpecific2 {
77 using order_qty_t=std::int32_t;
78
79 order_qty_t orderQty_;
80 order_qty_t displayQty;
81
82 explicit constexpr NewOrderSpecific2(order_qty_t ordQty) noexcept(true) FORCE_INLINE
83 : orderQty_(ordQty), displayQty(ordQty) {
84 }
85 order_qty_t orderQty() const noexcept(true) {
86 return orderQty_;
87 }
88 void orderQty(order_qty_t i) noexcept(true) {
89 orderQty_=i;
90 }
91 } __attribute__((packed));
92 struct NewOrderSpecific3 {
93 common::Anonymity anonymity=common::Anonymity::Anonymous;
94 common::Price_t stoppedPrice=0;
95 common::PassiveOnlyOrder passiveOnlyOrder_=common::PassiveOnlyOrder::NoConstraint;
96 common::ReservedField9_t reservedField;
97 int32_t minimumQuantity=0;
98
99 common::PassiveOnlyOrder FORCE_INLINE passiveOnlyOrder() const noexcept(true) {
100 return passiveOnlyOrder_;
101 }
102 void FORCE_INLINE passiveOnlyOrder(common::PassiveOnlyOrder poo) noexcept(true) {
103 passiveOnlyOrder_=poo;
104 }
105 static constexpr common::OrderSource FORCE_INLINE orderSource() noexcept(true) {
106 return common::OrderSource::MarketParticipantDealsOnOwnAccount;
107 }
108 static void FORCE_INLINE orderSource(common::OrderSource) noexcept(true) {
109 }
110 } __attribute__((packed));
111
112
113
114
115 struct NewQuoteSpecific1 {
116 common::Price_t bidPrice;
117 int32_t bidSize;
118 common::Price_t askPrice;
119 int32_t askSize;
120 } __attribute__((packed));
121 struct NewQuoteSpecific2 {
122 common::ReservedField10_t reservedField;
123 } __attribute__((packed));
124
125
126
127
128 struct OrderCancelReplaceRequestSpecific {
129 common::PassiveOnlyOrder passiveOnlyOrder_;
130 common::ReservedField9_t reservedField;
131 int32_t minimumQuantity=0;
132
133 common::PassiveOnlyOrder FORCE_INLINE passiveOnlyOrder() const noexcept(true) {
134 return passiveOnlyOrder_;
135 }
136 void FORCE_INLINE passiveOnlyOrder(common::PassiveOnlyOrder poo) noexcept(true) {
137 passiveOnlyOrder_=poo;
138 }
139 static constexpr common::OrderSource FORCE_INLINE orderSource() noexcept(true) {
140 return common::OrderSource::MarketParticipantDealsOnOwnAccount;
141 }
142 static void FORCE_INLINE orderSource(common::OrderSource) noexcept(true) {
143 }
144 } __attribute__((packed));
145
146
147
148
149 struct ExecutionReportSpecific1 {
150 using RejectCode_t=mit_lse::reject_codes_enum;
151 using RejectCodes_t=std::underlying_type<RejectCode_t>::type;
152
153 int32_t executedQty;
154 int32_t leavesQty;
155 common::Container container;
156 int32_t displayQty;
157 } __attribute__((packed));
158 struct ExecutionReportSpecific2 {
159 const char reservedField1='\0';
160 common::TypeOfTrade typeOfTrade;
161 common::Capacity capacity;
162 common::PriceDifferential priceDifferential;
163 common::PublicOrderID_t publicOrderID;
164 int32_t minimumQuantity=0;
165 } __attribute__((packed));
166
167 struct OrderMassCancelRequestSpecific1 {
168 common::SecurityID_t instrumentID_;
169 common::MESQualifier mesQualifier_=common::MESQualifier::NonMES;
170 const std::int8_t reservedField1=0;
171 common::Segment_t segment{};
172
173 explicit constexpr OrderMassCancelRequestSpecific1(common::SecurityID_t instID) noexcept(true) FORCE_INLINE
174 : instrumentID_(instID) {
175 }
176 common::SecurityID_t instrumentID() const noexcept(true) {
177 return instrumentID_;
178 }
179 void instrumentID(common::SecurityID_t i) noexcept(true) {
180 instrumentID_=i;
181 }
182 common::MESQualifier mesQualifier() const noexcept(true) {
183 return mesQualifier_;
184 }
185 void mesQualifier(common::MESQualifier m) noexcept(true) {
186 mesQualifier_=m;
187 }
188 } __attribute__((packed));
189
190 struct LogonReply : public common::LogonReply<mit_lse::reject_codes_enum> {
191 using base_t=common::LogonReply<mit_lse::reject_codes_enum>;
192 using RejectCode_t=base_t::RejectCode_t;
193 using RejectCodes_t=std::underlying_type<RejectCode_t>::type;
194 using base_t::base_t;
195
196 static constexpr const RejectCode_t logon_success=mit_lse::reject_codes_enum::tag_SUCCESS;
197 static constexpr const RejectCode_t invalid_logon_details=mit_lse::reject_codes_enum::AuthServer_INVALID_USERID_PWD______1;
198 static constexpr const RejectCode_t unknown_user=mit_lse::reject_codes_enum::AuthServer_USER_NOT_FOUND_4;
199 };
200
201 struct NewOrder : public common::NewOrder<NewOrderSpecific1, NewOrderSpecific2, NewOrderSpecific3> {
202 using base_t=common::NewOrder<NewOrderSpecific1, NewOrderSpecific2, NewOrderSpecific3>;
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
208
209
210
211
212
213 template<class SrcMsg> __stdcall
214 NewOrder(SrcMsg const &msg, ref_data_t rd) noexcept(true) FORCE_INLINE;
215 };
216
217 struct OrderCancelReplaceRequest : public common::OrderCancelReplaceRequest<NewOrderSpecific1, NewOrderSpecific2, OrderCancelReplaceRequestSpecific> {
218 using base_t=common::OrderCancelReplaceRequest<NewOrderSpecific1, NewOrderSpecific2, OrderCancelReplaceRequestSpecific>;
219 using base_t::base_t;
220 using order_qty_t=NewOrderSpecific2::order_qty_t;
221 using ref_data_t=common::ref_data_t;
222
223
224
225
226
227
228
229 template<class SrcMsg> explicit __stdcall
230 OrderCancelReplaceRequest(SrcMsg const &msg, ref_data_t rd) noexcept(true);
231 };
232
233 struct OrderCancelRequest : public common::OrderCancelRequest<NewOrderSpecific1> {
234 using base_t=common::OrderCancelRequest<NewOrderSpecific1>;
235 using base_t::base_t;
236 using ref_data_t=common::ref_data_t;
237
238
239
240
241
242
243
244 template<class SrcMsg> explicit __stdcall
245 OrderCancelRequest(SrcMsg const &msg, ref_data_t rd) noexcept(true);
246 };
247
248 struct MsgTypes {
249
250 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_UNITED_KINGDOM_XLON;
251
252 using ref_data=common::ref_data;
253 using ref_data_t=common::ref_data_t;
254
255 using MsgTypes_t=common::MsgType_t;
256 using UserName_t=common::UserName_t;
257 using Password_t=common::Password_t;
258 using SecurityID_t=common::SecurityID_t;
259 using Price_t=common::Price_t;
260 using ClientOrderID_t=common::ClientOrderID_t;
261 using OrderType=common::OrderType;
262 using Side=common::Side;
263 using ExecType=common::ExecType;
264 using AppID=common::AppID;
265 using OrderStatus=common::OrderStatus;
266 using logon_args_t=common::logon_args_t;
267
268 using Header_t=common::Header;
269 using NewOrder=LSE::NewOrder;
270 using OrderCancelRequest=LSE::OrderCancelRequest;
271 typedef common::OrderMassCancelRequest<OrderMassCancelRequestSpecific1> OrderMassCancelRequest;
272 using OrderCancelReplaceRequest=LSE::OrderCancelReplaceRequest;
273 typedef common::NewQuote<NewQuoteSpecific1, NewQuoteSpecific2> NewQuote;
274 typedef common::LogonRequest LogonRequest;
275 typedef common::LogoutRequest LogoutRequest;
276 using ClientHeartbeat=common::Heartbeat;
277 using ServerHeartbeat=common::Heartbeat;
278 typedef common::MissedMessageRequest MissedMessageRequest;
279 typedef common::ExecutionReport<ExecutionReportSpecific1, ExecutionReportSpecific2> ExecutionReport;
280 using OrderCancelReject=common::OrderCancelReject<common::OrderCancelRejectSpecific<mit_lse::reject_codes_enum>>;
281 using OrderMassCancelReport=common::OrderMassCancelReport<common::OrderMassCancelReportSpecific<mit_lse::reject_codes_enum>>;
282 using BusinessReject=common::BusinessReject<common::BusinessRejectSpecific<mit_lse::reject_codes_enum, mit_lse::reject_codes_enum::MatchingEngine_Unknown_instrument_9000>>;
283 using LogonReply=LSE::LogonReply;
284 typedef common::MissedMessageRequestAck MissedMessageRequestAck;
285 typedef common::MissedMessageReport MissedMessageReport;
286 using Reject=common::Reject<mit_lse::reject_codes_enum, mit_lse::reject_codes_enum::NativeGateway_Message_not_supported_102>;
287 typedef common::SystemStatus SystemStatus;
288
289 using Logout=LogoutRequest;
290
291 static inline constexpr MsgTypes_t MatchAll=std::numeric_limits<MsgTypes_t>::max()-1;
292 static inline constexpr MsgTypes_t Exit=std::numeric_limits<MsgTypes_t>::max();
293
294 using client_to_exchange_messages_t=boost::mpl::vector<
295 NewOrder,
296 OrderCancelRequest,
297 OrderMassCancelRequest,
298 OrderCancelReplaceRequest,
299 NewQuote,
300 LogonRequest,
301 LogoutRequest,
302 ClientHeartbeat,
303 MissedMessageRequest
304 >;
305
306 using exchange_to_client_messages_t=boost::mpl::vector<
307 ExecutionReport,
308 OrderCancelReject,
309 OrderMassCancelReport,
310 BusinessReject,
311 LogonReply,
312 Logout,
313 ServerHeartbeat,
314 MissedMessageRequestAck,
315 MissedMessageReport,
316 Reject,
317 SystemStatus
318 >;
319
320 enum : std::size_t {
321 min_size_client_to_exchange_msg=sizeof(
322 boost::mpl::deref<
323 boost::mpl::min_element<
324 boost::mpl::transform_view<client_to_exchange_messages_t, boost::mpl::sizeof_<boost::mpl::_1> >
325 >::type::base
326 >::type
327 ),
328 max_size_client_to_exchange_msg=sizeof(
329 boost::mpl::deref<
330 boost::mpl::max_element<
331 boost::mpl::transform_view<client_to_exchange_messages_t, boost::mpl::sizeof_<boost::mpl::_1> >
332 >::type::base
333 >::type
334 ),
335 min_size_exchange_to_client_msg=sizeof(
336 boost::mpl::deref<
337 boost::mpl::min_element<
338 boost::mpl::transform_view<exchange_to_client_messages_t, boost::mpl::sizeof_<boost::mpl::_1> >
339 >::type::base
340 >::type
341 ),
342 max_size_exchange_to_client_msg=sizeof(
343 boost::mpl::deref<
344 boost::mpl::max_element<
345 boost::mpl::transform_view<exchange_to_client_messages_t, boost::mpl::sizeof_<boost::mpl::_1> >
346 >::type::base
347 >::type
348 ),
349 min_msg_size=jmmcg::min<std::size_t, min_size_client_to_exchange_msg, min_size_exchange_to_client_msg>::value,
350 max_msg_size=jmmcg::max<std::size_t, max_size_client_to_exchange_msg, max_size_exchange_to_client_msg>::value,
351 header_t_size=sizeof(typename LogonRequest::Header_t)
352 };
353 BOOST_MPL_ASSERT_RELATION(max_msg_size, >=, header_t_size);
354
355 using msg_buffer_t=std::array<std::uint8_t, max_msg_size>;
356 using client_to_exchange_messages_container=boost::make_variant_over<client_to_exchange_messages_t>::type;
357 using exchange_to_client_messages_container=boost::make_variant_over<exchange_to_client_messages_t>::type;
358
359 static inline constexpr Price_t implied_decimal_places=common::implied_decimal_places;
360
361 static std::ostream &to_stream(std::ostream &) noexcept(false);
362 };
363
364
365
366
367 namespace tests {
368
369 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::Header_t), <=, MsgTypes::max_size_client_to_exchange_msg);
370 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::Header_t), <=, MsgTypes::max_size_exchange_to_client_msg);
371 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::Header_t), <=, MsgTypes::max_msg_size);
372 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::LogonRequest), ==, 80);
373 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::LogonReply), ==, 38);
374 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::LogoutRequest), ==, 24);
375 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::ClientHeartbeat), ==, 4);
376 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::ServerHeartbeat), ==, 4);
377 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::MissedMessageRequest), ==, 9);
378 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::MissedMessageRequestAck), ==, 5);
379 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::MissedMessageReport), ==, 5);
380 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::Reject), ==, 59);
381 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::SystemStatus), ==, 6);
382 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::NewOrder), ==, 101);
383 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::NewQuote), ==, 76);
384 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::OrderCancelReplaceRequest), ==, 116);
385 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::OrderCancelRequest), ==, 73);
386 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::OrderMassCancelRequest), ==, 46);
387 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::ExecutionReport), ==, 155);
388 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::OrderCancelReject), ==, 73);
389 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::OrderMassCancelReport), ==, 56);
390 BOOST_MPL_ASSERT_RELATION(sizeof(MsgTypes::BusinessReject), ==, 63);
391
392 }
393
394 } } } }
395
396 #include "messages_impl.hpp"
397
398 #endif