libjmmcg  release_579_6_g8cffd
A C++ library containing an eclectic mix of useful, advanced components.
batsboe_eu_simulators.cpp
Go to the documentation of this file.
1 /******************************************************************************
2 ** Copyright © 2015 by J.M.McGuiness, isimud@hussar.me.uk
3 **
4 ** This library is free software; you can redistribute it and/or
5 ** modify it under the terms of the GNU Lesser General Public
6 ** License as published by the Free Software Foundation; either
7 ** version 2.1 of the License, or (at your option) any later version.
8 **
9 ** This library is distributed in the hope that it will be useful,
10 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 ** Lesser General Public License for more details.
13 **
14 ** You should have received a copy of the GNU Lesser General Public
15 ** License along with this library; if not, write to the Free Software
16 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18 
19 #include "stdafx.h"
20 
21 #define BOOST_TEST_MODULE isimud_tests
22 #include <boost/test/included/unit_test.hpp>
23 
24 #include <boost/mpl/list.hpp>
25 
26 #include "../exchanges/BATSBOE/EU/v1/batsboe.hpp"
27 #include "../exchanges/BATSBOE/EU/v1/batsboe_sim.hpp"
28 #include "../exchanges/BATSBOE/EU/v2/batsboe.hpp"
29 #include "../exchanges/BATSBOE/EU/v2/batsboe_sim.hpp"
30 
31 using namespace libjmmcg;
32 using namespace libisimud;
33 
34 using api_thread_traits=ppd::thread_params<ppd::platform_api>;
35 
36 const boost::asio::ip::address primary_gw(boost::asio::ip::address_v4::loopback());
37 const unsigned short unused_primary_port=12347u;
38 const exchanges::BATSBOE::common::ClientOrderID_t clientOrderId1{"12345678901234test1"};
39 const exchanges::BATSBOE::common::SecurityID_t instID{"abcdefghijklmno"};
40 const exchanges::BATSBOE::common::Price_t price(1);
41 const exchanges::BATSBOE::common::SessionSubID_t sessionSubID{"ABC"};
42 const exchanges::BATSBOE::common::SeqNum_t sequenceNumber(1);
43 
44 typedef boost::mpl::list<
46 // TODO std::pair<exchanges::BATSBOE::EU::v2::connection_t, exchanges::BATSBOE::EU::v2::simulator_t>
48 
49 template<class exchg_t>
50 struct conn_args {
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;
54 
55  conn_pol_t conn_pol{
56  typename conn_pol_t::gateways_t(
58  ),
60  0,
61  {"000"},
64  false
65  },
67  0
68  }
69  };
70 };
71 
72 template<class exchg_t>
73 struct conn_args_n_sim : public conn_args<exchg_t> {
74  using base_t=conn_args<exchg_t>;
75  using simulator_t=typename base_t::simulator_t;
76 
77  typename simulator_t::proc_rules_t proc_rules;
78  no_latency_timestamps ts{0};
79  simulator_t svr{
80  boost::asio::ip::address(),
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,
85  proc_rules,
86  ts,
87  "sim" LIBJMMCG_ENQUOTE(__LINE__)
88  };
89 };
90 
91 template<class exchg_t>
92 struct conn_args_sim_n_link : public conn_args_n_sim<exchg_t> {
93  using base_t=conn_args_n_sim<exchg_t>;
94  using connection_t=typename base_t::connection_t;
95  using link_t=typename exchg_t::first_type;
96 
97  link_t link{
98  this->conn_pol,
99  link_t::skt_mgr_t::socket_t::socket_priority::low,
100  exchanges::common::thread_traits::client_to_exchange_thread.core
101  };
102 };
103 
104 template<class exchg_t>
106  using base_t=conn_args_n_sim<exchg_t>;
107  using connection_t=typename base_t::connection_t;
108  using simulator_t=typename base_t::simulator_t;
109 
111  const typename connection_t::msg_details_t::LogonRequest msg(
112  sequenceNumber,
113  sessionSubID,
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),
116  false
117  );
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::EU::MsgType::LogonReply);
124  BOOST_CHECK_EQUAL(reply.rejectCode(), exchanges::BATSBOE::common::LoginResponseStatus::LoginAccepted);
125  }
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);
135  }
136 };
137 
138 BOOST_AUTO_TEST_SUITE(exchange_gateways)
139 
140 BOOST_AUTO_TEST_SUITE(links)
141 
142 /**
143  \test Section 4.4: "Connectivity Policy" of [1] Test: primary gateway available.
144  ==========================================================================
145  Verify that less than 5 seconds passes if just the primary gateway is available.
146  [1] "BATS Chi-X Europe Binary Order Entry Specification", Version 1.44, 27 November, 2014
147 */
148 BOOST_AUTO_TEST_CASE_TEMPLATE(primary_gateway_available, exchg_t, exchg_t_types) {
149  using fixture_t=conn_args_n_sim<exchg_t>;
150  fixture_t f;
151 
152  auto const &begin=std::chrono::system_clock::now();
153  BOOST_REQUIRE_NO_THROW(
154  typename exchg_t::first_type link(
155  f.conn_pol,
156  exchg_t::first_type::skt_mgr_t::socket_t::socket_priority::low,
157  exchanges::common::thread_traits::client_to_exchange_thread.core
158  )
159  );
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());
162 }
163 
164 /**
165  \test Re-connect to the available primary gateway.
166  ============================================
167  Verify that less than 5 seconds passes if just the primary gateway is available for the re-connections.
168  [1] "BATS Chi-X Europe Binary Order Entry Specification", Version 1.44, 27 November, 2014
169 */
170 BOOST_AUTO_TEST_CASE_TEMPLATE(re_connnect, exchg_t, exchg_t_types) {
171  using fixture_t=conn_args_n_sim<exchg_t>;
172  fixture_t f;
173 
174  BOOST_REQUIRE_NO_THROW(
175  typename exchg_t::first_type link(
176  f.conn_pol,
177  exchg_t::first_type::skt_mgr_t::socket_t::socket_priority::low,
178  exchanges::common::thread_traits::client_to_exchange_thread.core
179  )
180  );
181  auto const &begin=std::chrono::system_clock::now();
182  BOOST_REQUIRE_NO_THROW(
183  typename exchg_t::first_type link(
184  f.conn_pol,
185  exchg_t::first_type::skt_mgr_t::socket_t::socket_priority::low,
186  exchanges::common::thread_traits::client_to_exchange_thread.core
187  )
188  );
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());
191 }
192 
193 BOOST_AUTO_TEST_SUITE_END()
194 
195 BOOST_AUTO_TEST_SUITE(admin)
196 
197 /**
198  \test "Establishing a connection" Test: LogonRequest response.
199  ========================================================
200  Verify that the response to a LogonRequest is a LogonReply.
201  [1] "BATS Chi-X Europe Binary Order Entry Specification", Version 1.44, 27 November, 2014
202 */
203 BOOST_AUTO_TEST_CASE_TEMPLATE(logon, exchg_t, exchg_t_types) {
204  using fixture_t=conn_args_sim_n_link<exchg_t>;
205  using connection_t=typename fixture_t::connection_t;
206  fixture_t f;
207 
208  const typename connection_t::msg_details_t::LogonRequest msg(
209  sequenceNumber,
210  sessionSubID,
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),
213  false
214  );
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::EU::MsgType::LogonReply);
221  BOOST_CHECK_EQUAL(reply.rejectCode(), exchanges::BATSBOE::common::LoginResponseStatus::LoginAccepted);
222 }
223 
224 /**
225  \test "Heartbeats" Test: Client Heartbeat.
226  ====================================
227  Verify that the response to a Heartbeat is nothing.
228  [1] "BATS Chi-X Europe Binary Order Entry Specification", Version 1.44, 27 November, 2014
229 */
230 BOOST_AUTO_TEST_CASE_TEMPLATE(client_heartbeat, exchg_t, exchg_t_types) {
231  using fixture_t=conn_args_sim_n_link<exchg_t>;
232  using connection_t=typename fixture_t::connection_t;
233  fixture_t f;
234 
235  const typename connection_t::msg_details_t::Heartbeat msg(sequenceNumber);
236  BOOST_CHECK_NO_THROW(f.link.send(msg));
237 }
238 
239 /**
240  \test "Heartbeats" Test: Server Heartbeat.
241  ====================================.
242  [1] "BATS Chi-X Europe Binary Order Entry Specification", Version 1.44, 27 November, 2014
243 */
244 BOOST_AUTO_TEST_CASE_TEMPLATE(server_heartbeat, exchg_t, exchg_t_types) {
245  using fixture_t=conn_args_n_sim<exchg_t>;
246  using connection_t=typename fixture_t::connection_t;
247  fixture_t f;
248 
249  const auto t1=std::chrono::high_resolution_clock::now();
250  typename exchg_t::first_type link(
251  f.conn_pol,
252  exchg_t::first_type::skt_mgr_t::socket_t::socket_priority::low,
253  exchanges::common::thread_traits::exchange_simulator_thread.core
254  );
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);
265 }
266 
267 /**
268  \test "Terminating a connection" Test: LogoutRequest.
269  ===============================================
270  Verify that the response to a LogoutRequest is a Logout.
271  [1] "BATS Chi-X Europe Binary Order Entry Specification", Version 1.44, 27 November, 2014
272 */
273 BOOST_AUTO_TEST_CASE_TEMPLATE(logout, exchg_t, exchg_t_types) {
274  using fixture_t=conn_args_sim_n_link<exchg_t>;
275  using connection_t=typename fixture_t::connection_t;
276  fixture_t f;
277 
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);
286 }
287 
288 /**
289  \test "Establishing a connection" Test: LogonRequest & LogoutRequest response.
290  ============================================================================================
291  Verify the behaviour of a LogonRequest followed by a and LogoutRequest.
292  [1] "BATS Chi-X Europe Binary Order Entry Specification", Version 1.44, 27 November, 2014
293 */
294 BOOST_AUTO_TEST_CASE_TEMPLATE(logon_logout, exchg_t, exchg_t_types) {
295  using fixture_t=conn_args_sim_n_link<exchg_t>;
296  using connection_t=typename fixture_t::connection_t;
297  fixture_t f;
298 
299  const typename connection_t::msg_details_t::LogonRequest logon_msg(
300  sequenceNumber,
301  sessionSubID,
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),
304  false
305  );
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::EU::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);
321 }
322 
323 /**
324  \test "Establishing a connection" of [1] Test: Re-LogonRequest & LogoutRequest response.
325  ==================================================================================
326  Verify the behaviour of a LogonRequest followed by a and LogoutRequest, repeated.
327  [1] "BATS Chi-X Europe Binary Order Entry Specification", Version 1.44, 27 November, 2014
328 */
329 /* TODO - doesn't pass as not fixed....
330 BOOST_AUTO_TEST_CASE_TEMPLATE(re_logon_logout, exchg_t, exchg_t_types) {
331  using fixture_t=conn_args_n_sim<exchg_t>;
332  using connection_t=typename fixture_t::connection_t;
333  fixture_t f;
334 
335  {
336  typename exchg_t::first_type link(f.conn_pol, exchg_t::first_type::skt_mgr_t::socket_t::socket_priority::low);
337  const typename connection_t::msg_details_t::LogonRequest logon_msg(
338  sequenceNumber,
339  sessionSubID,
340  typename connection_t::msg_details_t::UserName_t(f.conn_pol.logon_args.username),
341  typename connection_t::msg_details_t::Password_t(f.conn_pol.logon_args.password),
342  false
343  );
344  BOOST_REQUIRE_NO_THROW(link.send(logon_msg));
345  typename connection_t::msg_details_t::LogonReply logon_reply;
346  BOOST_REQUIRE_NO_THROW(link.receive(logon_reply));
347  BOOST_CHECK_EQUAL(logon_reply.start_of_message, exchanges::BATSBOE::common::msg_start_code);
348  BOOST_CHECK_LE(logon_reply.length(), sizeof(typename connection_t::msg_details_t::LogonReply));
349  BOOST_CHECK_EQUAL(logon_reply.type(), exchanges::BATSBOE::EU::MsgType::LogonReply);
350  BOOST_CHECK_EQUAL(logon_reply.rejectCode(), exchanges::BATSBOE::common::LoginResponseStatus::LoginAccepted);
351  const typename connection_t::msg_details_t::LogoutRequest logout_msg(sequenceNumber);
352  BOOST_REQUIRE_NO_THROW(link.send(logout_msg));
353  typename connection_t::msg_details_t::Logout logout_reply;
354  BOOST_REQUIRE_NO_THROW(link.receive(logout_reply));
355  BOOST_CHECK_EQUAL(logout_reply.start_of_message, exchanges::BATSBOE::common::msg_start_code);
356  BOOST_CHECK_LE(logout_reply.length(), sizeof(typename connection_t::msg_details_t::Logout));
357  BOOST_CHECK_EQUAL(logout_reply.type(), exchanges::BATSBOE::common::MsgType::Logout);
358  BOOST_CHECK_EQUAL(logout_reply.logoutReason, exchanges::BATSBOE::common::LogoutReason::UserRequested);
359  }
360  {
361  typename exchg_t::first_type link(f.conn_pol, exchg_t::first_type::skt_mgr_t::socket_t::socket_priority::low);
362  const typename connection_t::msg_details_t::LogonRequest logon_msg(
363  sequenceNumber,
364  sessionSubID,
365  typename connection_t::msg_details_t::UserName_t(f.conn_pol.logon_args.username),
366  typename connection_t::msg_details_t::Password_t(f.conn_pol.logon_args.password),
367  false
368  );
369  BOOST_REQUIRE_NO_THROW(link.send(logon_msg));
370  typename connection_t::msg_details_t::LogonReply logon_reply;
371  BOOST_REQUIRE_NO_THROW(link.receive(logon_reply));
372  BOOST_CHECK_EQUAL(logon_reply.start_of_message, exchanges::BATSBOE::common::msg_start_code);
373  BOOST_CHECK_LE(logon_reply.length(), sizeof(typename connection_t::msg_details_t::LogonReply));
374  BOOST_CHECK_EQUAL(logon_reply.type(), exchanges::BATSBOE::EU::MsgType::LogonReply);
375  BOOST_CHECK_EQUAL(logon_reply.rejectCode(), exchanges::BATSBOE::common::LoginResponseStatus::LoginAccepted);
376  const typename connection_t::msg_details_t::LogoutRequest logout_msg(sequenceNumber);
377  BOOST_REQUIRE_NO_THROW(link.send(logout_msg));
378  typename connection_t::msg_details_t::Logout logout_reply;
379  BOOST_REQUIRE_NO_THROW(link.receive(logout_reply));
380  BOOST_CHECK_EQUAL(logout_reply.start_of_message, exchanges::BATSBOE::common::msg_start_code);
381  BOOST_CHECK_LE(logout_reply.length(), sizeof(typename connection_t::msg_details_t::Logout));
382  BOOST_CHECK_EQUAL(logout_reply.type(), exchanges::BATSBOE::common::MsgType::Logout);
383  BOOST_CHECK_EQUAL(logout_reply.logoutReason, exchanges::BATSBOE::common::LogoutReason::UserRequested);
384  }
385 }
386 */
387 BOOST_AUTO_TEST_SUITE_END()
388 
389 BOOST_AUTO_TEST_SUITE(client_initiated)
390 
391 /**
392  \test "Order handling" of [1] Test: Response to an invalid NewOrder.
393  =======================================================
394  Verify that the response to an invalid NewOrder is a Reject.
395  [1] "BATS Chi-X Europe Binary Order Entry Specification", Version 1.44, 27 November, 2014
396 */
397 BOOST_AUTO_TEST_CASE_TEMPLATE(reject, exchg_t, exchg_t_types) {
398  using fixture_t=conn_args_sim_n_link_logon_logoff<exchg_t>;
399  using connection_t=typename fixture_t::connection_t;
400  fixture_t f;
401 
402  const typename connection_t::msg_details_t::NewOrder_t msg(
403  sequenceNumber,
404  clientOrderId1,
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
411  );
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);
420 }
421 
422 /**
423  \test "Order handling" of [1] Test: Response to an invalid OrderCancelRequest.
424  =================================================================
425  Verify that the response to an invalid OrderCancelRequest is a OrderCancelReject.
426  [1] "BATS Chi-X Europe Binary Order Entry Specification", Version 1.44, 27 November, 2014
427 */
428 BOOST_AUTO_TEST_CASE_TEMPLATE(cancel_reject, exchg_t, exchg_t_types) {
429  using fixture_t=conn_args_sim_n_link_logon_logoff<exchg_t>;
430  using connection_t=typename fixture_t::connection_t;
431  fixture_t f;
432 
433  const typename connection_t::msg_details_t::OrderCancelRequest msg(
434  sequenceNumber,
435  clientOrderId1
436  );
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());
444 }
445 
446 /**
447  \test "Order handling" of [1] Test: Response to a valid OrderCancelRequest.
448  ==============================================================
449  Verify that the response to a valid OrderCancelRequest is a cancelled order ExecutionReport.
450  [1] "BATS Chi-X Europe Binary Order Entry Specification", Version 1.44, 27 November, 2014
451 */
452 BOOST_AUTO_TEST_CASE_TEMPLATE(cancel_accept, exchg_t, exchg_t_types) {
453  using fixture_t=conn_args_sim_n_link_logon_logoff<exchg_t>;
454  using connection_t=typename fixture_t::connection_t;
455  fixture_t f;
456 
457  const typename connection_t::msg_details_t::NewOrder_t msg(
458  sequenceNumber,
459  clientOrderId1,
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
466  );
467  BOOST_REQUIRE_NO_THROW(f.link.send(msg));
468  const typename connection_t::msg_details_t::OrderCancelRequest msg1(
469  sequenceNumber,
470  clientOrderId1
471  );
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);
480 }
481 
482 /**
483  \test "Order handling" of [1] Test: Response to an invalid OrderCancelReplaceRequest.
484  ========================================================================
485  Verify that the response to an invalid OrderCancelReplaceRequest is a cancelled order OrderCancelReject.
486  [1] "BATS Chi-X Europe Binary Order Entry Specification", Version 1.44, 27 November, 2014
487 */
488 BOOST_AUTO_TEST_CASE_TEMPLATE(modify_reject, exchg_t, exchg_t_types) {
489  using fixture_t=conn_args_sim_n_link_logon_logoff<exchg_t>;
490  using connection_t=typename fixture_t::connection_t;
491  fixture_t f;
492 
493  const typename connection_t::msg_details_t::OrderCancelReplaceRequest msg(
494  sequenceNumber,
495  clientOrderId1,
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
499  );
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);
508 }
509 
510 /**
511  \test "Order handling" of [1] Test: Response to a valid OrderCancelReplaceRequest.
512  =====================================================================
513  Verify that the response to a valid OrderCancelReplaceRequest is a cancelled order ExecutionReport.
514  [1] "BATS Chi-X Europe Binary Order Entry Specification", Version 1.44, 27 November, 2014
515 */
516 BOOST_AUTO_TEST_CASE_TEMPLATE(modify_accept, exchg_t, exchg_t_types) {
517  using fixture_t=conn_args_sim_n_link_logon_logoff<exchg_t>;
518  using connection_t=typename fixture_t::connection_t;
519  fixture_t f;
520 
521  const typename connection_t::msg_details_t::NewOrder_t msg(
522  sequenceNumber,
523  clientOrderId1,
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
530  );
531  BOOST_REQUIRE_NO_THROW(f.link.send(msg));
532  const typename connection_t::msg_details_t::OrderCancelReplaceRequest msg1(
533  sequenceNumber,
534  clientOrderId1,
535  exchg_t::second_type::proc_rules_t::quantity_limit,
536  msg.limitPrice()+2,
537  exchg_t::first_type::msg_details_t::Side::Sell
538  );
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());
549 }
550 
551 BOOST_AUTO_TEST_SUITE(new_order)
552 
553 BOOST_AUTO_TEST_SUITE(buy)
554 
555 BOOST_AUTO_TEST_SUITE(day)
556 
557 BOOST_AUTO_TEST_SUITE(market)
558 
559 /**
560  \test "Order handling" of [1] Test: Response to a BUY, DAY, MARKET NewOrder is a filled ExecutionReport.
561  ===========================================================================================
562  Verify that the response to a buy, day, market NewOrder is a filled ExecutionReport.
563  [1] "BATS Chi-X Europe Binary Order Entry Specification", Version 1.44, 27 November, 2014
564 */
565 BOOST_AUTO_TEST_CASE_TEMPLATE(new_order, exchg_t, exchg_t_types) {
566  using fixture_t=conn_args_sim_n_link_logon_logoff<exchg_t>;
567  using connection_t=typename fixture_t::connection_t;
568  fixture_t f;
569 
570  const typename connection_t::msg_details_t::NewOrder_t msg(
571  sequenceNumber,
572  clientOrderId1,
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
579  );
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());
592 }
593 
594 /**
595  \test "Order handling" of [1] Test: Response to a BUY, DAY, MARKET NewOrder is a partially-filled ExecutionReport.
596  ==============================================================================================================
597  Verify that the response to a suitably large, buy, day, market NewOrder is a partially-filled ExecutionReport.
598  [1] "BATS Chi-X Europe Binary Order Entry Specification", Version 1.44, 27 November, 2014
599 */
600 BOOST_AUTO_TEST_CASE_TEMPLATE(partial_fill, exchg_t, exchg_t_types) {
601  using fixture_t=conn_args_sim_n_link_logon_logoff<exchg_t>;
602  using connection_t=typename fixture_t::connection_t;
603  fixture_t f;
604 
605  const typename connection_t::msg_details_t::NewOrder_t msg(
606  sequenceNumber,
607  clientOrderId1,
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
614  );
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());
627 }
628 
629 /**
630  \test "Order handling" of [1] Test: Response to a OrderCancelRequest is a cancelled ExecutionReport.
631  ==============================================================================================
632  Verify that the response to a OrderCancelRequest of the remaining quantity of a suitably large, buy, day, market NewOrder is a cancelled ExecutionReport.
633  [1] "BATS Chi-X Europe Binary Order Entry Specification", Version 1.44, 27 November, 2014
634 */
635 BOOST_AUTO_TEST_CASE_TEMPLATE(partial_fill_cancel, exchg_t, exchg_t_types) {
636  using fixture_t=conn_args_sim_n_link_logon_logoff<exchg_t>;
637  using connection_t=typename fixture_t::connection_t;
638  fixture_t f;
639 
640  const typename connection_t::msg_details_t::NewOrder_t new_order(
641  sequenceNumber,
642  clientOrderId1,
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
649  );
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(
654  sequenceNumber,
655  clientOrderId1
656  );
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());
669 }
670 
671 /**
672  \test "Order handling" of [1] Test: Response to a OrderCancelReplaceRequest is a replaced ExecutionReport.
673  ==============================================================================================================
674  Verify that the response to a OrderCancelReplaceRequest of the remaining quantity of a suitably large, buy, day, market NewOrder is a replaced ExecutionReport.
675  [1] "BATS Chi-X Europe Binary Order Entry Specification", Version 1.44, 27 November, 2014
676 */
677 BOOST_AUTO_TEST_CASE_TEMPLATE(partial_fill_replace, exchg_t, exchg_t_types) {
678  using fixture_t=conn_args_sim_n_link_logon_logoff<exchg_t>;
679  using connection_t=typename fixture_t::connection_t;
680  fixture_t f;
681 
682  const typename connection_t::msg_details_t::NewOrder_t new_order(
683  sequenceNumber,
684  clientOrderId1,
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
691  );
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(
696  sequenceNumber,
697  clientOrderId1,
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
701  );
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);
712 }
713 
714 BOOST_AUTO_TEST_SUITE_END()
715 
716 BOOST_AUTO_TEST_SUITE(limit)
717 
718 /**
719  \test Section 9.1 "Order handling" of [1] Test: Response to a BUY, DAY, LIBATSBOE NewOrder is a filled ExecutionReport.
720  ==============================================================================================================
721  Verify that the response to a buy, day, limit NewOrder is a filled ExecutionReport.
722  [1] "BATSBOE203 - MILLENNIUM EXCHANGE Native Trading Gateway"
723 */
724 BOOST_AUTO_TEST_CASE_TEMPLATE(new_order, exchg_t, exchg_t_types) {
725  using fixture_t=conn_args_sim_n_link_logon_logoff<exchg_t>;
726  using connection_t=typename fixture_t::connection_t;
727  fixture_t f;
728 
729  const typename connection_t::msg_details_t::NewOrder_t new_order(
730  sequenceNumber,
731  clientOrderId1,
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
738  );
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());
751 }
752 
753 /**
754  \test Section 9.1 "Order handling" of [1] Test: Response to a suitable BUY, DAY, LIBATSBOE NewOrder followed by an OrderCancelRequest is a cancelled ExecutionReport.
755  ===========================================================================================================================================================
756  Verify that the response to a buy, day, limit NewOrder that is open on the exchange then cancelled is a cancelled ExecutionReport.
757  [1] "BATSBOE203 - MILLENNIUM EXCHANGE Native Trading Gateway"
758 */
759 BOOST_AUTO_TEST_CASE_TEMPLATE(open_cancelled, exchg_t, exchg_t_types) {
760  using fixture_t=conn_args_sim_n_link_logon_logoff<exchg_t>;
761  using connection_t=typename fixture_t::connection_t;
762  fixture_t f;
763 
764  const typename connection_t::msg_details_t::NewOrder_t new_order(
765  sequenceNumber,
766  clientOrderId1,
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
773  );
774  BOOST_REQUIRE_NO_THROW(f.link.send(new_order));
775  const typename connection_t::msg_details_t::OrderCancelRequest cancel(
776  sequenceNumber,
777  clientOrderId1
778  );
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());
791 }
792 
793 /**
794  \test Section 9.1 "Order handling" of [1] Test: Response to a suitable BUY, DAY, LIBATSBOE NewOrder followed by an OrderCancelReplaceRequest is a cancelled ExecutionReport.
795  ==================================================================================================================================================================
796  Verify that the response to a buy, day, limit NewOrder that is open on the exchange then modified is a cancelled ExecutionReport.
797  [1] "BATSBOE203 - MILLENNIUM EXCHANGE Native Trading Gateway"
798 */
799 BOOST_AUTO_TEST_CASE_TEMPLATE(open_replace, exchg_t, exchg_t_types) {
800  using fixture_t=conn_args_sim_n_link_logon_logoff<exchg_t>;
801  using connection_t=typename fixture_t::connection_t;
802  fixture_t f;
803 
804  const typename connection_t::msg_details_t::NewOrder_t new_order(
805  sequenceNumber,
806  clientOrderId1,
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
813  );
814  BOOST_REQUIRE_NO_THROW(f.link.send(new_order));
815  const typename connection_t::msg_details_t::OrderCancelReplaceRequest replace(
816  sequenceNumber,
817  clientOrderId1,
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
821  );
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);
832 }
833 
834 BOOST_AUTO_TEST_SUITE_END()
835 
836 BOOST_AUTO_TEST_SUITE_END()
837 
838 BOOST_AUTO_TEST_SUITE_END()
839 
840 BOOST_AUTO_TEST_SUITE_END()
841 
842 BOOST_AUTO_TEST_SUITE_END()
843 
844 BOOST_AUTO_TEST_SUITE_END()