Python implementation of Shin's method for calculating implied probabilities from bookmaker odds
Project description
shin
A Python implementation of Shin's method [1, 2] for calculating implied probabilities from bookmaker odds.
Probabilities calculated in this way have been shown to be more accurate than those obtained by the standard approach of dividing the inverse odds by the booksum [3].
Installation
Requires Python 3.9 or above.
pip install shin
Usage
import shin
shin.calculate_implied_probabilities([2.6, 2.4, 4.3])
[0.37299406033208965, 0.4047794109200184, 0.2222265287474275]
Shin's method assumes there is some unknown proportion of bettors that are insiders, z
, and this proportion along with
the implied probabilities can be estimated using an iterative procedure described in [4].
Diagnostic information from the iterative procedure can be obtained by setting the full_output
argument to True
:
import shin
shin.calculate_implied_probabilities([2.6, 2.4, 4.3], full_output=True)
ShinOptimisationDetails(
implied_probabilities=[0.37299406033208965, 0.4047794109200184, 0.2222265287474275],
iterations=426,
delta=9.667822098435863e-13,
z=0.01694251276407055
)
The returned object contains the following fields:
implied_probablities
iterations
- compare this value to themax_iterations
argument (default =1000
) to check for failed convergencedelta
- the final change inz
for the final iteration. Compare with theconvergence_threshold
argument (default =1e-12
) to assess convergencez
- the estimated proportion of theoretical betting volume coming from insider traders
When there are only two outcomes, z
can be calculated analytically [3]. In this case, the iterations
and
delta
fields of the returned dict
are 0
to reflect this:
import shin
shin.calculate_implied_probabilities([1.5, 2.74], full_output=True)
ShinOptimisationDetails(
implied_probabilities=[0.6508515815085157, 0.3491484184914841],
iterations=0.0,
delta=0.0,
z=0.03172728540646625
)
Note that with two outcomes, Shin's method is equivalent to the Additive Method of [5].
What's New in Version 0.2.0?
The latest version improves support for static typing and includes a breaking change.
Breaking Change To calculate_implied_probabilities()
Signature
All arguments to calculate_implied_probabilities()
other than odds
are now keyword only arguments. This change
simplified declaration of overloads to support typing the function's return value and will allow for more flexibility
in the API.
from shin import calculate_implied_probabilities
# still works
calculate_implied_probabilities([2.0, 2.0])
calculate_implied_probabilities(odds=[2.0, 2.0])
calculate_implied_probabilities([2.0, 2.0], full_output=True)
## also any other combination of passing arguments as keyword args remains the same
# passing any arg other than `odds` as positional is now an error
calculate_implied_probabilibies([2.0, 2.0], 1000) # Error
calculate_implied_probabilities([2.0, 2.0], max_iterations=1000) # OK
calculate_impolied_probabilities([2.0, 2.0], 1000, 1e-12, True) # Error
calculate_implied_probabilities([2.0, 2.0], max_iterations=1000, convergence_threshold=1e-12, full_output=True) # OK
See this commit for more details.
Full Output Type
The full_output
argument now returns a ShinOptimisationDetails
object instead of a dict
. This object is a
dataclass
with the same fields as the dict
that was previously returned.
For the read-only case, the ShinOptimisationDetails
object can be used as a drop-in replacement for the dict
that
was previously returned as it supports __getitem__()
.
This change was introduced to support generic typing of the implied_probabilities
, currently not supported by
TypedDict
in versions of Python < 3.11.
See this and this for more details.
What's New in Version 0.1.0?
The latest version introduces some substantial changes and breaking API changes.
Default Return Value Behaviour
Previously shin.calculate_implied_probabilities
would return a dict
that contained convergence details of the
iterative fitting procedure along with the implied probabilities:
import shin
shin.calculate_implied_probabilities([2.6, 2.4, 4.3])
{'implied_probabilities': [0.37299406033208965,
0.4047794109200184,
0.2222265287474275],
'iterations': 425,
'delta': 9.667822098435863e-13,
'z': 0.01694251276407055}
The default behaviour now is for the function to only return the implied probabilities:
import shin
shin.calculate_implied_probabilities([2.6, 2.4, 4.3])
[0.37299406033208965, 0.4047794109200184, 0.2222265287474275]
The full output can still be had by setting the full_output
argument to True
:
import shin
shin.calculate_implied_probabilities([2.6, 2.4, 4.3], full_output=True)
{'implied_probabilities': [0.37299406033208965,
0.4047794109200184,
0.2222265287474275],
'iterations': 425,
'delta': 9.667822098435863e-13,
'z': 0.01694251276407055}
Passing Mappings
A common scenario is to have a mapping between some selection identifiers and their odds. You can now pass such
mappings to shin.calculate_implied_probabilities
and have a new dict
mapping between the selection identifiers and
their probabilities returned:
import shin
shin.calculate_implied_probabilities({"HOME": 2.6, "AWAY": 2.4, "DRAW": 4.3})
{'HOME': 0.37299406033208965,
'AWAY': 0.4047794109200184,
'DRAW': 0.2222265287474275}
This also works when asking for the full output to be returned:
import shin
shin.calculate_implied_probabilities({"HOME": 2.6, "AWAY": 2.4, "DRAW": 4.3}, full_output=True)
{'implied_probabilities': {'HOME': 0.37299406033208965,
'AWAY': 0.4047794109200184,
'DRAW': 0.2222265287474275},
'iterations': 426,
'delta': 9.667822098435863e-13,
'z': 0.01694251276407055}
Controlling the Optimiser
Starting in version 0.1.0, the iterative procedure is implemented in Rust which provides a considerable performance
boost. If you would like to use the old Python based optimiser use the force_python_optimiser
argument:
import timeit
timeit.timeit(
"shin.calculate_implied_probabilities([2.6, 2.4, 4.3], force_python_optimiser=True)",
setup="import shin",
number=10000
)
3.9101167659973726
import timeit
timeit.timeit(
"shin.calculate_implied_probabilities([2.6, 2.4, 4.3])",
setup="import shin",
number=10000
)
0.14442387002054602
References
[1] H. S. Shin, “Prices of State Contingent Claims with Insider traders, and the Favorite-Longshot Bias”. The Economic Journal, 1992, 102, pp. 426-435.
[2] H. S. Shin, “Measuring the Incidence of Insider Trading in a Market for State-Contingent Claims”. The Economic Journal, 1993, 103(420), pp. 1141-1153.
[3] E. Štrumbelj, "On determining probability forecasts from betting odds". International Journal of Forecasting, 2014, Volume 30, Issue 4, pp. 934-943.
[4] B. Jullien and B. Salanié, "Measuring the Incidence of Insider Trading: A Comment on Shin". The Economic Journal, 1994, 104(427), pp. 1418–1419
[5] S. Clarke, S. Kovalchik, M. Ingram, "Adjusting bookmaker’s odds to allow for overround". American Journal of Sports Science, 2017, Volume 5, Issue 6, pp. 45-49.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
File details
Details for the file shin-0.2.0.tar.gz
.
File metadata
- Download URL: shin-0.2.0.tar.gz
- Upload date:
- Size: 13.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.5.1
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 6d9c935c65ce873a40f88a45308b7074c62155424b72a51e8183d0258623b294 |
|
MD5 | 6cd3e5296a5d3852846729d2c4c77020 |
|
BLAKE2b-256 | 0d37af5790f175120593f0ea36b06000f04bec7ec984b8127ea02df8d24a253b |
File details
Details for the file shin-0.2.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
.
File metadata
- Download URL: shin-0.2.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 989.8 kB
- Tags: PyPy, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.5.1
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 5f23175ed33042e474d928c3908159ab040183061ae7bc1885364815d68cd114 |
|
MD5 | 0ee164e41540a025bb43d8d0a92836df |
|
BLAKE2b-256 | 4c07e9d578cc2de819a01af54354ca2d13683192d46c37b0e0c237add4a198e4 |
File details
Details for the file shin-0.2.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
.
File metadata
- Download URL: shin-0.2.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 989.8 kB
- Tags: PyPy, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.5.1
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 680d29084d2f1f04c3fcaa56066cd8cf773c5152fcb8afcf04bd09a961ba179e |
|
MD5 | 8148a35f1ce617a752c83d647e2af774 |
|
BLAKE2b-256 | 87fe5c5b75229010a36f236443c2dc83018b85480ad80a0544e09f41c4dd2dd0 |
File details
Details for the file shin-0.2.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
.
File metadata
- Download URL: shin-0.2.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 978.8 kB
- Tags: PyPy, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.5.1
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | f6da0b02b02940f201a58ed51b9a5b0c231a0298e5e6f33839af40757defa5c2 |
|
MD5 | c6074494b54fb5acf2803c6861a8bc76 |
|
BLAKE2b-256 | f0ade49e94924fb784657196aca0911054e3c928b9c77f253774c36a25464c6b |
File details
Details for the file shin-0.2.0-cp312-none-win_amd64.whl
.
File metadata
- Download URL: shin-0.2.0-cp312-none-win_amd64.whl
- Upload date:
- Size: 108.0 kB
- Tags: CPython 3.12, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.5.1
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | fe047c8803d0569c8f4ddbac96965d7970547d704ca3be45c14cf64111a0a2e8 |
|
MD5 | 6dfb7014b3d674d0fd8b5ee482585e8a |
|
BLAKE2b-256 | 1579d3d9c8b64d9bad798b908ff18575e4d96e9e956de16d77dd63f069140773 |
File details
Details for the file shin-0.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
.
File metadata
- Download URL: shin-0.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 990.1 kB
- Tags: CPython 3.12, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.5.1
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | af4bce8f65c79055049199471df2cc8489b9c60a27798a40106704658e13cb8d |
|
MD5 | 60c63eda3a0f8ee01679c7688dc13394 |
|
BLAKE2b-256 | 68350e443f24ef7acacbeb524d27118d3e907f69a8d8c587018c22cfc78296c4 |
File details
Details for the file shin-0.2.0-cp312-cp312-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl
.
File metadata
- Download URL: shin-0.2.0-cp312-cp312-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl
- Upload date:
- Size: 416.8 kB
- Tags: CPython 3.12, macOS 10.9+ universal2 (ARM64, x86-64), macOS 10.9+ x86-64, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.5.1
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 9cbb3ff3109582e699c16bc600fcf5c6bc847b9978db98c7dd257a6b05a4c23d |
|
MD5 | 1f7f30eb96bdb033e3aa03587da9c710 |
|
BLAKE2b-256 | b5c4080e004dc8dfb6dda5205c0c8410f01513abe0aaa183afd9b993d2e0db1e |
File details
Details for the file shin-0.2.0-cp311-none-win_amd64.whl
.
File metadata
- Download URL: shin-0.2.0-cp311-none-win_amd64.whl
- Upload date:
- Size: 108.0 kB
- Tags: CPython 3.11, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.5.1
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 44b74066c9e8d5b729e50dad59648721ec5e0a81706b14014a1873807e77b63d |
|
MD5 | 044413032bbac568f59c139f0be9c7e3 |
|
BLAKE2b-256 | f6a1f02b15e2f134bd399d40bcb52ec905687b2f554b798f32ca14cd30441b33 |
File details
Details for the file shin-0.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
.
File metadata
- Download URL: shin-0.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 990.0 kB
- Tags: CPython 3.11, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.5.1
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 6cf67fd0ca062039b4c2723cc826b0d9ce7e78ea31b7c71543941233b9e093e9 |
|
MD5 | 1ed1dbd2635be6f25d9ca18236071e8a |
|
BLAKE2b-256 | 96e8f9a7d1713b00f226a97a992acb824107a539c196b10cd83e9506fc92f55b |
File details
Details for the file shin-0.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
.
File metadata
- Download URL: shin-0.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 978.7 kB
- Tags: CPython 3.11, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.5.1
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 6cb28d4dfe7f01cbade32b72c6eb82e1b8a419e7f8836ed0c1fedf63fd6df329 |
|
MD5 | f0f2705648c48f7665586c68f42349f1 |
|
BLAKE2b-256 | f637f9c7c920c1ce9078d4db915d39ea5423b4b853bda0a68a003a6909623b20 |
File details
Details for the file shin-0.2.0-cp311-cp311-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl
.
File metadata
- Download URL: shin-0.2.0-cp311-cp311-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl
- Upload date:
- Size: 416.8 kB
- Tags: CPython 3.11, macOS 10.9+ universal2 (ARM64, x86-64), macOS 10.9+ x86-64, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.5.1
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 61ad8fa2064b03d3d70f80d9819c4f46375a899633f78e68825fbea919dadec0 |
|
MD5 | c9c533003d609b9a5a1a03834bc20ba7 |
|
BLAKE2b-256 | 3d106e17749fa8289b57418ea902380d938c965137a7531024ecbdbb318ffb31 |
File details
Details for the file shin-0.2.0-cp310-none-win_amd64.whl
.
File metadata
- Download URL: shin-0.2.0-cp310-none-win_amd64.whl
- Upload date:
- Size: 108.0 kB
- Tags: CPython 3.10, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.5.1
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | dd17c13cd58e5c6ad101841448678200c1a70b8065ce6911fe51e05ecef1f673 |
|
MD5 | 49b15398ebb5e854134a20156ad74acb |
|
BLAKE2b-256 | 4a2696f604b269de8902ed46fd65814ebcb8d68a98d438762293bf5185a3abc3 |
File details
Details for the file shin-0.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
.
File metadata
- Download URL: shin-0.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 990.0 kB
- Tags: CPython 3.10, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.5.1
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | f8689cefb6fd95cc9fe839f715b005d33a93a0f770cc16fd4697c34263b3b913 |
|
MD5 | 72ba85ce6cab3143c8362fa32c4a1b6f |
|
BLAKE2b-256 | c5c7530002637a63d3ca0d0cedf8e5a2dc40edefc6275b9dbd38df4b250c0596 |
File details
Details for the file shin-0.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
.
File metadata
- Download URL: shin-0.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 978.7 kB
- Tags: CPython 3.10, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.5.1
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 1335e53c68cbd7eed02a6686e0c312ceb26bee757a05548e6028ab003738317a |
|
MD5 | feddf5c74642b33ecc3c96a755bc6488 |
|
BLAKE2b-256 | 0b3005d748005df087aa435347cb0344f052be1b9be3ff26474b3eeee0c72a17 |
File details
Details for the file shin-0.2.0-cp39-none-win_amd64.whl
.
File metadata
- Download URL: shin-0.2.0-cp39-none-win_amd64.whl
- Upload date:
- Size: 108.0 kB
- Tags: CPython 3.9, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.5.1
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 7f604062b3d425789dec536ea5de0e2d67e9939d715fd0b42795a5266175315a |
|
MD5 | 6fa58f2e2de8ff6e6f10eeab1e172c7e |
|
BLAKE2b-256 | 2b0be6efcffeeaeee472af585f6912f07100f1f9893aef0226789d79906cb860 |
File details
Details for the file shin-0.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
.
File metadata
- Download URL: shin-0.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 989.8 kB
- Tags: CPython 3.9, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.5.1
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 3d796c3470e80b547eb1dda90f3a4991363d8879ed4f92e48fb9228d52571af3 |
|
MD5 | 1c11df00d59d0b6f6a491ff9c2dd7067 |
|
BLAKE2b-256 | 158757e32c27263c64ea5bb48959737fb8468f769320dea9f54a83a94348a579 |
File details
Details for the file shin-0.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
.
File metadata
- Download URL: shin-0.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 978.5 kB
- Tags: CPython 3.9, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.5.1
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | d63ee4f2cddd543b14f86a85d6932ad8d7a5d1839139b165531a2e885a52a28f |
|
MD5 | dff62875c598daa8911117d2b9622d13 |
|
BLAKE2b-256 | b4d15fbcf97c198cb175650b3c7837bdf166605645087a2abaef297c1392d1fe |