rodders 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/lib/FixedOdds.rb +38 -23
- data/rodders.gemspec +3 -4
- data/spec/FixedOdds_spec.rb +34 -30
- metadata +16 -17
- data/lib/Rational.rb +0 -9
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.3.0
|
data/lib/FixedOdds.rb
CHANGED
@@ -11,14 +11,16 @@ class FixedOdds
|
|
11
11
|
|
12
12
|
# creates a new FixedOdds from a string which can be in fractional,
|
13
13
|
# moneyline or decimal format
|
14
|
+
# @note strings like '5' are parsed as decimal odds, not as being
|
15
|
+
# equivalent to '5/1'
|
14
16
|
# @param [String] odds the odds in fractional, moneyline or decimal form
|
15
17
|
# @return [FixedOdds]
|
16
18
|
def FixedOdds.from_s(odds)
|
17
19
|
case
|
18
|
-
when
|
19
|
-
when
|
20
|
-
when
|
21
|
-
else
|
20
|
+
when self.fractional_odds?(odds) then self.fractional_odds odds
|
21
|
+
when self.moneyline_odds?(odds) then self.moneyline_odds odds
|
22
|
+
when self.decimal_odds?(odds) then self.decimal_odds odds
|
23
|
+
else raise ArgumentError, %{could not parse "#{odds}"}
|
22
24
|
end
|
23
25
|
end
|
24
26
|
|
@@ -55,7 +57,7 @@ class FixedOdds
|
|
55
57
|
# @param [String] fractional odds in fractional form
|
56
58
|
# @return (see FixedOdds.from_s)
|
57
59
|
def FixedOdds.fractional_odds(fractional)
|
58
|
-
raise %{could not parse "#{fractional}" as fractional odds} unless
|
60
|
+
raise %{could not parse "#{fractional}" as fractional odds} unless self.fractional_odds?(fractional)
|
59
61
|
return new(Rational('1/1')) if fractional == 'evens' || fractional == 'even money'
|
60
62
|
if /(?<numerator>\d+)(\/|-to-)(?<denominator>\d+)/ =~ fractional then r = Rational("#{numerator}/#{denominator}") end
|
61
63
|
r = r.reciprocal if fractional.end_with? ' on'
|
@@ -71,10 +73,11 @@ class FixedOdds
|
|
71
73
|
# creates a new FixedOdds from moneyline form. Examples are
|
72
74
|
# * +400
|
73
75
|
# * -500
|
76
|
+
# @note (see #from_s)
|
74
77
|
# @param [String] moneyline odds in moneyline form
|
75
78
|
# @return (see FixedOdds.from_s)
|
76
79
|
def FixedOdds.moneyline_odds(moneyline)
|
77
|
-
raise %{could not parse "#{moneyline}" as moneyline odds} unless
|
80
|
+
raise %{could not parse "#{moneyline}" as moneyline odds} unless self.moneyline_odds?(moneyline)
|
78
81
|
sign = moneyline[0]
|
79
82
|
if sign == '+' then new(Rational("#{moneyline}/100"))
|
80
83
|
else new(Rational("100/#{moneyline.to_i.magnitude}"))
|
@@ -87,15 +90,15 @@ class FixedOdds
|
|
87
90
|
# @param [String] decimal odds in decimal form
|
88
91
|
# @return (see FixedOdds.from_s)
|
89
92
|
def FixedOdds.decimal_odds(decimal)
|
90
|
-
raise %{could not parse "#{decimal}" as decimal odds} unless
|
93
|
+
raise %{could not parse "#{decimal}" as decimal odds} unless self.decimal_odds?(decimal)
|
91
94
|
new(Rational(decimal.to_f - 1))
|
92
95
|
end
|
93
96
|
|
94
97
|
# calculates the profit won on a winning bet
|
95
|
-
# @param [
|
98
|
+
# @param [Money] stake the stake
|
96
99
|
# @return [Money] the profit
|
97
100
|
def profit_on_winning_stake(stake)
|
98
|
-
stake
|
101
|
+
stake * @fractional_odds
|
99
102
|
end
|
100
103
|
|
101
104
|
# calculates the total return on a winning bet
|
@@ -103,15 +106,15 @@ class FixedOdds
|
|
103
106
|
# @param (see #profit_on_winning_stake)
|
104
107
|
# @return [Money] the total winnings
|
105
108
|
def total_return_on_winning_stake(stake)
|
106
|
-
profit_on_winning_stake(stake) + stake
|
109
|
+
profit_on_winning_stake(stake) + stake
|
107
110
|
end
|
108
111
|
|
109
112
|
# calculates the magnitude of the stake needed to
|
110
113
|
# win the specified amount in profit
|
111
|
-
# @param [
|
114
|
+
# @param [Money] win the desired profit
|
112
115
|
# @return [Money] the stake required to realise that profit on a winning bet
|
113
116
|
def stake_needed_to_win win
|
114
|
-
win
|
117
|
+
win / @fractional_odds
|
115
118
|
end
|
116
119
|
|
117
120
|
# string representation in fractional form like '4/1'
|
@@ -129,7 +132,7 @@ class FixedOdds
|
|
129
132
|
# string representation in moneyline form
|
130
133
|
# @return [String] moneyline form representation
|
131
134
|
def to_s_moneyline
|
132
|
-
integral_number_with_sign_regex =
|
135
|
+
integral_number_with_sign_regex = '%+d'
|
133
136
|
|
134
137
|
if @fractional_odds > 1.0
|
135
138
|
integral_number_with_sign_regex % (fractional_odds * 100).to_i
|
@@ -141,17 +144,29 @@ class FixedOdds
|
|
141
144
|
# string representation in decimal form
|
142
145
|
# @return [String] decimal form representation
|
143
146
|
def to_s_decimal
|
144
|
-
|
147
|
+
'%g' % (fractional_odds + 1)
|
145
148
|
end
|
146
149
|
|
147
|
-
|
148
|
-
def ==(other)
|
149
|
-
other.fractional_odds == @fractional_odds
|
150
|
-
end
|
150
|
+
protected
|
151
151
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
152
|
+
# equality method
|
153
|
+
def ==(other)
|
154
|
+
other.fractional_odds == @fractional_odds
|
155
|
+
end
|
156
|
+
|
157
|
+
# low odds are those which pay out the most money
|
158
|
+
# on a winning bet and vice-versa
|
159
|
+
def <=>(other)
|
160
|
+
other.fractional_odds <=> @fractional_odds
|
161
|
+
end
|
157
162
|
end
|
163
|
+
|
164
|
+
class Rational
|
165
|
+
# calculates the reciprocal
|
166
|
+
# @example
|
167
|
+
# Rational(2/3).reciprocal #=> Rational(3/2)
|
168
|
+
# @return [Rational] the reciprocal
|
169
|
+
def reciprocal
|
170
|
+
1 / self
|
171
|
+
end
|
172
|
+
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 = "0.
|
8
|
+
s.version = "0.3.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 = "2011-11
|
12
|
+
s.date = "2011-12-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 = [
|
@@ -27,7 +27,6 @@ Gem::Specification.new do |s|
|
|
27
27
|
"VERSION",
|
28
28
|
"lib/FixedOdds.rb",
|
29
29
|
"lib/MutuallyExclusiveCollection.rb",
|
30
|
-
"lib/Rational.rb",
|
31
30
|
"rodders.gemspec",
|
32
31
|
"spec/FixedOdds_spec.rb",
|
33
32
|
"spec/MutuallyExclusiveCollection_spec.rb",
|
@@ -37,7 +36,7 @@ Gem::Specification.new do |s|
|
|
37
36
|
s.homepage = "http://github.com/nigel-lowry/rodders"
|
38
37
|
s.licenses = ["MIT"]
|
39
38
|
s.require_paths = ["lib"]
|
40
|
-
s.rubygems_version = "1.8.
|
39
|
+
s.rubygems_version = "1.8.12"
|
41
40
|
s.summary = "Fixed odds betting library"
|
42
41
|
|
43
42
|
if s.respond_to? :specification_version then
|
data/spec/FixedOdds_spec.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# coding: utf-8
|
1
2
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
3
|
|
3
4
|
describe "FixedOdds" do
|
@@ -5,10 +6,10 @@ describe "FixedOdds" do
|
|
5
6
|
describe "fractional_odds factory" do
|
6
7
|
it "should raise error if not fractional odds" do
|
7
8
|
expect {
|
8
|
-
FixedOdds.fractional_odds '
|
9
|
+
FixedOdds.fractional_odds '5'
|
9
10
|
}.to raise_error(
|
10
11
|
RuntimeError,
|
11
|
-
/could not parse "
|
12
|
+
/could not parse "5" as fractional odds/
|
12
13
|
)
|
13
14
|
end
|
14
15
|
|
@@ -100,26 +101,26 @@ describe "FixedOdds" do
|
|
100
101
|
end
|
101
102
|
|
102
103
|
describe "positive figures" do
|
103
|
-
it "should treat '+400' as meaning winning
|
104
|
+
it "should treat '+400' as meaning winning £400 on a £100 bet" do
|
104
105
|
plus400 = FixedOdds.moneyline_odds('+400')
|
105
|
-
plus400.profit_on_winning_stake(
|
106
|
+
plus400.profit_on_winning_stake(Money.from_fixnum(100, :GBP)).should == Money.from_fixnum(400, :GBP)
|
106
107
|
end
|
107
108
|
|
108
|
-
it "should treat +100 as meaning winning
|
109
|
+
it "should treat +100 as meaning winning £100 on a £100 bet" do
|
109
110
|
plus100 = FixedOdds.moneyline_odds('+100')
|
110
|
-
plus100.profit_on_winning_stake(
|
111
|
+
plus100.profit_on_winning_stake(Money.from_fixnum(100, :GBP)).should == Money.from_fixnum(100, :GBP)
|
111
112
|
end
|
112
113
|
end
|
113
114
|
|
114
115
|
describe "negative figures" do
|
115
|
-
it "should treat '-400' as meaning you need to wager
|
116
|
+
it "should treat '-400' as meaning you need to wager £400 to win £100" do
|
116
117
|
minus400 = FixedOdds.moneyline_odds('-400')
|
117
|
-
minus400.profit_on_winning_stake(
|
118
|
+
minus400.profit_on_winning_stake(Money.from_fixnum(400, :GBP)).should == Money.from_fixnum(100, :GBP)
|
118
119
|
end
|
119
120
|
|
120
|
-
it "should treat '-100' as meaning you need to wager
|
121
|
+
it "should treat '-100' as meaning you need to wager £100 to win £100 (which is identical to '+100')" do
|
121
122
|
minus100 = FixedOdds.moneyline_odds('-100')
|
122
|
-
minus100.profit_on_winning_stake(
|
123
|
+
minus100.profit_on_winning_stake(Money.from_fixnum(100, :GBP)).should == Money.from_fixnum(100, :GBP)
|
123
124
|
end
|
124
125
|
end
|
125
126
|
end
|
@@ -134,19 +135,19 @@ describe "FixedOdds" do
|
|
134
135
|
)
|
135
136
|
end
|
136
137
|
|
137
|
-
it "should treat '2' as meaning you have to wager
|
138
|
+
it "should treat '2' as meaning you have to wager £100 to win £100" do
|
138
139
|
d2 = FixedOdds.decimal_odds('2')
|
139
|
-
d2.profit_on_winning_stake(
|
140
|
+
d2.profit_on_winning_stake(Money.from_fixnum(100, :GBP)).should == Money.from_fixnum(100, :GBP)
|
140
141
|
end
|
141
142
|
|
142
|
-
it "should treat '5' as meaning you have to wager
|
143
|
+
it "should treat '5' as meaning you have to wager £100 to win £400" do
|
143
144
|
d5 = FixedOdds.decimal_odds('5')
|
144
|
-
d5.profit_on_winning_stake(
|
145
|
+
d5.profit_on_winning_stake(Money.from_fixnum(100, :GBP)).should == Money.from_fixnum(400, :GBP)
|
145
146
|
end
|
146
147
|
|
147
|
-
it "should treat '1.25' as meaning yo have to wager
|
148
|
+
it "should treat '1.25' as meaning yo have to wager £400 to win £100" do
|
148
149
|
d1_25 = FixedOdds.decimal_odds('1.25')
|
149
|
-
d1_25.profit_on_winning_stake(
|
150
|
+
d1_25.profit_on_winning_stake(Money.from_fixnum(400, :GBP)).should == Money.from_fixnum(100, :GBP)
|
150
151
|
end
|
151
152
|
end
|
152
153
|
|
@@ -224,8 +225,11 @@ describe "FixedOdds" do
|
|
224
225
|
end
|
225
226
|
|
226
227
|
describe "decimal odds" do
|
227
|
-
it "should parse integral odds" do
|
228
|
-
|
228
|
+
it "should parse integral odds of '2' as decimal odds, not as fractional odds of '2/1'" do
|
229
|
+
decimal_odds_2 = FixedOdds.from_s('2')
|
230
|
+
|
231
|
+
decimal_odds_2.should == FixedOdds.decimal_odds('2')
|
232
|
+
decimal_odds_2.should_not == FixedOdds.fractional_odds('2/1')
|
229
233
|
end
|
230
234
|
|
231
235
|
it "should parse floating-point odds" do
|
@@ -345,38 +349,38 @@ describe "FixedOdds" do
|
|
345
349
|
end
|
346
350
|
|
347
351
|
describe "#profit_on_winning_stake" do
|
348
|
-
it "should return a profit of
|
352
|
+
it "should return a profit of £400 on a £100 stake on a 4/1 bet" do
|
349
353
|
fourToOne = FixedOdds.fractional_odds '4/1'
|
350
|
-
fourToOne.profit_on_winning_stake(
|
354
|
+
fourToOne.profit_on_winning_stake(Money.from_fixnum(100, :GBP)).should == Money.from_fixnum(400, :GBP)
|
351
355
|
end
|
352
356
|
|
353
|
-
it "should return a profit of
|
357
|
+
it "should return a profit of £25 on a £100 stake with a 1/4 bet" do
|
354
358
|
oneToFour = FixedOdds.fractional_odds '1/4'
|
355
|
-
oneToFour.profit_on_winning_stake(
|
359
|
+
oneToFour.profit_on_winning_stake(Money.from_fixnum(100, :GBP)).should == Money.from_fixnum(25, :GBP)
|
356
360
|
end
|
357
361
|
end
|
358
362
|
|
359
363
|
describe "#total_return_on_winning_stake" do
|
360
|
-
it "should show that the full amount back on a winning 4/1 bet with a
|
364
|
+
it "should show that the full amount back on a winning 4/1 bet with a £100 stake is £500" do
|
361
365
|
fourToOne = FixedOdds.fractional_odds '4/1'
|
362
|
-
fourToOne.total_return_on_winning_stake(
|
366
|
+
fourToOne.total_return_on_winning_stake(Money.from_fixnum(100, :GBP)).should == Money.from_fixnum(500, :GBP)
|
363
367
|
end
|
364
368
|
|
365
|
-
it "should show that the full amount back on a winning 1/4 bet with a
|
369
|
+
it "should show that the full amount back on a winning 1/4 bet with a £100 stake is £125" do
|
366
370
|
oneToFour = FixedOdds.fractional_odds '1/4'
|
367
|
-
oneToFour.total_return_on_winning_stake(
|
371
|
+
oneToFour.total_return_on_winning_stake(Money.from_fixnum(100, :GBP)).should == Money.from_fixnum(125, :GBP)
|
368
372
|
end
|
369
373
|
end
|
370
374
|
|
371
375
|
describe "#stake_needed_to_win" do
|
372
|
-
it "should be
|
376
|
+
it "should be £1 on a 1/1 to win £1" do
|
373
377
|
oneToOne = FixedOdds.fractional_odds '1/1'
|
374
|
-
oneToOne.stake_needed_to_win(
|
378
|
+
oneToOne.stake_needed_to_win(Money.from_fixnum(1, :GBP)).should == Money.from_fixnum(1, :GBP)
|
375
379
|
end
|
376
380
|
|
377
|
-
it "should be
|
381
|
+
it "should be £100 on 4/1 to win £400" do
|
378
382
|
fourToOne = FixedOdds.fractional_odds '4/1'
|
379
|
-
fourToOne.stake_needed_to_win(
|
383
|
+
fourToOne.stake_needed_to_win(Money.from_fixnum(400, :GBP)).should == Money.from_fixnum(100, :GBP)
|
380
384
|
end
|
381
385
|
end
|
382
386
|
|
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: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-11
|
12
|
+
date: 2011-12-11 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: money
|
16
|
-
requirement: &
|
16
|
+
requirement: &70347044732340 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70347044732340
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rspec
|
27
|
-
requirement: &
|
27
|
+
requirement: &70347044731860 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: 2.3.0
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70347044731860
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: yard
|
38
|
-
requirement: &
|
38
|
+
requirement: &70347044731320 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: 0.6.0
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70347044731320
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: bundler
|
49
|
-
requirement: &
|
49
|
+
requirement: &70347044730800 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ~>
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: 1.0.0
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70347044730800
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: jeweler
|
60
|
-
requirement: &
|
60
|
+
requirement: &70347044730320 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ~>
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: 1.6.4
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *70347044730320
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: rcov
|
71
|
-
requirement: &
|
71
|
+
requirement: &70347044729800 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ! '>='
|
@@ -76,7 +76,7 @@ dependencies:
|
|
76
76
|
version: '0'
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *70347044729800
|
80
80
|
description: Converts between fractional, decimal and moneyline odds for betting and
|
81
81
|
gambling. Calculates how much can be won on a given stake.
|
82
82
|
email: nigel-lowry@ultra.eclipse.co.uk
|
@@ -96,7 +96,6 @@ files:
|
|
96
96
|
- VERSION
|
97
97
|
- lib/FixedOdds.rb
|
98
98
|
- lib/MutuallyExclusiveCollection.rb
|
99
|
-
- lib/Rational.rb
|
100
99
|
- rodders.gemspec
|
101
100
|
- spec/FixedOdds_spec.rb
|
102
101
|
- spec/MutuallyExclusiveCollection_spec.rb
|
@@ -117,7 +116,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
117
116
|
version: '0'
|
118
117
|
segments:
|
119
118
|
- 0
|
120
|
-
hash:
|
119
|
+
hash: 2781179272829975536
|
121
120
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
122
121
|
none: false
|
123
122
|
requirements:
|
@@ -126,7 +125,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
126
125
|
version: '0'
|
127
126
|
requirements: []
|
128
127
|
rubyforge_project:
|
129
|
-
rubygems_version: 1.8.
|
128
|
+
rubygems_version: 1.8.12
|
130
129
|
signing_key:
|
131
130
|
specification_version: 3
|
132
131
|
summary: Fixed odds betting library
|