Skip to main content

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 the max_iterations argument (default = 1000) to check for failed convergence
  • delta - the final change in z for the final iteration. Compare with the convergence_threshold argument (default = 1e-12) to assess convergence
  • z - 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

shin-0.2.0.tar.gz (13.1 kB view details)

Uploaded Source

Built Distributions

shin-0.2.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (989.8 kB view details)

Uploaded PyPy manylinux: glibc 2.17+ x86-64

shin-0.2.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (989.8 kB view details)

Uploaded PyPy manylinux: glibc 2.17+ x86-64

shin-0.2.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (978.8 kB view details)

Uploaded PyPy manylinux: glibc 2.17+ ARM64

shin-0.2.0-cp312-none-win_amd64.whl (108.0 kB view details)

Uploaded CPython 3.12 Windows x86-64

shin-0.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (990.1 kB view details)

Uploaded CPython 3.12 manylinux: glibc 2.17+ x86-64

shin-0.2.0-cp312-cp312-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl (416.8 kB view details)

Uploaded CPython 3.12 macOS 10.9+ universal2 (ARM64, x86-64) macOS 10.9+ x86-64 macOS 11.0+ ARM64

shin-0.2.0-cp311-none-win_amd64.whl (108.0 kB view details)

Uploaded CPython 3.11 Windows x86-64

shin-0.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (990.0 kB view details)

Uploaded CPython 3.11 manylinux: glibc 2.17+ x86-64

shin-0.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (978.7 kB view details)

Uploaded CPython 3.11 manylinux: glibc 2.17+ ARM64

shin-0.2.0-cp311-cp311-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl (416.8 kB view details)

Uploaded CPython 3.11 macOS 10.9+ universal2 (ARM64, x86-64) macOS 10.9+ x86-64 macOS 11.0+ ARM64

shin-0.2.0-cp310-none-win_amd64.whl (108.0 kB view details)

Uploaded CPython 3.10 Windows x86-64

shin-0.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (990.0 kB view details)

Uploaded CPython 3.10 manylinux: glibc 2.17+ x86-64

shin-0.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (978.7 kB view details)

Uploaded CPython 3.10 manylinux: glibc 2.17+ ARM64

shin-0.2.0-cp39-none-win_amd64.whl (108.0 kB view details)

Uploaded CPython 3.9 Windows x86-64

shin-0.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (989.8 kB view details)

Uploaded CPython 3.9 manylinux: glibc 2.17+ x86-64

shin-0.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (978.5 kB view details)

Uploaded CPython 3.9 manylinux: glibc 2.17+ ARM64

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

Hashes for shin-0.2.0.tar.gz
Algorithm Hash digest
SHA256 6d9c935c65ce873a40f88a45308b7074c62155424b72a51e8183d0258623b294
MD5 6cd3e5296a5d3852846729d2c4c77020
BLAKE2b-256 0d37af5790f175120593f0ea36b06000f04bec7ec984b8127ea02df8d24a253b

See more details on using hashes here.

File details

Details for the file shin-0.2.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for shin-0.2.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 5f23175ed33042e474d928c3908159ab040183061ae7bc1885364815d68cd114
MD5 0ee164e41540a025bb43d8d0a92836df
BLAKE2b-256 4c07e9d578cc2de819a01af54354ca2d13683192d46c37b0e0c237add4a198e4

See more details on using hashes here.

File details

Details for the file shin-0.2.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for shin-0.2.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 680d29084d2f1f04c3fcaa56066cd8cf773c5152fcb8afcf04bd09a961ba179e
MD5 8148a35f1ce617a752c83d647e2af774
BLAKE2b-256 87fe5c5b75229010a36f236443c2dc83018b85480ad80a0544e09f41c4dd2dd0

See more details on using hashes here.

File details

Details for the file shin-0.2.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for shin-0.2.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 f6da0b02b02940f201a58ed51b9a5b0c231a0298e5e6f33839af40757defa5c2
MD5 c6074494b54fb5acf2803c6861a8bc76
BLAKE2b-256 f0ade49e94924fb784657196aca0911054e3c928b9c77f253774c36a25464c6b

See more details on using hashes here.

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

Hashes for shin-0.2.0-cp312-none-win_amd64.whl
Algorithm Hash digest
SHA256 fe047c8803d0569c8f4ddbac96965d7970547d704ca3be45c14cf64111a0a2e8
MD5 6dfb7014b3d674d0fd8b5ee482585e8a
BLAKE2b-256 1579d3d9c8b64d9bad798b908ff18575e4d96e9e956de16d77dd63f069140773

See more details on using hashes here.

File details

Details for the file shin-0.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for shin-0.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 af4bce8f65c79055049199471df2cc8489b9c60a27798a40106704658e13cb8d
MD5 60c63eda3a0f8ee01679c7688dc13394
BLAKE2b-256 68350e443f24ef7acacbeb524d27118d3e907f69a8d8c587018c22cfc78296c4

See more details on using hashes here.

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

File hashes

Hashes for shin-0.2.0-cp312-cp312-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 9cbb3ff3109582e699c16bc600fcf5c6bc847b9978db98c7dd257a6b05a4c23d
MD5 1f7f30eb96bdb033e3aa03587da9c710
BLAKE2b-256 b5c4080e004dc8dfb6dda5205c0c8410f01513abe0aaa183afd9b993d2e0db1e

See more details on using hashes here.

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

Hashes for shin-0.2.0-cp311-none-win_amd64.whl
Algorithm Hash digest
SHA256 44b74066c9e8d5b729e50dad59648721ec5e0a81706b14014a1873807e77b63d
MD5 044413032bbac568f59c139f0be9c7e3
BLAKE2b-256 f6a1f02b15e2f134bd399d40bcb52ec905687b2f554b798f32ca14cd30441b33

See more details on using hashes here.

File details

Details for the file shin-0.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for shin-0.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 6cf67fd0ca062039b4c2723cc826b0d9ce7e78ea31b7c71543941233b9e093e9
MD5 1ed1dbd2635be6f25d9ca18236071e8a
BLAKE2b-256 96e8f9a7d1713b00f226a97a992acb824107a539c196b10cd83e9506fc92f55b

See more details on using hashes here.

File details

Details for the file shin-0.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for shin-0.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 6cb28d4dfe7f01cbade32b72c6eb82e1b8a419e7f8836ed0c1fedf63fd6df329
MD5 f0f2705648c48f7665586c68f42349f1
BLAKE2b-256 f637f9c7c920c1ce9078d4db915d39ea5423b4b853bda0a68a003a6909623b20

See more details on using hashes here.

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

File hashes

Hashes for shin-0.2.0-cp311-cp311-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 61ad8fa2064b03d3d70f80d9819c4f46375a899633f78e68825fbea919dadec0
MD5 c9c533003d609b9a5a1a03834bc20ba7
BLAKE2b-256 3d106e17749fa8289b57418ea902380d938c965137a7531024ecbdbb318ffb31

See more details on using hashes here.

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

Hashes for shin-0.2.0-cp310-none-win_amd64.whl
Algorithm Hash digest
SHA256 dd17c13cd58e5c6ad101841448678200c1a70b8065ce6911fe51e05ecef1f673
MD5 49b15398ebb5e854134a20156ad74acb
BLAKE2b-256 4a2696f604b269de8902ed46fd65814ebcb8d68a98d438762293bf5185a3abc3

See more details on using hashes here.

File details

Details for the file shin-0.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for shin-0.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 f8689cefb6fd95cc9fe839f715b005d33a93a0f770cc16fd4697c34263b3b913
MD5 72ba85ce6cab3143c8362fa32c4a1b6f
BLAKE2b-256 c5c7530002637a63d3ca0d0cedf8e5a2dc40edefc6275b9dbd38df4b250c0596

See more details on using hashes here.

File details

Details for the file shin-0.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for shin-0.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 1335e53c68cbd7eed02a6686e0c312ceb26bee757a05548e6028ab003738317a
MD5 feddf5c74642b33ecc3c96a755bc6488
BLAKE2b-256 0b3005d748005df087aa435347cb0344f052be1b9be3ff26474b3eeee0c72a17

See more details on using hashes here.

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

Hashes for shin-0.2.0-cp39-none-win_amd64.whl
Algorithm Hash digest
SHA256 7f604062b3d425789dec536ea5de0e2d67e9939d715fd0b42795a5266175315a
MD5 6fa58f2e2de8ff6e6f10eeab1e172c7e
BLAKE2b-256 2b0be6efcffeeaeee472af585f6912f07100f1f9893aef0226789d79906cb860

See more details on using hashes here.

File details

Details for the file shin-0.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for shin-0.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 3d796c3470e80b547eb1dda90f3a4991363d8879ed4f92e48fb9228d52571af3
MD5 1c11df00d59d0b6f6a491ff9c2dd7067
BLAKE2b-256 158757e32c27263c64ea5bb48959737fb8468f769320dea9f54a83a94348a579

See more details on using hashes here.

File details

Details for the file shin-0.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for shin-0.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 d63ee4f2cddd543b14f86a85d6932ad8d7a5d1839139b165531a2e885a52a28f
MD5 dff62875c598daa8911117d2b9622d13
BLAKE2b-256 b4d15fbcf97c198cb175650b3c7837bdf166605645087a2abaef297c1392d1fe

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page