Change the rounding used when matching bets to never round, bets are always matched at
exactly the maker's odds.
This commit is contained in:
parent
85b26c6905
commit
93088a204d
6 changed files with 229 additions and 39 deletions
|
|
@ -274,7 +274,7 @@ void_result bet_place_evaluator::do_evaluate(const bet_place_operation& op)
|
|||
}
|
||||
|
||||
// is it possible to match this bet
|
||||
FC_ASSERT(bet_object::get_matching_amount(op.amount_to_bet.amount, op.backer_multiplier, op.back_or_lay) != 0,
|
||||
FC_ASSERT(bet_object::get_exact_matching_amount(op.amount_to_bet.amount, op.backer_multiplier, op.back_or_lay) != 0,
|
||||
"Bet cannot be matched");
|
||||
|
||||
#if 0
|
||||
|
|
|
|||
|
|
@ -1,29 +1,74 @@
|
|||
#include <graphene/chain/betting_market_object.hpp>
|
||||
#include <boost/math/common_factor_rt.hpp>
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
|
||||
/* static */ share_type bet_object::get_matching_amount(share_type bet_amount, bet_multiplier_type backer_multiplier, bet_type back_or_lay)
|
||||
/* static */ share_type bet_object::get_approximate_matching_amount(share_type bet_amount, bet_multiplier_type backer_multiplier, bet_type back_or_lay, bool round_up /* = false */)
|
||||
{
|
||||
fc::uint128_t amount_to_match_128 = bet_amount.value;
|
||||
|
||||
if (back_or_lay == bet_type::back)
|
||||
{
|
||||
amount_to_match_128 *= backer_multiplier - GRAPHENE_BETTING_ODDS_PRECISION;
|
||||
if (round_up)
|
||||
amount_to_match_128 += GRAPHENE_BETTING_ODDS_PRECISION - 1;
|
||||
amount_to_match_128 /= GRAPHENE_BETTING_ODDS_PRECISION;
|
||||
}
|
||||
else
|
||||
{
|
||||
amount_to_match_128 *= GRAPHENE_BETTING_ODDS_PRECISION;
|
||||
if (round_up)
|
||||
amount_to_match_128 += backer_multiplier - GRAPHENE_BETTING_ODDS_PRECISION - 1;
|
||||
amount_to_match_128 /= backer_multiplier - GRAPHENE_BETTING_ODDS_PRECISION;
|
||||
}
|
||||
return amount_to_match_128.to_uint64();
|
||||
}
|
||||
|
||||
share_type bet_object::get_matching_amount() const
|
||||
share_type bet_object::get_approximate_matching_amount(bool round_up /* = false */) const
|
||||
{
|
||||
return get_matching_amount(amount_to_bet.amount, backer_multiplier, back_or_lay);
|
||||
return get_approximate_matching_amount(amount_to_bet.amount, backer_multiplier, back_or_lay, round_up);
|
||||
}
|
||||
|
||||
/* static */ share_type bet_object::get_exact_matching_amount(share_type bet_amount, bet_multiplier_type backer_multiplier, bet_type back_or_lay)
|
||||
{
|
||||
share_type back_ratio;
|
||||
share_type lay_ratio;
|
||||
std::tie(back_ratio, lay_ratio) = get_ratio(backer_multiplier);
|
||||
if (back_or_lay == bet_type::back)
|
||||
return bet_amount / back_ratio * lay_ratio;
|
||||
else
|
||||
return bet_amount / lay_ratio * back_ratio;
|
||||
}
|
||||
|
||||
share_type bet_object::get_exact_matching_amount() const
|
||||
{
|
||||
return get_exact_matching_amount(amount_to_bet.amount, backer_multiplier, back_or_lay);
|
||||
}
|
||||
|
||||
/* static */ std::pair<share_type, share_type> bet_object::get_ratio(bet_multiplier_type backer_multiplier)
|
||||
{
|
||||
share_type gcd = boost::math::gcd<bet_multiplier_type>(GRAPHENE_BETTING_ODDS_PRECISION, backer_multiplier - GRAPHENE_BETTING_ODDS_PRECISION);
|
||||
return std::make_pair(GRAPHENE_BETTING_ODDS_PRECISION / gcd, (backer_multiplier - GRAPHENE_BETTING_ODDS_PRECISION) / gcd);
|
||||
}
|
||||
|
||||
std::pair<share_type, share_type> bet_object::get_ratio() const
|
||||
{
|
||||
return get_ratio(backer_multiplier);
|
||||
}
|
||||
|
||||
share_type bet_object::get_minimum_matchable_amount() const
|
||||
{
|
||||
share_type gcd = boost::math::gcd<bet_multiplier_type>(GRAPHENE_BETTING_ODDS_PRECISION, backer_multiplier - GRAPHENE_BETTING_ODDS_PRECISION);
|
||||
return (back_or_lay == bet_type::back ? GRAPHENE_BETTING_ODDS_PRECISION : backer_multiplier - GRAPHENE_BETTING_ODDS_PRECISION) / gcd;
|
||||
}
|
||||
|
||||
share_type bet_object::get_minimum_matching_amount() const
|
||||
{
|
||||
share_type gcd = boost::math::gcd<bet_multiplier_type>(GRAPHENE_BETTING_ODDS_PRECISION, backer_multiplier - GRAPHENE_BETTING_ODDS_PRECISION);
|
||||
return (back_or_lay == bet_type::lay ? GRAPHENE_BETTING_ODDS_PRECISION : backer_multiplier - GRAPHENE_BETTING_ODDS_PRECISION) / gcd;
|
||||
}
|
||||
|
||||
|
||||
share_type betting_market_position_object::reduce()
|
||||
{
|
||||
share_type additional_not_cancel_balance = std::min(pay_if_payout_condition, pay_if_not_payout_condition);
|
||||
|
|
|
|||
|
|
@ -16,9 +16,13 @@ void database::cancel_bet( const bet_object& bet, bool create_virtual_op )
|
|||
adjust_balance(bet.bettor_id, amount_to_refund); //return unmatched stake + fees
|
||||
//TODO: do special fee accounting as required
|
||||
if (create_virtual_op)
|
||||
push_applied_operation(bet_canceled_operation(bet.bettor_id, bet.id,
|
||||
bet.amount_to_bet,
|
||||
bet.amount_reserved_for_fees));
|
||||
{
|
||||
bet_canceled_operation bet_canceled_virtual_op(bet.bettor_id, bet.id,
|
||||
bet.amount_to_bet,
|
||||
bet.amount_reserved_for_fees);
|
||||
//idump((bet_canceled_virtual_op));
|
||||
push_applied_operation(std::move(bet_canceled_virtual_op));
|
||||
}
|
||||
remove(bet);
|
||||
}
|
||||
|
||||
|
|
@ -55,7 +59,7 @@ void database::validate_betting_market_group_resolutions(const betting_market_gr
|
|||
{
|
||||
const betting_market_object& betting_market = *betting_market_itr;
|
||||
// every betting market in the group tied with resolution
|
||||
idump((betting_market.id)(resolutions));
|
||||
//idump((betting_market.id)(resolutions));
|
||||
assert(resolutions.count(betting_market.id));
|
||||
++betting_market_itr;
|
||||
}
|
||||
|
|
@ -181,7 +185,7 @@ void database::resolve_betting_market_group(const betting_market_group_object& b
|
|||
// pay winning - rake
|
||||
adjust_balance(bettor_id, asset(payout_amounts - rake_amount, betting_market_group.asset_id));
|
||||
// [ROL]
|
||||
idump((payout_amounts)(net_profits.value)(rake_amount.value));
|
||||
//idump((payout_amounts)(net_profits.value)(rake_amount.value));
|
||||
|
||||
push_applied_operation(betting_market_group_resolved_operation(bettor_id,
|
||||
betting_market_group.id,
|
||||
|
|
@ -212,14 +216,17 @@ void database::get_required_deposit_for_bet(const betting_market_object& betting
|
|||
bool maybe_cull_small_bet( database& db, const bet_object& bet_object_to_cull )
|
||||
{
|
||||
/**
|
||||
* There are times when this bet can't be matched (for example, it's now laying a 2:1 bet for
|
||||
* 1 satoshi, so it could only be matched by half a satoshi). Remove these bets from
|
||||
* the books.
|
||||
* There are times when this bet can't be even partially matched at its stated odds
|
||||
* For example, say it's a back bet for 20 satoshis at 1.92 odds (which comes out to 25:23
|
||||
* odds). It's not possible for it to match at exact odds since it's < 25
|
||||
*
|
||||
* Remove these bets from the books to reduce clutter.
|
||||
*/
|
||||
|
||||
if( bet_object_to_cull.get_matching_amount() == 0 )
|
||||
share_type minimum_matchable_amount = bet_object_to_cull.get_minimum_matchable_amount();
|
||||
if (bet_object_to_cull.amount_to_bet.amount < minimum_matchable_amount)
|
||||
{
|
||||
ilog("applied epsilon logic");
|
||||
dlog("culling small bet of ${amount}, smaller than the minimum ${minimum_matchable_amount} at odds ${odds}",
|
||||
("amount", bet_object_to_cull.amount_to_bet.amount)("minimum_matchable_amount", minimum_matchable_amount)("odds", bet_object_to_cull.backer_multiplier));
|
||||
db.cancel_bet(bet_object_to_cull);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -284,11 +291,14 @@ bool bet_was_matched(database& db, const bet_object& bet,
|
|||
|
||||
// generate a virtual "match" op
|
||||
asset asset_amount_bet(amount_bet, bet.amount_to_bet.asset_id);
|
||||
db.push_applied_operation(bet_matched_operation(bet.bettor_id, bet.id, bet.betting_market_id,
|
||||
asset_amount_bet,
|
||||
fee_paid,
|
||||
actual_multiplier,
|
||||
guaranteed_winnings_returned));
|
||||
|
||||
bet_matched_operation bet_matched_virtual_op(bet.bettor_id, bet.id, bet.betting_market_id,
|
||||
asset_amount_bet,
|
||||
fee_paid,
|
||||
actual_multiplier,
|
||||
guaranteed_winnings_returned);
|
||||
//idump((bet_matched_virtual_op));
|
||||
db.push_applied_operation(std::move(bet_matched_virtual_op));
|
||||
|
||||
// update the bet on the books
|
||||
if (asset_amount_bet == bet.amount_to_bet)
|
||||
|
|
@ -328,23 +338,51 @@ int match_bet(database& db, const bet_object& taker_bet, const bet_object& maker
|
|||
assert(taker_bet.back_or_lay != maker_bet.back_or_lay);
|
||||
|
||||
int result = 0;
|
||||
share_type maximum_amount_to_match = taker_bet.get_matching_amount();
|
||||
//idump((taker_bet)(maker_bet));
|
||||
|
||||
if (maximum_amount_to_match <= maker_bet.amount_to_bet.amount)
|
||||
{
|
||||
// we will consume the entire taker bet
|
||||
result |= bet_was_matched(db, taker_bet, taker_bet.amount_to_bet.amount, maximum_amount_to_match, maker_bet.backer_multiplier, true);
|
||||
result |= bet_was_matched(db, maker_bet, maximum_amount_to_match, taker_bet.amount_to_bet.amount, maker_bet.backer_multiplier, true) << 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// we will consume the entire maker bet. Figure out how much of the taker bet we can fill.
|
||||
share_type taker_amount = maker_bet.get_matching_amount();
|
||||
share_type maker_amount = bet_object::get_matching_amount(taker_amount, maker_bet.backer_multiplier, taker_bet.back_or_lay);
|
||||
// using the maker's odds, figure out how much of the maker's bet we would match, rounding down
|
||||
// go ahead and get look up the ratio for the bet (a bet with odds 1.92 will have a ratio 25:23)
|
||||
share_type back_odds_ratio;
|
||||
share_type lay_odds_ratio;
|
||||
std::tie(back_odds_ratio, lay_odds_ratio) = maker_bet.get_ratio();
|
||||
|
||||
result |= bet_was_matched(db, taker_bet, taker_amount, maker_amount, maker_bet.backer_multiplier, true);
|
||||
result |= bet_was_matched(db, maker_bet, maker_amount, taker_amount, maker_bet.backer_multiplier, true) << 1;
|
||||
// and make some shortcuts to get to the maker's and taker's side of the ratio
|
||||
const share_type& maker_odds_ratio = maker_bet.back_or_lay == bet_type::back ? back_odds_ratio : lay_odds_ratio;
|
||||
const share_type& taker_odds_ratio = maker_bet.back_or_lay == bet_type::back ? lay_odds_ratio : back_odds_ratio;
|
||||
//idump((back_odds_ratio)(lay_odds_ratio));
|
||||
//idump((maker_odds_ratio)(taker_odds_ratio));
|
||||
|
||||
// now figure out how much of the maker bet we'll consume. We don't yet know whether the maker or taker
|
||||
// will be the limiting factor.
|
||||
share_type maximum_taker_factor = taker_bet.amount_to_bet.amount / taker_odds_ratio;
|
||||
share_type maximum_maker_factor = maker_bet.amount_to_bet.amount / maker_odds_ratio;
|
||||
share_type maximum_factor = std::min(maximum_taker_factor, maximum_maker_factor);
|
||||
share_type maker_amount_to_match = maximum_factor * maker_odds_ratio;
|
||||
share_type taker_amount_to_match = maximum_factor * taker_odds_ratio;
|
||||
//idump((maker_amount_to_match)(taker_amount_to_match));
|
||||
|
||||
// TODO: analyze whether maximum_maker_amount_to_match can ever be zero here
|
||||
assert(maker_amount_to_match != 0);
|
||||
if (maker_amount_to_match == 0)
|
||||
return 0;
|
||||
|
||||
#ifndef NDEBUG
|
||||
assert(taker_amount_to_match <= taker_bet.amount_to_bet.amount);
|
||||
assert(taker_amount_to_match / taker_odds_ratio * taker_odds_ratio == taker_amount_to_match);
|
||||
{
|
||||
// verify we're getting the odds we expect
|
||||
fc::uint128_t payout_128 = maker_amount_to_match.value;
|
||||
payout_128 += taker_amount_to_match.value;
|
||||
payout_128 *= GRAPHENE_BETTING_ODDS_PRECISION;
|
||||
payout_128 /= maker_bet.back_or_lay == bet_type::back ? maker_amount_to_match.value : taker_amount_to_match.value;
|
||||
assert(payout_128.to_uint64() == maker_bet.backer_multiplier);
|
||||
}
|
||||
#endif
|
||||
|
||||
//idump((taker_amount_to_match)(maker_amount_to_match));
|
||||
|
||||
result |= bet_was_matched(db, taker_bet, taker_amount_to_match, maker_amount_to_match, maker_bet.backer_multiplier, true);
|
||||
result |= bet_was_matched(db, maker_bet, maker_amount_to_match, taker_amount_to_match, maker_bet.backer_multiplier, true) << 1;
|
||||
|
||||
assert(result != 0);
|
||||
return result;
|
||||
|
|
|
|||
|
|
@ -98,8 +98,21 @@ class bet_object : public graphene::db::abstract_object< bet_object >
|
|||
|
||||
bet_type back_or_lay;
|
||||
|
||||
static share_type get_matching_amount(share_type bet_amount, bet_multiplier_type backer_multiplier, bet_type back_or_lay);
|
||||
share_type get_matching_amount() const;
|
||||
static share_type get_approximate_matching_amount(share_type bet_amount, bet_multiplier_type backer_multiplier, bet_type back_or_lay, bool round_up = false);
|
||||
|
||||
// returns the amount of a bet that completely matches this bet
|
||||
share_type get_approximate_matching_amount(bool round_up = false) const;
|
||||
|
||||
static share_type get_exact_matching_amount(share_type bet_amount, bet_multiplier_type backer_multiplier, bet_type back_or_lay);
|
||||
share_type get_exact_matching_amount() const;
|
||||
|
||||
static std::pair<share_type, share_type> get_ratio(bet_multiplier_type backer_multiplier);
|
||||
std::pair<share_type, share_type> get_ratio() const;
|
||||
|
||||
// returns the minimum amount this bet could have that could be matched at these odds
|
||||
share_type get_minimum_matchable_amount() const;
|
||||
// returns the minimum amount another user could bet to match this bet at these odds
|
||||
share_type get_minimum_matching_amount() const;
|
||||
};
|
||||
|
||||
class betting_market_position_object : public graphene::db::abstract_object< betting_market_position_object >
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ binned_order_book bookie_api_impl::get_binned_order_book(graphene::chain::bettin
|
|||
{
|
||||
std::shared_ptr<graphene::chain::database> db = app.chain_database();
|
||||
const auto& bet_odds_idx = db->get_index_type<graphene::chain::bet_object_index>().indices().get<graphene::chain::by_odds>();
|
||||
const chain_parameters& current_params = db->get_global_properties().parameters;
|
||||
|
||||
graphene::chain::bet_multiplier_type bin_size = GRAPHENE_BETTING_ODDS_PRECISION;
|
||||
if (precision > 0)
|
||||
|
|
@ -68,7 +69,8 @@ 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_matching_amount();;
|
||||
current_order_bin.amount_to_bet = current_bin->get_approximate_matching_amount(true /* round up */);
|
||||
//idump((*current_bin)(current_order_bin));
|
||||
if (current_bin->back_or_lay == bet_type::lay)
|
||||
result.aggregated_back_bets.emplace_back(std::move(current_order_bin));
|
||||
else // current_bin is aggregating back positions
|
||||
|
|
@ -91,12 +93,14 @@ binned_order_book bookie_api_impl::get_binned_order_book(graphene::chain::bettin
|
|||
{
|
||||
// if there is no current bin, create one appropriate for the bet we're processing
|
||||
current_bin = graphene::chain::bet_object();
|
||||
|
||||
current_bin->backer_multiplier = (bet_odds_iter->backer_multiplier + bin_size - 1) / bin_size * bin_size;
|
||||
current_bin->amount_to_bet.amount = 0;
|
||||
current_bin->backer_multiplier = std::min<graphene::chain::bet_multiplier_type>(current_bin->backer_multiplier, current_params.max_bet_multiplier);
|
||||
current_bin->back_or_lay = bet_odds_iter->back_or_lay == bet_type::back ? bet_type::lay : bet_type::back;
|
||||
current_bin->amount_to_bet.amount = 0;
|
||||
}
|
||||
|
||||
current_bin->amount_to_bet.amount += bet_odds_iter->get_matching_amount();
|
||||
current_bin->amount_to_bet.amount += bet_odds_iter->get_exact_matching_amount();
|
||||
}
|
||||
if (current_bin)
|
||||
flush_current_bin();
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
#include <graphene/chain/proposal_object.hpp>
|
||||
#include <graphene/chain/betting_market_object.hpp>
|
||||
|
||||
#include <graphene/bookie/bookie_api.hpp>
|
||||
//#include <boost/algorithm/string/replace.hpp>
|
||||
|
||||
using namespace graphene::chain;
|
||||
|
|
@ -144,6 +145,95 @@ BOOST_AUTO_TEST_CASE(simple_bet_win)
|
|||
} FC_LOG_AND_RETHROW()
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(binned_order_books)
|
||||
{
|
||||
try
|
||||
{
|
||||
ACTORS( (alice)(bob) );
|
||||
CREATE_ICE_HOCKEY_BETTING_MARKET();
|
||||
|
||||
graphene::bookie::bookie_api bookie_api(app);
|
||||
|
||||
// give alice and bob 10k each
|
||||
transfer(account_id_type(), alice_id, asset(10000));
|
||||
transfer(account_id_type(), bob_id, asset(10000));
|
||||
|
||||
// place back bets at decimal odds of 1.55, 1.6, 1.65, 1.66, and 1.67
|
||||
place_bet(bob_id, capitals_win_market.id, bet_type::back, asset(100, asset_id_type()), 155 * GRAPHENE_BETTING_ODDS_PRECISION / 100, 2);
|
||||
place_bet(bob_id, capitals_win_market.id, bet_type::back, asset(100, asset_id_type()), 16 * GRAPHENE_BETTING_ODDS_PRECISION / 10, 2);
|
||||
place_bet(bob_id, capitals_win_market.id, bet_type::back, asset(100, asset_id_type()), 165 * GRAPHENE_BETTING_ODDS_PRECISION / 100, 2);
|
||||
place_bet(bob_id, capitals_win_market.id, bet_type::back, asset(100, asset_id_type()), 166 * GRAPHENE_BETTING_ODDS_PRECISION / 100, 2);
|
||||
place_bet(bob_id, capitals_win_market.id, bet_type::back, asset(100, asset_id_type()), 167 * GRAPHENE_BETTING_ODDS_PRECISION / 100, 2);
|
||||
|
||||
const auto& bet_odds_idx = db.get_index_type<bet_object_index>().indices().get<by_odds>();
|
||||
|
||||
auto 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;
|
||||
}
|
||||
|
||||
graphene::bookie::binned_order_book binned_orders_point_one = bookie_api.get_binned_order_book(capitals_win_market.id, 1);
|
||||
idump((binned_orders_point_one));
|
||||
|
||||
// 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
|
||||
BOOST_CHECK_EQUAL(binned_orders_point_one.aggregated_back_bets.size(), 2);
|
||||
BOOST_CHECK_EQUAL(binned_orders_point_one.aggregated_lay_bets.size(), 0);
|
||||
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 */);
|
||||
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, 2);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
place_bet(bob_id, capitals_win_market.id, bet_type::lay, asset(100, asset_id_type()), 155 * GRAPHENE_BETTING_ODDS_PRECISION / 100, 2);
|
||||
place_bet(bob_id, capitals_win_market.id, bet_type::lay, asset(100, asset_id_type()), 16 * GRAPHENE_BETTING_ODDS_PRECISION / 10, 2);
|
||||
place_bet(bob_id, capitals_win_market.id, bet_type::lay, asset(100, asset_id_type()), 165 * GRAPHENE_BETTING_ODDS_PRECISION / 100, 2);
|
||||
place_bet(bob_id, capitals_win_market.id, bet_type::lay, asset(100, asset_id_type()), 166 * GRAPHENE_BETTING_ODDS_PRECISION / 100, 2);
|
||||
place_bet(bob_id, capitals_win_market.id, bet_type::lay, asset(100, asset_id_type()), 167 * GRAPHENE_BETTING_ODDS_PRECISION / 100, 2);
|
||||
|
||||
binned_orders_point_one = bookie_api.get_binned_order_book(capitals_win_market.id, 1);
|
||||
idump((binned_orders_point_one));
|
||||
|
||||
// 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
|
||||
BOOST_CHECK_EQUAL(binned_orders_point_one.aggregated_back_bets.size(), 0);
|
||||
BOOST_CHECK_EQUAL(binned_orders_point_one.aggregated_lay_bets.size(), 2);
|
||||
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 */);
|
||||
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, 2);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
BOOST_CHECK(bet_odds_idx.lower_bound(std::make_tuple(capitals_win_market.id)) == bet_odds_idx.end());
|
||||
|
||||
} FC_LOG_AND_RETHROW()
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( peerplays_sport_create_test )
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue