This source file includes following definitions.
- BOOST_AUTO_TEST_SUITE
- BOOST_AUTO_TEST_CASE_TEMPLATE
- BOOST_AUTO_TEST_SUITE_END
- BOOST_AUTO_TEST_CASE_TEMPLATE
- BOOST_AUTO_TEST_CASE_TEMPLATE
- BOOST_AUTO_TEST_CASE_TEMPLATE
- BOOST_AUTO_TEST_CASE_TEMPLATE
- BOOST_AUTO_TEST_SUITE_END
- BOOST_AUTO_TEST_CASE_TEMPLATE
- BOOST_AUTO_TEST_CASE_TEMPLATE
- BOOST_AUTO_TEST_CASE_TEMPLATE
- BOOST_AUTO_TEST_CASE_TEMPLATE
- BOOST_AUTO_TEST_SUITE
- BOOST_AUTO_TEST_CASE_TEMPLATE
- BOOST_AUTO_TEST_CASE_TEMPLATE
- BOOST_AUTO_TEST_CASE_TEMPLATE
- BOOST_AUTO_TEST_SUITE_END
- BOOST_AUTO_TEST_CASE_TEMPLATE
- BOOST_AUTO_TEST_CASE_TEMPLATE
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 #include "stdafx.h"
22
23 #define BOOST_TEST_MODULE libjmmcg_tests
24 #include <boost/test/included/unit_test.hpp>
25
26 #include <boost/test/test_case_template.hpp>
27 #include <boost/mpl/list.hpp>
28
29 #include "../exchanges/BATSBOE/US/v1/batsboe.hpp"
30 #include "../exchanges/BATSBOE/US/v1/batsboe_sim.hpp"
31 #include "../exchanges/BATSBOE/US/v2/batsboe.hpp"
32 #include "../exchanges/BATSBOE/US/v2/batsboe_sim.hpp"
33
34 const boost::asio::ip::address primary_gw(boost::asio::ip::address_v4::loopback());
35 const unsigned short unused_primary_port=12347u;
36 const isimud::exchanges::BATSBOE::common::ClientOrderID_t clientOrderId1{"12345678901234test1"};
37 const isimud::exchanges::BATSBOE::common::SecurityID_t instID{"abcdefghijklmno"};
38 const isimud::exchanges::BATSBOE::common::Price_t price(1);
39 const isimud::exchanges::BATSBOE::common::SessionSubID_t sessionSubID{"ABC"};
40 const uint32_t sequenceNumber(1);
41
42 typedef boost::mpl::list<
43 std::pair<isimud::exchanges::BATSBOE::US::v1::connection_t, isimud::exchanges::BATSBOE::US::v1::simulator_t>
44
45 > exchg_t_types;
46
47 template<class exchg_t>
48 struct conn_args {
49 using connection_t=typename exchg_t::first_type;
50 using simulator_t=typename exchg_t::second_type;
51 using conn_pol_t=typename connection_t::conn_pol_t;
52
53 conn_pol_t conn_pol{
54 typename conn_pol_t::gateways_t(
55 std::make_pair(primary_gw, unused_primary_port)
56 ),
57 isimud::exchanges::BATSBOE::common::logon_args_t{
58 0,
59 {"000"},
60 simulator_t::proc_rules_t::username,
61 simulator_t::proc_rules_t::password,
62 false
63 },
64 isimud::exchanges::BATSBOE::common::logoff_args_t{
65 0
66 }
67 };
68 };
69
70 template<class exchg_t>
71 struct conn_args_n_sim : public conn_args<exchg_t> {
72 using base_t=conn_args<exchg_t>;
73 using simulator_t=typename base_t::simulator_t;
74
75 typename simulator_t::proc_rules_t proc_rules;
76 simulator_t svr{boost::asio::ip::address(), unused_primary_port, proc_rules};
77 };
78
79 template<class exchg_t>
80 struct conn_args_sim_n_link : public conn_args_n_sim<exchg_t> {
81 using base_t=conn_args_n_sim<exchg_t>;
82 using connection_t=typename base_t::connection_t;
83 using link_t=typename exchg_t::first_type;
84
85 link_t link{this->conn_pol};
86 };
87
88 template<class exchg_t>
89 struct conn_args_sim_n_link_logon_logoff : public conn_args_sim_n_link<exchg_t> {
90 using base_t=conn_args_sim_n_link<exchg_t>;
91 using connection_t=typename base_t::connection_t;
92 using simulator_t=typename base_t::simulator_t;
93
94 conn_args_sim_n_link_logon_logoff() {
95 const typename connection_t::msg_details_t::LogonRequest msg(
96 sequenceNumber,
97 sessionSubID,
98 typename connection_t::msg_details_t::UserName_t(this->conn_pol.logon_args.username),
99 typename connection_t::msg_details_t::Password_t(this->conn_pol.logon_args.password),
100 false
101 );
102 BOOST_REQUIRE_NO_THROW(this->link.send(msg));
103 typename connection_t::msg_details_t::LogonReply reply;
104 BOOST_REQUIRE_NO_THROW(this->link.receive(reply));
105 BOOST_CHECK_EQUAL(reply.start_of_message, isimud::exchanges::BATSBOE::common::msg_start_code);
106 BOOST_CHECK_LE(reply.length(), sizeof(typename connection_t::msg_details_t::LogonReply));
107 BOOST_CHECK_EQUAL(reply.type(), isimud::exchanges::BATSBOE::US::MsgType::LogonReply);
108 BOOST_CHECK_EQUAL(reply.rejectCode(), isimud::exchanges::BATSBOE::common::LoginResponseStatus::LoginAccepted);
109 }
110 ~conn_args_sim_n_link_logon_logoff() {
111 const typename connection_t::msg_details_t::LogoutRequest msg(sequenceNumber);
112 BOOST_REQUIRE_NO_THROW(this->link.send(msg));
113 typename connection_t::msg_details_t::Logout reply;
114 BOOST_REQUIRE_NO_THROW(this->link.receive(reply));
115 BOOST_CHECK_EQUAL(reply.start_of_message, isimud::exchanges::BATSBOE::common::msg_start_code);
116 BOOST_CHECK_LE(reply.length(), sizeof(typename connection_t::msg_details_t::Logout));
117 BOOST_CHECK_EQUAL(reply.type(), isimud::exchanges::BATSBOE::common::MsgType::Logout);
118 BOOST_CHECK_EQUAL(reply.logoutReason, isimud::exchanges::BATSBOE::common::LogoutReason::UserRequested);
119 }
120 };
121
122 BOOST_AUTO_TEST_SUITE(exchanges)
123
124 BOOST_AUTO_TEST_SUITE(links)
125
126
127
128
129
130
131
132 BOOST_AUTO_TEST_CASE_TEMPLATE(primary_gateway_available, exchg_t, exchg_t_types) {
133 using fixture_t=conn_args_n_sim<exchg_t>;
134 fixture_t f;
135
136 auto const &begin=std::chrono::system_clock::now();
137 BOOST_REQUIRE_NO_THROW(typename exchg_t::first_type link(f.conn_pol));
138 auto const &end=std::chrono::system_clock::now();
139 BOOST_CHECK_LT(std::chrono::duration_cast<std::chrono::seconds>(end-begin).count(), fixture_t::conn_pol_t::min_timeout.count());
140 }
141
142
143
144
145
146
147
148 BOOST_AUTO_TEST_CASE_TEMPLATE(re_connnect, exchg_t, exchg_t_types) {
149 using fixture_t=conn_args_n_sim<exchg_t>;
150 fixture_t f;
151
152 BOOST_REQUIRE_NO_THROW(typename exchg_t::first_type link(f.conn_pol));
153 auto const &begin=std::chrono::system_clock::now();
154 BOOST_REQUIRE_NO_THROW(typename exchg_t::first_type link(f.conn_pol));
155 auto const &end=std::chrono::system_clock::now();
156 BOOST_CHECK_LT(std::chrono::duration_cast<std::chrono::seconds>(end-begin).count(), fixture_t::conn_pol_t::min_timeout.count());
157 }
158
159 BOOST_AUTO_TEST_SUITE_END()
160
161 BOOST_AUTO_TEST_SUITE(admin)
162
163
164
165
166
167
168
169 BOOST_AUTO_TEST_CASE_TEMPLATE(logon, exchg_t, exchg_t_types) {
170 using fixture_t=conn_args_sim_n_link<exchg_t>;
171 using connection_t=typename fixture_t::connection_t;
172 fixture_t f;
173
174 const typename connection_t::msg_details_t::LogonRequest msg(
175 sequenceNumber,
176 sessionSubID,
177 typename connection_t::msg_details_t::UserName_t(f.conn_pol.logon_args.username),
178 typename connection_t::msg_details_t::Password_t(f.conn_pol.logon_args.password),
179 false
180 );
181 BOOST_REQUIRE_NO_THROW(f.link.send(msg));
182 typename connection_t::msg_details_t::LogonReply reply;
183 BOOST_REQUIRE_NO_THROW(f.link.receive(reply));
184 BOOST_CHECK_EQUAL(reply.start_of_message, isimud::exchanges::BATSBOE::common::msg_start_code);
185 BOOST_CHECK_LE(reply.length(), sizeof(typename connection_t::msg_details_t::LogonReply));
186 BOOST_CHECK_EQUAL(reply.type(), isimud::exchanges::BATSBOE::US::MsgType::LogonReply);
187 BOOST_CHECK_EQUAL(reply.rejectCode(), isimud::exchanges::BATSBOE::common::LoginResponseStatus::LoginAccepted);
188 }
189
190
191
192
193
194
195
196 BOOST_AUTO_TEST_CASE_TEMPLATE(client_heartbeat, exchg_t, exchg_t_types) {
197 using fixture_t=conn_args_sim_n_link<exchg_t>;
198 using connection_t=typename fixture_t::connection_t;
199 fixture_t f;
200
201 const typename connection_t::msg_details_t::Heartbeat msg(sequenceNumber);
202 BOOST_CHECK_NO_THROW(f.link.send(msg));
203 }
204
205
206
207
208
209
210 BOOST_AUTO_TEST_CASE_TEMPLATE(server_heartbeat, exchg_t, exchg_t_types) {
211 using fixture_t=conn_args_n_sim<exchg_t>;
212 using connection_t=typename fixture_t::connection_t;
213 fixture_t f;
214
215 const auto t1=std::chrono::high_resolution_clock::now();
216 typename exchg_t::first_type link(f.conn_pol);
217 typename connection_t::msg_details_t::ServerHeartbeat msg(sequenceNumber);
218 BOOST_REQUIRE_NO_THROW(link.receive(msg));
219 const auto t2=std::chrono::high_resolution_clock::now();
220 BOOST_CHECK_EQUAL(msg.start_of_message, isimud::exchanges::BATSBOE::common::msg_start_code);
221 BOOST_CHECK_EQUAL(msg.type(), isimud::exchanges::BATSBOE::common::MsgType::ServerHeartbeat);
222 BOOST_CHECK_EQUAL(msg.matchingUnit, 0);
223 BOOST_CHECK_EQUAL(msg.sequenceNumber, connection_t::msg_details_t::ServerHeartbeat::seq_num);
224 BOOST_CHECK_GE(msg.length(), connection_t::msg_details_t::header_t_size);
225 BOOST_CHECK_LE(msg.length(), sizeof(typename connection_t::msg_details_t::ServerHeartbeat));
226 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);
227 }
228
229
230
231
232
233
234
235 BOOST_AUTO_TEST_CASE_TEMPLATE(logout, exchg_t, exchg_t_types) {
236 using fixture_t=conn_args_sim_n_link<exchg_t>;
237 using connection_t=typename fixture_t::connection_t;
238 fixture_t f;
239
240 const typename connection_t::msg_details_t::LogoutRequest msg(sequenceNumber);
241 BOOST_REQUIRE_NO_THROW(f.link.send(msg));
242 typename connection_t::msg_details_t::Logout reply;
243 BOOST_REQUIRE_NO_THROW(f.link.receive(reply));
244 BOOST_CHECK_EQUAL(reply.start_of_message, isimud::exchanges::BATSBOE::common::msg_start_code);
245 BOOST_CHECK_LE(reply.length(), sizeof(typename connection_t::msg_details_t::Logout));
246 BOOST_CHECK_EQUAL(reply.type(), isimud::exchanges::BATSBOE::common::MsgType::Logout);
247 BOOST_CHECK_EQUAL(reply.logoutReason, isimud::exchanges::BATSBOE::common::LogoutReason::UserRequested);
248 }
249
250
251
252
253
254
255
256 BOOST_AUTO_TEST_CASE_TEMPLATE(logon_logout, exchg_t, exchg_t_types) {
257 using fixture_t=conn_args_sim_n_link<exchg_t>;
258 using connection_t=typename fixture_t::connection_t;
259 fixture_t f;
260
261 const typename connection_t::msg_details_t::LogonRequest logon_msg(
262 sequenceNumber,
263 sessionSubID,
264 typename connection_t::msg_details_t::UserName_t(f.conn_pol.logon_args.username),
265 typename connection_t::msg_details_t::Password_t(f.conn_pol.logon_args.password),
266 false
267 );
268 BOOST_REQUIRE_NO_THROW(f.link.send(logon_msg));
269 typename connection_t::msg_details_t::LogonReply logon_reply;
270 BOOST_REQUIRE_NO_THROW(f.link.receive(logon_reply));
271 BOOST_CHECK_EQUAL(logon_reply.start_of_message, isimud::exchanges::BATSBOE::common::msg_start_code);
272 BOOST_CHECK_LE(logon_reply.length(), sizeof(typename connection_t::msg_details_t::LogonReply));
273 BOOST_CHECK_EQUAL(logon_reply.type(), isimud::exchanges::BATSBOE::US::MsgType::LogonReply);
274 BOOST_CHECK_EQUAL(logon_reply.rejectCode(), isimud::exchanges::BATSBOE::common::LoginResponseStatus::LoginAccepted);
275 const typename connection_t::msg_details_t::LogoutRequest logout_msg(sequenceNumber);
276 BOOST_REQUIRE_NO_THROW(f.link.send(logout_msg));
277 typename connection_t::msg_details_t::Logout logout_reply;
278 BOOST_REQUIRE_NO_THROW(f.link.receive(logout_reply));
279 BOOST_CHECK_EQUAL(logout_reply.start_of_message, isimud::exchanges::BATSBOE::common::msg_start_code);
280 BOOST_CHECK_LE(logout_reply.length(), sizeof(typename connection_t::msg_details_t::Logout));
281 BOOST_CHECK_EQUAL(logout_reply.type(), isimud::exchanges::BATSBOE::common::MsgType::Logout);
282 BOOST_CHECK_EQUAL(logout_reply.logoutReason, isimud::exchanges::BATSBOE::common::LogoutReason::UserRequested);
283 }
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349 BOOST_AUTO_TEST_SUITE_END()
350
351 BOOST_AUTO_TEST_SUITE(client_initiated)
352
353
354
355
356
357
358
359 BOOST_AUTO_TEST_CASE_TEMPLATE(reject, exchg_t, exchg_t_types) {
360 using fixture_t=conn_args_sim_n_link_logon_logoff<exchg_t>;
361 using connection_t=typename fixture_t::connection_t;
362 fixture_t f;
363
364 const typename connection_t::msg_details_t::NewOrder msg(
365 sequenceNumber,
366 clientOrderId1,
367 exchg_t::first_type::msg_details_t::OrderType::Market,
368 isimud::exchanges::BATSBOE::common::TIF::Day,
369 exchg_t::first_type::msg_details_t::Side::Buy,
370 exchg_t::second_type::proc_rules_t::invalidInstrumentID,
371 exchg_t::second_type::proc_rules_t::quantity_limit-1,
372 exchg_t::second_type::proc_rules_t::scaled_price
373 );
374 BOOST_REQUIRE_NO_THROW(f.link.send(msg));
375 typename connection_t::msg_details_t::OrderRejected reply;
376 BOOST_REQUIRE_NO_THROW(f.link.receive(reply));
377 BOOST_CHECK_EQUAL(reply.start_of_message, isimud::exchanges::BATSBOE::common::msg_start_code);
378 BOOST_CHECK_LE(reply.length(), sizeof(typename connection_t::msg_details_t::OrderRejected));
379 BOOST_CHECK_EQUAL(reply.type(), isimud::exchanges::BATSBOE::common::MsgType::OrderRejected);
380 BOOST_CHECK_EQUAL(reply.clientOrderID(), msg.clientOrderID());
381 BOOST_CHECK_EQUAL(reply.orderRejectReason, isimud::exchanges::BATSBOE::common::OrderRejectReason::SymbolNotSupported);
382 }
383
384
385
386
387
388
389
390 BOOST_AUTO_TEST_CASE_TEMPLATE(cancel_reject, exchg_t, exchg_t_types) {
391 using fixture_t=conn_args_sim_n_link_logon_logoff<exchg_t>;
392 using connection_t=typename fixture_t::connection_t;
393 fixture_t f;
394
395 const typename connection_t::msg_details_t::OrderCancelRequest msg(
396 sequenceNumber,
397 clientOrderId1
398 );
399 BOOST_REQUIRE_NO_THROW(f.link.send(msg));
400 typename connection_t::msg_details_t::OrderCancelReject reply;
401 BOOST_REQUIRE_NO_THROW(f.link.receive(reply));
402 BOOST_CHECK_EQUAL(reply.start_of_message, isimud::exchanges::BATSBOE::common::msg_start_code);
403 BOOST_CHECK_LE(reply.length(), sizeof(typename connection_t::msg_details_t::OrderCancelReject));
404 BOOST_CHECK_EQUAL(reply.type(), isimud::exchanges::BATSBOE::common::MsgType::CancelRejected);
405 BOOST_CHECK_EQUAL(reply.clientOrderID(), msg.originalClientOrderID());
406 }
407
408
409
410
411
412
413
414 BOOST_AUTO_TEST_CASE_TEMPLATE(cancel_accept, exchg_t, exchg_t_types) {
415 using fixture_t=conn_args_sim_n_link_logon_logoff<exchg_t>;
416 using connection_t=typename fixture_t::connection_t;
417 fixture_t f;
418
419 const typename connection_t::msg_details_t::NewOrder msg(
420 sequenceNumber,
421 clientOrderId1,
422 exchg_t::first_type::msg_details_t::OrderType::Limit,
423 isimud::exchanges::BATSBOE::common::TIF::Day,
424 exchg_t::first_type::msg_details_t::Side::Buy,
425 exchg_t::second_type::proc_rules_t::instrumentID,
426 exchg_t::second_type::proc_rules_t::quantity_limit-1,
427 exchg_t::second_type::proc_rules_t::scaled_price+1
428 );
429 BOOST_REQUIRE_NO_THROW(f.link.send(msg));
430 const typename connection_t::msg_details_t::OrderCancelRequest msg1(
431 sequenceNumber,
432 clientOrderId1
433 );
434 BOOST_REQUIRE_NO_THROW(f.link.send(msg1));
435 typename connection_t::msg_details_t::OrderCancelled reply;
436 BOOST_REQUIRE_NO_THROW(f.link.receive(reply));
437 BOOST_CHECK_EQUAL(reply.start_of_message, isimud::exchanges::BATSBOE::common::msg_start_code);
438 BOOST_CHECK_LE(reply.length(), sizeof(typename connection_t::msg_details_t::OrderCancelled));
439 BOOST_CHECK_EQUAL(reply.type(), isimud::exchanges::BATSBOE::common::MsgType::OrderCancelled);
440 BOOST_CHECK_EQUAL(reply.clientOrderID(), msg.clientOrderID());
441 BOOST_CHECK_EQUAL(reply.cancelReason, isimud::exchanges::BATSBOE::common::OrderRejectReason::UserRequested);
442 }
443
444
445
446
447
448
449
450 BOOST_AUTO_TEST_CASE_TEMPLATE(modify_reject, exchg_t, exchg_t_types) {
451 using fixture_t=conn_args_sim_n_link_logon_logoff<exchg_t>;
452 using connection_t=typename fixture_t::connection_t;
453 fixture_t f;
454
455 const typename connection_t::msg_details_t::OrderCancelReplaceRequest msg(
456 sequenceNumber,
457 clientOrderId1,
458 exchg_t::second_type::proc_rules_t::quantity_limit,
459 exchg_t::second_type::proc_rules_t::scaled_price,
460 exchg_t::first_type::msg_details_t::Side::Sell
461 );
462 BOOST_REQUIRE_NO_THROW(f.link.send(msg));
463 typename connection_t::msg_details_t::UserModifyRejected reply;
464 BOOST_REQUIRE_NO_THROW(f.link.receive(reply));
465 BOOST_CHECK_EQUAL(reply.start_of_message, isimud::exchanges::BATSBOE::common::msg_start_code);
466 BOOST_CHECK_LE(reply.length(), sizeof(typename connection_t::msg_details_t::UserModifyRejected));
467 BOOST_CHECK_EQUAL(reply.type(), isimud::exchanges::BATSBOE::common::MsgType::UserModifyRejected);
468 BOOST_CHECK_EQUAL(reply.clientOrderID(), msg.originalClientOrderID());
469 BOOST_CHECK_EQUAL(reply.modifyRejectReason, isimud::exchanges::BATSBOE::common::OrderRejectReason::ClOrdIDNotMatchKnownOrder);
470 }
471
472
473
474
475
476
477
478 BOOST_AUTO_TEST_CASE_TEMPLATE(modify_accept, exchg_t, exchg_t_types) {
479 using fixture_t=conn_args_sim_n_link_logon_logoff<exchg_t>;
480 using connection_t=typename fixture_t::connection_t;
481 fixture_t f;
482
483 const typename connection_t::msg_details_t::NewOrder msg(
484 sequenceNumber,
485 clientOrderId1,
486 exchg_t::first_type::msg_details_t::OrderType::Limit,
487 isimud::exchanges::BATSBOE::common::TIF::Day,
488 exchg_t::first_type::msg_details_t::Side::Buy,
489 exchg_t::second_type::proc_rules_t::instrumentID,
490 exchg_t::second_type::proc_rules_t::quantity_limit-1,
491 exchg_t::second_type::proc_rules_t::scaled_price+1
492 );
493 BOOST_REQUIRE_NO_THROW(f.link.send(msg));
494 const typename connection_t::msg_details_t::OrderCancelReplaceRequest msg1(
495 sequenceNumber,
496 clientOrderId1,
497 exchg_t::second_type::proc_rules_t::quantity_limit,
498 msg.limitPrice()+2,
499 exchg_t::first_type::msg_details_t::Side::Sell
500 );
501 BOOST_REQUIRE_NO_THROW(f.link.send(msg1));
502 typename connection_t::msg_details_t::OrderModified reply;
503 BOOST_REQUIRE_NO_THROW(f.link.receive(reply));
504 BOOST_CHECK_EQUAL(reply.start_of_message, isimud::exchanges::BATSBOE::common::msg_start_code);
505 BOOST_CHECK_LE(reply.length(), sizeof(typename connection_t::msg_details_t::OrderModified));
506 BOOST_CHECK_EQUAL(reply.type(), isimud::exchanges::BATSBOE::common::MsgType::OrderModified);
507 BOOST_CHECK_EQUAL(reply.clientOrderID(), msg.clientOrderID());
508 BOOST_CHECK_EQUAL(reply.limitPrice(), msg1.limitPrice());
509 BOOST_CHECK_EQUAL(reply.side(), exchg_t::first_type::msg_details_t::Side::Sell);
510 BOOST_CHECK_EQUAL(reply.orderQty(), msg1.orderQty());
511 }
512
513 BOOST_AUTO_TEST_SUITE(new_order)
514
515 BOOST_AUTO_TEST_SUITE(buy)
516
517 BOOST_AUTO_TEST_SUITE(day)
518
519 BOOST_AUTO_TEST_SUITE(market)
520
521
522
523
524
525
526
527 BOOST_AUTO_TEST_CASE_TEMPLATE(new_order, exchg_t, exchg_t_types) {
528 using fixture_t=conn_args_sim_n_link_logon_logoff<exchg_t>;
529 using connection_t=typename fixture_t::connection_t;
530 fixture_t f;
531
532 const typename connection_t::msg_details_t::NewOrder msg(
533 sequenceNumber,
534 clientOrderId1,
535 exchg_t::first_type::msg_details_t::OrderType::Market,
536 isimud::exchanges::BATSBOE::common::TIF::Day,
537 exchg_t::first_type::msg_details_t::Side::Buy,
538 exchg_t::second_type::proc_rules_t::instrumentID,
539 exchg_t::second_type::proc_rules_t::quantity_limit-1,
540 exchg_t::second_type::proc_rules_t::scaled_price
541 );
542 BOOST_REQUIRE_NO_THROW(f.link.send(msg));
543 typename connection_t::msg_details_t::ExecutionReport reply;
544 BOOST_REQUIRE_NO_THROW(f.link.receive(reply));
545 BOOST_CHECK_EQUAL(reply.start_of_message, isimud::exchanges::BATSBOE::common::msg_start_code);
546 BOOST_CHECK_LE(reply.length(), sizeof(typename connection_t::msg_details_t::ExecutionReport));
547 BOOST_CHECK_EQUAL(reply.type(), isimud::exchanges::BATSBOE::common::MsgType::OrderExecution);
548 BOOST_CHECK_EQUAL(reply.clientOrderID(), msg.clientOrderID());
549 BOOST_CHECK_EQUAL(reply.instrumentID(), exchg_t::second_type::proc_rules_t::instrumentID);
550 BOOST_CHECK_EQUAL(reply.side(), exchg_t::first_type::msg_details_t::Side::Buy);
551 BOOST_CHECK_EQUAL(reply.executedQty(), msg.orderQty());
552 BOOST_CHECK_EQUAL(reply.leavesQty(), 0);
553 BOOST_CHECK_EQUAL(reply.executedPrice(), msg.limitPrice());
554 }
555
556
557
558
559
560
561
562 BOOST_AUTO_TEST_CASE_TEMPLATE(partial_fill, exchg_t, exchg_t_types) {
563 using fixture_t=conn_args_sim_n_link_logon_logoff<exchg_t>;
564 using connection_t=typename fixture_t::connection_t;
565 fixture_t f;
566
567 const typename connection_t::msg_details_t::NewOrder msg(
568 sequenceNumber,
569 clientOrderId1,
570 exchg_t::first_type::msg_details_t::OrderType::Market,
571 isimud::exchanges::BATSBOE::common::TIF::Day,
572 exchg_t::first_type::msg_details_t::Side::Buy,
573 exchg_t::second_type::proc_rules_t::instrumentID,
574 exchg_t::second_type::proc_rules_t::quantity_limit+1,
575 exchg_t::second_type::proc_rules_t::scaled_price
576 );
577 BOOST_REQUIRE_NO_THROW(f.link.send(msg));
578 typename connection_t::msg_details_t::ExecutionReport reply;
579 BOOST_REQUIRE_NO_THROW(f.link.receive(reply));
580 BOOST_CHECK_EQUAL(reply.start_of_message, isimud::exchanges::BATSBOE::common::msg_start_code);
581 BOOST_CHECK_LE(reply.length(), sizeof(typename connection_t::msg_details_t::ExecutionReport));
582 BOOST_CHECK_EQUAL(reply.type(), isimud::exchanges::BATSBOE::common::MsgType::OrderExecution);
583 BOOST_CHECK_EQUAL(reply.clientOrderID(), msg.clientOrderID());
584 BOOST_CHECK_EQUAL(reply.instrumentID(), exchg_t::second_type::proc_rules_t::instrumentID);
585 BOOST_CHECK_EQUAL(reply.side(), exchg_t::first_type::msg_details_t::Side::Buy);
586 BOOST_CHECK_EQUAL(reply.executedQty(), exchg_t::second_type::proc_rules_t::quantity_limit);
587 BOOST_CHECK_EQUAL(reply.leavesQty(), msg.orderQty()-exchg_t::second_type::proc_rules_t::quantity_limit);
588 BOOST_CHECK_EQUAL(reply.executedPrice(), msg.limitPrice());
589 }
590
591
592
593
594
595
596
597 BOOST_AUTO_TEST_CASE_TEMPLATE(partial_fill_cancel, exchg_t, exchg_t_types) {
598 using fixture_t=conn_args_sim_n_link_logon_logoff<exchg_t>;
599 using connection_t=typename fixture_t::connection_t;
600 fixture_t f;
601
602 const typename connection_t::msg_details_t::NewOrder new_order(
603 sequenceNumber,
604 clientOrderId1,
605 exchg_t::first_type::msg_details_t::OrderType::Market,
606 isimud::exchanges::BATSBOE::common::TIF::Day,
607 exchg_t::first_type::msg_details_t::Side::Buy,
608 exchg_t::second_type::proc_rules_t::instrumentID,
609 exchg_t::second_type::proc_rules_t::quantity_limit+1,
610 exchg_t::second_type::proc_rules_t::scaled_price
611 );
612 BOOST_REQUIRE_NO_THROW(f.link.send(new_order));
613 typename connection_t::msg_details_t::ExecutionReport partial_fill;
614 BOOST_REQUIRE_NO_THROW(f.link.receive(partial_fill));
615 const typename connection_t::msg_details_t::OrderCancelRequest cancel(
616 sequenceNumber,
617 clientOrderId1
618 );
619 BOOST_REQUIRE_NO_THROW(f.link.send(cancel));
620 typename connection_t::msg_details_t::OrderCancelled reply;
621 BOOST_REQUIRE_NO_THROW(f.link.receive(reply));
622 BOOST_CHECK_EQUAL(reply.start_of_message, isimud::exchanges::BATSBOE::common::msg_start_code);
623 BOOST_CHECK_LE(reply.length(), sizeof(typename connection_t::msg_details_t::OrderCancelled));
624 BOOST_CHECK_EQUAL(reply.type(), isimud::exchanges::BATSBOE::common::MsgType::OrderCancelled);
625 BOOST_CHECK_EQUAL(reply.clientOrderID(), new_order.clientOrderID());
626 BOOST_CHECK_EQUAL(reply.side(), exchg_t::first_type::msg_details_t::Side::Buy);
627 BOOST_CHECK_EQUAL(reply.orderQty(), new_order.orderQty()-exchg_t::second_type::proc_rules_t::quantity_limit);
628 BOOST_CHECK_EQUAL(reply.leavesQty(), new_order.orderQty()-exchg_t::second_type::proc_rules_t::quantity_limit);
629 BOOST_CHECK_EQUAL(reply.lastShares(), 0);
630 BOOST_CHECK_EQUAL(reply.lastPrice(), new_order.limitPrice());
631 }
632
633
634
635
636
637
638
639 BOOST_AUTO_TEST_CASE_TEMPLATE(partial_fill_replace, exchg_t, exchg_t_types) {
640 using fixture_t=conn_args_sim_n_link_logon_logoff<exchg_t>;
641 using connection_t=typename fixture_t::connection_t;
642 fixture_t f;
643
644 const typename connection_t::msg_details_t::NewOrder new_order(
645 sequenceNumber,
646 clientOrderId1,
647 exchg_t::first_type::msg_details_t::OrderType::Market,
648 isimud::exchanges::BATSBOE::common::TIF::Day,
649 exchg_t::first_type::msg_details_t::Side::Buy,
650 exchg_t::second_type::proc_rules_t::instrumentID,
651 exchg_t::second_type::proc_rules_t::quantity_limit+1,
652 exchg_t::second_type::proc_rules_t::scaled_price
653 );
654 BOOST_REQUIRE_NO_THROW(f.link.send(new_order));
655 typename connection_t::msg_details_t::ExecutionReport partial_fill;
656 BOOST_REQUIRE_NO_THROW(f.link.receive(partial_fill));
657 const typename connection_t::msg_details_t::OrderCancelReplaceRequest replace(
658 sequenceNumber,
659 clientOrderId1,
660 partial_fill.leavesQty()+1,
661 exchg_t::second_type::proc_rules_t::scaled_price*2,
662 exchg_t::first_type::msg_details_t::Side::Sell
663 );
664 BOOST_REQUIRE_NO_THROW(f.link.send(replace));
665 typename connection_t::msg_details_t::OrderModified reply;
666 BOOST_REQUIRE_NO_THROW(f.link.receive(reply));
667 BOOST_CHECK_EQUAL(reply.start_of_message, isimud::exchanges::BATSBOE::common::msg_start_code);
668 BOOST_CHECK_LE(reply.length(), sizeof(typename connection_t::msg_details_t::ExecutionReport));
669 BOOST_CHECK_EQUAL(reply.type(), isimud::exchanges::BATSBOE::common::MsgType::OrderModified);
670 BOOST_CHECK_EQUAL(reply.clientOrderID(), new_order.clientOrderID());
671 BOOST_CHECK_EQUAL(reply.limitPrice(), new_order.limitPrice()*2);
672 BOOST_CHECK_EQUAL(reply.orderQty(), partial_fill.leavesQty()+1);
673 BOOST_CHECK_EQUAL(reply.side(), exchg_t::first_type::msg_details_t::Side::Sell);
674 }
675
676 BOOST_AUTO_TEST_SUITE_END()
677
678 BOOST_AUTO_TEST_SUITE(limit)
679
680
681
682
683
684
685
686 BOOST_AUTO_TEST_CASE_TEMPLATE(new_order, exchg_t, exchg_t_types) {
687 using fixture_t=conn_args_sim_n_link_logon_logoff<exchg_t>;
688 using connection_t=typename fixture_t::connection_t;
689 fixture_t f;
690
691 const typename connection_t::msg_details_t::NewOrder new_order(
692 sequenceNumber,
693 clientOrderId1,
694 exchg_t::first_type::msg_details_t::OrderType::Limit,
695 isimud::exchanges::BATSBOE::common::TIF::Day,
696 exchg_t::first_type::msg_details_t::Side::Buy,
697 exchg_t::second_type::proc_rules_t::instrumentID,
698 exchg_t::second_type::proc_rules_t::quantity_limit-1,
699 exchg_t::second_type::proc_rules_t::scaled_price-1
700 );
701 BOOST_REQUIRE_NO_THROW(f.link.send(new_order));
702 typename connection_t::msg_details_t::ExecutionReport reply;
703 BOOST_REQUIRE_NO_THROW(f.link.receive(reply));
704 BOOST_CHECK_EQUAL(reply.start_of_message, isimud::exchanges::BATSBOE::common::msg_start_code);
705 BOOST_CHECK_LE(reply.length(), sizeof(typename connection_t::msg_details_t::ExecutionReport));
706 BOOST_CHECK_EQUAL(reply.type(), isimud::exchanges::BATSBOE::common::MsgType::OrderExecution);
707 BOOST_CHECK_EQUAL(reply.clientOrderID(), new_order.clientOrderID());
708 BOOST_CHECK_EQUAL(reply.instrumentID(), exchg_t::second_type::proc_rules_t::instrumentID);
709 BOOST_CHECK_EQUAL(reply.side(), exchg_t::first_type::msg_details_t::Side::Buy);
710 BOOST_CHECK_EQUAL(reply.executedQty(), new_order.orderQty());
711 BOOST_CHECK_EQUAL(reply.leavesQty(), 0);
712 BOOST_CHECK_EQUAL(reply.executedPrice(), new_order.limitPrice());
713 }
714
715
716
717
718
719
720
721 BOOST_AUTO_TEST_CASE_TEMPLATE(open_cancelled, exchg_t, exchg_t_types) {
722 using fixture_t=conn_args_sim_n_link_logon_logoff<exchg_t>;
723 using connection_t=typename fixture_t::connection_t;
724 fixture_t f;
725
726 const typename connection_t::msg_details_t::NewOrder new_order(
727 sequenceNumber,
728 clientOrderId1,
729 exchg_t::first_type::msg_details_t::OrderType::Limit,
730 isimud::exchanges::BATSBOE::common::TIF::Day,
731 exchg_t::first_type::msg_details_t::Side::Buy,
732 exchg_t::second_type::proc_rules_t::instrumentID,
733 exchg_t::second_type::proc_rules_t::quantity_limit-1,
734 exchg_t::second_type::proc_rules_t::scaled_price+1
735 );
736 BOOST_REQUIRE_NO_THROW(f.link.send(new_order));
737 const typename connection_t::msg_details_t::OrderCancelRequest cancel(
738 sequenceNumber,
739 clientOrderId1
740 );
741 BOOST_REQUIRE_NO_THROW(f.link.send(cancel));
742 typename connection_t::msg_details_t::OrderCancelled reply;
743 BOOST_REQUIRE_NO_THROW(f.link.receive(reply));
744 BOOST_CHECK_EQUAL(reply.start_of_message, isimud::exchanges::BATSBOE::common::msg_start_code);
745 BOOST_CHECK_LE(reply.length(), sizeof(typename connection_t::msg_details_t::OrderCancelled));
746 BOOST_CHECK_EQUAL(reply.type(), isimud::exchanges::BATSBOE::common::MsgType::OrderCancelled);
747 BOOST_CHECK_EQUAL(reply.clientOrderID(), new_order.clientOrderID());
748 BOOST_CHECK_EQUAL(reply.side(), exchg_t::first_type::msg_details_t::Side::Buy);
749 BOOST_CHECK_EQUAL(reply.orderQty(), new_order.orderQty());
750 BOOST_CHECK_EQUAL(reply.leavesQty(), new_order.orderQty());
751 BOOST_CHECK_EQUAL(reply.lastShares(), 0);
752 BOOST_CHECK_EQUAL(reply.lastPrice(), new_order.limitPrice());
753 }
754
755
756
757
758
759
760
761 BOOST_AUTO_TEST_CASE_TEMPLATE(open_replace, exchg_t, exchg_t_types) {
762 using fixture_t=conn_args_sim_n_link_logon_logoff<exchg_t>;
763 using connection_t=typename fixture_t::connection_t;
764 fixture_t f;
765
766 const typename connection_t::msg_details_t::NewOrder new_order(
767 sequenceNumber,
768 clientOrderId1,
769 exchg_t::first_type::msg_details_t::OrderType::Limit,
770 isimud::exchanges::BATSBOE::common::TIF::Day,
771 exchg_t::first_type::msg_details_t::Side::Buy,
772 exchg_t::second_type::proc_rules_t::instrumentID,
773 exchg_t::second_type::proc_rules_t::quantity_limit-1,
774 exchg_t::second_type::proc_rules_t::scaled_price+1
775 );
776 BOOST_REQUIRE_NO_THROW(f.link.send(new_order));
777 const typename connection_t::msg_details_t::OrderCancelReplaceRequest replace(
778 sequenceNumber,
779 clientOrderId1,
780 new_order.orderQty()+1,
781 exchg_t::second_type::proc_rules_t::scaled_price*2,
782 exchg_t::first_type::msg_details_t::Side::Sell
783 );
784 BOOST_REQUIRE_NO_THROW(f.link.send(replace));
785 typename connection_t::msg_details_t::OrderModified reply;
786 BOOST_REQUIRE_NO_THROW(f.link.receive(reply));
787 BOOST_CHECK_EQUAL(reply.start_of_message, isimud::exchanges::BATSBOE::common::msg_start_code);
788 BOOST_CHECK_LE(reply.length(), sizeof(typename connection_t::msg_details_t::ExecutionReport));
789 BOOST_CHECK_EQUAL(reply.type(), isimud::exchanges::BATSBOE::common::MsgType::OrderModified);
790 BOOST_CHECK_EQUAL(reply.clientOrderID(), new_order.clientOrderID());
791 BOOST_CHECK_EQUAL(reply.limitPrice(), replace.limitPrice());
792 BOOST_CHECK_EQUAL(reply.orderQty(), new_order.orderQty()+1);
793 BOOST_CHECK_EQUAL(reply.side(), exchg_t::first_type::msg_details_t::Side::Sell);
794 }
795
796 BOOST_AUTO_TEST_SUITE_END()
797
798 BOOST_AUTO_TEST_SUITE_END()
799
800 BOOST_AUTO_TEST_SUITE_END()
801
802 BOOST_AUTO_TEST_SUITE_END()
803
804 BOOST_AUTO_TEST_SUITE_END()
805
806 BOOST_AUTO_TEST_SUITE_END()