21 #define BOOST_TEST_MODULE isimud_tests
22 #include <boost/test/included/unit_test.hpp>
24 #include <boost/mpl/list.hpp>
26 #include "../exchanges/BATSBOE/US/v1/batsboe.hpp"
27 #include "../exchanges/BATSBOE/US/v1/batsboe_sim.hpp"
28 #include "../exchanges/BATSBOE/US/v2/batsboe.hpp"
29 #include "../exchanges/BATSBOE/US/v2/batsboe_sim.hpp"
31 using namespace libjmmcg;
32 using namespace libisimud;
49 template<
class exchg_t>
51 using connection_t=
typename exchg_t::first_type;
52 using simulator_t=
typename exchg_t::second_type;
53 using conn_pol_t=
typename connection_t::conn_pol_t;
72 template<
class exchg_t>
75 using simulator_t=
typename base_t::simulator_t;
78 no_latency_timestamps
ts{0
};
82 simulator_t::socket_t::socket_priority::high,
83 api_thread_traits::processor_mask_type(exchanges::common::thread_traits::exchange_simulator_thread.core),
84 exchanges::common::thread_traits::exchange_simulator_thread.priority,
91 template<
class exchg_t>
94 using connection_t=
typename base_t::connection_t;
95 using link_t=
typename exchg_t::first_type;
99 link_t::skt_mgr_t::socket_t::socket_priority::low,
104 template<
class exchg_t>
107 using connection_t=
typename base_t::connection_t;
108 using simulator_t=
typename base_t::simulator_t;
111 const typename connection_t::msg_details_t::LogonRequest msg(
114 typename connection_t::msg_details_t::UserName_t(
this->conn_pol.logon_args.username),
115 typename connection_t::msg_details_t::Password_t(
this->conn_pol.logon_args.password),
118 BOOST_REQUIRE_NO_THROW(
this->link.send(msg));
119 typename connection_t::msg_details_t::LogonReply reply;
120 BOOST_REQUIRE_NO_THROW(
this->link.receive(reply));
121 BOOST_CHECK_EQUAL(reply.start_of_message, exchanges::BATSBOE::common::msg_start_code);
122 BOOST_CHECK_LE(reply.length(),
sizeof(
typename connection_t::msg_details_t::LogonReply));
123 BOOST_CHECK_EQUAL(reply.type(), exchanges::BATSBOE::US::MsgType::LogonReply);
124 BOOST_CHECK_EQUAL(reply.rejectCode(), exchanges::BATSBOE::common::LoginResponseStatus::LoginAccepted);
127 const typename connection_t::msg_details_t::LogoutRequest msg(
sequenceNumber);
128 BOOST_REQUIRE_NO_THROW(
this->link.send(msg));
129 typename connection_t::msg_details_t::Logout reply;
130 BOOST_REQUIRE_NO_THROW(
this->link.receive(reply));
131 BOOST_CHECK_EQUAL(reply.start_of_message, exchanges::BATSBOE::common::msg_start_code);
132 BOOST_CHECK_LE(reply.length(),
sizeof(
typename connection_t::msg_details_t::Logout));
133 BOOST_CHECK_EQUAL(reply.type(), exchanges::BATSBOE::common::MsgType::Logout);
134 BOOST_CHECK_EQUAL(reply.logoutReason, exchanges::BATSBOE::common::LogoutReason::UserRequested);
138 BOOST_AUTO_TEST_SUITE(exchange_gateways)
140 BOOST_AUTO_TEST_SUITE(links)
148 BOOST_AUTO_TEST_CASE_TEMPLATE(primary_gateway_available, exchg_t, exchg_t_types) {
152 auto const &begin=
std::chrono::system_clock::now();
153 BOOST_REQUIRE_NO_THROW(
154 typename exchg_t::first_type link(
156 exchg_t::first_type::skt_mgr_t::socket_t::socket_priority::low,
157 exchanges::common::thread_traits::client_to_exchange_thread.core
160 auto const &end=
std::chrono::system_clock::now();
161 BOOST_CHECK_LT(std::chrono::duration_cast<std::chrono::seconds>(end-begin).count(), fixture_t::conn_pol_t::min_timeout.count());
170 BOOST_AUTO_TEST_CASE_TEMPLATE(re_connnect, exchg_t, exchg_t_types) {
174 BOOST_REQUIRE_NO_THROW(
175 typename exchg_t::first_type link(
177 exchg_t::first_type::skt_mgr_t::socket_t::socket_priority::low,
178 exchanges::common::thread_traits::client_to_exchange_thread.core
181 auto const &begin=
std::chrono::system_clock::now();
182 BOOST_REQUIRE_NO_THROW(
183 typename exchg_t::first_type link(
185 exchg_t::first_type::skt_mgr_t::socket_t::socket_priority::low,
186 exchanges::common::thread_traits::client_to_exchange_thread.core
189 auto const &end=
std::chrono::system_clock::now();
190 BOOST_CHECK_LT(std::chrono::duration_cast<std::chrono::seconds>(end-begin).count(), fixture_t::conn_pol_t::min_timeout.count());
193 BOOST_AUTO_TEST_SUITE_END()
195 BOOST_AUTO_TEST_SUITE(admin)
203 BOOST_AUTO_TEST_CASE_TEMPLATE(logon, exchg_t, exchg_t_types) {
205 using connection_t=
typename fixture_t::connection_t;
208 const typename connection_t::msg_details_t::LogonRequest msg(
211 typename connection_t::msg_details_t::UserName_t(f.conn_pol.logon_args.username),
212 typename connection_t::msg_details_t::Password_t(f.conn_pol.logon_args.password),
215 BOOST_REQUIRE_NO_THROW(f.link.send(msg));
216 typename connection_t::msg_details_t::LogonReply reply;
217 BOOST_REQUIRE_NO_THROW(f.link.receive(reply));
218 BOOST_CHECK_EQUAL(reply.start_of_message, exchanges::BATSBOE::common::msg_start_code);
219 BOOST_CHECK_LE(reply.length(),
sizeof(
typename connection_t::msg_details_t::LogonReply));
220 BOOST_CHECK_EQUAL(reply.type(), exchanges::BATSBOE::US::MsgType::LogonReply);
221 BOOST_CHECK_EQUAL(reply.rejectCode(), exchanges::BATSBOE::common::LoginResponseStatus::LoginAccepted);
230 BOOST_AUTO_TEST_CASE_TEMPLATE(client_heartbeat, exchg_t, exchg_t_types) {
232 using connection_t=
typename fixture_t::connection_t;
235 const typename connection_t::msg_details_t::Heartbeat msg(
sequenceNumber);
236 BOOST_CHECK_NO_THROW(f.link.send(msg));
244 BOOST_AUTO_TEST_CASE_TEMPLATE(server_heartbeat, exchg_t, exchg_t_types) {
246 using connection_t=
typename fixture_t::connection_t;
249 const auto t1=
std::chrono::high_resolution_clock::now();
250 typename exchg_t::first_type link(
252 exchg_t::first_type::skt_mgr_t::socket_t::socket_priority::low,
255 typename connection_t::msg_details_t::ServerHeartbeat msg(
sequenceNumber);
256 BOOST_REQUIRE_NO_THROW(link.receive(msg));
257 const auto t2=
std::chrono::high_resolution_clock::now();
258 BOOST_CHECK_EQUAL(msg.start_of_message, exchanges::BATSBOE::common::msg_start_code);
259 BOOST_CHECK_EQUAL(msg.type(), exchanges::BATSBOE::common::MsgType::ServerHeartbeat);
260 BOOST_CHECK_EQUAL(msg.matchingUnit, 0);
261 BOOST_CHECK_EQUAL(msg.sequenceNumber, connection_t::msg_details_t::ServerHeartbeat::seq_num);
262 BOOST_CHECK_GE(msg.length(), connection_t::msg_details_t::header_t_size);
263 BOOST_CHECK_LE(msg.length(),
sizeof(
typename connection_t::msg_details_t::ServerHeartbeat));
264 BOOST_CHECK_CLOSE(
static_cast<
float>(std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count()),
static_cast<
float>(std::chrono::duration_cast<std::chrono::milliseconds>(fixture_t::simulator_t::svr_mgr_t::heartbeats_t::heartbeat_interval).count()), 0.1);
273 BOOST_AUTO_TEST_CASE_TEMPLATE(logout, exchg_t, exchg_t_types) {
275 using connection_t=
typename fixture_t::connection_t;
278 const typename connection_t::msg_details_t::LogoutRequest msg(
sequenceNumber);
279 BOOST_REQUIRE_NO_THROW(f.link.send(msg));
280 typename connection_t::msg_details_t::Logout reply;
281 BOOST_REQUIRE_NO_THROW(f.link.receive(reply));
282 BOOST_CHECK_EQUAL(reply.start_of_message, exchanges::BATSBOE::common::msg_start_code);
283 BOOST_CHECK_LE(reply.length(),
sizeof(
typename connection_t::msg_details_t::Logout));
284 BOOST_CHECK_EQUAL(reply.type(), exchanges::BATSBOE::common::MsgType::Logout);
285 BOOST_CHECK_EQUAL(reply.logoutReason, exchanges::BATSBOE::common::LogoutReason::UserRequested);
294 BOOST_AUTO_TEST_CASE_TEMPLATE(logon_logout, exchg_t, exchg_t_types) {
296 using connection_t=
typename fixture_t::connection_t;
299 const typename connection_t::msg_details_t::LogonRequest logon_msg(
302 typename connection_t::msg_details_t::UserName_t(f.conn_pol.logon_args.username),
303 typename connection_t::msg_details_t::Password_t(f.conn_pol.logon_args.password),
306 BOOST_REQUIRE_NO_THROW(f.link.send(logon_msg));
307 typename connection_t::msg_details_t::LogonReply logon_reply;
308 BOOST_REQUIRE_NO_THROW(f.link.receive(logon_reply));
309 BOOST_CHECK_EQUAL(logon_reply.start_of_message, exchanges::BATSBOE::common::msg_start_code);
310 BOOST_CHECK_LE(logon_reply.length(),
sizeof(
typename connection_t::msg_details_t::LogonReply));
311 BOOST_CHECK_EQUAL(logon_reply.type(), exchanges::BATSBOE::US::MsgType::LogonReply);
312 BOOST_CHECK_EQUAL(logon_reply.rejectCode(), exchanges::BATSBOE::common::LoginResponseStatus::LoginAccepted);
313 const typename connection_t::msg_details_t::LogoutRequest logout_msg(
sequenceNumber);
314 BOOST_REQUIRE_NO_THROW(f.link.send(logout_msg));
315 typename connection_t::msg_details_t::Logout logout_reply;
316 BOOST_REQUIRE_NO_THROW(f.link.receive(logout_reply));
317 BOOST_CHECK_EQUAL(logout_reply.start_of_message, exchanges::BATSBOE::common::msg_start_code);
318 BOOST_CHECK_LE(logout_reply.length(),
sizeof(
typename connection_t::msg_details_t::Logout));
319 BOOST_CHECK_EQUAL(logout_reply.type(), exchanges::BATSBOE::common::MsgType::Logout);
320 BOOST_CHECK_EQUAL(logout_reply.logoutReason, exchanges::BATSBOE::common::LogoutReason::UserRequested);
387 BOOST_AUTO_TEST_SUITE_END()
389 BOOST_AUTO_TEST_SUITE(client_initiated)
397 BOOST_AUTO_TEST_CASE_TEMPLATE(reject, exchg_t, exchg_t_types) {
399 using connection_t=
typename fixture_t::connection_t;
402 const typename connection_t::msg_details_t::NewOrder_t msg(
405 exchg_t::first_type::msg_details_t::OrderType::Market,
406 exchanges::BATSBOE::common::TIF::Day,
407 exchg_t::first_type::msg_details_t::Side::Buy,
408 exchg_t::second_type::proc_rules_t::invalidInstrumentID,
409 exchg_t::second_type::proc_rules_t::quantity_limit-1,
410 exchg_t::second_type::proc_rules_t::scaled_price
412 BOOST_REQUIRE_NO_THROW(f.link.send(msg));
413 typename connection_t::msg_details_t::OrderRejected reply;
414 BOOST_REQUIRE_NO_THROW(f.link.receive(reply));
415 BOOST_CHECK_EQUAL(reply.start_of_message, exchanges::BATSBOE::common::msg_start_code);
416 BOOST_CHECK_LE(reply.length(),
sizeof(
typename connection_t::msg_details_t::OrderRejected));
417 BOOST_CHECK_EQUAL(reply.type(), exchanges::BATSBOE::common::MsgType::OrderRejected);
418 BOOST_CHECK_EQUAL(reply.clientOrderID(), msg.clientOrderID());
419 BOOST_CHECK_EQUAL(reply.orderRejectReason, exchanges::BATSBOE::common::OrderRejectReason::SymbolNotSupported);
428 BOOST_AUTO_TEST_CASE_TEMPLATE(cancel_reject, exchg_t, exchg_t_types) {
430 using connection_t=
typename fixture_t::connection_t;
433 const typename connection_t::msg_details_t::OrderCancelRequest msg(
437 BOOST_REQUIRE_NO_THROW(f.link.send(msg));
438 typename connection_t::msg_details_t::OrderCancelReject reply;
439 BOOST_REQUIRE_NO_THROW(f.link.receive(reply));
440 BOOST_CHECK_EQUAL(reply.start_of_message, exchanges::BATSBOE::common::msg_start_code);
441 BOOST_CHECK_LE(reply.length(),
sizeof(
typename connection_t::msg_details_t::OrderCancelReject));
442 BOOST_CHECK_EQUAL(reply.type(), exchanges::BATSBOE::common::MsgType::CancelRejected);
443 BOOST_CHECK_EQUAL(reply.clientOrderID(), msg.originalClientOrderID());
452 BOOST_AUTO_TEST_CASE_TEMPLATE(cancel_accept, exchg_t, exchg_t_types) {
454 using connection_t=
typename fixture_t::connection_t;
457 const typename connection_t::msg_details_t::NewOrder_t msg(
460 exchg_t::first_type::msg_details_t::OrderType::Limit,
461 exchanges::BATSBOE::common::TIF::Day,
462 exchg_t::first_type::msg_details_t::Side::Buy,
463 exchg_t::second_type::proc_rules_t::instrumentID,
464 exchg_t::second_type::proc_rules_t::quantity_limit-1,
465 exchg_t::second_type::proc_rules_t::scaled_price+1
467 BOOST_REQUIRE_NO_THROW(f.link.send(msg));
468 const typename connection_t::msg_details_t::OrderCancelRequest msg1(
472 BOOST_REQUIRE_NO_THROW(f.link.send(msg1));
473 typename connection_t::msg_details_t::OrderCancelled reply;
474 BOOST_REQUIRE_NO_THROW(f.link.receive(reply));
475 BOOST_CHECK_EQUAL(reply.start_of_message, exchanges::BATSBOE::common::msg_start_code);
476 BOOST_CHECK_LE(reply.length(),
sizeof(
typename connection_t::msg_details_t::OrderCancelled));
477 BOOST_CHECK_EQUAL(reply.type(), exchanges::BATSBOE::common::MsgType::OrderCancelled);
478 BOOST_CHECK_EQUAL(reply.clientOrderID(), msg.clientOrderID());
479 BOOST_CHECK_EQUAL(reply.cancelReason, exchanges::BATSBOE::common::OrderRejectReason::UserRequested);
488 BOOST_AUTO_TEST_CASE_TEMPLATE(modify_reject, exchg_t, exchg_t_types) {
490 using connection_t=
typename fixture_t::connection_t;
493 const typename connection_t::msg_details_t::OrderCancelReplaceRequest msg(
496 exchg_t::second_type::proc_rules_t::quantity_limit,
497 exchg_t::second_type::proc_rules_t::scaled_price,
498 exchg_t::first_type::msg_details_t::Side::Sell
500 BOOST_REQUIRE_NO_THROW(f.link.send(msg));
501 typename connection_t::msg_details_t::UserModifyRejected reply;
502 BOOST_REQUIRE_NO_THROW(f.link.receive(reply));
503 BOOST_CHECK_EQUAL(reply.start_of_message, exchanges::BATSBOE::common::msg_start_code);
504 BOOST_CHECK_LE(reply.length(),
sizeof(
typename connection_t::msg_details_t::UserModifyRejected));
505 BOOST_CHECK_EQUAL(reply.type(), exchanges::BATSBOE::common::MsgType::UserModifyRejected);
506 BOOST_CHECK_EQUAL(reply.clientOrderID(), msg.originalClientOrderID());
507 BOOST_CHECK_EQUAL(reply.modifyRejectReason, exchanges::BATSBOE::common::OrderRejectReason::ClOrdIDNotMatchKnownOrder);
516 BOOST_AUTO_TEST_CASE_TEMPLATE(modify_accept, exchg_t, exchg_t_types) {
518 using connection_t=
typename fixture_t::connection_t;
521 const typename connection_t::msg_details_t::NewOrder_t msg(
524 exchg_t::first_type::msg_details_t::OrderType::Limit,
525 exchanges::BATSBOE::common::TIF::Day,
526 exchg_t::first_type::msg_details_t::Side::Buy,
527 exchg_t::second_type::proc_rules_t::instrumentID,
528 exchg_t::second_type::proc_rules_t::quantity_limit-1,
529 exchg_t::second_type::proc_rules_t::scaled_price+1
531 BOOST_REQUIRE_NO_THROW(f.link.send(msg));
532 const typename connection_t::msg_details_t::OrderCancelReplaceRequest msg1(
535 exchg_t::second_type::proc_rules_t::quantity_limit,
537 exchg_t::first_type::msg_details_t::Side::Sell
539 BOOST_REQUIRE_NO_THROW(f.link.send(msg1));
540 typename connection_t::msg_details_t::OrderModified reply;
541 BOOST_REQUIRE_NO_THROW(f.link.receive(reply));
542 BOOST_CHECK_EQUAL(reply.start_of_message, exchanges::BATSBOE::common::msg_start_code);
543 BOOST_CHECK_LE(reply.length(),
sizeof(
typename connection_t::msg_details_t::OrderModified));
544 BOOST_CHECK_EQUAL(reply.type(), exchanges::BATSBOE::common::MsgType::OrderModified);
545 BOOST_CHECK_EQUAL(reply.clientOrderID(), msg.clientOrderID());
546 BOOST_CHECK_EQUAL(reply.limitPrice(), msg1.limitPrice());
547 BOOST_CHECK_EQUAL(reply.side(), exchg_t::first_type::msg_details_t::Side::Sell);
548 BOOST_CHECK_EQUAL(reply.orderQty(), msg1.orderQty());
551 BOOST_AUTO_TEST_SUITE(new_order)
553 BOOST_AUTO_TEST_SUITE(buy)
555 BOOST_AUTO_TEST_SUITE(day)
557 BOOST_AUTO_TEST_SUITE(market)
565 BOOST_AUTO_TEST_CASE_TEMPLATE(new_order, exchg_t, exchg_t_types) {
567 using connection_t=
typename fixture_t::connection_t;
570 const typename connection_t::msg_details_t::NewOrder_t msg(
573 exchg_t::first_type::msg_details_t::OrderType::Market,
574 exchanges::BATSBOE::common::TIF::Day,
575 exchg_t::first_type::msg_details_t::Side::Buy,
576 exchg_t::second_type::proc_rules_t::instrumentID,
577 exchg_t::second_type::proc_rules_t::quantity_limit-1,
578 exchg_t::second_type::proc_rules_t::scaled_price
580 BOOST_REQUIRE_NO_THROW(f.link.send(msg));
581 typename connection_t::msg_details_t::ExecutionReport reply;
582 BOOST_REQUIRE_NO_THROW(f.link.receive(reply));
583 BOOST_CHECK_EQUAL(reply.start_of_message, exchanges::BATSBOE::common::msg_start_code);
584 BOOST_CHECK_LE(reply.length(),
sizeof(
typename connection_t::msg_details_t::ExecutionReport));
585 BOOST_CHECK_EQUAL(reply.type(), exchanges::BATSBOE::common::MsgType::OrderExecution);
586 BOOST_CHECK_EQUAL(reply.clientOrderID(), msg.clientOrderID());
587 BOOST_CHECK_EQUAL(reply.instrumentID(), exchg_t::second_type::proc_rules_t::instrumentID);
588 BOOST_CHECK_EQUAL(reply.side(), exchg_t::first_type::msg_details_t::Side::Buy);
589 BOOST_CHECK_EQUAL(reply.executedQty(), msg.orderQty());
590 BOOST_CHECK_EQUAL(reply.leavesQty(), 0);
591 BOOST_CHECK_EQUAL(reply.executedPrice(), msg.limitPrice());
600 BOOST_AUTO_TEST_CASE_TEMPLATE(partial_fill, exchg_t, exchg_t_types) {
602 using connection_t=
typename fixture_t::connection_t;
605 const typename connection_t::msg_details_t::NewOrder_t msg(
608 exchg_t::first_type::msg_details_t::OrderType::Market,
609 exchanges::BATSBOE::common::TIF::Day,
610 exchg_t::first_type::msg_details_t::Side::Buy,
611 exchg_t::second_type::proc_rules_t::instrumentID,
612 exchg_t::second_type::proc_rules_t::quantity_limit+1,
613 exchg_t::second_type::proc_rules_t::scaled_price
615 BOOST_REQUIRE_NO_THROW(f.link.send(msg));
616 typename connection_t::msg_details_t::ExecutionReport reply;
617 BOOST_REQUIRE_NO_THROW(f.link.receive(reply));
618 BOOST_CHECK_EQUAL(reply.start_of_message, exchanges::BATSBOE::common::msg_start_code);
619 BOOST_CHECK_LE(reply.length(),
sizeof(
typename connection_t::msg_details_t::ExecutionReport));
620 BOOST_CHECK_EQUAL(reply.type(), exchanges::BATSBOE::common::MsgType::OrderExecution);
621 BOOST_CHECK_EQUAL(reply.clientOrderID(), msg.clientOrderID());
622 BOOST_CHECK_EQUAL(reply.instrumentID(), exchg_t::second_type::proc_rules_t::instrumentID);
623 BOOST_CHECK_EQUAL(reply.side(), exchg_t::first_type::msg_details_t::Side::Buy);
624 BOOST_CHECK_EQUAL(reply.executedQty(), exchg_t::second_type::proc_rules_t::quantity_limit);
625 BOOST_CHECK_EQUAL(reply.leavesQty(), msg.orderQty()-exchg_t::second_type::proc_rules_t::quantity_limit);
626 BOOST_CHECK_EQUAL(reply.executedPrice(), msg.limitPrice());
635 BOOST_AUTO_TEST_CASE_TEMPLATE(partial_fill_cancel, exchg_t, exchg_t_types) {
637 using connection_t=
typename fixture_t::connection_t;
640 const typename connection_t::msg_details_t::NewOrder_t new_order(
643 exchg_t::first_type::msg_details_t::OrderType::Market,
644 exchanges::BATSBOE::common::TIF::Day,
645 exchg_t::first_type::msg_details_t::Side::Buy,
646 exchg_t::second_type::proc_rules_t::instrumentID,
647 exchg_t::second_type::proc_rules_t::quantity_limit+1,
648 exchg_t::second_type::proc_rules_t::scaled_price
650 BOOST_REQUIRE_NO_THROW(f.link.send(new_order));
651 typename connection_t::msg_details_t::ExecutionReport partial_fill;
652 BOOST_REQUIRE_NO_THROW(f.link.receive(partial_fill));
653 const typename connection_t::msg_details_t::OrderCancelRequest cancel(
657 BOOST_REQUIRE_NO_THROW(f.link.send(cancel));
658 typename connection_t::msg_details_t::OrderCancelled reply;
659 BOOST_REQUIRE_NO_THROW(f.link.receive(reply));
660 BOOST_CHECK_EQUAL(reply.start_of_message, exchanges::BATSBOE::common::msg_start_code);
661 BOOST_CHECK_LE(reply.length(),
sizeof(
typename connection_t::msg_details_t::OrderCancelled));
662 BOOST_CHECK_EQUAL(reply.type(), exchanges::BATSBOE::common::MsgType::OrderCancelled);
663 BOOST_CHECK_EQUAL(reply.clientOrderID(), new_order.clientOrderID());
664 BOOST_CHECK_EQUAL(reply.side(), exchg_t::first_type::msg_details_t::Side::Buy);
665 BOOST_CHECK_EQUAL(reply.orderQty(), new_order.orderQty()-exchg_t::second_type::proc_rules_t::quantity_limit);
666 BOOST_CHECK_EQUAL(reply.leavesQty(), new_order.orderQty()-exchg_t::second_type::proc_rules_t::quantity_limit);
667 BOOST_CHECK_EQUAL(reply.lastShares(), 0);
668 BOOST_CHECK_EQUAL(reply.lastPrice(), new_order.limitPrice());
677 BOOST_AUTO_TEST_CASE_TEMPLATE(partial_fill_replace, exchg_t, exchg_t_types) {
679 using connection_t=
typename fixture_t::connection_t;
682 const typename connection_t::msg_details_t::NewOrder_t new_order(
685 exchg_t::first_type::msg_details_t::OrderType::Market,
686 exchanges::BATSBOE::common::TIF::Day,
687 exchg_t::first_type::msg_details_t::Side::Buy,
688 exchg_t::second_type::proc_rules_t::instrumentID,
689 exchg_t::second_type::proc_rules_t::quantity_limit+1,
690 exchg_t::second_type::proc_rules_t::scaled_price
692 BOOST_REQUIRE_NO_THROW(f.link.send(new_order));
693 typename connection_t::msg_details_t::ExecutionReport partial_fill;
694 BOOST_REQUIRE_NO_THROW(f.link.receive(partial_fill));
695 const typename connection_t::msg_details_t::OrderCancelReplaceRequest replace(
698 partial_fill.leavesQty()+1,
699 exchg_t::second_type::proc_rules_t::scaled_price*2,
700 exchg_t::first_type::msg_details_t::Side::Sell
702 BOOST_REQUIRE_NO_THROW(f.link.send(replace));
703 typename connection_t::msg_details_t::OrderModified reply;
704 BOOST_REQUIRE_NO_THROW(f.link.receive(reply));
705 BOOST_CHECK_EQUAL(reply.start_of_message, exchanges::BATSBOE::common::msg_start_code);
706 BOOST_CHECK_LE(reply.length(),
sizeof(
typename connection_t::msg_details_t::ExecutionReport));
707 BOOST_CHECK_EQUAL(reply.type(), exchanges::BATSBOE::common::MsgType::OrderModified);
708 BOOST_CHECK_EQUAL(reply.clientOrderID(), new_order.clientOrderID());
709 BOOST_CHECK_EQUAL(reply.limitPrice(), new_order.limitPrice()*2);
710 BOOST_CHECK_EQUAL(reply.orderQty(), partial_fill.leavesQty()+1);
711 BOOST_CHECK_EQUAL(reply.side(), exchg_t::first_type::msg_details_t::Side::Sell);
714 BOOST_AUTO_TEST_SUITE_END()
716 BOOST_AUTO_TEST_SUITE(limit)
724 BOOST_AUTO_TEST_CASE_TEMPLATE(new_order, exchg_t, exchg_t_types) {
726 using connection_t=
typename fixture_t::connection_t;
729 const typename connection_t::msg_details_t::NewOrder_t new_order(
732 exchg_t::first_type::msg_details_t::OrderType::Limit,
733 exchanges::BATSBOE::common::TIF::Day,
734 exchg_t::first_type::msg_details_t::Side::Buy,
735 exchg_t::second_type::proc_rules_t::instrumentID,
736 exchg_t::second_type::proc_rules_t::quantity_limit-1,
737 exchg_t::second_type::proc_rules_t::scaled_price-1
739 BOOST_REQUIRE_NO_THROW(f.link.send(new_order));
740 typename connection_t::msg_details_t::ExecutionReport reply;
741 BOOST_REQUIRE_NO_THROW(f.link.receive(reply));
742 BOOST_CHECK_EQUAL(reply.start_of_message, exchanges::BATSBOE::common::msg_start_code);
743 BOOST_CHECK_LE(reply.length(),
sizeof(
typename connection_t::msg_details_t::ExecutionReport));
744 BOOST_CHECK_EQUAL(reply.type(), exchanges::BATSBOE::common::MsgType::OrderExecution);
745 BOOST_CHECK_EQUAL(reply.clientOrderID(), new_order.clientOrderID());
746 BOOST_CHECK_EQUAL(reply.instrumentID(), exchg_t::second_type::proc_rules_t::instrumentID);
747 BOOST_CHECK_EQUAL(reply.side(), exchg_t::first_type::msg_details_t::Side::Buy);
748 BOOST_CHECK_EQUAL(reply.executedQty(), new_order.orderQty());
749 BOOST_CHECK_EQUAL(reply.leavesQty(), 0);
750 BOOST_CHECK_EQUAL(reply.executedPrice(), new_order.limitPrice());
759 BOOST_AUTO_TEST_CASE_TEMPLATE(open_cancelled, exchg_t, exchg_t_types) {
761 using connection_t=
typename fixture_t::connection_t;
764 const typename connection_t::msg_details_t::NewOrder_t new_order(
767 exchg_t::first_type::msg_details_t::OrderType::Limit,
768 exchanges::BATSBOE::common::TIF::Day,
769 exchg_t::first_type::msg_details_t::Side::Buy,
770 exchg_t::second_type::proc_rules_t::instrumentID,
771 exchg_t::second_type::proc_rules_t::quantity_limit-1,
772 exchg_t::second_type::proc_rules_t::scaled_price+1
774 BOOST_REQUIRE_NO_THROW(f.link.send(new_order));
775 const typename connection_t::msg_details_t::OrderCancelRequest cancel(
779 BOOST_REQUIRE_NO_THROW(f.link.send(cancel));
780 typename connection_t::msg_details_t::OrderCancelled reply;
781 BOOST_REQUIRE_NO_THROW(f.link.receive(reply));
782 BOOST_CHECK_EQUAL(reply.start_of_message, exchanges::BATSBOE::common::msg_start_code);
783 BOOST_CHECK_LE(reply.length(),
sizeof(
typename connection_t::msg_details_t::OrderCancelled));
784 BOOST_CHECK_EQUAL(reply.type(), exchanges::BATSBOE::common::MsgType::OrderCancelled);
785 BOOST_CHECK_EQUAL(reply.clientOrderID(), new_order.clientOrderID());
786 BOOST_CHECK_EQUAL(reply.side(), exchg_t::first_type::msg_details_t::Side::Buy);
787 BOOST_CHECK_EQUAL(reply.orderQty(), new_order.orderQty());
788 BOOST_CHECK_EQUAL(reply.leavesQty(), new_order.orderQty());
789 BOOST_CHECK_EQUAL(reply.lastShares(), 0);
790 BOOST_CHECK_EQUAL(reply.lastPrice(), new_order.limitPrice());
799 BOOST_AUTO_TEST_CASE_TEMPLATE(open_replace, exchg_t, exchg_t_types) {
801 using connection_t=
typename fixture_t::connection_t;
804 const typename connection_t::msg_details_t::NewOrder_t new_order(
807 exchg_t::first_type::msg_details_t::OrderType::Limit,
808 exchanges::BATSBOE::common::TIF::Day,
809 exchg_t::first_type::msg_details_t::Side::Buy,
810 exchg_t::second_type::proc_rules_t::instrumentID,
811 exchg_t::second_type::proc_rules_t::quantity_limit-1,
812 exchg_t::second_type::proc_rules_t::scaled_price+1
814 BOOST_REQUIRE_NO_THROW(f.link.send(new_order));
815 const typename connection_t::msg_details_t::OrderCancelReplaceRequest replace(
818 new_order.orderQty()+1,
819 exchg_t::second_type::proc_rules_t::scaled_price*2,
820 exchg_t::first_type::msg_details_t::Side::Sell
822 BOOST_REQUIRE_NO_THROW(f.link.send(replace));
823 typename connection_t::msg_details_t::OrderModified reply;
824 BOOST_REQUIRE_NO_THROW(f.link.receive(reply));
825 BOOST_CHECK_EQUAL(reply.start_of_message, exchanges::BATSBOE::common::msg_start_code);
826 BOOST_CHECK_LE(reply.length(),
sizeof(
typename connection_t::msg_details_t::ExecutionReport));
827 BOOST_CHECK_EQUAL(reply.type(), exchanges::BATSBOE::common::MsgType::OrderModified);
828 BOOST_CHECK_EQUAL(reply.clientOrderID(), new_order.clientOrderID());
829 BOOST_CHECK_EQUAL(reply.limitPrice(), replace.limitPrice());
830 BOOST_CHECK_EQUAL(reply.orderQty(), new_order.orderQty()+1);
831 BOOST_CHECK_EQUAL(reply.side(), exchg_t::first_type::msg_details_t::Side::Sell);
834 BOOST_AUTO_TEST_SUITE_END()
836 BOOST_AUTO_TEST_SUITE_END()
838 BOOST_AUTO_TEST_SUITE_END()
840 BOOST_AUTO_TEST_SUITE_END()
842 BOOST_AUTO_TEST_SUITE_END()
844 BOOST_AUTO_TEST_SUITE_END()