rodders 3.0.1 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -14,3 +14,10 @@ group :development do
14
14
  gem "jeweler", "~> 1.6.4"
15
15
  gem "simplecov"
16
16
  end
17
+
18
+ group :development, :test do
19
+ gem 'debugger'
20
+ end
21
+
22
+ gem 'activesupport'
23
+ gem 'i18n'
data/Gemfile.lock CHANGED
@@ -1,6 +1,17 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
+ activesupport (3.2.8)
5
+ i18n (~> 0.6)
6
+ multi_json (~> 1.0)
7
+ columnize (0.3.6)
8
+ debugger (1.1.3)
9
+ columnize (>= 0.3.1)
10
+ debugger-linecache (~> 1.1.1)
11
+ debugger-ruby_core_source (~> 1.1.2)
12
+ debugger-linecache (1.1.1)
13
+ debugger-ruby_core_source (>= 1.1.1)
14
+ debugger-ruby_core_source (1.1.2)
4
15
  diff-lcs (1.1.3)
5
16
  git (1.2.5)
6
17
  i18n (0.6.0)
@@ -32,7 +43,10 @@ PLATFORMS
32
43
  ruby
33
44
 
34
45
  DEPENDENCIES
46
+ activesupport
35
47
  bundler (~> 1.0.0)
48
+ debugger
49
+ i18n
36
50
  jeweler (~> 1.6.4)
37
51
  money
38
52
  rspec (~> 2.9.0)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.0.1
1
+ 3.1.0
data/lib/fixed_odds.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'money'
2
+ require 'active_support/all'
2
3
 
3
4
  # Represents fixed odds used in gambling and betting. Supports fractional,
4
5
  # moneyline and decimal representations. Can calculate the profit
@@ -58,11 +59,11 @@ class FixedOdds
58
59
  # @return (see FixedOdds.from_s)
59
60
  def FixedOdds.fractional_odds fractional
60
61
  raise %{could not parse "#{fractional}" as fractional odds} unless self.fractional_odds?(fractional)
61
- return new(1.to_r) if fractional == 'evens' or fractional == 'even money'
62
+ return new(1.to_r) if fractional.inquiry.evens? or fractional == 'even money'
62
63
 
63
64
  o = /(?<numerator>\d+)(\/|-to-)(?<denominator>\d+)/.match fractional
64
65
  r = Rational o[:numerator], o[:denominator]
65
- r = r.reciprocal if fractional.end_with? ' on'
66
+ r = 1 / r if fractional.ends_with? ' on'
66
67
  new r
67
68
  end
68
69
 
@@ -80,9 +81,12 @@ class FixedOdds
80
81
  # @return (see FixedOdds.from_s)
81
82
  def FixedOdds.moneyline_odds moneyline
82
83
  raise %{could not parse "#{moneyline}" as moneyline odds} unless self.moneyline_odds?(moneyline)
83
- sign = moneyline[0]
84
- if sign == '+' then new(Rational(moneyline, 100))
85
- else new(Rational(100, -moneyline.to_i))
84
+
85
+ case moneyline[0]
86
+ when '+'
87
+ new(Rational(moneyline, 100))
88
+ else
89
+ new(Rational(100, -moneyline.to_i))
86
90
  end
87
91
  end
88
92
 
@@ -158,14 +162,4 @@ class FixedOdds
158
162
  def <=> other
159
163
  other.fractional_odds <=> @fractional_odds
160
164
  end
161
- end
162
-
163
- class Rational
164
- # calculates the reciprocal
165
- # @example
166
- # Rational(2/3).reciprocal #=> Rational(3/2)
167
- # @return [Rational] the reciprocal
168
- def reciprocal
169
- 1 / self
170
- end
171
165
  end
@@ -4,7 +4,7 @@
4
4
  class MutuallyExclusiveCollection
5
5
  # create a new collection with the given odds
6
6
  # @param [Array<FixedOdds>] mutually_exclusive_outcome_odds the odds for all the mutually exclusive outcomes
7
- def initialize(mutually_exclusive_outcome_odds)
7
+ def initialize mutually_exclusive_outcome_odds
8
8
  @mutually_exclusive_outcome_odds = mutually_exclusive_outcome_odds.sort
9
9
  end
10
10
 
@@ -43,31 +43,27 @@ class MutuallyExclusiveCollection
43
43
  # @return [Number] the bookmaker's return rate as a percentage
44
44
  def bookmakers_return_rate
45
45
  fs = fractions
46
- fs.any? ? 1 - fs.reduce(:*) / fs.reduce(:+) : 0
46
+ 1 - fs.reduce(:*) / fs.reduce(:+) if fs.any?
47
47
  end
48
48
 
49
49
  # hash of the odds and what percentage of the total stake should go on each
50
50
  # @return [Hash<FixedOdds, Number>] hash of odds to percentages
51
51
  def percentages
52
- hash = {}
53
- @mutually_exclusive_outcome_odds.each {|odds| hash[odds] = 1 / odds.fractional_odds / sum_inverse_outcome }
54
- hash
52
+ @mutually_exclusive_outcome_odds.each_with_object({}) {|odds, hash| hash[odds] = 1 / odds.fractional_odds / sum_inverse_outcome }
55
53
  end
56
54
 
57
55
  # hash of the odds and what stakes to put on each given a total stake
58
56
  # @param [Money] total_stake the money to distribute on the outcomes
59
57
  # @return [Hash<FixedOdds, Money>] hash of odds to stakes
60
58
  def stakes_for_total_stake total_stake
61
- hash = {}
62
- @mutually_exclusive_outcome_odds.each {|odds| hash[odds] = total_stake / odds.fractional_odds / sum_inverse_outcome }
63
- hash
59
+ @mutually_exclusive_outcome_odds.each_with_object({}) {|odds, hash| hash[odds] = total_stake / odds.fractional_odds / sum_inverse_outcome }
64
60
  end
65
61
 
66
62
  # hash of the odds and the stakes needed to make the specified profit
67
63
  # @param (see #stakes_for_total_stake)
68
64
  # @return (see #stakes_for_total_stake)
69
65
  def stakes_for_profit desired_profit
70
- stakes_for_total_stake(stake_to_profit(desired_profit))
66
+ stakes_for_total_stake stake_to_profit desired_profit
71
67
  end
72
68
 
73
69
  # the stake needed to win the desired profit
@@ -97,6 +93,6 @@ class MutuallyExclusiveCollection
97
93
  end
98
94
 
99
95
  def fractions
100
- @mutually_exclusive_outcome_odds.collect {|o| o.fractional_odds }
96
+ @mutually_exclusive_outcome_odds.collect &:fractional_odds
101
97
  end
102
98
  end
data/rodders.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "rodders"
8
- s.version = "3.0.1"
8
+ s.version = "3.1.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Nigel Lowry"]
12
- s.date = "2012-05-12"
12
+ s.date = "2012-11-11"
13
13
  s.description = "Converts between fractional, decimal and moneyline odds for betting and gambling. Calculates how much can be won on a given stake."
14
14
  s.email = "nigel-lowry@ultra.eclipse.co.uk"
15
15
  s.extra_rdoc_files = [
@@ -36,7 +36,7 @@ Gem::Specification.new do |s|
36
36
  s.homepage = "http://github.com/nigel-lowry/rodders"
37
37
  s.licenses = ["MIT"]
38
38
  s.require_paths = ["lib"]
39
- s.rubygems_version = "1.8.23"
39
+ s.rubygems_version = "1.8.24"
40
40
  s.summary = "Fixed odds betting library"
41
41
 
42
42
  if s.respond_to? :specification_version then
@@ -44,26 +44,35 @@ Gem::Specification.new do |s|
44
44
 
45
45
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
46
46
  s.add_runtime_dependency(%q<money>, [">= 0"])
47
+ s.add_runtime_dependency(%q<activesupport>, [">= 0"])
48
+ s.add_runtime_dependency(%q<i18n>, [">= 0"])
47
49
  s.add_development_dependency(%q<rspec>, ["~> 2.9.0"])
48
50
  s.add_development_dependency(%q<yard>, ["~> 0.6.0"])
49
51
  s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
50
52
  s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
51
53
  s.add_development_dependency(%q<simplecov>, [">= 0"])
54
+ s.add_development_dependency(%q<debugger>, [">= 0"])
52
55
  else
53
56
  s.add_dependency(%q<money>, [">= 0"])
57
+ s.add_dependency(%q<activesupport>, [">= 0"])
58
+ s.add_dependency(%q<i18n>, [">= 0"])
54
59
  s.add_dependency(%q<rspec>, ["~> 2.9.0"])
55
60
  s.add_dependency(%q<yard>, ["~> 0.6.0"])
56
61
  s.add_dependency(%q<bundler>, ["~> 1.0.0"])
57
62
  s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
58
63
  s.add_dependency(%q<simplecov>, [">= 0"])
64
+ s.add_dependency(%q<debugger>, [">= 0"])
59
65
  end
60
66
  else
61
67
  s.add_dependency(%q<money>, [">= 0"])
68
+ s.add_dependency(%q<activesupport>, [">= 0"])
69
+ s.add_dependency(%q<i18n>, [">= 0"])
62
70
  s.add_dependency(%q<rspec>, ["~> 2.9.0"])
63
71
  s.add_dependency(%q<yard>, ["~> 0.6.0"])
64
72
  s.add_dependency(%q<bundler>, ["~> 1.0.0"])
65
73
  s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
66
74
  s.add_dependency(%q<simplecov>, [">= 0"])
75
+ s.add_dependency(%q<debugger>, [">= 0"])
67
76
  end
68
77
  end
69
78
 
@@ -16,13 +16,13 @@ describe "FixedOdds" do
16
16
  it "does not change the input string with 'against'" do
17
17
  value = '4/1 against'
18
18
  FixedOdds.fractional_odds(value)
19
- value.end_with?('against').should == true
19
+ value.end_with?('against').should be
20
20
  end
21
21
 
22
22
  it "does not modify the input string with 'on'" do
23
23
  value = '4/1 on'
24
24
  FixedOdds.fractional_odds(value)
25
- value.end_with?('on').should == true
25
+ value.end_with?('on').should be
26
26
  end
27
27
 
28
28
  specify { FixedOdds.fractional_odds('4/1 against').should == FixedOdds.fractional_odds('4/1') }
@@ -80,12 +80,12 @@ describe "FixedOdds" do
80
80
  )
81
81
  end
82
82
 
83
- specify { FixedOdds.moneyline_odds('+400').profit_on_stake(Money.parse '£100').should == Money.parse('£400') }
84
- specify { FixedOdds.moneyline_odds('+100').profit_on_stake(Money.parse '£100').should == Money.parse('£100') }
83
+ specify { FixedOdds.moneyline_odds('+400').profit_on_stake('£100'.to_money).should == '£400'.to_money }
84
+ specify { FixedOdds.moneyline_odds('+100').profit_on_stake('£100'.to_money).should == '£100'.to_money }
85
85
 
86
- specify { FixedOdds.moneyline_odds('-400').profit_on_stake(Money.parse '£400').should == Money.parse('£100') }
87
- specify { FixedOdds.moneyline_odds('-100').profit_on_stake(Money.parse '£100').should == Money.parse('£100') }
88
- specify { FixedOdds.moneyline_odds('+100').profit_on_stake(Money.parse '£100').should == Money.parse('£100') }
86
+ specify { FixedOdds.moneyline_odds('-400').profit_on_stake('£400'.to_money).should == '£100'.to_money }
87
+ specify { FixedOdds.moneyline_odds('-100').profit_on_stake('£100'.to_money).should == '£100'.to_money }
88
+ specify { FixedOdds.moneyline_odds('+100').profit_on_stake('£100'.to_money).should == '£100'.to_money }
89
89
  end
90
90
 
91
91
  describe ".decimal_odds" do
@@ -98,9 +98,9 @@ describe "FixedOdds" do
98
98
  )
99
99
  end
100
100
 
101
- specify { FixedOdds.decimal_odds('2').profit_on_stake(Money.parse '£1').should == Money.parse('£1') }
102
- specify { FixedOdds.decimal_odds('5').profit_on_stake(Money.parse '£1').should == Money.parse('£4') }
103
- specify { FixedOdds.decimal_odds('1.25').profit_on_stake(Money.parse '£4').should == Money.parse('£1') }
101
+ specify { FixedOdds.decimal_odds('2').profit_on_stake('£1'.to_money).should == '£1'.to_money }
102
+ specify { FixedOdds.decimal_odds('5').profit_on_stake('£1'.to_money).should == '£4'.to_money }
103
+ specify { FixedOdds.decimal_odds('1.25').profit_on_stake('£4'.to_money).should == '£1'.to_money }
104
104
  end
105
105
 
106
106
  describe ".from_s" do
@@ -25,7 +25,7 @@ describe "MutuallyExclusiveCollection" do
25
25
  @bookmaker = MutuallyExclusiveCollection.new []
26
26
  end
27
27
 
28
- specify { @bookmaker.bookmakers_return_rate.should == 0 }
28
+ specify { @bookmaker.bookmakers_return_rate.should be_nil }
29
29
  end
30
30
 
31
31
  context "decimal odds arbitrage" do
@@ -48,7 +48,7 @@ describe "MutuallyExclusiveCollection" do
48
48
  specify { @bookmaker1.bookmakers_return_rate.should be_within(0.0001).of(0.0534) }
49
49
  specify { @bookmaker2.bookmakers_return_rate.should be_within(0.0001).of(0.0478) }
50
50
 
51
- specify { @bookmaker_vulnerable_to_arbitrage.profit_on_stake(Money.parse '£100').should == Money.parse('£4.63') }
51
+ specify { @bookmaker_vulnerable_to_arbitrage.profit_on_stake('£100'.to_money).should == '£4.63'.to_money }
52
52
  specify { @bookmaker_vulnerable_to_arbitrage.profit_percentage.should be_within(0.001).of(0.046) }
53
53
  end
54
54
 
@@ -64,7 +64,7 @@ describe "MutuallyExclusiveCollection" do
64
64
 
65
65
  specify { @bookmaker_vulnerable_to_arbitrage.should be_arbitrageable }
66
66
  its(:profit_percentage) { should be_within(0.001).of(0.2) }
67
- specify { @bookmaker_vulnerable_to_arbitrage.profit_on_stake(Money.parse '£500').should == Money.parse('£100') }
67
+ specify { @bookmaker_vulnerable_to_arbitrage.profit_on_stake('£500'.to_money).should == '£100'.to_money }
68
68
  end
69
69
 
70
70
  context "more than two mutually exclusive events" do
@@ -96,27 +96,27 @@ describe "MutuallyExclusiveCollection" do
96
96
  total = Money.parse '£500'
97
97
  amounts = @bookmaker_vulnerable_to_arbitrage.stakes_for_total_stake total
98
98
  amounts.should have(3).items
99
- amounts[@odds1].should == Money.parse('£396.14')
100
- amounts[@odds2].should == Money.parse('£73.57')
101
- amounts[@odds3].should == Money.parse('£30.29')
99
+ amounts[@odds1].should == '£396.14'.to_money
100
+ amounts[@odds2].should == '£73.57'.to_money
101
+ amounts[@odds3].should == '£30.29'.to_money
102
102
  amounts.values.reduce(:+).should == total
103
103
  end
104
104
  end
105
105
 
106
- specify { @bookmaker_vulnerable_to_arbitrage.profit_on_stake(Money.parse '£500').should == Money.parse('£14.98') }
106
+ specify { @bookmaker_vulnerable_to_arbitrage.profit_on_stake('£500'.to_money).should == '£14.98'.to_money }
107
107
 
108
108
  describe "#stakes_for_profit" do
109
109
  it "gives the right amounts" do
110
- amounts = @bookmaker_vulnerable_to_arbitrage.stakes_for_profit Money.parse '£750'
110
+ amounts = @bookmaker_vulnerable_to_arbitrage.stakes_for_profit '£750'.to_money
111
111
  amounts.should have(3).items
112
- amounts[@odds1].should == Money.parse('£19833.33')
113
- amounts[@odds2].should == Money.parse('£3683.33')
114
- amounts[@odds3].should == Money.parse('£1516.67')
115
- amounts.values.reduce(:+).should == Money.parse('£25033.33')
112
+ amounts[@odds1].should == '£19833.33'.to_money
113
+ amounts[@odds2].should == '£3683.33'.to_money
114
+ amounts[@odds3].should == '£1516.67'.to_money
115
+ amounts.values.reduce(:+).should == '£25033.33'.to_money
116
116
  end
117
117
  end
118
118
 
119
- specify { @bookmaker_vulnerable_to_arbitrage.stake_to_profit(Money.parse '£750').should == Money.parse('£25033.33') }
119
+ specify { @bookmaker_vulnerable_to_arbitrage.stake_to_profit('£750'.to_money).should == '£25033.33'.to_money }
120
120
  end
121
121
 
122
122
  context "different events with same odds" do
@@ -128,7 +128,7 @@ describe "MutuallyExclusiveCollection" do
128
128
  end
129
129
 
130
130
  specify { @bookmaker_vulnerable_to_arbitrage.should be_arbitrageable }
131
- specify { @bookmaker_vulnerable_to_arbitrage.profit_on_stake(Money.parse '£100').should == Money.parse('£650') }
131
+ specify { @bookmaker_vulnerable_to_arbitrage.profit_on_stake('£100'.to_money).should == '£650'.to_money }
132
132
 
133
133
  describe "#percentages" do
134
134
  it "gives the percentages to put on each bet" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rodders
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.1
4
+ version: 3.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-05-12 00:00:00.000000000 Z
12
+ date: 2012-11-11 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: money
@@ -27,6 +27,38 @@ dependencies:
27
27
  - - ! '>='
28
28
  - !ruby/object:Gem::Version
29
29
  version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: activesupport
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: i18n
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
30
62
  - !ruby/object:Gem::Dependency
31
63
  name: rspec
32
64
  requirement: !ruby/object:Gem::Requirement
@@ -107,6 +139,22 @@ dependencies:
107
139
  - - ! '>='
108
140
  - !ruby/object:Gem::Version
109
141
  version: '0'
142
+ - !ruby/object:Gem::Dependency
143
+ name: debugger
144
+ requirement: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ! '>='
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
+ type: :development
151
+ prerelease: false
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ! '>='
156
+ - !ruby/object:Gem::Version
157
+ version: '0'
110
158
  description: Converts between fractional, decimal and moneyline odds for betting and
111
159
  gambling. Calculates how much can be won on a given stake.
112
160
  email: nigel-lowry@ultra.eclipse.co.uk
@@ -146,7 +194,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
146
194
  version: '0'
147
195
  segments:
148
196
  - 0
149
- hash: -1158855232544155326
197
+ hash: 437333735277840555
150
198
  required_rubygems_version: !ruby/object:Gem::Requirement
151
199
  none: false
152
200
  requirements:
@@ -155,7 +203,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
155
203
  version: '0'
156
204
  requirements: []
157
205
  rubyforge_project:
158
- rubygems_version: 1.8.23
206
+ rubygems_version: 1.8.24
159
207
  signing_key:
160
208
  specification_version: 3
161
209
  summary: Fixed odds betting library