Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import matplotlib.pyplot as plt | |
| BURGUNDY = "#5A1414" | |
| GOLD = "#FFB612" | |
| # Hidden model performance constants (Boosted NN) | |
| TP_COUNT = 588 | |
| FP_COUNT = 1310 | |
| # ----------------------------- | |
| # Core economics (TP/FP-aware) | |
| # ----------------------------- | |
| def compute_profit( | |
| tier1_contract, # full contract value for TRUE Tier 1 (e.g., 24.3M) | |
| tier2_contract, # full contract value for TRUE Tier 2 (e.g., 2.7M) | |
| premium_rate, # e.g., 0.007 (0.7%) | |
| injury_rate, # e.g., 0.003 (0.3%) | |
| payout_pct_contract, # e.g., 0.6 or 0.8 (portion paid out under PTD) | |
| combine_players, # e.g., 300-330 | |
| insured_pct_players # % of combine players insured (predicted Tier 1) | |
| ): | |
| # Players insured per year (predicted Tier 1) | |
| players_insured = combine_players * insured_pct_players | |
| # Precision among insured (TP share) from model constants | |
| denom = TP_COUNT + FP_COUNT | |
| precision = (TP_COUNT / denom) if denom > 0 else 0.0 | |
| # Profit per insured player IF actually Tier 1 | |
| profit_t1 = (premium_rate * tier1_contract) - (injury_rate * payout_pct_contract * tier1_contract) | |
| # Profit per insured player IF actually Tier 2 (false positive) | |
| profit_t2 = (premium_rate * tier2_contract) - (injury_rate * payout_pct_contract * tier1_contract) | |
| # Expected profit per insured player, accounting for TP/FP mix | |
| profit_per_player = precision * profit_t1 + (1 - precision) * profit_t2 | |
| # Expected annual profit | |
| annual_profit = players_insured * profit_per_player | |
| # Breakdown (useful outputs) | |
| insured_t1 = players_insured * precision | |
| insured_t2 = players_insured * (1 - precision) | |
| return annual_profit, profit_per_player, players_insured, insured_t1, insured_t2, precision | |
| # ----------------------------- | |
| # Sensitivity chart | |
| # ----------------------------- | |
| def sensitivity_plot( | |
| tier1_contract, | |
| tier2_contract, | |
| premium_rate, | |
| injury_rate, | |
| payout_pct_contract, | |
| combine_players, | |
| insured_pct_players | |
| ): | |
| def annual(t1, t2, pr, ir, pay): | |
| return compute_profit( | |
| t1, t2, pr, ir, pay, | |
| combine_players, insured_pct_players | |
| )[0] | |
| # Salary sensitivity: scale BOTH tiers together ±20% | |
| salary_vals = [ | |
| annual(tier1_contract * 0.8, tier2_contract, premium_rate, injury_rate, payout_pct_contract), | |
| annual(tier1_contract, tier2_contract, premium_rate, injury_rate, payout_pct_contract), | |
| annual(tier1_contract * 1.2, tier2_contract, premium_rate, injury_rate, payout_pct_contract), | |
| ] | |
| # Premium sensitivity ±0.2% (0.002) | |
| premium_vals = [ | |
| annual(tier1_contract, tier2_contract, max(premium_rate - 0.002, 0.0), injury_rate, payout_pct_contract), | |
| annual(tier1_contract, tier2_contract, premium_rate, injury_rate, payout_pct_contract), | |
| annual(tier1_contract, tier2_contract, premium_rate + 0.002, injury_rate, payout_pct_contract), | |
| ] | |
| # Injury sensitivity ±0.1% (0.001) | |
| injury_vals = [ | |
| annual(tier1_contract, tier2_contract, premium_rate, max(injury_rate - 0.001, 0.0), payout_pct_contract), | |
| annual(tier1_contract, tier2_contract, premium_rate, injury_rate, payout_pct_contract), | |
| annual(tier1_contract, tier2_contract, premium_rate, injury_rate + 0.001, payout_pct_contract), | |
| ] | |
| labels = [ | |
| "Salary -20%", "Salary Base", "Salary +20%", | |
| "Premium -0.2%", "Premium Base", "Premium +0.2%", | |
| "Injury -0.1%", "Injury Base", "Injury +0.1%", | |
| ] | |
| values = salary_vals + premium_vals + injury_vals | |
| fig, ax = plt.subplots(figsize=(10, 4.3)) | |
| ax.bar(labels, values, color=GOLD, edgecolor=BURGUNDY, linewidth=0.8) | |
| ax.axhline(0, color=BURGUNDY, linewidth=2) | |
| ax.set_title("Sensitivity of Expected Annual Profit to Key Assumptions", | |
| color=BURGUNDY, fontsize=14, fontweight="bold") | |
| ax.set_ylabel("Expected Annual Profit ($)") | |
| ax.tick_params(axis="x", rotation=35) | |
| fig.tight_layout() | |
| return fig | |
| # ----------------------------- | |
| # Run button handler | |
| # ----------------------------- | |
| def run_simulator( | |
| tier1_contract, | |
| tier2_contract, | |
| premium_rate, | |
| injury_rate, | |
| combine_players, | |
| insured_pct_players, | |
| payout_pct_contract, | |
| ): | |
| annual_profit, profit_per_player, insured_players, insured_t1, insured_t2, precision = compute_profit( | |
| tier1_contract, | |
| tier2_contract, | |
| premium_rate, | |
| injury_rate, | |
| payout_pct_contract, | |
| combine_players, | |
| insured_pct_players | |
| ) | |
| fig = sensitivity_plot( | |
| tier1_contract, | |
| tier2_contract, | |
| premium_rate, | |
| injury_rate, | |
| payout_pct_contract, | |
| combine_players, | |
| insured_pct_players | |
| ) | |
| return ( | |
| round(annual_profit,0), | |
| round(profit_per_player,0), | |
| round(insured_players, 0), | |
| round(insured_t1, 0), | |
| round(insured_t2, 0), | |
| round(precision, 3), | |
| fig, | |
| ) | |
| # ----------------------------- | |
| # Styling (Burgundy + Gold) | |
| # ----------------------------- | |
| custom_css = f""" | |
| :root {{ | |
| --primary-500: {BURGUNDY} !important; | |
| --primary-600: {BURGUNDY} !important; | |
| --primary-700: #4A0F0F !important; | |
| --accent-color: {BURGUNDY} !important; | |
| }} | |
| label span {{ | |
| color: {BURGUNDY} !important; | |
| font-weight: 700; | |
| }} | |
| .gr-markdown h2, .gr-markdown h3 {{ | |
| color: {BURGUNDY} !important; | |
| }} | |
| .gr-slider input[type="range"] {{ | |
| accent-color: {BURGUNDY} !important; | |
| }} | |
| input[type="range"]::-webkit-slider-thumb {{ | |
| background: {GOLD} !important; | |
| border: 2px solid {BURGUNDY} !important; | |
| }} | |
| input[type="range"]::-moz-range-thumb {{ | |
| background: {GOLD} !important; | |
| border: 2px solid {BURGUNDY} !important; | |
| }} | |
| input[type="range"]:focus::-webkit-slider-thumb {{ | |
| box-shadow: 0 0 0 4px rgba(255, 182, 18, 0.45); | |
| }} | |
| .gr-button {{ | |
| background-color: {BURGUNDY} !important; | |
| color: {GOLD} !important; | |
| font-weight: 800 !important; | |
| border-radius: 10px !important; | |
| }} | |
| .gr-button:hover {{ | |
| background-color: #4A0F0F !important; | |
| }} | |
| .gr-label span {{ | |
| background-color: {BURGUNDY} !important; | |
| color: {GOLD} !important; | |
| border-radius: 6px; | |
| padding: 2px 6px; | |
| }} | |
| """ | |
| # ----------------------------- | |
| # UI | |
| # ----------------------------- | |
| with gr.Blocks() as demo: | |
| gr.Markdown(f""" | |
| <h2 style="color:{BURGUNDY}; margin-bottom:0.2rem;"> | |
| NFL Combine Insurance Revenue Simulator (TP/FP-adjusted) | |
| </h2> | |
| <p style="margin-top:0.2rem;"> | |
| Uses hidden boosted-NN precision derived from TP={TP_COUNT} and FP={FP_COUNT} (precision ≈ {TP_COUNT/(TP_COUNT+FP_COUNT):.3f}). | |
| Adjust assumptions to stress-test expected annual profit. | |
| </p> | |
| """) | |
| with gr.Row(): | |
| tier1_contract = gr.Slider( | |
| 18_000_000, 30_000_000, value=24_300_000, step=100_000, | |
| label="Tier 1 Avg Full Contract ($)" | |
| ) | |
| tier2_contract = gr.Slider( | |
| 750_000, 6_000_000, value=2_700_000, step=50_000, | |
| label="Tier 2 Avg Full Contract ($)" | |
| ) | |
| with gr.Row(): | |
| premium_rate = gr.Slider( | |
| 0.003, 0.010, value=0.007, step=0.001, | |
| label="Premium Rate" | |
| ) | |
| injury_rate = gr.Slider( | |
| 0.001, 0.010, value=0.003, step=0.001, | |
| label="Injury / Payout Probability" | |
| ) | |
| with gr.Row(): | |
| combine_players = gr.Slider( | |
| 300, 330, value=330, step=1, | |
| label="Total Combine Participants Per Year" | |
| ) | |
| insured_pct_players = gr.Slider( | |
| 0.20, 0.60, value=0.40, step=0.01, | |
| label="Percent of Players Insured" | |
| ) | |
| payout_pct_contract = gr.Slider( | |
| 0.40, 0.90, value=0.60, step=0.05, | |
| label="Percent of Contract Paid Out on PTD" | |
| ) | |
| gr.Markdown("### Key Outputs") | |
| with gr.Row(): | |
| annual_out = gr.Number(label="Expected Annual Profit ($)") | |
| profit_out = gr.Number(label="Profit per Insured Player ($)") | |
| insured_out = gr.Number(label="Players Insured Per Year") | |
| with gr.Row(): | |
| insured_t1_out = gr.Number(label="Expected Tier 1 Insured ") | |
| insured_t2_out = gr.Number(label="Expected Tier 2 Insured ") | |
| precision_out = gr.Number(label="Precision Among Insured ") | |
| sensitivity = gr.Plot(label="Sensitivity Analysis") | |
| run_btn = gr.Button("Run Simulation", variant="primary") | |
| run_btn.click( | |
| fn=run_simulator, | |
| inputs=[ | |
| tier1_contract, | |
| tier2_contract, | |
| premium_rate, | |
| injury_rate, | |
| combine_players, | |
| insured_pct_players, | |
| payout_pct_contract, | |
| ], | |
| outputs=[ | |
| annual_out, | |
| profit_out, | |
| insured_out, | |
| insured_t1_out, | |
| insured_t2_out, | |
| precision_out, | |
| sensitivity | |
| ], | |
| ) | |
| if __name__ == "__main__": | |
| demo.launch( | |
| theme=gr.themes.Soft(), | |
| css=custom_css, | |
| share=True | |
| ) | |