diff --git a/betting_simulator.html b/betting_simulator.html
index df32f24e..ed336685 100644
--- a/betting_simulator.html
+++ b/betting_simulator.html
@@ -28,7 +28,7 @@
});
}]);
- startApp.controller('Page1Controller', ['$scope', 'Notification', function($scope, Notification) {
+ startApp.controller('Page1Controller', ['$scope', 'Notification', '$interval', function($scope, Notification, $interval) {
let precision = 5;
let percentage_fee = new Big(0);//new Big('0.02');
let bet_id_sequence = 0;
@@ -352,7 +352,7 @@
let result = 0;
if (taker_bet.bettor == maker_bet.bettor) {
- Notification.error({message: 'You just matched your own bet. The simple algorithm does not yet account for this, so the results may be incorrect', delay: 10000});
+ //Notification.error({message: 'You just matched your own bet. The simple algorithm does not yet account for this, so the results may be incorrect', delay: 10000});
// let bettor_balances = $scope.account_balances['simple'][taker_bet.account_name];
@@ -434,24 +434,32 @@
simulation_event_log_entry.add_log_message(`pretending we pay the full bet amount of ${new_bet.amount_to_bet.toFixed()} into refundable, so the fake refundable is now ${fake_bettor_balances.refundable_unmatched_bets.toFixed()}`);
}
+ let fake_bettor_balances_for_lays_first = fake_bettor_balances.clone();
+
// run the (filtered) order books -- this returns the lowest balance in refundable_unmatched_bets during the simulation
let backs_minimum_refundable_unmatched_bets = simulate_order_book(bettor_backs, fake_bettor_balances, 'back', simulation_event_log_entry);
fake_bettor_balances.refundable_unmatched_bets = backs_minimum_refundable_unmatched_bets;
- simulation_event_log_entry.add_log_message(`after simulating backs, we reduce our simulated refundable ${fake_bettor_balances.refundable_unmatched_bets.toFixed()} to before simulating lays`);
+ simulation_event_log_entry.add_log_message(`[backs first] after simulating backs, we reduce our simulated refundable ${fake_bettor_balances.refundable_unmatched_bets.toFixed()} to before simulating lays`);
let lays_minimum_refundable_unmatched_bets = simulate_order_book(bettor_lays, fake_bettor_balances, 'lay', simulation_event_log_entry);
fake_bettor_balances.refundable_unmatched_bets = lays_minimum_refundable_unmatched_bets;
- simulation_event_log_entry.add_log_message(`after simulating lays, our simulated refundable is ${fake_bettor_balances.refundable_unmatched_bets.toFixed()}`);
-
-
- // TODO: THIS IS WRONG:
- // let minimum_refundable_unmatched_bets = big_min(backs_minimum_refundable_unmatched_bets, lays_minimum_refundable_unmatched_bets);
- // but so is this:
- //let minimum_refundable_unmatched_bets = backs_minimum_refundable_unmatched_bets.plus(lays_minimum_refundable_unmatched_bets);
- //simulation_event_log_entry.add_log_message(`minimum_refundable_unmatched_bets = ${minimum_refundable_unmatched_bets.toFixed()}`);
- // this should be right:
+ simulation_event_log_entry.add_log_message(`[backs first] after simulating lays, our simulated refundable is ${fake_bettor_balances.refundable_unmatched_bets.toFixed()}`);
let minimum_refundable_unmatched_bets = lays_minimum_refundable_unmatched_bets;
+
+ simulation_event_log_entry.add_log_message(`now simulating in the other order (lays, then backs) to see if we get a different answer`);
+ let lays_first_lays_minimum_refundable_unmatched_bets = simulate_order_book(bettor_lays, fake_bettor_balances_for_lays_first, 'lay', simulation_event_log_entry);
+ fake_bettor_balances_for_lays_first.refundable_unmatched_bets = lays_first_lays_minimum_refundable_unmatched_bets;
+ simulation_event_log_entry.add_log_message(`[lays first] after simulating lays, our simulated refundable is ${fake_bettor_balances_for_lays_first.refundable_unmatched_bets.toFixed()}`);
+ let lays_first_backs_minimum_refundable_unmatched_bets = simulate_order_book(bettor_backs, fake_bettor_balances_for_lays_first, 'back', simulation_event_log_entry);
+ fake_bettor_balances_for_lays_first.refundable_unmatched_bets = lays_first_backs_minimum_refundable_unmatched_bets;
+ simulation_event_log_entry.add_log_message(`[lays first] after simulating backs, we reduce our simulated refundable ${fake_bettor_balances_for_lays_first.refundable_unmatched_bets.toFixed()} to before simulating lays`);
+
+ if (!fake_bettor_balances_for_lays_first.refundable_unmatched_bets.eq(fake_bettor_balances.refundable_unmatched_bets)) {
+ Notification.error({message: `Results differe between backs-first and lays-first: backs-first: ${fake_bettor_balances.refundable_unmatched_bets.toFixed()}, lays-first: ${fake_bettor_balances_for_lays_first.refundable_unmatched_bets.toFixed()}`});
+ }
+
+
if (new_bet)
{
parent_event_log_entry.add_log_message(`At the end of simulation, minimum_refundable was ${minimum_refundable_unmatched_bets.toFixed()}`);
@@ -680,12 +688,69 @@
}
};
- // $scope.place_bet(new Bet("alice", "back", 10, 10, 0));
- // $scope.place_bet(new Bet("bob", "lay", 90, 10, 0));
- // $scope.place_bet(new Bet("alice", "lay", 50, 2, 0));
- // $scope.place_bet(new Bet("bob", "back", 50, 2, 0)); // locked in profit of 40 for alice
- // $scope.place_bet(new Bet("alice", "back", 50, 2, 0));
- // $scope.place_bet(new Bet("bob", "lay", 50, 2, 0));
+ let get_random_int = (min, max) => {
+ min = Math.ceil(min);
+ max = Math.floor(max);
+ return Math.floor(Math.random() * (max - min)) + min;
+ };
+
+ let random_bet_timer = null;
+ let place_random_bet = () => {
+ let back_or_lay = get_random_int(0, 2) == 0 ? 'back' : 'lay';
+ let bettor = all_account_names[get_random_int(0, 2 /* all_account_names.length*/ )];
+ let amount_to_bet = get_random_int(1, 11) * 10;
+ let odds = get_random_int(2,11);
+
+ $scope.place_bet(new Bet(bettor, back_or_lay, amount_to_bet, odds, 0));
+
+ // check global invariants
+ for (var balance_system_name in $scope.account_balances)
+ if ($scope.account_balances.hasOwnProperty(balance_system_name))
+ if ($scope.global_invariant_is_violated(balance_system_name)) {
+ Notification.error({message: `Random bet violated global invariant for ${balance_system_name}`, delay: 10000});
+ $interval.cancel(random_bet_timer);
+ return;
+ }
+
+ // check per-account invariants
+ for (var balance_system_name in $scope.account_balances)
+ if ($scope.account_balances.hasOwnProperty(balance_system_name)) {
+ let balance_system = $scope.account_balances[balance_system_name];
+ for (var account_name in balance_system)
+ if (balance_system.hasOwnProperty(account_name))
+ if ($scope.invariant_is_violated(balance_system_name, account_name)) {
+ Notification.error({message: `Random bet violated account invariant for ${account_name} in ${balance_system_name}`, delay: 10000});
+ $interval.cancel(random_bet_timer);
+ return;
+ }
+ }
+
+ // check matching between accounting systems
+ let simple_balances = $scope.account_balances['simple'];
+ for (var account_name in simple_balances)
+ if (simple_balances.hasOwnProperty(account_name))
+ if ($scope.position_element_is_inconsistent(account_name, 'balance') ||
+ $scope.position_element_is_inconsistent(account_name, 'win') ||
+ $scope.position_element_is_inconsistent(account_name, 'not_win') ||
+ $scope.position_element_is_inconsistent(account_name, 'cancel') ||
+ $scope.position_element_is_inconsistent(account_name, 'not_cancel') ||
+ $scope.position_element_is_inconsistent(account_name, 'refundable_unmatched_bets') ||
+ $scope.position_element_is_inconsistent(account_name, 'fees_paid')) {
+ Notification.error({message: `Random bet from ${bettor} exposed difference between simple and complex accounting system`, delay: 10000});
+ $interval.cancel(random_bet_timer);
+ return;
+ }
+ $scope.clear_event_log();
+ };
+ //random_bet_timer = $interval(place_random_bet, 150);
+
+
+ //$scope.place_bet(new Bet("alice", "back", 10, 10, 0));
+ //$scope.place_bet(new Bet("bob", "lay", 90, 10, 0));
+ //$scope.place_bet(new Bet("alice", "lay", 50, 2, 0));
+ //$scope.place_bet(new Bet("bob", "back", 50, 2, 0)); // locked in profit of 40 for alice
+ //$scope.place_bet(new Bet("alice", "back", 40, 2, 0));
+ //$scope.place_bet(new Bet("bob", "lay", 40, 2, 0));
// $scope.place_bet(new Bet("alice", "back", 100, 2, 0));
// $scope.place_bet(new Bet("alice", "back", 100, 4, 0));
@@ -695,12 +760,6 @@
// $scope.place_bet(new Bet("bob", "lay", 400, 4, 0));
// $scope.place_bet(new Bet("charlie", "lay", 850, 8, 0));
- //$scope.place_bet(new Bet("bob", "lay", 500, 6, 0));
- //$scope.place_bet(new Bet("bob", "lay", 500, 6, 0));
- //$scope.place_bet(new Bet("bob", "lay", 500, 6, 0));
- //$scope.place_bet(new Bet("bob", "lay", 500, 6, 0));
- //$scope.place_bet(new Bet("bob", "lay", 500, 6, 0));
-
//$scope.place_bet(new Bet("alice", "lay", 100, 10, 0));
//$scope.place_bet(new Bet("bob", "back", 900, 10, 0));
//$scope.place_bet(new Bet("alice", "back", 100, 4, 0));