There's nothing wrong with estimating p-values using Monte Carlo simulations. There is, however, something wrong with estimating p-values using Monte Carlo simulations
in Excel. It's hard on the soul.
Here's a very simple Monte Carlo script coded in Perl. (You can download a free copy of Perl from
http://www.activeperl.com/.) On a decent machine you should easily be able to run 2,000,000 55-bet trials in a minute or less. You should modify the EDGE, TRIALS, and BOGEY constants to suit your needs.
Code:
#!perl
# Author: ganchrow@sbrforum.com
# a very simple implementation of the
# Monte Carlo method in fixed odds
# sports betting
use strict;
use warnings;
### edit from here ###
use constant EDGE => 0;
use constant TRIALS => 3_000_000;
use constant BOGEY => 0.1572035; # as % of risk amount
### don't edit below this line unless you know what you're doing ###
my @odds_ra = ();
my $total_risk = 0;
while(<>) {
chomp;
my ($us,) = split;
next unless $us;
my $dec = &us2dec($us);
my $prob = (1+EDGE)/$dec;
my $risk = 1/($dec-1);
push @odds_ra, [$prob, $dec, $risk, 1];
$total_risk += $risk;
}
my ($sum,$sumsq,$qualifiers,) = (0.0, 0.0, 0,);
my $pct_bogey = BOGEY * $total_risk ;
foreach my $i ( 1 .. TRIALS) {
my $this_trial_result = 0;
print STDERR "Trial $i\n" if $i%10_000 == 0;
foreach my $j (0 .. $#odds_ra) {
my ($prob, $dec, $risk, $win,) = @{$odds_ra[$j]};
my $r = rand();
my $this_bet_result;
if ($r < $prob) {
# win
$this_bet_result = $win;
} else {
$this_bet_result = -$risk;
}
$this_trial_result += $this_bet_result;
}
print "$this_trial_result\n";
$qualifiers++ if $this_trial_result >= $pct_bogey;
$sum += $this_trial_result;
$sumsq += $this_trial_result*$this_trial_result;
}
my $mean = $sum / TRIALS;
my $stddev = sqrt($sumsq / TRIALS - $mean*$mean);
my $frequency = $qualifiers / TRIALS;
print STDERR "Mean \t$mean\n";
print STDERR "Std. Dev.\t$stddev\n";
print STDERR "Qual \t$frequency\n";
sub us2dec {
my $us = shift;
return (
$us >= 0 ? 1+$us/100 : 1-100/$us
);
}
The script takes a text file of newline separated US-style odds and outputs to STDOUT the results of each of the trials (so you'll want to redirect STDOUT to a file), and to STDERR the mean, variance, and frequency with which the specified bogey (about 15.7% in your example) is reached.
I'll just note that the script uses the Perl built-in rand() function, which has a fairly low periodicity. There's a Perl module available from
CPAN that implements the Mersenne twister pseudorandom number generation algorithm, which can be used a drop-in replacement for rand(). If you're going to be doing any moderately serious Monte Carlo sims and don't feel like coding in C, you should definitely hook that up (although it will slow down your sim). You can even seed it with data from
http://www.random.org. It's about 10 extra lines of code. Let me know if you want it.
The only way to calculate an exact closed-form solution goes, would be to enumerate each of the 2
55 different outcomes, which would of course be completely impractical.
Another possibility would be to break up the 55 bets into manageable tranches of (let's say) 11 bets apiece, enumerate the results for each tranche using, and then determine exact p-values using the binomial distribution. You could then use Fisher's chi-square method to determine a joint significance for the entire data set.
Assuming all bets are independent of one another, then the simplest method would just be to appeal to the Central Limit Theorem. Take the sums of the variances of each bet (betting to win n unit at decimal odds d and edge E, variance would be (1+E)*(d-E-1) * n^2 / (d-1)^2) and then take the square root of that sum to obtain the standard deviation and a z-score. (So for zero-edge and betting to win 1 unit, variance would just be d-1.)
In your example, assuming no edge, we get a standard deviation of about 15.47%. This means your results of ~15.72% is about 1.016 standard devs from breakeven for a p-value of about 15.48% (=1-NORMSDIST(1.016)).