class MutuallyExclusiveCollection

A collection of mutually exclusive odds for different outcomes. Includes methods for sports betting arbitrage. Due to the discrete nature of real-world monetary amounts, there may be small rounding errors.

Public Class Methods

new(mutually_exclusive_outcome_odds) click to toggle source

create a new collection with the given odds @param [Array<FixedOdds>] mutually_exclusive_outcome_odds the odds for all the mutually exclusive outcomes

# File lib/mutually_exclusive_collection.rb, line 9
def initialize mutually_exclusive_outcome_odds
  @mutually_exclusive_outcome_odds = mutually_exclusive_outcome_odds
end

Public Instance Methods

arbitrageable?() click to toggle source

tells if arbitrage is possible for a collection of odds @return [Boolean] true if profit can be made regardless of the outcome, false otherwise

# File lib/mutually_exclusive_collection.rb, line 44
def arbitrageable?
  sum_inverse_outcome < 1
end
bookmakers_return_rate() click to toggle source

the bookmaker’s return rate @return [Number] the bookmaker’s return rate as a percentage

# File lib/mutually_exclusive_collection.rb, line 50
def bookmakers_return_rate
  fs = fractions
  1 - fs.reduce(:*) / fs.reduce(:+) if fs.any?
end
each() { |outcome| ... } click to toggle source
# File lib/mutually_exclusive_collection.rb, line 13
def each
  @mutually_exclusive_outcome_odds.each {|outcome| yield outcome }
end
in_ascending_probability() click to toggle source

the odds in ascending order of probability @return [Array<FixedOdds>] odds in ascending probability

# File lib/mutually_exclusive_collection.rb, line 31
def in_ascending_probability
  sort
end
in_descending_probability() click to toggle source

the odds in descending order of probability @return [Array<FixedOdds>] odds in descending probability

# File lib/mutually_exclusive_collection.rb, line 37
def in_descending_probability
  sort.reverse
end
least_likely() click to toggle source

the least likely of the odds to occur @return [FixedOdds] the least likely odd

# File lib/mutually_exclusive_collection.rb, line 19
def least_likely
  min
end
most_likely() click to toggle source

the most likely of the odds to occur @return [FixedOdds] the most likely odd

# File lib/mutually_exclusive_collection.rb, line 25
def most_likely
  max
end
percentages() click to toggle source

hash of the odds and what percentage of the total stake should go on each @return [Hash<FixedOdds, Number>] hash of odds to percentages

# File lib/mutually_exclusive_collection.rb, line 57
def percentages
  @mutually_exclusive_outcome_odds.each_with_object({}) {|odds, hash| hash[odds] = 1 / odds.fractional_odds / sum_inverse_outcome }
end
profit_on_stake(total_stake) click to toggle source

the profit won given the total stake to distribute @param (see stakes_for_total_stake) @return [Money] the profit that can be made from a total stake

# File lib/mutually_exclusive_collection.rb, line 85
def profit_on_stake total_stake
  total_stake * profit_percentage
end
profit_percentage() click to toggle source

profit percentage available on this arb @return [Number] the percentage profit available on the arb

# File lib/mutually_exclusive_collection.rb, line 91
def profit_percentage
  sum = sum_inverse_outcome
  (1 - sum) / sum
end
stake_to_profit(desired_profit) click to toggle source

the stake needed to win the desired profit @param [Money] desired_profit the profit to gain from arbitrage @return [Money] the stake necessary to realise the desired profit

# File lib/mutually_exclusive_collection.rb, line 78
def stake_to_profit desired_profit
  desired_profit / profit_percentage
end
stakes_for_profit(desired_profit) click to toggle source

hash of the odds and the stakes needed to make the specified profit @param (see stakes_for_total_stake) @return (see stakes_for_total_stake)

# File lib/mutually_exclusive_collection.rb, line 71
def stakes_for_profit desired_profit
  stakes_for_total_stake stake_to_profit desired_profit
end
stakes_for_total_stake(total_stake) click to toggle source

hash of the odds and what stakes to put on each given a total stake @param [Money] total_stake the money to distribute on the outcomes @return [Hash<FixedOdds, Money>] hash of odds to stakes

# File lib/mutually_exclusive_collection.rb, line 64
def stakes_for_total_stake total_stake
  @mutually_exclusive_outcome_odds.each_with_object({}) {|odds, hash| hash[odds] = total_stake / odds.fractional_odds / sum_inverse_outcome }
end

Private Instance Methods

fractions() click to toggle source
# File lib/mutually_exclusive_collection.rb, line 101
def fractions
  @mutually_exclusive_outcome_odds.collect &:fractional_odds
end
sum_inverse_outcome() click to toggle source
# File lib/mutually_exclusive_collection.rb, line 97
def sum_inverse_outcome
  fractions.reduce(0) {|sum, n| sum + Rational(1, n) }
end