Package: shin
shinA 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].InstallationRequires Python 3.9 or above.pip install shinUsageimportshinshin.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 thefull_outputargument toTrue:importshinshin.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}The returneddictcontains the following fields:implied_probablitiesiterations- compare this value to themax_iterationsargument (default =1000) to check for failed convergencedelta- the final change inzfor the final iteration. Compare with theconvergence_thresholdargument
(default =1e-12) to assess convergencez- the estimated proportion of theoretical betting volume coming from insider tradersWhen there are only two outcomes,zcan be calculated analytically [3]. In this case, theiterationsanddeltafields of the returneddictare0to reflect this:importshinshin.calculate_implied_probabilities([1.5,2.74],full_output=True){'implied_probabilities': [0.6508515815085157, 0.3491484184914841],
 'iterations': 0,
 'delta': 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.1.0?The latest version introduces some substantial changes and breaking API changes.Default Return Value BehaviourPreviouslyshin.calculate_implied_probabilitieswould return adictthat contained convergence details of the
iterative fitting procedure along with the implied probabilities:importshinshin.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:importshinshin.calculate_implied_probabilities([2.6,2.4,4.3])[0.37299406033208965, 0.4047794109200184, 0.2222265287474275]The full output can still be had by setting thefull_outputargument toTrue:importshinshin.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 MappingsA common scenario is to have a mapping between some selection identifiers and their odds. You can now pass such
mappings toshin.calculate_implied_probabilitiesand have a newdictmapping between the selection identifiers and
their probabilities returned:importshinshin.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:importshinshin.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 OptimiserStarting 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 theforce_python_optimiserargument:importtimeittimeit.timeit("shin.calculate_implied_probabilities([2.6, 2.4, 4.3], force_python_optimiser=True)",setup="import shin",number=10000)3.9101167659973726importtimeittimeit.timeit("shin.calculate_implied_probabilities([2.6, 2.4, 4.3])",setup="import shin",number=10000)0.14442387002054602References[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.