views:

72

answers:

1

I'm creating an online bookmaker odds comparison site for soccer and I'm wondering how to calculate the best odds in Ruby/Rails.

I have two models: fixture and odds

Fixture has home and away teams, and odds model has bookmaker ID, home odds, draw odds and away odds.

I have selections which just stores the selected fixtures/teams in the DB.

I'm thinking of doing it this way where I create an multi-dimensional array of the different bookmakers and then add the fixture_id and 1,2 or 3 for home/draw/away and then use that as the key to add the odds

Something like odds[bookmaker][fixture][1/2/3] = price then add up the odds = count(odds[bookmaker][fixture][1/2/3])?

Is there an easier way? Maybe do it in the DB?

+1  A: 

Without taking performance into account - it's probably not an issue and anyway, we shouldn't optimise for performance until we know we have a problem - I'd say you might introduce a Bookmaker model (if only to store the name) and start making use of ActiveRecord associations. I'd also consider splitting Odds into the three individual result types, which could be more flexible, especially if you want to add more bets later. You might get something like:

class Bookmaker < ActiveRecord::Base
  has_many :odds
end

class Odd < ActiveRecord::Base # good name? Price is almost as common and less likely to be misinterpreted
  belongs_to :fixture
  belongs_to :bookmaker
  # let's assume we use result type = 1/2/3 or maybe :home/:draw/:away
end

class Fixture < ActiveRecord::Base
  has_many :odds
end

What you look to be trying to do is calculate the best price for each result across all bookies making a price on that fixture, or the "overround". If it's less than 100% then a potential arbitrage exists.

class Odd
  named_scope :for_result, lambda { |res_tp| {:conditions => ['type = ?', res_tp]}}
end

class Fixture
  def best_price(res_type)
    # assumes you have odds stored as a percentage
    odds.for_result(res_type).minimum(:pctage)
  end
  def overround
    [:home, :away, :draw].inject(0.0){|sum, res_tp| sum + best_price(res_tp)}
  end
end

I'm sure the above doesn't exactly fit your data, but it might give an idea of how you might go about it.

Mike Woodhouse
I do have a bookmaker model- its the actual getting best odds for multiple bets that is the key.
chris
odds are stored in decimal
chris