import%20marimo%0A%0A__generated_with%20%3D%20%220.18.4%22%0Aapp%20%3D%20marimo.App(width%3D%22medium%22)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20inputs_header%20%3D%20mo.md(%22%23%20Dixon-Coles%20Poisson%20Calibration%22)%0A%0A%20%20%20%20tg_line%20%3D%20mo.ui.number(start%3D0%2C%20stop%3D10%2C%20step%3D0.25%2C%20value%3D2.25%2C%20label%3D%22Line%22)%0A%20%20%20%20tg_over_odds%20%3D%20mo.ui.number(start%3D1.01%2C%20stop%3D10%2C%20step%3D0.01%2C%20value%3D1.88%2C%20label%3D%22Over%20Odds%22)%0A%20%20%20%20tg_under_odds%20%3D%20mo.ui.number(start%3D1.01%2C%20stop%3D10%2C%20step%3D0.01%2C%20value%3D2.00%2C%20label%3D%22Under%20Odds%22)%0A%0A%20%20%20%20ah_line%20%3D%20mo.ui.number(start%3D-5%2C%20stop%3D5%2C%20step%3D0.25%2C%20value%3D0.25%2C%20label%3D%22Line%22)%0A%20%20%20%20ah_home_odds%20%3D%20mo.ui.number(start%3D1.01%2C%20stop%3D10%2C%20step%3D0.01%2C%20value%3D1.76%2C%20label%3D%22Home%20Odds%22)%0A%20%20%20%20ah_away_odds%20%3D%20mo.ui.number(start%3D1.01%2C%20stop%3D10%2C%20step%3D0.01%2C%20value%3D2.13%2C%20label%3D%22Away%20Odds%22)%0A%0A%20%20%20%20rho_input%20%3D%20mo.ui.number(start%3D-0.30%2C%20stop%3D0.10%2C%20step%3D0.01%2C%20value%3D-0.10%2C%20label%3D%22%CF%81%22)%0A%0A%20%20%20%20tg_header%20%3D%20mo.md(%22**Total%20Goals%20Market**%22)%0A%20%20%20%20tg_inputs%20%3D%20mo.hstack(%5Btg_line%2C%20tg_over_odds%2C%20tg_under_odds%5D%2C%20justify%3D%22start%22)%0A%0A%20%20%20%20ah_header%20%3D%20mo.md(%22**Asian%20Handicap%20Market**%22)%0A%20%20%20%20ah_inputs%20%3D%20mo.hstack(%5Bah_line%2C%20ah_home_odds%2C%20ah_away_odds%5D%2C%20justify%3D%22start%22)%0A%0A%20%20%20%20adj_header%20%3D%20mo.md(%22**Dixon-Coles%20Dependence%20Parameter**%22)%0A%20%20%20%20adj_inputs%20%3D%20mo.hstack(%5Brho_input%5D%2C%20justify%3D%22start%22)%0A%0A%20%20%20%20mo.vstack(%0A%20%20%20%20%20%20%20%20%5Binputs_header%2C%20tg_header%2C%20tg_inputs%2C%20ah_header%2C%20ah_inputs%2C%20adj_header%2C%20adj_inputs%5D%2C%0A%20%20%20%20%20%20%20%20align%3D%22stretch%22%2C%0A%20%20%20%20)%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%20%20ah_away_odds%2C%0A%20%20%20%20%20%20%20%20ah_home_odds%2C%0A%20%20%20%20%20%20%20%20ah_line%2C%0A%20%20%20%20%20%20%20%20rho_input%2C%0A%20%20%20%20%20%20%20%20tg_line%2C%0A%20%20%20%20%20%20%20%20tg_over_odds%2C%0A%20%20%20%20%20%20%20%20tg_under_odds%2C%0A%20%20%20%20)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(%0A%20%20%20%20ah_away_odds%2C%0A%20%20%20%20ah_home_odds%2C%0A%20%20%20%20ah_line%2C%0A%20%20%20%20rf%2C%0A%20%20%20%20rho_input%2C%0A%20%20%20%20tg_line%2C%0A%20%20%20%20tg_over_odds%2C%0A%20%20%20%20tg_under_odds%2C%0A)%3A%0A%20%20%20%20%23%20Build%20quote%20objects%20from%20inputs%0A%20%20%20%20quote_tg%20%3D%20rf.Quote.build(%0A%20%20%20%20%20%20%20%20line%3Drf.QuotedLine(tg_line.value)%2C%0A%20%20%20%20%20%20%20%20market%3Drf.Market.TOTAL_GOAL%2C%0A%20%20%20%20%20%20%20%20side_pair%3D%5Brf.BetState.OVER%2C%20rf.BetState.UNDR%5D%2C%0A%20%20%20%20%20%20%20%20odds_pair%3D%5Brf.DecimalOdds(tg_over_odds.value)%2C%20rf.DecimalOdds(tg_under_odds.value)%5D%2C%0A%20%20%20%20)%0A%0A%20%20%20%20quote_ah%20%3D%20rf.Quote.build(%0A%20%20%20%20%20%20%20%20line%3Drf.QuotedLine(ah_line.value)%2C%0A%20%20%20%20%20%20%20%20market%3Drf.Market.ASIAN_HCAP%2C%0A%20%20%20%20%20%20%20%20side_pair%3D%5Brf.BetState.HOME%2C%20rf.BetState.AWAY%5D%2C%0A%20%20%20%20%20%20%20%20odds_pair%3D%5Brf.DecimalOdds(ah_home_odds.value)%2C%20rf.DecimalOdds(ah_away_odds.value)%5D%2C%0A%20%20%20%20)%0A%0A%20%20%20%20%23%20Calibrate%20model%20%E2%80%94%20single%20call%20replaces%20all%20root-finding%20logic%0A%20%20%20%20model%20%3D%20rf.DixonColes.calibrate(tg_quote%3Dquote_tg%2C%20ah_quote%3Dquote_ah%2C%20rho%3Drho_input.value)%0A%20%20%20%20return%20model%2C%20quote_ah%2C%20quote_tg%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo%2C%20model%2C%20quote_ah%2C%20quote_tg%2C%20rf)%3A%0A%0A%20%20%20%20%23%20Model-implied%20odds%20(adjusted%20and%20base)%0A%20%20%20%20tg_model_quote%20%3D%20rf.TotalGoals(line%3Dquote_tg.line.value).implied_odds(model%3Dmodel)%0A%20%20%20%20ah_model_quote%20%3D%20rf.AsianHandicap(line%3Dquote_ah.line.value).implied_odds(model%3Dmodel)%0A%0A%20%20%20%20tg_base_quote%20%3D%20rf.TotalGoals(line%3Dquote_tg.line.value).implied_odds(model%3Dmodel.dist)%0A%20%20%20%20ah_base_quote%20%3D%20rf.AsianHandicap(line%3Dquote_ah.line.value).implied_odds(model%3Dmodel.dist)%0A%0A%20%20%20%20%23%20Margin%20analysis%0A%20%20%20%20tg_margin%20%3D%20quote_tg.implied_margin()%0A%20%20%20%20ah_margin%20%3D%20quote_ah.implied_margin()%0A%20%20%20%20tg_market%20%3D%20quote_tg.margin_strip()%0A%20%20%20%20ah_market%20%3D%20quote_ah.margin_strip()%0A%20%20%20%20tg_model_with_margin%20%3D%20tg_model_quote.margin_set(tg_margin)%0A%20%20%20%20ah_model_with_margin%20%3D%20ah_model_quote.margin_set(ah_margin)%0A%0A%20%20%20%20%23%20Display%0A%20%20%20%20results_header%20%3D%20mo.md(%22%23%23%20Results%22)%0A%0A%20%20%20%20_lh%20%3D%20model.dist.lambda_home%0A%20%20%20%20_la%20%3D%20model.dist.lambda_away%0A%0A%20%20%20%20params_table%20%3D%20mo.md(f%22%22%22%0A%20%20%20%20%7C%20%CE%BB_home%20%7C%20%CE%BB_away%20%7C%20%CE%BB_total%20%7C%20%CE%BB_diff%20%7C%0A%20%20%20%20%7C%3A------%3A%7C%3A------%3A%7C%3A-------%3A%7C%3A------%3A%7C%0A%20%20%20%20%7C%20%7B_lh%3A.2f%7D%20%7C%20%7B_la%3A.2f%7D%20%7C%20%7B_lh%20%2B%20_la%3A.2f%7D%20%7C%20%7B_lh%20-%20_la%3A.2f%7D%20%7C%0A%20%20%20%20%22%22%22)%0A%0A%20%20%20%20adj_table%20%3D%20mo.md(f%22%22%22%0A%20%20%20%20%7C%20%CF%81%20(rho)%20%7C%0A%20%20%20%20%7C%3A-------%3A%7C%0A%20%20%20%20%7C%20%7Bmodel.rho%3A%2B.2f%7D%20%7C%0A%20%20%20%20%22%22%22)%0A%0A%20%20%20%20margins_table%20%3D%20mo.md(f%22%22%22%0A%20%20%20%20%7C%20TG%20Margin%20%7C%20AH%20Margin%20%7C%0A%20%20%20%20%7C%3A---------%3A%7C%3A---------%3A%7C%0A%20%20%20%20%7C%20%7Btg_margin%20*%20100%3A.1f%7D%25%20%7C%20%7Bah_margin%20*%20100%3A.1f%7D%25%20%7C%0A%20%20%20%20%22%22%22)%0A%0A%20%20%20%20params_and_margins%20%3D%20mo.hstack(%5Bparams_table%2C%20adj_table%2C%20margins_table%5D%2C%20justify%3D%22space-around%22)%0A%0A%20%20%20%20tg_quote_table%20%3D%20mo.md(f%22%22%22%0A%20%20%20%20**TG%5B%7Bquote_tg.line.value%3A%2B.2f%7D%5D%20Market**%0A%0A%20%20%20%20%7C%20Side%20%7C%20Quote%20%7C%20Quote%20(-%7Btg_margin%20*%20100%3A.1f%7D%25)%20%7C%0A%20%20%20%20%7C%3A----%3A%7C%3A-----%3A%7C%3A--------------%3A%7C%0A%20%20%20%20%7C%20Over%20%7C%20%7Bquote_tg.side_a.odds.value%3A.2f%7D%20%7C%20%7Btg_market.side_a.odds.value%3A.2f%7D%20%7C%0A%20%20%20%20%7C%20Under%20%7C%20%7Bquote_tg.side_b.odds.value%3A.2f%7D%20%7C%20%7Btg_market.side_b.odds.value%3A.2f%7D%20%7C%0A%20%20%20%20%22%22%22)%0A%0A%20%20%20%20tg_model_table%20%3D%20mo.md(f%22%22%22%0A%20%20%20%20**TG%5B%7Bquote_tg.line.value%3A%2B.2f%7D%5D%20Adjusted%20Model**%0A%0A%20%20%20%20%7C%20Side%20%7C%20Base%20%7C%20Adjusted%20%7C%20Adjusted%20(%2B%7Btg_margin%20*%20100%3A.1f%7D%25)%20%7C%0A%20%20%20%20%7C%3A----%3A%7C%3A----%3A%7C%3A--------%3A%7C%3A--------------%3A%7C%0A%20%20%20%20%7C%20Over%20%7C%20%7Btg_base_quote.side_a.odds.value%3A.2f%7D%20%7C%20%7Btg_model_quote.side_a.odds.value%3A.2f%7D%20%7C%20%7Btg_model_with_margin.side_a.odds.value%3A.2f%7D%20%7C%0A%20%20%20%20%7C%20Under%20%7C%20%7Btg_base_quote.side_b.odds.value%3A.2f%7D%20%7C%20%7Btg_model_quote.side_b.odds.value%3A.2f%7D%20%7C%20%7Btg_model_with_margin.side_b.odds.value%3A.2f%7D%20%7C%0A%20%20%20%20%22%22%22)%0A%0A%20%20%20%20ah_quote_table%20%3D%20mo.md(f%22%22%22%0A%20%20%20%20**AH%5B%7Bquote_ah.line.value%3A%2B.2f%7D%5D%20Market**%0A%0A%20%20%20%20%7C%20Side%20%7C%20Quote%20%7C%20Quote%20(-%7Bah_margin%20*%20100%3A.1f%7D%25)%20%7C%0A%20%20%20%20%7C%3A----%3A%7C%3A-----%3A%7C%3A--------------%3A%7C%0A%20%20%20%20%7C%20Home%20%7C%20%7Bquote_ah.side_a.odds.value%3A.2f%7D%20%7C%20%7Bah_market.side_a.odds.value%3A.2f%7D%20%7C%0A%20%20%20%20%7C%20Away%20%7C%20%7Bquote_ah.side_b.odds.value%3A.2f%7D%20%7C%20%7Bah_market.side_b.odds.value%3A.2f%7D%20%7C%0A%20%20%20%20%22%22%22)%0A%0A%20%20%20%20ah_model_table%20%3D%20mo.md(f%22%22%22%0A%20%20%20%20**AH%5B%7Bquote_ah.line.value%3A%2B.2f%7D%5D%20Adjusted%20Model**%0A%0A%20%20%20%20%7C%20Side%20%7C%20Base%20%7C%20Adjusted%20%7C%20Adjusted%20(%2B%7Bah_margin%20*%20100%3A.1f%7D%25)%20%7C%0A%20%20%20%20%7C%3A----%3A%7C%3A----%3A%7C%3A--------%3A%7C%3A--------------%3A%7C%0A%20%20%20%20%7C%20Home%20%7C%20%7Bah_base_quote.side_a.odds.value%3A.2f%7D%20%7C%20%7Bah_model_quote.side_a.odds.value%3A.2f%7D%20%7C%20%7Bah_model_with_margin.side_a.odds.value%3A.2f%7D%20%7C%0A%20%20%20%20%7C%20Away%20%7C%20%7Bah_base_quote.side_b.odds.value%3A.2f%7D%20%7C%20%7Bah_model_quote.side_b.odds.value%3A.2f%7D%20%7C%20%7Bah_model_with_margin.side_b.odds.value%3A.2f%7D%20%7C%0A%20%20%20%20%22%22%22)%0A%0A%20%20%20%20tg_tables%20%3D%20mo.hstack(%5Btg_quote_table%2C%20tg_model_table%5D)%0A%20%20%20%20ah_tables%20%3D%20mo.hstack(%5Bah_quote_table%2C%20ah_model_table%5D)%0A%0A%20%20%20%20mo.vstack(%5Bresults_header%2C%20params_and_margins%2C%20tg_tables%2C%20ah_tables%5D%2C%20align%3D%22stretch%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(model%2C%20pd%2C%20plt%2C%20rf%2C%20rho_input)%3A%0A%20%20%20%20grid%20%3D%20rf.GoalGrid(n%3D10)%0A%0A%20%20%20%20pmfA%20%3D%20model.dist.pmf(data%3Dgrid)%0A%20%20%20%20pmfB%20%3D%20model.pmf(data%3Dgrid)%0A%0A%20%20%20%20sumsA%20%3D%20rf.sum_diagonals(pmfA.to_numpy())%0A%20%20%20%20sumsB%20%3D%20rf.sum_diagonals(pmfB.to_numpy())%0A%0A%20%20%20%20title_params%20%3D%20f%22%CF%81%3D%7Brho_input.value%3A%2B.2f%7D%22%0A%20%20%20%20_fig%2C%20ax%20%3D%20plt.subplots(figsize%3D(8%2C%203))%0A%20%20%20%20data%20%3D%20pd.concat(%5BsumsA%2C%20sumsB%5D%2C%20axis%3D1%2C%20keys%3D%5B%22original%22%2C%20%22modified%22%5D)%0A%20%20%20%20data.plot.bar(ax%3Dax)%0A%20%20%20%20ax.set_title(f%22goal%20difference%20probability%20under%20%7Btitle_params%7D%22)%0A%20%20%20%20return%20(data%2C)%0A%0A%0A%40app.cell%0Adef%20_(data)%3A%0A%20%20%20%20data%5B%22diff%22%5D%20%3D%20data.modified%20-%20data.original%0A%20%20%20%20print(data.loc%5B-4%3A4%5D)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_()%3A%0A%20%20%20%20import%20marimo%20as%20mo%0A%20%20%20%20import%20matplotlib.pyplot%20as%20plt%0A%20%20%20%20import%20pandas%20as%20pd%0A%20%20%20%20import%20seaborn%20as%20sns%0A%0A%20%20%20%20import%20pyrf%20as%20rf%0A%0A%20%20%20%20sns.set_style(%22whitegrid%22)%0A%20%20%20%20return%20mo%2C%20pd%2C%20plt%2C%20rf%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20app.run()%0A
543a9ab4203aae27061ba82859457a35