JayBeams  0.1
Another project to have fun coding.
ut_array_based_order_book.cpp
Go to the documentation of this file.
3 
4 #include <boost/test/unit_test.hpp>
5 
6 /**
7  * @test Trivial verification that array_based_order_book works as expected.
8  */
9 BOOST_AUTO_TEST_CASE(array_based_order_book_trivial) {
10  using namespace jb::itch5;
11  testing::test_order_book_type_trivial<array_based_order_book>();
12 }
13 
14 /**
15  * @test Verify that array_based_order_book handles add and reduce as expected.
16  */
17 
18 BOOST_AUTO_TEST_CASE(array_based_order_book_test) {
19  using namespace jb::itch5;
20  testing::test_order_book_type_add_reduce<array_based_order_book>();
21 }
22 
23 /**
24  * @test Verify that array_based_order_book handles errors as expected.
25  */
26 BOOST_AUTO_TEST_CASE(array_based_order_book_errors) {
27  using namespace jb::itch5;
28  testing::test_order_book_type_errors<array_based_order_book>();
29  testing::test_order_book_type_errors_spec<array_based_order_book>();
30 }
31 
32 /**
33  * @test Verify that the buy side of array_based_order_book works as
34  * expected.
35  * Test inside changes at the top levels, and one price moved from
36  * bottom to top to become the new inside.
37  */
38 BOOST_AUTO_TEST_CASE(array_based_order_book_buy) {
39  using namespace jb::itch5;
40 
41  const std::size_t ticks = 5000;
44 
45  // Add a new order ...
46  auto r = tested.add_order(price4_t(100000), 100);
47  // .. best quote should change
48  auto actual = tested.best_quote();
49  BOOST_CHECK_EQUAL(actual.first, price4_t(100000));
50  BOOST_CHECK_EQUAL(actual.second, 100);
51  // handler should return true... it is the first price set
52  BOOST_CHECK_EQUAL(r, true);
53  // .. and the book_depth should be incremented
54  BOOST_CHECK_EQUAL(tested.count(), 1);
55 
56  // ... adding below the best bid has no effect ...
57  r = tested.add_order(price4_t(99900), 300);
58  actual = tested.best_quote();
59  BOOST_CHECK_EQUAL(actual.first, price4_t(100000));
60  BOOST_CHECK_EQUAL(actual.second, 100);
61  BOOST_CHECK_EQUAL(r, false);
62  // .. and the book_depth should be incremented
63  BOOST_CHECK_EQUAL(tested.count(), 2);
64 
65  // ... adding below the top_level_ low limit has not effect...
66  r = tested.add_order(price4_t(500), 700);
67  actual = tested.best_quote();
68  BOOST_CHECK_EQUAL(actual.first, price4_t(100000));
69  BOOST_CHECK_EQUAL(actual.second, 100);
70  BOOST_CHECK_EQUAL(r, false);
71  // worst bid is now at the bottom_levels
72  actual = tested.worst_quote();
73  BOOST_CHECK_EQUAL(actual.first, price4_t(500));
74  BOOST_CHECK_EQUAL(actual.second, 700);
75  // .. and the book_depth should be incremented
76  BOOST_CHECK_EQUAL(tested.count(), 3);
77 
78  // ... update at the bid increases the qty ...
79  r = tested.add_order(price4_t(100000), 400);
80  actual = tested.best_quote();
81  BOOST_CHECK_EQUAL(actual.first, price4_t(100000));
82  BOOST_CHECK_EQUAL(actual.second, 500);
83  // ... still change at the bid
84  BOOST_CHECK_EQUAL(r, true);
85  // .. and the book_depth should not be incremented
86  BOOST_CHECK_EQUAL(tested.count(), 3);
87 
88  // ... a better price changes both price and qty ...
89  r = tested.add_order(price4_t(100100), 200);
90  actual = tested.best_quote();
91  BOOST_CHECK_EQUAL(actual.first, price4_t(100100));
92  BOOST_CHECK_EQUAL(actual.second, 200);
93  BOOST_CHECK_EQUAL(r, true); // inside moves up
94  // .. and the book_depth should be incremented
95  BOOST_CHECK_EQUAL(tested.count(), 4);
96 
97  // ... decrease (400 out of 500) below the bid has no effect ...
98  r = tested.reduce_order(price4_t(100000), 400);
99  actual = tested.best_quote();
100  BOOST_CHECK_EQUAL(actual.first, price4_t(100100));
101  BOOST_CHECK_EQUAL(actual.second, 200);
102  BOOST_CHECK_EQUAL(r, false);
103  // .. and the book depth should not be decremented
104  BOOST_CHECK_EQUAL(tested.count(), 4);
105 
106  // ... even when it is over the existing quantity ...
107  // reducing 200 out of 100, count should decrement ...
108  r = tested.reduce_order(price4_t(100000), 200);
109  actual = tested.best_quote();
110  BOOST_CHECK_EQUAL(actual.first, price4_t(100100));
111  BOOST_CHECK_EQUAL(actual.second, 200);
112  BOOST_CHECK_EQUAL(r, false);
113  // .. and the book_depth should be decremented
114  BOOST_CHECK_EQUAL(tested.count(), 3);
115 
116  // ... deleting the best bid uncovers the best price ...
117  r = tested.reduce_order(price4_t(100100), 200);
118  actual = tested.best_quote();
119  BOOST_CHECK_EQUAL(actual.first, price4_t(99900));
120  BOOST_CHECK_EQUAL(actual.second, 300);
121  BOOST_CHECK_EQUAL(r, true);
122  // .. and the book_depth should be decremented
123  BOOST_CHECK_EQUAL(tested.count(), 2);
124 
125  // ... deleting the remaining price takes the book depth to 0
126  r = tested.reduce_order(price4_t(99900), 300);
127  actual = tested.best_quote();
128  // ... it moves one price from the bottom to the top
129  // and it is the new inside now...
130  BOOST_CHECK_EQUAL(actual.first, price4_t(500));
131  BOOST_CHECK_EQUAL(actual.second, 700);
132  BOOST_CHECK_EQUAL(r, true);
133  // .. and the book_depth should be decremented
134  BOOST_CHECK_EQUAL(tested.count(), 1);
135  r = tested.reduce_order(price4_t(500), 700);
136  actual = tested.best_quote();
137  BOOST_CHECK_EQUAL(actual.first, price4_t(0));
138  BOOST_CHECK_EQUAL(actual.second, 0);
139  BOOST_CHECK_EQUAL(r, true);
140  // .. and the book_depth should be decremented
141  BOOST_CHECK_EQUAL(tested.count(), 0);
142 }
143 
144 /**
145  * @test Verity that the sell side of array_based_order_book works as
146  * expected.
147  * Test inside changes at the top levels, and one price moved from
148  * bottom to top to become the new inside.
149  */
150 BOOST_AUTO_TEST_CASE(array_based_order_book_sell) {
151  using namespace jb::itch5;
152 
153  const std::size_t ticks = 5000;
156 
157  // Add a new order ...
158  auto r = tested.add_order(price4_t(100000), 100);
159  // .. the best quote should change
160  auto actual = tested.best_quote();
161  BOOST_CHECK_EQUAL(actual.first, price4_t(100000));
162  BOOST_CHECK_EQUAL(actual.second, 100);
163  BOOST_CHECK_EQUAL(r, true); // first order
164  // .. and the book_depth should be incremented
165  BOOST_CHECK_EQUAL(tested.count(), 1);
166 
167  // ... adding above the best offer has no effect ...
168  r = tested.add_order(price4_t(100100), 300);
169  actual = tested.best_quote();
170  BOOST_CHECK_EQUAL(actual.first, price4_t(100000));
171  BOOST_CHECK_EQUAL(actual.second, 100);
172  BOOST_CHECK_EQUAL(r, false);
173  // .. and the book_depth should be incremented
174  BOOST_CHECK_EQUAL(tested.count(), 2);
175 
176  // ... adding above the top_level_ low limit has not effect...
177  // but count is incremented...
178  r = tested.add_order(price4_t(1000000), 100);
179  actual = tested.best_quote();
180  BOOST_CHECK_EQUAL(actual.first, price4_t(100000));
181  BOOST_CHECK_EQUAL(actual.second, 100);
182  BOOST_CHECK_EQUAL(r, false);
183  // worst bid is now at the bottom_levels
184  actual = tested.worst_quote();
185  BOOST_CHECK_EQUAL(actual.first, price4_t(1000000));
186  BOOST_CHECK_EQUAL(actual.second, 100);
187  // .. and the book_depth should be incremented
188  BOOST_CHECK_EQUAL(tested.count(), 3);
189 
190  // ... update at the offer increases the qty ...
191  r = tested.add_order(price4_t(100000), 400);
192  actual = tested.best_quote();
193  BOOST_CHECK_EQUAL(actual.first, price4_t(100000));
194  BOOST_CHECK_EQUAL(actual.second, 500);
195  // handler should return true... it is an inside change
196  BOOST_CHECK_EQUAL(r, true);
197  // .. and the book_depth should not change
198  BOOST_CHECK_EQUAL(tested.count(), 3);
199 
200  // ... a better price changes both price and qty ...
201  r = tested.add_order(price4_t(99900), 200);
202  actual = tested.best_quote();
203  BOOST_CHECK_EQUAL(actual.first, price4_t(99900));
204  BOOST_CHECK_EQUAL(actual.second, 200);
205  BOOST_CHECK_EQUAL(r, true);
206  // .. and the book_depth should be incremented
207  BOOST_CHECK_EQUAL(tested.count(), 4);
208 
209  // ... decrease above the offer has no effect ...
210  // reduce 400 out of 500, so still same count
211  r = tested.reduce_order(price4_t(100000), 400);
212  actual = tested.best_quote();
213  BOOST_CHECK_EQUAL(actual.first, price4_t(99900));
214  BOOST_CHECK_EQUAL(actual.second, 200);
215  BOOST_CHECK_EQUAL(r, false);
216  // .. and the book_depth should not change
217  BOOST_CHECK_EQUAL(tested.count(), 4);
218 
219  // ... even when it is over the existing quantity ...
220  // but reduce the count
221  r = tested.reduce_order(price4_t(100000), 200);
222  actual = tested.best_quote();
223  BOOST_CHECK_EQUAL(actual.first, price4_t(99900));
224  BOOST_CHECK_EQUAL(actual.second, 200);
225  BOOST_CHECK_EQUAL(r, false);
226  // .. and the book_depth should be incremented
227  BOOST_CHECK_EQUAL(tested.count(), 3);
228 
229  // ... deleting the best offer uncovers the best price ...
230  r = tested.reduce_order(price4_t(99900), 200);
231  actual = tested.best_quote();
232  BOOST_CHECK_EQUAL(actual.first, price4_t(100100));
233  BOOST_CHECK_EQUAL(actual.second, 300);
234  BOOST_CHECK_EQUAL(r, true);
235  // .. and the book_depth should be incremented
236  BOOST_CHECK_EQUAL(tested.count(), 2);
237 
238  // ... deleting the remaining price takes the book depth to 0
239  r = tested.reduce_order(price4_t(100100), 300);
240  actual = tested.best_quote();
241  BOOST_CHECK_EQUAL(actual.first, price4_t(1000000));
242  BOOST_CHECK_EQUAL(actual.second, 100);
243  // handler should return true
244  BOOST_CHECK_EQUAL(r, true);
245  // .. and the book_depth should be decremented
246  BOOST_CHECK_EQUAL(tested.count(), 1);
247 
248  // ... deleting the remaining price takes the book depth to 0
249  r = tested.reduce_order(price4_t(1000000), 100);
250  actual = tested.best_quote();
251  BOOST_CHECK_EQUAL(actual.first, price4_t(200000UL * 10000));
252  BOOST_CHECK_EQUAL(actual.second, 0);
253  // handler should return true
254  BOOST_CHECK_EQUAL(r, true);
255  // .. and the book_depth should be decremented
256  BOOST_CHECK_EQUAL(tested.count(), 0);
257 }
258 
259 /**
260  * @test Verify that the buy side of array_based_order_book works as
261  * expected.
262  * Works adding and removing prices at the limit of top level range
263  * to verify move form and to the bottom level work as expected on those
264  * border cases.
265  */
266 BOOST_AUTO_TEST_CASE(array_based_order_book_buy_range) {
267  using namespace jb::itch5;
268 
269  const std::size_t ticks = 5000;
272 
273  // build a book around $50.00 (limits built around when
274  // first price is added...
275  // top end limit is now 200 * ticks...
276  auto rs = tested.add_order(price4_t(100 * ticks), 100);
277  BOOST_CHECK_EQUAL(rs, true);
278 
279  // now add one better price, inside changes...
280  rs = tested.add_order(price4_t(100 * ticks + 100), 100);
281  BOOST_CHECK_EQUAL(rs, true);
282 
283  // and 3 prices(*) down, nothing changes, but the count..
284  rs = tested.add_order(price4_t(100 * ticks - 100), 100);
285  BOOST_CHECK_EQUAL(rs, false);
286  rs = tested.add_order(price4_t(100 * ticks - 200), 100);
287  BOOST_CHECK_EQUAL(rs, false);
288  rs = tested.add_order(price4_t(100 * ticks - 300), 100);
289  BOOST_CHECK_EQUAL(rs, false);
290  BOOST_CHECK_EQUAL(tested.count(), 5);
291 
292  // change the inside 2 ticks below the limit
293  rs = tested.add_order(price4_t(200 * ticks - 200), 100);
294  BOOST_CHECK_EQUAL(rs, true);
295 
296  // change the inside right below the limit
297  rs = tested.add_order(price4_t(200 * ticks - 100), 100);
298  BOOST_CHECK_EQUAL(rs, true);
299 
300  // change the inside right at the limit (therefore out)
301  // new limits are now 100*tick and 300*tick
302  // the 3 prices (*) are now at the bottom levels (test move_to_bottom)
303  rs = tested.add_order(price4_t(200 * ticks), 100);
304  BOOST_CHECK_EQUAL(rs, true);
305 
306  // change the inside far above the limit
307  // all the prices, but the new inside, are now at the bottom levels
308  // this is in preration to test move_from_botom...
309  rs = tested.add_order(price4_t(1600 * ticks), 100);
310  BOOST_CHECK_EQUAL(rs, true);
311 
312  // add new price, this is the second best price now....
313  rs = tested.add_order(price4_t(200 * ticks + 100), 100);
314  BOOST_CHECK_EQUAL(rs, false);
315 
316  // remove that far above price
317  // new inside is price4_t(200*ticks + 100, previous one)...
318  // prices were moved_from_bottom, some were not.,,
319  rs = tested.reduce_order(price4_t(1600 * ticks), 100);
320  BOOST_CHECK_EQUAL(rs, true);
321 
322  // now remove prices around 200*ticks~... should not move prices...
323  // remove the inside
324  rs = tested.reduce_order(price4_t(200 * ticks + 100), 100);
325  BOOST_CHECK_EQUAL(rs, true);
326  // remove the inside
327  rs = tested.reduce_order(price4_t(200 * ticks), 100);
328  BOOST_CHECK_EQUAL(rs, true);
329  // remove the inside
330  rs = tested.reduce_order(price4_t(200 * ticks - 100), 100);
331  BOOST_CHECK_EQUAL(rs, true);
332 
333  // new inside is right at the bottom of the range...
334  rs = tested.reduce_order(price4_t(200 * ticks - 200), 100);
335  BOOST_CHECK_EQUAL(rs, true);
336 
337  // remove the inside, prices are move from the bottom
338  rs = tested.reduce_order(price4_t(100 * ticks + 100), 100);
339  BOOST_CHECK_EQUAL(rs, true);
340 
341  // remove the last 4 prices
342  rs = tested.reduce_order(price4_t(100 * ticks), 100);
343  BOOST_CHECK_EQUAL(rs, true);
344  rs = tested.reduce_order(price4_t(100 * ticks - 100), 100);
345  BOOST_CHECK_EQUAL(rs, true);
346  rs = tested.reduce_order(price4_t(100 * ticks - 200), 100);
347  BOOST_CHECK_EQUAL(rs, true);
348  rs = tested.reduce_order(price4_t(100 * ticks - 300), 100);
349  BOOST_CHECK_EQUAL(rs, true);
350  BOOST_CHECK_EQUAL(tested.count(), 0);
351 }
352 
353 /**
354  * @test Verify that the buy side of array_based_order_book works as
355  * expected.
356  * Works adding and removing prices at the limit of top level range
357  * to verify move form and to the bottom level work as expected on those
358  * border cases.
359  */
360 BOOST_AUTO_TEST_CASE(array_based_order_book_sell_range) {
361  using namespace jb::itch5;
362 
363  const std::size_t ticks = 5000;
366 
367  BOOST_CHECK_EQUAL(tested.count(), 0);
368  // build a book around 1000*ticks
369  // top levels range is 900*ticks by 1100*ticks
370  auto rs = tested.add_order(price4_t(1000 * ticks), 100);
371  BOOST_CHECK_EQUAL(rs, true);
372 
373  // new inside, same range...
374  rs = tested.add_order(price4_t(1000 * ticks - 100), 100);
375  BOOST_CHECK_EQUAL(rs, true);
376  // a 3 prices(*) to test the move_to_bottom trigger...
377  rs = tested.add_order(price4_t(1000 * ticks + 100), 100);
378  BOOST_CHECK_EQUAL(rs, false);
379  rs = tested.add_order(price4_t(1000 * ticks + 200), 100);
380  BOOST_CHECK_EQUAL(rs, false);
381  rs = tested.add_order(price4_t(1000 * ticks + 300), 100);
382  BOOST_CHECK_EQUAL(rs, false);
383  BOOST_CHECK_EQUAL(tested.count(), 5);
384 
385  // change the inside right below the limit
386  rs = tested.add_order(price4_t(900 * ticks + 100), 100);
387  BOOST_CHECK_EQUAL(rs, true);
388 
389  // change the inside right at the limit
390  // ... limit is excluded so it triggers the move to bottom
391  rs = tested.add_order(price4_t(900 * ticks), 100);
392  BOOST_CHECK_EQUAL(rs, true);
393 
394  // change the inside
395  rs = tested.add_order(price4_t(900 * ticks - 100), 100);
396  BOOST_CHECK_EQUAL(rs, true);
397 
398  // change the inside far above the limit
399  // all prices move to bottom
400  rs = tested.add_order(price4_t(100 * ticks), 100);
401  BOOST_CHECK_EQUAL(rs, true);
402 
403  // add a new price far below
404  // in preparation to test move from bottom
405  rs = tested.add_order(price4_t(1000 * ticks - 300), 100);
406  BOOST_CHECK_EQUAL(rs, false);
407 
408  // add a new price far below
409  rs = tested.add_order(price4_t(900 * ticks - 200), 100);
410  BOOST_CHECK_EQUAL(rs, false);
411 
412  // remove the far above inside
413  // all prices (but 3 prices (*)) are move from bottom back to top levels...
414  rs = tested.reduce_order(price4_t(100 * ticks), 100);
415  BOOST_CHECK_EQUAL(rs, true);
416 
417  // now remove prices around 900*ticks to move the rest of the prices back...
418  // removed the inside
419  rs = tested.reduce_order(price4_t(900 * ticks - 200), 100);
420  BOOST_CHECK_EQUAL(rs, true);
421  // removed the inside
422  rs = tested.reduce_order(price4_t(900 * ticks - 100), 100);
423  BOOST_CHECK_EQUAL(rs, true);
424  // removed the inside
425  rs = tested.reduce_order(price4_t(900 * ticks), 100);
426  BOOST_CHECK_EQUAL(rs, true);
427 
428  // removed the inside, new inside right at the bottom of the range...
429  // the rest of prices are moved from the bottom
430  rs = tested.reduce_order(price4_t(900 * ticks + 100), 100);
431  BOOST_CHECK_EQUAL(rs, true);
432 
433  // removed the inside, new range
434  rs = tested.reduce_order(price4_t(1000 * ticks - 300), 100);
435  BOOST_CHECK_EQUAL(rs, true);
436 
437  // removed the last 5 prices
438  rs = tested.reduce_order(price4_t(1000 * ticks - 100), 100);
439  BOOST_CHECK_EQUAL(rs, true);
440  rs = tested.reduce_order(price4_t(1000 * ticks), 100);
441  BOOST_CHECK_EQUAL(rs, true);
442  rs = tested.reduce_order(price4_t(1000 * ticks + 100), 100);
443  BOOST_CHECK_EQUAL(rs, true);
444  rs = tested.reduce_order(price4_t(1000 * ticks + 200), 100);
445  BOOST_CHECK_EQUAL(rs, true);
446  rs = tested.reduce_order(price4_t(1000 * ticks + 300), 100);
447  BOOST_CHECK_EQUAL(rs, true);
448  BOOST_CHECK_EQUAL(tested.count(), 0);
449 }
450 
451 /**
452  * @test Verify that the buy side of array_based_order_book
453  * works as expected.
454  * Test suite for prices below $1.00. A smaller tick offset is used to
455  * facilitate the tests
456  * Works adding and removing prices at the limit of top level range
457  * to verify move form and to the bottom level work as expected on those
458  * border cases.
459  */
460 BOOST_AUTO_TEST_CASE(array_based_order_book_buy_small_tick) {
461  using namespace jb::itch5;
462 
465 
466  // build a book around 15 cents
467  // top level range is 0c (included) by 30c (excluded)
468  auto rs = tested.add_order(price4_t(1500), 100);
469  BOOST_CHECK_EQUAL(rs, true);
470 
471  rs = tested.add_order(price4_t(1501), 100);
472  BOOST_CHECK_EQUAL(rs, true);
473  rs = tested.add_order(price4_t(1502), 100);
474  BOOST_CHECK_EQUAL(rs, true);
475  rs = tested.add_order(price4_t(1499), 100);
476  BOOST_CHECK_EQUAL(rs, false);
477  rs = tested.add_order(price4_t(1498), 100);
478  BOOST_CHECK_EQUAL(rs, false);
479 
480  // change the inside right below the limit
481  // no prices moved...
482  rs = tested.add_order(price4_t(2998), 100);
483  BOOST_CHECK_EQUAL(rs, true);
484 
485  // change the inside right at the limit
486  // mo prices moved...
487  rs = tested.add_order(price4_t(2999), 100);
488  BOOST_CHECK_EQUAL(rs, true);
489 
490  // change the inside right above the limit
491  // new range is 15c by 45c
492  // .. prices below 15c are moved to the bottom...
493  rs = tested.add_order(price4_t(3000), 100);
494  BOOST_CHECK_EQUAL(rs, true);
495 
496  // change the inside far above the limit
497  // all prices, but the new inside, are moved to the bottom
498  rs = tested.add_order(price4_t(9999), 100);
499  BOOST_CHECK_EQUAL(rs, true);
500 
501  // add order far below
502  rs = tested.add_order(price4_t(3001), 100);
503  BOOST_CHECK_EQUAL(rs, false);
504 
505  // remove the far above inside
506  // new top levels range is 15.01c by 45.01c
507  // so some prices are moved back from bottom levels...
508  rs = tested.reduce_order(price4_t(9999), 100);
509  BOOST_CHECK_EQUAL(rs, true);
510 
511  // remove price to test
512  rs = tested.reduce_order(price4_t(1502), 100);
513  BOOST_CHECK_EQUAL(rs, false);
514  rs = tested.reduce_order(price4_t(2998), 100);
515  BOOST_CHECK_EQUAL(rs, false);
516  // remove the inside
517  rs = tested.reduce_order(price4_t(3001), 100);
518  BOOST_CHECK_EQUAL(rs, true);
519  rs = tested.reduce_order(price4_t(3000), 100);
520  BOOST_CHECK_EQUAL(rs, true);
521  rs = tested.reduce_order(price4_t(2999), 100);
522  BOOST_CHECK_EQUAL(rs, true);
523 
524  // remove inside at the bottom
525  rs = tested.reduce_order(price4_t(1501), 100);
526  BOOST_CHECK_EQUAL(rs, true);
527 
528  // remove last 3 prices
529  rs = tested.reduce_order(price4_t(1500), 100);
530  BOOST_CHECK_EQUAL(rs, true);
531  rs = tested.reduce_order(price4_t(1499), 100);
532  BOOST_CHECK_EQUAL(rs, true);
533  rs = tested.reduce_order(price4_t(1498), 100);
534  BOOST_CHECK_EQUAL(rs, true);
535  BOOST_CHECK_EQUAL(tested.count(), 0);
536 }
537 
538 /**
539  * @test Verify that the buy side of array_based_order_book
540  * works as expected.
541  * Test suite for prices below $1.00. A smaller tick offset is used to
542  * facilitate the tests
543  * Works adding and removing prices at the limit of top level range
544  * to verify move form and to the bottom level work as expected on those
545  * border cases.
546  */
547 BOOST_AUTO_TEST_CASE(array_based_order_book_sell_small_tick) {
548  using namespace jb::itch5;
549 
552 
553  // build a book around 75 cents
554  // top levels range is 60c by 90c
555  auto rs = tested.add_order(price4_t(7500), 100);
556  BOOST_CHECK_EQUAL(rs, true);
557 
558  rs = tested.add_order(price4_t(7501), 100);
559  BOOST_CHECK_EQUAL(rs, false);
560  rs = tested.add_order(price4_t(7502), 100);
561  BOOST_CHECK_EQUAL(rs, false);
562  rs = tested.add_order(price4_t(7499), 100);
563  BOOST_CHECK_EQUAL(rs, true);
564  rs = tested.add_order(price4_t(7498), 100);
565  BOOST_CHECK_EQUAL(rs, true);
566 
567  // change the inside right at the limit
568  rs = tested.add_order(price4_t(6000), 100);
569  BOOST_CHECK_EQUAL(rs, true);
570 
571  // change the inside above the limit
572  rs = tested.add_order(price4_t(5999), 100);
573  BOOST_CHECK_EQUAL(rs, true);
574 
575  // change the inside far above the limit
576  // move all prices, but the new inside, to the bottom levels...
577  rs = tested.add_order(price4_t(989), 100);
578  BOOST_CHECK_EQUAL(rs, true);
579 
580  // add order far below
581  rs = tested.add_order(price4_t(5998), 100);
582  BOOST_CHECK_EQUAL(rs, false);
583 
584  // remove the far above inside
585  // prices are move back from the bottom...
586  rs = tested.reduce_order(price4_t(989), 100);
587  BOOST_CHECK_EQUAL(rs, true);
588 
589  // remove price to test
590  rs = tested.reduce_order(price4_t(5999), 100);
591  BOOST_CHECK_EQUAL(rs, false);
592  rs = tested.reduce_order(price4_t(6000), 100);
593  BOOST_CHECK_EQUAL(rs, false);
594 
595  // remove the inside
596  // the rest of the prices is moved back to the top levels
597  rs = tested.reduce_order(price4_t(5998), 100);
598  BOOST_CHECK_EQUAL(rs, true);
599 
600  rs = tested.reduce_order(price4_t(7498), 100);
601  BOOST_CHECK_EQUAL(rs, true);
602 
603  // remove last 4 prices
604  rs = tested.reduce_order(price4_t(7499), 100);
605  BOOST_CHECK_EQUAL(rs, true);
606  rs = tested.reduce_order(price4_t(7500), 100);
607  BOOST_CHECK_EQUAL(rs, true);
608  rs = tested.reduce_order(price4_t(7501), 100);
609  BOOST_CHECK_EQUAL(rs, true);
610  rs = tested.reduce_order(price4_t(7502), 100);
611  BOOST_CHECK_EQUAL(rs, true);
612  BOOST_CHECK_EQUAL(tested.count(), 0);
613 }
614 
615 /**
616  * @test itch5arrayinside exception generated. Adding test case to fix the
617  * problem.
618  */
619 BOOST_AUTO_TEST_CASE(array_based_order_book_sell_small_tick_bug01) {
620  using namespace jb::itch5;
621 
622  const std::size_t ticks = 5000;
625 
626  // add shares 100 @199999.9900
627  auto rs = tested.add_order(price4_t(1999999900), 100);
628  BOOST_CHECK_EQUAL(rs, true);
629 
630  // add 100 @0.5850
631  rs = tested.add_order(price4_t(5850), 100);
632  BOOST_CHECK_EQUAL(rs, true);
633 
634  // add +100 (200 now) @0.5850
635  rs = tested.add_order(price4_t(5850), 100);
636  BOOST_CHECK_EQUAL(rs, true);
637  // remove shares 100 @199999.9900
638  rs = tested.reduce_order(price4_t(1999999900), 100);
639  BOOST_CHECK_EQUAL(rs, false);
640  // add shares 100 @199999.9900
641  rs = tested.add_order(price4_t(1999999900), 100);
642  BOOST_CHECK_EQUAL(rs, false);
643 
644  // add 100 @0.0130 (px_inside_ now)
645  rs = tested.add_order(price4_t(130), 100);
646  BOOST_CHECK_EQUAL(rs, true);
647 
648  // add 500 @0.0150
649  rs = tested.add_order(price4_t(150), 100);
650  BOOST_CHECK_EQUAL(rs, false);
651  // remove shares 100 @0.5850
652  rs = tested.reduce_order(price4_t(5850), 100);
653  BOOST_CHECK_EQUAL(rs, false);
654 }
655 
656 /**
657  * @test Verify that array_based_order_book::config works as expected.
658  */
659 BOOST_AUTO_TEST_CASE(array_based_order_book_config_simple) {
660  using namespace jb::itch5;
661  BOOST_CHECK_NO_THROW(array_based_order_book::config().validate());
662  BOOST_CHECK_THROW(
664  BOOST_CHECK_NO_THROW(
665  array_based_order_book::config().max_size(3000).validate());
666 }
Contains classes and functions to parse NASDAQ ITCH-5.0 messages, more information about ITCH-5...
BOOST_AUTO_TEST_CASE(array_based_order_book_trivial)
Represent one side of the book.
Configure an array_based_order_book config object.
A simple class to communicate the result of parsing the options.
Definition: usage.hpp:11
bool reduce_order(price4_t px, int qty)
Reduce the quantity for a given price.
bool add_order(price4_t px, int qty)
Add a price and quantity to the side order book.
price_field< std::uint32_t, 10000 > price4_t
Convenience definition for Price(4) fields.