From 8ef5335a707a1777a245a7a03a2f8238c5b7ca39 Mon Sep 17 00:00:00 2001 From: Eric Frias Date: Thu, 3 May 2018 18:54:04 -0400 Subject: [PATCH] Change the bookie plugin's binned order books to more closely match the behavior of the bet matching algorithm where the taker's bet is now the limiting factor --- libraries/plugins/bookie/bookie_api.cpp | 14 ++++++-------- tests/betting/betting_tests.cpp | 21 +++++++++++++++++++-- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/libraries/plugins/bookie/bookie_api.cpp b/libraries/plugins/bookie/bookie_api.cpp index ce01a99b..798fe474 100644 --- a/libraries/plugins/bookie/bookie_api.cpp +++ b/libraries/plugins/bookie/bookie_api.cpp @@ -61,8 +61,6 @@ binned_order_book bookie_api_impl::get_binned_order_book(graphene::chain::bettin binned_order_book result; // use a bet_object here for convenience. we really only use it to track the amount, odds, and back_or_lay - // note, the current bin is accumulating the matching bets, so it will be of type 'lay' when we're - // binning 'back' bets, and vice versa fc::optional current_bin; auto flush_current_bin = [¤t_bin, &result]() @@ -72,9 +70,9 @@ binned_order_book bookie_api_impl::get_binned_order_book(graphene::chain::bettin order_bin current_order_bin; current_order_bin.backer_multiplier = current_bin->backer_multiplier; - current_order_bin.amount_to_bet = current_bin->get_approximate_matching_amount(true /* round up */); + current_order_bin.amount_to_bet = current_bin->amount_to_bet.amount; //idump((*current_bin)(current_order_bin)); - if (current_bin->back_or_lay == bet_type::lay) + if (current_bin->back_or_lay == bet_type::back) result.aggregated_back_bets.emplace_back(std::move(current_order_bin)); else // current_bin is aggregating back positions result.aggregated_lay_bets.emplace_back(std::move(current_order_bin)); @@ -89,7 +87,7 @@ binned_order_book bookie_api_impl::get_binned_order_book(graphene::chain::bettin ++bet_odds_iter) { if (current_bin && - (bet_odds_iter->back_or_lay == current_bin->back_or_lay /* we have switched from back to lay bets */ || + (bet_odds_iter->back_or_lay != current_bin->back_or_lay /* we have switched from back to lay bets */ || (bet_odds_iter->back_or_lay == bet_type::back ? bet_odds_iter->backer_multiplier > current_bin->backer_multiplier : bet_odds_iter->backer_multiplier < current_bin->backer_multiplier))) flush_current_bin(); @@ -105,19 +103,19 @@ binned_order_book bookie_api_impl::get_binned_order_book(graphene::chain::bettin { current_bin->backer_multiplier = (bet_odds_iter->backer_multiplier + bin_size - 1) / bin_size * bin_size; current_bin->backer_multiplier = std::min(current_bin->backer_multiplier, current_params.max_bet_multiplier); - current_bin->back_or_lay = bet_type::lay; + current_bin->back_or_lay = bet_type::back; } else { current_bin->backer_multiplier = bet_odds_iter->backer_multiplier / bin_size * bin_size; current_bin->backer_multiplier = std::max(current_bin->backer_multiplier, current_params.min_bet_multiplier); - current_bin->back_or_lay = bet_type::back; + current_bin->back_or_lay = bet_type::lay; } current_bin->amount_to_bet.amount = 0; } - current_bin->amount_to_bet.amount += bet_odds_iter->get_exact_matching_amount(); + current_bin->amount_to_bet.amount += bet_odds_iter->amount_to_bet.amount; } if (current_bin) flush_current_bin(); diff --git a/tests/betting/betting_tests.cpp b/tests/betting/betting_tests.cpp index 82d2d80d..e58f4dbb 100644 --- a/tests/betting/betting_tests.cpp +++ b/tests/betting/betting_tests.cpp @@ -356,12 +356,14 @@ BOOST_AUTO_TEST_CASE(binned_order_books) // the binned orders returned should be chosen so that we if we assume those orders are real and we place // matching lay orders, we will completely consume the underlying orders and leave no orders on the books + // + // for the bets bob placed above, we should get: 200 @ 1.6, 300 @ 1.7 BOOST_CHECK_EQUAL(binned_orders_point_one.aggregated_back_bets.size(), 2u); BOOST_CHECK_EQUAL(binned_orders_point_one.aggregated_lay_bets.size(), 0u); for (const graphene::bookie::order_bin& binned_order : binned_orders_point_one.aggregated_back_bets) { // compute the matching lay order - share_type lay_amount = bet_object::get_approximate_matching_amount(binned_order.amount_to_bet, binned_order.backer_multiplier, bet_type::back, false /* round down */); + share_type lay_amount = bet_object::get_approximate_matching_amount(binned_order.amount_to_bet, binned_order.backer_multiplier, bet_type::back, true /* round up */); ilog("Alice is laying with ${lay_amount} at odds ${odds} to match the binned back amount ${back_amount}", ("lay_amount", lay_amount)("odds", binned_order.backer_multiplier)("back_amount", binned_order.amount_to_bet)); place_bet(alice_id, capitals_win_market.id, bet_type::lay, asset(lay_amount, asset_id_type()), binned_order.backer_multiplier); } @@ -377,6 +379,7 @@ BOOST_AUTO_TEST_CASE(binned_order_books) BOOST_CHECK(bet_odds_idx.lower_bound(std::make_tuple(capitals_win_market.id)) == bet_odds_idx.end()); // place lay bets at decimal odds of 1.55, 1.6, 1.65, 1.66, and 1.67 + // these bets will get rounded down, actual amounts are 99, 99, 91, 99, and 67 place_bet(bob_id, capitals_win_market.id, bet_type::lay, asset(100, asset_id_type()), 155 * GRAPHENE_BETTING_ODDS_PRECISION / 100); place_bet(bob_id, capitals_win_market.id, bet_type::lay, asset(100, asset_id_type()), 16 * GRAPHENE_BETTING_ODDS_PRECISION / 10); place_bet(bob_id, capitals_win_market.id, bet_type::lay, asset(100, asset_id_type()), 165 * GRAPHENE_BETTING_ODDS_PRECISION / 100); @@ -388,16 +391,30 @@ BOOST_AUTO_TEST_CASE(binned_order_books) // the binned orders returned should be chosen so that we if we assume those orders are real and we place // matching lay orders, we will completely consume the underlying orders and leave no orders on the books + // + // for the bets bob placed above, we shoudl get 356 @ 1.6, 99 @ 1.5 BOOST_CHECK_EQUAL(binned_orders_point_one.aggregated_back_bets.size(), 0u); BOOST_CHECK_EQUAL(binned_orders_point_one.aggregated_lay_bets.size(), 2u); for (const graphene::bookie::order_bin& binned_order : binned_orders_point_one.aggregated_lay_bets) { // compute the matching lay order - share_type back_amount = bet_object::get_approximate_matching_amount(binned_order.amount_to_bet, binned_order.backer_multiplier, bet_type::lay, false /* round down */); + share_type back_amount = bet_object::get_approximate_matching_amount(binned_order.amount_to_bet, binned_order.backer_multiplier, bet_type::lay, true /* round up */); ilog("Alice is backing with ${back_amount} at odds ${odds} to match the binned lay amount ${lay_amount}", ("back_amount", back_amount)("odds", binned_order.backer_multiplier)("lay_amount", binned_order.amount_to_bet)); place_bet(alice_id, capitals_win_market.id, bet_type::back, asset(back_amount, asset_id_type()), binned_order.backer_multiplier); + + ilog("After alice's bet, order book is:"); + bet_iter = bet_odds_idx.lower_bound(std::make_tuple(capitals_win_market.id)); + while (bet_iter != bet_odds_idx.end() && + bet_iter->betting_market_id == capitals_win_market.id) + { + idump((*bet_iter)); + ++bet_iter; + } + + } + bet_iter = bet_odds_idx.lower_bound(std::make_tuple(capitals_win_market.id)); while (bet_iter != bet_odds_idx.end() && bet_iter->betting_market_id == capitals_win_market.id)