23 template<
class SrcMsgDetails,
class DestMsgDetails>
26 using row_t=libjmmcg::
msm::
unroll::
row_types<
typename src_msg_details_t::MsgType_t,
typename dest_msg_details_t::MsgTypes_t>;
27 using transition_table=
typename msm_base_t::
template rows<
28 typename row_t::
template row<
29 src_msg_details_t::NewOrder_t::static_type,
30 typename base_t::
template convert_then_send_seq_num<
typename src_msg_details_t::NewOrder_t,
typename dest_msg_details_t::NewOrder_t>,
31 dest_msg_details_t::NewOrder_t::static_type
33 typename row_t::
template row<
34 src_msg_details_t::OrderCancelRequest::static_type,
35 typename base_t::
template convert_then_send_seq_num<
typename src_msg_details_t::OrderCancelRequest,
typename dest_msg_details_t::OrderCancelRequest>,
36 dest_msg_details_t::OrderCancelRequest::static_type
38 typename row_t::
template row<
39 src_msg_details_t::OrderCancelReplace::static_type,
40 typename base_t::
template convert_then_send_seq_num<
typename src_msg_details_t::OrderCancelReplace,
typename dest_msg_details_t::OrderCancelReplaceRequest>,
41 dest_msg_details_t::OrderCancelReplaceRequest::static_type
44 typename row_t::
template row<
45 src_msg_details_t::MatchAll,
46 typename base_t::
template send_reject<
typename src_msg_details_t::Reject,
true>,
47 dest_msg_details_t::OrderRejected::static_type
55 client_to_exchange_transformations<SrcMsgDetails, DestMsgDetails>::
process_msg(
typename src_msg_details_t::msg_buffer_t
const &buff, SktT &exchg_skt, SktT &client_skt) {
57 typename src_msg_details_t::Header_t
const &hdr=
reinterpret_cast<
typename src_msg_details_t::Header_t
const &>(buff);
58 const auto last_state=msm.process(hdr.type(), buff, exchg_skt, client_skt);
59 return last_state==dest_msg_details_t::Exit;
62 template<
class SrcMsgDetails,
class DestMsgDetails>
inline std::string
63 client_to_exchange_transformations<SrcMsgDetails, DestMsgDetails>::
to_string()
const noexcept(
false) {
64 std::ostringstream ss;
66 <<
"\n\tCurrent sequence number="<<sequenceNumber
67 <<
"Source message details: ";
68 SrcMsgDetails::to_stream(ss);
69 ss<<
"\n\tDestination message details: ";
70 DestMsgDetails::to_stream(ss);
74 template<
class SrcMsgDetails,
class DestMsgDetails>
inline std::ostream &
75 operator<<(
std::ostream &os, client_to_exchange_transformations<SrcMsgDetails, DestMsgDetails>
const &ec)
noexcept(
false) {
80 template<
class SrcMsgDetails,
class DestMsgDetails>
81 struct exchange_to_client_transformations<SrcMsgDetails, DestMsgDetails>::business_state_machine_t : libjmmcg::
msm::
unroll::
state_transition_table<business_state_machine_t> {
83 using row_t=libjmmcg::
msm::
unroll::
row_types<
typename src_msg_details_t::MsgTypes_t,
typename dest_msg_details_t::MsgType_t>;
84 using transition_table=
typename msm_base_t::
template rows<
85 typename row_t::
template row<
86 src_msg_details_t::OrderRejected::static_type,
87 typename base_t::
template convert_then_send<
typename src_msg_details_t::OrderRejected,
typename dest_msg_details_t::OrderRejected>,
88 dest_msg_details_t::OrderRejected::static_type
90 typename row_t::
template row<
91 src_msg_details_t::OrderCancelReject::static_type,
92 typename base_t::
template convert_then_send<
typename src_msg_details_t::OrderCancelReject,
typename dest_msg_details_t::CancelRejected>,
93 dest_msg_details_t::CancelRejected::static_type
95 typename row_t::
template row<
96 src_msg_details_t::UserModifyRejected::static_type,
97 typename base_t::
template convert_then_send<
typename src_msg_details_t::UserModifyRejected,
typename dest_msg_details_t::BusinessMessageReject>,
98 dest_msg_details_t::BusinessMessageReject::static_type
100 typename row_t::
template row<
101 src_msg_details_t::OrderCancelled::static_type,
102 typename base_t::
template convert_then_send<
typename src_msg_details_t::OrderCancelled,
typename dest_msg_details_t::ExecutionReport>,
103 dest_msg_details_t::ExecutionReport::static_type
105 typename row_t::
template row<
106 src_msg_details_t::ExecutionReport::static_type,
107 typename base_t::
template convert_then_send<
typename src_msg_details_t::ExecutionReport,
typename dest_msg_details_t::ExecutionReport>,
108 dest_msg_details_t::ExecutionReport::static_type
111 typename row_t::
template row<
112 src_msg_details_t::MatchAll,
113 typename base_t::
template send_reject<
typename dest_msg_details_t::Reject,
true>,
114 dest_msg_details_t::Reject::static_type
119 template<
class SrcMsgDetails,
class DestMsgDetails>
120 struct exchange_to_client_transformations<SrcMsgDetails, DestMsgDetails>::admin_state_machine_t : libjmmcg::
msm::
unroll::
state_transition_table<admin_state_machine_t> {
122 using row_t=libjmmcg::
msm::
unroll::
row_types<
typename src_msg_details_t::MsgTypes_t,
typename dest_msg_details_t::MsgType_t>;
123 using transition_table=
typename msm_base_t::
template rows<
131 typename row_t::
template row<
132 src_msg_details_t::ServerHeartbeat::static_type,
133 typename base_t::
template convert_then_send_seq_num<
typename src_msg_details_t::ClientHeartbeat,
typename src_msg_details_t::ClientHeartbeat,
false>,
134 dest_msg_details_t::ClientHeartbeat::static_type
143 typename row_t::
template row<
144 src_msg_details_t::Logout::static_type,
145 typename msm_base_t::no_op,
146 dest_msg_details_t::Exit
149 typename row_t::
template row<
150 src_msg_details_t::MatchAll,
151 typename base_t::
template match_all_response<business_machine>,
152 dest_msg_details_t::Reject::static_type
158 template<
class SktT,
class ClientCxn>
160 exchange_to_client_transformations<SrcMsgDetails, DestMsgDetails>::
process_msg(
typename src_msg_details_t::msg_buffer_t
const &buff, SktT &exchg_skt, ClientCxn &client_cxn) {
162 typename src_msg_details_t::Header_t
const &hdr=
reinterpret_cast<
typename src_msg_details_t::Header_t
const &>(buff);
163 const auto last_state=admin_msm.process(
static_cast<
typename src_msg_details_t::MsgTypes_t>(hdr.type()), buff, exchg_skt, client_cxn);
164 return last_state==dest_msg_details_t::Exit;
167 template<
class SrcMsgDetails,
class DestMsgDetails>
inline std::string
168 exchange_to_client_transformations<SrcMsgDetails, DestMsgDetails>::
to_string()
const noexcept(
false) {
169 std::ostringstream os;
170 os<<
"Source message details: ";
171 SrcMsgDetails::to_stream(os);
172 os<<
"\n\tDestination message details: ";
173 DestMsgDetails::to_stream(os);
177 template<
class SrcMsgDetails,
class DestMsgDetails>
inline std::ostream &
178 operator<<(
std::ostream &os, exchange_to_client_transformations<SrcMsgDetails, DestMsgDetails>
const &ec)
noexcept(
false) {
183 template<
class SrcMsgDetails>
186 using row_t=libjmmcg::
msm::
unroll::
row_types<
typename msg_details_t::MsgTypes_t,
typename msg_details_t::MsgTypes_t>;
192 : sim_resp(v.sim_resp) {}
199 template<
auto state,
auto next,
class SktT>
200 auto operator()(
typename msg_details_t::msg_buffer_t
const &buff, SktT &, SktT &client_skt)
const noexcept(
false) {
201 typename msg_details_t::LogonRequest
const &msg=
reinterpret_cast<
typename msg_details_t::LogonRequest
const &>(buff);
202 assert(msg.type()==
static_cast<
typename msg_details_t::MsgType_t>(state));
203 typename msg_details_t::LogonReply reply(sim_resp.sequenceNumber);
204 if (
std::strcmp(msg.userName.begin(), sim_resp.username.begin())==0) {
205 if (
std::strcmp(msg.password.begin(), sim_resp.password.begin())==0) {
206 reply.rejectCode(msg_details_t::LoginResponseStatus::LoginAccepted);
207 client_skt.write(reply);
209 reply.rejectCode(msg_details_t::LoginResponseStatus::NotAuthorized);
210 client_skt.write(reply);
213 reply.rejectCode(msg_details_t::LoginResponseStatus::NotAuthorized);
214 client_skt.write(reply);
220 simulator_responses &sim_resp;
227 : sim_resp(v.sim_resp) {}
234 template<
auto state,
auto next,
class SktT>
235 auto operator()(
typename msg_details_t::msg_buffer_t
const &, SktT &, SktT &client_skt)
const noexcept(
false) {
237 client_skt.write(reply);
242 simulator_responses &sim_resp;
249 : sim_resp(v.sim_resp) {}
256 template<
auto state,
auto,
class SktT>
258 operator()(
typename msg_details_t::msg_buffer_t
const &buff, SktT &, SktT &client_skt)
const noexcept(
false) {
259 typename msg_details_t::OrderCancelRequest
const &msg=
reinterpret_cast<
typename msg_details_t::OrderCancelRequest
const &>(buff);
260 assert(
static_cast<
typename msg_details_t::MsgTypes_t>(msg.type())==
static_cast<
typename msg_details_t::MsgTypes_t>(state));
261 assert(!std::string(msg.originalClientOrderID().data()).empty());
262 auto cancelled_order=sim_resp.order_book.find(msg.originalClientOrderID());
263 if (cancelled_order!=sim_resp.order_book.end()) {
264 const typename msg_details_t::OrderCancelled reply(
265 sim_resp.sequenceNumber,
266 msg.originalClientOrderID(),
267 msg_details_t::OrderRejectReason::UserRequested,
268 cancelled_order->second.limitPrice(),
269 cancelled_order->second.side(),
271 cancelled_order->second.orderQty()
273 sim_resp.order_book.erase(msg.originalClientOrderID());
274 client_skt.write(reply);
275 return msg_details_t::OrderCancelled::static_type;
277 const typename msg_details_t::OrderCancelReject reply(sim_resp.sequenceNumber, msg.originalClientOrderID(), msg_details_t::OrderRejectReason::ClOrdIDNotMatchKnownOrder);
278 client_skt.write(reply);
279 return msg_details_t::OrderCancelReject::static_type;
284 simulator_responses &sim_resp;
291 : sim_resp(v.sim_resp) {}
298 template<
auto state,
auto,
class SktT>
300 operator()(
typename msg_details_t::msg_buffer_t
const &buff, SktT &, SktT &client_skt)
const noexcept(
false) {
301 typename msg_details_t::OrderCancelReplaceRequest
const &msg=
reinterpret_cast<
typename msg_details_t::OrderCancelReplaceRequest
const &>(buff);
302 assert(
static_cast<
typename msg_details_t::MsgTypes_t>(msg.type())==
static_cast<
typename msg_details_t::MsgTypes_t>(state));
303 auto modified_order=sim_resp.order_book.find(msg.originalClientOrderID());
304 if (modified_order!=sim_resp.order_book.end()) {
305 modified_order->second.limitPrice(msg.limitPrice());
306 modified_order->second.orderQty(msg.orderQty());
307 modified_order->second.side(msg.side());
308 const typename msg_details_t::OrderModified reply(
309 sim_resp.sequenceNumber,
310 msg.originalClientOrderID(),
311 modified_order->second.limitPrice(),
312 modified_order->second.side(),
313 modified_order->second.orderQty()
315 client_skt.write(reply);
316 return msg_details_t::OrderModified::static_type;
319 client_skt.write(reply);
320 return msg_details_t::UserModifyRejected::static_type;
325 simulator_responses &sim_resp;
332 : sim_resp(v.sim_resp) {}
339 template<
auto state,
auto,
class SktT>
341 operator()(
typename msg_details_t::msg_buffer_t
const &buff, SktT &, SktT &client_skt)
const noexcept(
false) {
342 typename msg_details_t::NewOrder_t
const &msg=
reinterpret_cast<
typename msg_details_t::NewOrder_t
const &>(buff);
343 assert(
static_cast<
typename msg_details_t::MsgTypes_t>(msg.type())==
static_cast<
typename msg_details_t::MsgTypes_t>(state));
345 if (msg.instrumentID()==sim_resp.instrumentID) {
346 typename msg_details_t::ExecutionReport reply(
347 sim_resp.sequenceNumber,
349 sim_resp.scaled_price,
353 if (msg.orderQty()<=sim_resp.quantity_limit) {
354 if (msg.orderType()==msg_details_t::OrderType::Market
355 || (msg.side()==msg_details_t::Side::Buy && msg.limitPrice()<sim_resp.scaled_price)
356 || (msg.side()==msg_details_t::Side::Sell && msg.limitPrice()>sim_resp.scaled_price)) {
357 reply.executedQty(msg.orderQty());
359 reply.executedPrice(msg.limitPrice());
360 client_skt.write(reply);
362 sim_resp.order_book.emplace(msg.clientOrderID(), msg);
363 assert(!sim_resp.order_book.empty());
364 assert(sim_resp.order_book.find(msg.clientOrderID())!=sim_resp.order_book.end());
367 auto new_item=sim_resp.order_book.emplace(msg.clientOrderID(), msg);
368 new_item.first->second.orderQty(msg.orderQty()-sim_resp.quantity_limit);
369 reply.executedQty(sim_resp.quantity_limit);
370 reply.leavesQty(msg.orderQty()-sim_resp.quantity_limit);
371 assert(!sim_resp.order_book.empty());
372 assert(sim_resp.order_book.find(msg.clientOrderID())!=sim_resp.order_book.end());
373 client_skt.write(reply);
375 return msg_details_t::ExecutionReport::static_type;
377 const typename msg_details_t::OrderRejected reply(sim_resp.sequenceNumber, msg.clientOrderID(), msg_details_t::OrderRejectReason::SymbolNotSupported);
378 client_skt.write(reply);
379 return msg_details_t::OrderRejected::static_type;
384 simulator_responses &sim_resp;
391 : sim_resp(v.sim_resp) {}
397 template<
auto state,
auto next,
class SktT>
399 operator()(
typename msg_details_t::msg_buffer_t
const &, SktT &, SktT &client_skt)
const {
400 const typename msg_details_t::OrderRejected response(sim_resp.sequenceNumber,
typename msg_details_t::ClientOrderID_t(), msg_details_t::OrderRejected::unknown_msg);
401 client_skt.write(response);
406 simulator_responses &sim_resp;
408 using transition_table=
typename msm_base_t::
template rows<
409 typename row_t::
template row<
410 msg_details_t::LogonRequest::static_type,
412 msg_details_t::LogonReply::static_type
417 typename row_t::
template row<
418 msg_details_t::ClientHeartbeat::static_type,
419 typename msm_base_t::no_op,
420 msg_details_t::ServerHeartbeat::static_type
422 typename row_t::
template row<
423 msg_details_t::LogoutRequest::static_type,
427 typename row_t::
template row<
428 msg_details_t::OrderCancelRequest::static_type,
430 msg_details_t::OrderCancelled::static_type|msg_details_t::OrderCancelReject::static_type
432 typename row_t::
template row<
433 msg_details_t::OrderCancelReplaceRequest::static_type,
435 msg_details_t::OrderModified::static_type|msg_details_t::UserModifyRejected::static_type
437 typename row_t::
template row<
438 msg_details_t::NewOrder_t::static_type,
440 msg_details_t::ExecutionReport::static_type|msg_details_t::OrderRejected::static_type
443 typename row_t::
template row<
444 msg_details_t::MatchAll,
446 msg_details_t::OrderRejected::static_type
452 template<
class SktT,
class ClientCxn>
454 simulator_responses<SrcMsgDetails>::
process_msg(
typename msg_details_t::msg_buffer_t
const &buff, SktT &exchg_skt, ClientCxn &client_cxn) {
455 ++(
this->sequenceNumber);
456 typename msg_details_t::Header_t
const &hdr=
reinterpret_cast<
typename msg_details_t::Header_t
const &>(buff);
457 const auto last_state=msm.process(
static_cast<
typename msg_details_t::MsgTypes_t>(hdr.type()), buff, exchg_skt, client_cxn);
458 return last_state==msg_details_t::Exit;
461 template<
class SrcMsgDetails>
inline std::string
462 simulator_responses<SrcMsgDetails>::
to_string()
const noexcept(
false) {
463 std::ostringstream os;
465 <<base_t::to_string()
471 template<
class SrcMsgDetails>
inline std::ostream &
472 operator<<(
std::ostream &os, simulator_responses<SrcMsgDetails>
const &ec)
noexcept(
false) {