CoolFace
Apppublic

TrueDFS/NBA_Betting_Models_Origin

sourceHugging Faceupdated 2y agoView on Hugging Face
0likes
app.py763 linesDownload Raw Back to root
1import streamlit as st2st.set_page_config(layout="wide")3 4for name in dir():5    if not name.startswith('_'):6        del globals()[name]7 8import numpy as np9from numpy import where as np_where10import pandas as pd11import pymongo12import random13import gc14import streamlit as st15import scipy.stats as stats16from datetime import datetime17 18@st.cache_resource19def init_conn():20 21        uri = st.secrets['mongo_uri']22        client = pymongo.MongoClient(uri, retryWrites=True, serverSelectionTimeoutMS=100000)23        db = client["NBA_DFS"]24        prop_db = client["Props_DB"]25      26        return db, prop_db27 28db, prop_db = init_conn()29 30game_format = {'Paydirt Win%': '{:.2%}', 'Vegas Win%': '{:.2%}'}31prop_format = {'L5 Success': '{:.2%}', 'L10_Success': '{:.2%}', 'L20_success': '{:.2%}', 'Matchup Boost': '{:.2%}', 'Trending Over': '{:.2%}', 'Trending Under': '{:.2%}',32               'Implied Over': '{:.2%}', 'Implied Under': '{:.2%}', 'Over Edge': '{:.2%}', 'Under Edge': '{:.2%}'}33sim_format = {'Trending Over': '{:.2%}', 'Trending Under': '{:.2%}', 'Imp Over': '{:.2%}', 'Imp Under': '{:.2%}', 'Over%': '{:.2%}', 'Under%': '{:.2%}', 'Edge': '{:.2%}'}34prop_table_options = ['NBA_GAME_PLAYER_POINTS', 'NBA_GAME_PLAYER_REBOUNDS', 'NBA_GAME_PLAYER_ASSISTS', 'NBA_GAME_PLAYER_POINTS_REBOUNDS_ASSISTS', 'NBA_GAME_PLAYER_POINTS_REBOUNDS', 'NBA_GAME_PLAYER_POINTS_ASSISTS', 'NBA_GAME_PLAYER_REBOUNDS_ASSISTS']35all_sim_vars = ['NBA_GAME_PLAYER_POINTS', 'NBA_GAME_PLAYER_REBOUNDS', 'NBA_GAME_PLAYER_ASSISTS', 'NBA_GAME_PLAYER_POINTS_REBOUNDS_ASSISTS', 'NBA_GAME_PLAYER_POINTS_REBOUNDS', 'NBA_GAME_PLAYER_POINTS_ASSISTS', 'NBA_GAME_PLAYER_REBOUNDS_ASSISTS']36pick6_sim_vars = ['Points', 'Rebounds', 'Assists', 'Points + Assists + Rebounds', 'Points + Assists', 'Points + Rebounds', 'Assists + Rebounds']37sim_all_hold = pd.DataFrame(columns=['Player', 'Team', 'Book', 'Prop Type', 'Prop', 'Mean_Outcome', 'Imp Over', 'Trending Over', 'Over%', 'Imp Under', 'Trending Under', 'Under%', 'Bet?', 'Edge'])38 39def calculate_poisson(row):40    mean_val = row['Mean_Outcome']41    threshold = row['Prop']42    cdf_value = stats.poisson.cdf(threshold, mean_val)43    probability = 1 - cdf_value44    return probability45 46def add_column(df):47    return_df = df48    return_df['2P'] = return_df["Minutes"] * return_df["FG2M"]49    return_df['3P'] = return_df["Minutes"] * return_df["Threes"]50    return_df['FT'] = return_df["Minutes"] * return_df["FTM"]51    return_df['Points'] = (return_df["2P"] * 2) + (return_df["3P"] * 3) + return_df['FT']52    return_df['Rebounds'] = return_df["Minutes"] * return_df["TRB"]53    return_df['Assists'] = return_df["Minutes"] * return_df["AST"]54    return_df['PRA'] = return_df['Points'] + return_df['Rebounds'] + return_df['Assists']55    return_df['PR'] = return_df['Points'] + return_df['Rebounds']56    return_df['PA'] = return_df['Points'] + return_df['Assists']57    return_df['RA'] = return_df['Rebounds'] + return_df['Assists']58    return_df['Steals'] = return_df["Minutes"] * return_df["STL"]59    return_df['Blocks'] = return_df["Minutes"] * return_df["BLK"]60    return_df['Turnovers'] = return_df["Minutes"] * return_df["TOV"]61    return_df['Fantasy'] = (return_df["2P"] * 3) + (return_df["3P"] * 3.5) + return_df['FT'] + (return_df["Rebounds"] * 1.25) + (return_df["Assists"] * 1.5) + (return_df["Steals"] * 2) + (return_df["Blocks"] * 2) + (return_df["Turnovers"] * -.5)62    63    export_df = return_df[['Player', 'Position', 'Team', 'Opp', 'Minutes', '2P', '3P', 'FT', 'Points', 'Rebounds', 'Assists', 'PRA', 'PR', 'PA', 'RA', 'Steals', 'Blocks', 'Turnovers', 'Fantasy']]64    65    return export_df66 67@st.cache_resource(ttl = 300)68def init_baselines():69    collection = db["Game_Betting_Model"] 70    cursor = collection.find()71 72    raw_display = pd.DataFrame(list(cursor))73    raw_display = raw_display[['Team', 'Opp', 'PD Team Points', 'PD Opp Points', 'VEG Team Points', 'VEG Opp Points', 'PD Proj Total', 'VEG Proj Total', 'PD Over%', 'PD Over Odds', 'PD Under%', 'PD Under Odds',74                               'PD Proj Winner', 'PD Proj Spread', 'PD W Spread', 'VEG W Spread', 'PD Win%', 'PD Odds']]75    raw_display.replace('#DIV/0!', np.nan, inplace=True)76    game_model = raw_display.dropna()77 78    collection = db["Player_Stats"] 79    cursor = collection.find()80 81    raw_display = pd.DataFrame(list(cursor))82    raw_display.replace('', np.nan, inplace=True)83    raw_display = raw_display.rename(columns={"Name": "Player"})84    raw_baselines = raw_display[['Player', 'Position', 'Team', 'Opp', 'Minutes', 'FGM', 'FGA', 'FG2M', 'FG2A', 'Threes', 'FG3A', 'FTM', 'FTA', 'TRB', 'AST', 'STL', 'BLK', 'TOV', 'PRA', 'PR', 'PA', 'RA']]85    raw_baselines = raw_baselines[raw_baselines['Minutes'] > 0]86    raw_baselines['Player'].replace(['Jaren Jackson', 'Nic Claxton', 'Jabari Smith', 'Lu Dort', 'Moe Wagner', 'Kyle Kuzma', 'Trey Murphy', 'Cameron Thomas'],87                                 ['Jaren Jackson Jr.', 'Nicolas Claxton', 'Jabari Smith Jr.', 'Luguentz Dort', 'Moritz Wagner', 'Kyle Kuzma Jr.',88                                  'Trey Murphy III', 'Cam Thomas'], inplace=True)89    90    player_stats = raw_display[['Player', 'Position', 'Team', 'Opp', 'Minutes', '3P', 'Points', 'Rebounds', 'Assists', 'Steals', 'Blocks', 'Turnovers', 'Fantasy']]91    player_stats = player_stats[player_stats['Minutes'] > 0]92 93    player_stats['Player'].replace(['Jaren Jackson', 'Nic Claxton', 'Jabari Smith', 'Lu Dort', 'Moe Wagner', 'Kyle Kuzma', 'Trey Murphy', 'Cameron Thomas'],94                                 ['Jaren Jackson Jr.', 'Nicolas Claxton', 'Jabari Smith Jr.', 'Luguentz Dort', 'Moritz Wagner', 'Kyle Kuzma Jr.',95                                  'Trey Murphy III', 'Cam Thomas'], inplace=True)96    97 98    timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")99 100    collection = db["Prop_Trends"] 101    cursor = collection.find()102 103    raw_display = pd.DataFrame(list(cursor))104    raw_display.replace('', np.nan, inplace=True)105    raw_display = raw_display[['Name', 'over_prop', 'over_line', 'under_prop', 'under_line', 'OddsType', 'PropType', 'No Vig', 'Team', 'L5 Success', 'L10_Success', 'L20_success', 'L10 Avg', 'Projection',106                               'Proj Diff', 'Matchup Boost', 'Implied Over', 'Trending Over', 'Over Edge', 'Implied Under', 'Trending Under', 'Under Edge']]107    raw_display = raw_display.rename(columns={"Name": "Player", "OddsType": "book", "PropType": "prop_type"})108    prop_frame = raw_display.dropna(subset='Player')109    110    collection = db["Pick6_Trends"] 111    cursor = collection.find()112 113    raw_display = pd.DataFrame(list(cursor))114    raw_display = raw_display[['Player', 'over_prop', 'over_line', 'under_prop', 'under_line', 'book', 'prop_type', 'No Vig', 'Team', 'L5 Success', 'L10_Success', 'L20_success', 'L10 Avg', 'Projection',115                               'Proj Diff', 'Matchup Boost', 'Implied Over', 'Trending Over', 'Over Edge', 'Implied Under', 'Trending Under', 'Under Edge']]116    pick_frame = raw_display.drop_duplicates(subset=['Player', 'prop_type'], keep='first')117    pick_frame = pick_frame.reset_index(drop=True)118 119    prop_frame['Player'].replace(['Jaren Jackson', 'Nic Claxton', 'Jabari Smith', 'Lu Dort', 'Moe Wagner', 'Kyle Kuzma', 'Trey Murphy', 'Cameron Thomas'],120                                 ['Jaren Jackson Jr.', 'Nicolas Claxton', 'Jabari Smith Jr.', 'Luguentz Dort', 'Moritz Wagner', 'Kyle Kuzma Jr.',121                                  'Trey Murphy III', 'Cam Thomas'], inplace=True)122    pick_frame['Player'].replace(['Jaren Jackson', 'Nic Claxton', 'Jabari Smith', 'Lu Dort', 'Moe Wagner', 'Kyle Kuzma', 'Trey Murphy', 'Cameron Thomas'],123                                 ['Jaren Jackson Jr.', 'Nicolas Claxton', 'Jabari Smith Jr.', 'Luguentz Dort', 'Moritz Wagner', 'Kyle Kuzma Jr.',124                                  'Trey Murphy III', 'Cam Thomas'], inplace=True)125    126    collection = prop_db["NBA_Props"] 127    cursor = collection.find()128 129    raw_display = pd.DataFrame(list(cursor))130    market_props = raw_display[['Name', 'Position', 'Projection', 'PropType', 'OddsType', 'over_pay', 'under_pay']]131    market_props['over_prop'] = market_props['Projection']132    market_props['over_line'] = market_props['over_pay'].apply(lambda x: (x - 1) * 100 if x >= 2.0 else -100 / (x - 1))133    market_props['under_prop'] = market_props['Projection']134    market_props['under_line'] = market_props['under_pay'].apply(lambda x: (x - 1) * 100 if x >= 2.0 else -100 / (x - 1))135    136    return game_model, raw_baselines, player_stats, prop_frame, pick_frame, market_props, timestamp137 138def calculate_no_vig(row):139    def implied_probability(american_odds):140        if american_odds < 0:141            return (-american_odds) / ((-american_odds) + 100)142        else:143            return 100 / (american_odds + 100)144 145    over_line = row['over_line']146    under_line = row['under_line']147    over_prop = row['over_prop']148    149    over_prob = implied_probability(over_line)150    under_prob = implied_probability(under_line)151    152    total_prob = over_prob + under_prob153    no_vig_prob = (over_prob / total_prob + 0.5) * over_prop154    155    return no_vig_prob156 157def convert_df_to_csv(df):158    return df.to_csv().encode('utf-8')159 160game_model, raw_baselines, player_stats, prop_frame, pick_frame, market_props, timestamp = init_baselines()161t_stamp = f"Last Update: " + str(timestamp) + f" CST"162 163tab1, tab2, tab3, tab4, tab5, tab6 = st.tabs(["Game Betting Model", 'Prop Market', "Player Projections", "Prop Trend Table", "Player Prop Simulations", "Stat Specific Simulations"])164 165with tab1:166    st.info(t_stamp)167    if st.button("Reset Data", key='reset1'):168              st.cache_data.clear()169              game_model, raw_baselines, player_stats, prop_frame, pick_frame, market_props, timestamp = init_baselines()170              t_stamp = f"Last Update: " + str(timestamp) + f" CST"171    line_var1 = st.radio('How would you like to display odds?', options = ['Percentage', 'American'], key='line_var1')172    team_frame = game_model173    if line_var1 == 'Percentage':174        team_frame = team_frame[['Team', 'Opp', 'PD Team Points', 'PD Opp Points', 'VEG Team Points', 'VEG Opp Points', 'PD Proj Total', 'VEG Proj Total', 'PD Over%', 'PD Under%', 'PD Proj Winner', 'PD Proj Spread', 'PD W Spread', 'VEG W Spread', 'PD Win%']]175        team_frame = team_frame.set_index('Team')176        st.dataframe(team_frame.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(game_format, precision=2), use_container_width = True)177    if line_var1 == 'American':178        team_frame = team_frame[['Team', 'Opp', 'PD Team Points', 'PD Opp Points', 'VEG Team Points', 'VEG Opp Points', 'PD Proj Total', 'VEG Proj Total', 'PD Over Odds', 'PD Under Odds', 'PD Proj Winner', 'PD Proj Spread', 'PD W Spread', 'VEG W Spread', 'PD Odds']]179        team_frame = team_frame.set_index('Team')180        st.dataframe(team_frame.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(game_format, precision=2), use_container_width = True)181    182    st.download_button(183        label="Export Team Model",184        data=convert_df_to_csv(team_frame),185        file_name='NBA_team_betting_export.csv',186        mime='text/csv',187        key='team_export',188    )189 190with tab2:191    st.info(t_stamp)192    if st.button("Reset Data", key='reset2'):193              st.cache_data.clear()194              game_model, raw_baselines, player_stats, prop_frame, pick_frame, market_props, timestamp = init_baselines()195              t_stamp = f"Last Update: " + str(timestamp) + f" CST"196    market_type = st.selectbox('Select type of prop are you wanting to view', options = prop_table_options, key = 'market_type_key')197    disp_market = market_props.copy()198    disp_market = disp_market[disp_market['PropType'] == market_type]199    disp_market['No_Vig_Prop'] = disp_market.apply(calculate_no_vig, axis=1)200    fanduel_frame = disp_market[disp_market['OddsType'] == 'FANDUEL']201    fanduel_dict = dict(zip(fanduel_frame['Name'], fanduel_frame['No_Vig_Prop']))202    draftkings_frame = disp_market[disp_market['OddsType'] == 'DRAFTKINGS']203    draftkings_dict = dict(zip(draftkings_frame['Name'], draftkings_frame['No_Vig_Prop']))204    mgm_frame = disp_market[disp_market['OddsType'] == 'MGM']205    mgm_dict = dict(zip(mgm_frame['Name'], mgm_frame['No_Vig_Prop']))206    bet365_frame = disp_market[disp_market['OddsType'] == 'BET_365']207    bet365_dict = dict(zip(bet365_frame['Name'], bet365_frame['No_Vig_Prop']))208 209    disp_market['FANDUEL'] = disp_market['Name'].map(fanduel_dict)210    disp_market['DRAFTKINGS'] = disp_market['Name'].map(draftkings_dict)211    disp_market['MGM'] = disp_market['Name'].map(mgm_dict)212    disp_market['BET365'] = disp_market['Name'].map(bet365_dict)213 214    disp_market = disp_market[['Name', 'Position','FANDUEL', 'DRAFTKINGS', 'MGM', 'BET365']]215    disp_market = disp_market.drop_duplicates(subset=['Name'], keep='first', ignore_index=True)216 217    st.dataframe(disp_market.style.background_gradient(axis=1, subset=['FANDUEL', 'DRAFTKINGS', 'MGM', 'BET365'], cmap='RdYlGn').format(prop_format, precision=2), height = 1000, use_container_width = True)218    st.download_button(219        label="Export Market Props",220        data=convert_df_to_csv(disp_market),221        file_name='NFL_market_props_export.csv',222        mime='text/csv',223    )224 225with tab3:226    st.info(t_stamp)227    if st.button("Reset Data", key='reset3'):228              st.cache_data.clear()229              game_model, raw_baselines, player_stats, prop_frame, pick_frame, market_props, timestamp = init_baselines()230              t_stamp = f"Last Update: " + str(timestamp) + f" CST"231    split_var1 = st.radio("Would you like to view all teams or specific ones?", ('All', 'Specific Teams'), key='split_var1')232    if split_var1 == 'Specific Teams':233        team_var1 = st.multiselect('Which teams would you like to include in the tables?', options = player_stats['Team'].unique(), key='team_var1')234    elif split_var1 == 'All':235        team_var1 = player_stats.Team.values.tolist()236    player_stats = player_stats[player_stats['Team'].isin(team_var1)]237    player_stats_disp = player_stats.set_index('Player')238    player_stats_disp = player_stats_disp.sort_values(by='Fantasy', ascending=False)239    st.dataframe(player_stats_disp.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(precision=2), use_container_width = True)240    st.download_button(241        label="Export Prop Model",242        data=convert_df_to_csv(player_stats),243        file_name='NBA_stats_export.csv',244        mime='text/csv',245    )246    247with tab4:248    st.info(t_stamp)249    if st.button("Reset Data", key='reset4'):250              st.cache_data.clear()251              game_model, raw_baselines, player_stats, prop_frame, pick_frame, market_props, timestamp = init_baselines()252              t_stamp = f"Last Update: " + str(timestamp) + f" CST"253    split_var5 = st.radio("Would you like to view all teams or specific ones?", ('All', 'Specific Teams'), key='split_var5')254    if split_var5 == 'Specific Teams':255        team_var5 = st.multiselect('Which teams would you like to include in the tables?', options = player_stats['Team'].unique(), key='team_var5')256    elif split_var5 == 'All':257        team_var5 = player_stats.Team.values.tolist()258    book_split5 = st.radio("Would you like to view all books or specific ones?", ('All', 'Specific Books'), key='book_split5')259    if book_split5 == 'Specific Books':260        book_var5 = st.multiselect('Which books would you like to include in the tables?', options = ['BET_365', 'DRAFTKINGS', 'CONSENSUS', 'FANDUEL', 'MGM', 'UNIBET', 'WILLIAM_HILL'], key='book_var5')261    elif book_split5 == 'All':262        book_var5 = ['BET_365', 'DRAFTKINGS', 'CONSENSUS', 'FANDUEL', 'MGM', 'UNIBET', 'WILLIAM_HILL']263    prop_type_var2 = st.selectbox('Select type of prop are you wanting to view', options = prop_table_options)264    prop_frame_disp = prop_frame[prop_frame['Team'].isin(team_var5)]265    prop_frame_disp = prop_frame_disp[prop_frame_disp['book'].isin(book_var5)]266    prop_frame_disp = prop_frame_disp[prop_frame_disp['prop_type'] == prop_type_var2]267    prop_frame_disp = prop_frame_disp.sort_values(by='Trending Over', ascending=False)268    st.dataframe(prop_frame_disp.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(prop_format, precision=2), use_container_width = True)269    st.download_button(270        label="Export Prop Trends Model",271        data=convert_df_to_csv(prop_frame),272        file_name='NBA_prop_trends_export.csv',273        mime='text/csv',274    )275    276with tab5:277    st.info(t_stamp)278    if st.button("Reset Data", key='reset5'):279              st.cache_data.clear()280              game_model, raw_baselines, player_stats, prop_frame, pick_frame, market_props, timestamp = init_baselines()281              t_stamp = f"Last Update: " + str(timestamp) + f" CST"282    col1, col2 = st.columns([1, 5])283    284    with col2:285        df_hold_container = st.empty()286        info_hold_container = st.empty()287        plot_hold_container = st.empty()288    289    with col1:290        player_check = st.selectbox('Select player to simulate props', options = player_stats['Player'].unique())291        prop_type_var = st.selectbox('Select type of prop to simulate', options = ['points', 'threes', 'rebounds', 'assists', 'blocks', 'steals',292                                                                                   'PRA', 'points+rebounds', 'points+assists', 'rebounds+assists'])293 294        ou_var = st.selectbox('Select wether it is an over or under', options = ['Over', 'Under'])295        if prop_type_var == 'points':296            prop_var = st.number_input('Type in the prop offered (i.e 5.5)', min_value = 0.0, max_value = 50.5, value = 15.5, step = .5)297        elif prop_type_var == 'threes':298            prop_var = st.number_input('Type in the prop offered (i.e 5.5)', min_value = 0.0, max_value = 5.5, value = 1.5, step = .5)299        elif prop_type_var == 'rebounds':300            prop_var = st.number_input('Type in the prop offered (i.e 5.5)', min_value = 0.0, max_value = 25.5, value = 5.5, step = .5)301        elif prop_type_var == 'assists':302            prop_var = st.number_input('Type in the prop offered (i.e 5.5)', min_value = 0.0, max_value = 25.5, value = 5.5, step = .5)303        elif prop_type_var == 'blocks':304            prop_var = st.number_input('Type in the prop offered (i.e 5.5)', min_value = 0.0, max_value = 5.5, value = 1.5, step = .5)305        elif prop_type_var == 'steals':306            prop_var = st.number_input('Type in the prop offered (i.e 5.5)', min_value = 0.0, max_value = 5.5, value = 1.5, step = .5)307        elif prop_type_var == 'PRA':308            prop_var = st.number_input('Type in the prop offered (i.e 5.5)', min_value = 0.0, max_value = 65.5, value = 20.5, step = .5)309        elif prop_type_var == 'points+rebounds':310            prop_var = st.number_input('Type in the prop offered (i.e 5.5)', min_value = 0.0, max_value = 45.5, value = 10.5, step = .5)311        elif prop_type_var == 'points+assists':312            prop_var = st.number_input('Type in the prop offered (i.e 5.5)', min_value = 0.0, max_value = 45.5, value = 10.5, step = .5)313        elif prop_type_var == 'rebounds+assists':314            prop_var = st.number_input('Type in the prop offered (i.e 5.5)', min_value = 0.0, max_value = 45.5, value = 10.5, step = .5)315        line_var = st.number_input('Type in the line on the prop (i.e. -120)', min_value = -1500, max_value = 1500, value = -150, step = 1)316        line_var = line_var + 1317 318        if st.button('Simulate Prop'):319            with col2:320                   321                    with df_hold_container.container():322 323                        df = player_stats324                        st.write("sim started")325 326                        total_sims = 1000327 328                        df.replace("", 0, inplace=True)329 330                        player_var = df[df['Player'] == player_check]331                        player_var = player_var.reset_index()332 333                        if prop_type_var == 'points':334                            df['Median'] = pd.to_numeric(df['Points'], errors='coerce')335                        elif prop_type_var == 'threes':336                            df['Median'] = pd.to_numeric(df['3P'], errors='coerce')337                        elif prop_type_var == 'rebounds':338                            df['Median'] = pd.to_numeric(df['Rebounds'], errors='coerce')339                        elif prop_type_var == 'assists':340                            df['Median'] = pd.to_numeric(df['Assists'], errors='coerce')341                        elif prop_type_var == 'blocks':342                            df['Median'] = pd.to_numeric(df['Blocks'], errors='coerce')343                        elif prop_type_var == 'steals':344                            df['Median'] = pd.to_numeric(df['Steals'], errors='coerce')345                        elif prop_type_var == 'PRA':346                            df['Median'] = pd.to_numeric(df['Points'], errors='coerce') + pd.to_numeric(df['Rebounds'], errors='coerce') + pd.to_numeric(df['Assists'], errors='coerce')347                        elif prop_type_var == 'points+rebounds':348                            df['Median'] = pd.to_numeric(df['Points'], errors='coerce') + pd.to_numeric(df['Rebounds'], errors='coerce')349                        elif prop_type_var == 'points+assists':350                            df['Median'] = pd.to_numeric(df['Points'], errors='coerce') + pd.to_numeric(df['Assists'], errors='coerce')351                        elif prop_type_var == 'rebounds+assists':352                            df['Median'] = pd.to_numeric(df['Assists'], errors='coerce') + pd.to_numeric(df['Rebounds'], errors='coerce')353 354                        flex_file = df355                        flex_file['Floor'] = (flex_file['Median'] * .25) + (flex_file['Minutes'] * .25)356                        flex_file['Ceiling'] = flex_file['Median'] + 10 + (flex_file['Minutes'] * .25)357                        flex_file['STD'] = (flex_file['Median']/4)358                        flex_file = flex_file[['Player', 'Floor', 'Median', 'Ceiling', 'STD']]359 360                        hold_file = flex_file361                        overall_file = flex_file362                        salary_file = flex_file363 364                        overall_players = overall_file[['Player']]365 366                        for x in range(0,total_sims):367                            overall_file[x] = np.random.normal(overall_file['Median'],overall_file['STD'])368 369                        overall_file=overall_file.drop(['Player', 'Floor', 'Median', 'Ceiling', 'STD'], axis=1)370 371                        players_only = hold_file[['Player']]372 373                        player_outcomes = pd.merge(players_only, overall_file, left_index=True, right_index=True)374                        st.write("sim finished, calculating outcomes")375 376                        players_only['Mean_Outcome'] = overall_file.mean(axis=1)377                        players_only['Prop'] = prop_var378                        players_only['poisson_var'] = players_only.apply(calculate_poisson, axis=1)379                        players_only['10%'] = overall_file.quantile(0.1, axis=1)380                        players_only['90%'] = overall_file.quantile(0.9, axis=1)381                        if ou_var == 'Over':382                            players_only['beat_prop'] = np.where(players_only['Prop'] <= 3, players_only['poisson_var'], overall_file[overall_file > prop_var].count(axis=1)/float(total_sims))383                        elif ou_var == 'Under':384                            players_only['beat_prop'] = np.where(players_only['Prop'] <= 3, 1 - players_only['poisson_var'], (overall_file[overall_file < prop_var].count(axis=1)/float(total_sims)))385 386                        players_only['implied_odds'] = np.where(line_var <= 0, (-(line_var)/((-(line_var))+100)), 100/(line_var+100))387 388                        players_only['Player'] = hold_file[['Player']]389 390                        final_outcomes = players_only[['Player', '10%', 'Mean_Outcome', '90%', 'implied_odds', 'beat_prop']]391                        final_outcomes['Bet?'] = np.where(final_outcomes['beat_prop'] - final_outcomes['implied_odds'] >= .10, "Bet", "No Bet")392                        final_outcomes = final_outcomes[final_outcomes['Player'] == player_check]393                        player_outcomes = player_outcomes[player_outcomes['Player'] == player_check]394                        player_outcomes = player_outcomes.drop(columns=['Player']).transpose()395                        player_outcomes = player_outcomes.reset_index()396                        player_outcomes.columns = ['Instance', 'Outcome']397 398                        x1 = player_outcomes.Outcome.to_numpy()399 400                        print(x1)401 402                        hist_data = [x1]403 404                        group_labels = ['player outcomes']405 406                        fig = px.histogram(407                                player_outcomes, x='Outcome')408                        fig.add_vline(x=prop_var, line_dash="dash", line_color="green")409 410                        with df_hold_container:411                            df_hold_container = st.empty()412                            format_dict = {'10%': '{:.2f}', 'Mean_Outcome': '{:.2f}','90%': '{:.2f}', 'beat_prop': '{:.2%}','implied_odds': '{:.2%}'}413                            st.dataframe(final_outcomes.style.format(format_dict), use_container_width = True)414 415                        with info_hold_container:416                            st.info('The Y-axis is the percent of times in simulations that the player reaches certain thresholds, while the X-axis is the threshold to be met. The Green dotted line is the prop you entered. You can hover over any spot and see the percent to reach that mark.')417 418                        with plot_hold_container:419                            st.dataframe(player_outcomes, use_container_width = True)420                            plot_hold_container = st.empty()421                            st.plotly_chart(fig, use_container_width=True)422 423with tab6:424    st.info(t_stamp)425    st.info('The Over and Under percentages are a compositve percentage based on simulations, historical performance, and implied probabilities, and may be different than you would expect based purely on the median projection. Likewise, the Edge of a bet is not the only indicator of if you should make the bet or not as the suggestion is using a base acceptable threshold to determine how much edge you should have for each stat category.')426    if st.button("Reset Data/Load Data", key='reset6'):427              st.cache_data.clear()428              game_model, raw_baselines, player_stats, prop_frame, pick_frame, market_props, timestamp = init_baselines()429              t_stamp = f"Last Update: " + str(timestamp) + f" CST"430 431    settings_container = st.empty()432    df_hold_container = st.empty()433    export_container = st.empty()434    435    with settings_container.container():436        col1, col2, col3, col4 = st.columns([3, 3, 3, 3])437        with col1:438            game_select_var = st.selectbox('Select prop source', options = ['Aggregate', 'Pick6'])439        with col2:440            book_select_var = st.selectbox('Select book', options = ['ALL', 'BET_365', 'DRAFTKINGS', 'FANDUEL', 'MGM', 'UNIBET', 'WILLIAM_HILL'])441            if book_select_var == 'ALL':442                book_selections = ['BET_365', 'DRAFTKINGS', 'FANDUEL', 'MGM', 'UNIBET', 'WILLIAM_HILL']443            else:444                book_selections = [book_select_var]445            if game_select_var == 'Aggregate':446                prop_df = prop_frame[['Player', 'book', 'over_prop', 'over_line', 'under_line', 'prop_type', 'Trending Over', 'Trending Under']]447            elif game_select_var == 'Pick6':448                prop_df = pick_frame[['Player', 'book', 'over_prop', 'over_line', 'under_line', 'prop_type', 'Trending Over', 'Trending Under']]449                book_selections = ['Pick6']450        with col3:451            if game_select_var == 'Aggregate':452                prop_type_var = st.selectbox('Select prop category', options = ['All Props', 'NBA_GAME_PLAYER_POINTS', 'NBA_GAME_PLAYER_REBOUNDS', 'NBA_GAME_PLAYER_ASSISTS', 'NBA_GAME_PLAYER_POINTS_REBOUNDS_ASSISTS',453                                                                                'NBA_GAME_PLAYER_POINTS_REBOUNDS', 'NBA_GAME_PLAYER_POINTS_ASSISTS', 'NBA_GAME_PLAYER_REBOUNDS_ASSISTS', 'NBA_GAME_PLAYER_3_POINTERS_MADE'])454            elif game_select_var == 'Pick6':455                prop_type_var = st.selectbox('Select prop category', options = ['All Props', 'Points', 'Rebounds', 'Assists', 'Points + Assists + Rebounds', 'Points + Assists', 'Points + Rebounds', 'Assists + Rebounds', '3-Pointers Made'])456        with col4:457            st.download_button(458                    label="Download Prop Source",459                    data=convert_df_to_csv(prop_df),460                    file_name='Nba_prop_source.csv',461                    mime='text/csv',462                    key='prop_source',463                )464        465    if st.button('Simulate Prop Category'):466                   467        with df_hold_container.container():468            if prop_type_var == 'All Props':469                if game_select_var == 'Aggregate':470                    prop_df_raw = prop_frame[['Player', 'book', 'over_prop', 'over_line', 'under_line', 'prop_type', 'Trending Over', 'Trending Under']]471                    sim_vars = ['NBA_GAME_PLAYER_POINTS', 'NBA_GAME_PLAYER_REBOUNDS', 'NBA_GAME_PLAYER_ASSISTS', 'NBA_GAME_PLAYER_POINTS_REBOUNDS_ASSISTS', 'NBA_GAME_PLAYER_POINTS_REBOUNDS',472                                'NBA_GAME_PLAYER_POINTS_ASSISTS', 'NBA_GAME_PLAYER_REBOUNDS_ASSISTS', 'NBA_GAME_PLAYER_3_POINTERS_MADE']473                elif game_select_var == 'Pick6':474                    prop_df_raw = pick_frame[['Player', 'book', 'over_prop', 'over_line', 'under_line', 'prop_type', 'Trending Over', 'Trending Under']]475                    sim_vars = ['Points', 'Rebounds', 'Assists', 'Points + Assists + Rebounds', 'Points + Assists', 'Points + Rebounds', 'Assists + Rebounds', '3-Pointers Made']476                477                player_df = player_stats.copy()478                    479                for prop in sim_vars:480                    481                    for books in book_selections:482                        prop_df = prop_df_raw[prop_df_raw['prop_type'] == prop]483                        prop_df = prop_df[prop_df['book'] == books]484                        prop_df = prop_df[['Player', 'book', 'over_prop', 'over_line', 'under_line', 'prop_type', 'Trending Over', 'Trending Under']]485                        prop_df.rename(columns={"over_prop": "Prop"}, inplace = True)486                        prop_df['Over'] = 1 / prop_df['over_line']487                        prop_df['Under'] = 1 / prop_df['under_line']488 489                        prop_dict = dict(zip(prop_df.Player, prop_df.Prop))490                        prop_type_dict = dict(zip(prop_df.Player, prop_df.prop_type))491                        book_dict = dict(zip(prop_df.Player, prop_df.book))492                        over_dict = dict(zip(prop_df.Player, prop_df.Over))493                        under_dict = dict(zip(prop_df.Player, prop_df.Under))494                        trending_over_dict = dict(zip(prop_df.Player, prop_df['Trending Over']))495                        trending_under_dict = dict(zip(prop_df.Player, prop_df['Trending Under']))496 497                        player_df['book'] = player_df['Player'].map(book_dict)498                        player_df['Prop'] = player_df['Player'].map(prop_dict)499                        player_df['prop_type'] = player_df['Player'].map(prop_type_dict)500                        player_df['Trending Over'] = player_df['Player'].map(trending_over_dict)501                        player_df['Trending Under'] = player_df['Player'].map(trending_under_dict)502 503                        df = player_df.reset_index(drop=True)504 505                        team_dict = dict(zip(df.Player, df.Team))506                        507                        total_sims = 1000508 509                        df.replace("", 0, inplace=True)510                        511                        if prop == "NBA_GAME_PLAYER_POINTS" or prop == "Points":512                            df['Median'] = pd.to_numeric(df['Points'], errors='coerce')513                        elif prop == "NBA_GAME_PLAYER_REBOUNDS" or prop == "Rebounds":514                            df['Median'] = pd.to_numeric(df['Rebounds'], errors='coerce')515                        elif prop == "NBA_GAME_PLAYER_ASSISTS" or prop == "Assists":516                            df['Median'] = pd.to_numeric(df['Assists'], errors='coerce')517                        elif prop == "NBA_GAME_PLAYER_3_POINTERS_MADE" or prop == "3-Pointers Made":518                            df['Median'] = pd.to_numeric(df['3P'], errors='coerce')519                        elif prop == "NBA_GAME_PLAYER_POINTS_REBOUNDS_ASSISTS" or prop == "Points + Assists + Rebounds":520                            df['Median'] = pd.to_numeric(df['Points'], errors='coerce') + pd.to_numeric(df['Rebounds'], errors='coerce') + pd.to_numeric(df['Assists'], errors='coerce')521                        elif prop == "NBA_GAME_PLAYER_POINTS_REBOUNDS" or prop == "Points + Rebounds":522                            df['Median'] = pd.to_numeric(df['Points'], errors='coerce') + pd.to_numeric(df['Rebounds'], errors='coerce')523                        elif prop == "NBA_GAME_PLAYER_POINTS_ASSISTS" or prop == "Points + Assists":524                            df['Median'] = pd.to_numeric(df['Points'], errors='coerce') + pd.to_numeric(df['Assists'], errors='coerce')525                        elif prop == "NBA_GAME_PLAYER_REBOUNDS_ASSISTS" or prop == "Assists + Rebounds":526                            df['Median'] = pd.to_numeric(df['Rebounds'], errors='coerce') + pd.to_numeric(df['Assists'], errors='coerce')527                            528                        flex_file = df.copy()529                        flex_file['Floor'] = flex_file['Median'] * .25530                        flex_file['Ceiling'] = flex_file['Median'] + (flex_file['Median'] * 1.75)531                        flex_file['STD'] = flex_file['Median'] / 4532                        flex_file['Prop'] = flex_file['Player'].map(prop_dict)533                        flex_file = flex_file[['Player', 'book', 'Prop', 'Floor', 'Median', 'Ceiling', 'STD']]534 535                        hold_file = flex_file.copy()536                        overall_file = flex_file.copy()537                        prop_file = flex_file.copy()538                                539                        overall_players = overall_file[['Player']]540 541                        for x in range(0,total_sims):    542                            prop_file[x] = prop_file['Prop']543 544                        prop_file = prop_file.drop(['Player', 'book', 'Prop', 'Floor', 'Median', 'Ceiling', 'STD'], axis=1)545 546                        for x in range(0,total_sims):547                            overall_file[x] = np.random.normal(overall_file['Median'],overall_file['STD'])548 549                        overall_file=overall_file.drop(['Player', 'book', 'Prop', 'Floor', 'Median', 'Ceiling', 'STD'], axis=1)550 551                        players_only = hold_file[['Player']]552 553                        player_outcomes = pd.merge(players_only, overall_file, left_index=True, right_index=True)554 555                        prop_check = (overall_file - prop_file)556 557                        players_only['Mean_Outcome'] = overall_file.mean(axis=1)558                        players_only['Book'] = players_only['Player'].map(book_dict)559                        players_only['Prop'] = players_only['Player'].map(prop_dict)560                        players_only['Trending Over'] = players_only['Player'].map(trending_over_dict)561                        players_only['Trending Under'] = players_only['Player'].map(trending_under_dict)562                        players_only['over_adj'] = np_where((players_only['Mean_Outcome'] - players_only['Prop']) > 0, 1, (players_only['Mean_Outcome'] / players_only['Prop']))563                        players_only['under_adj'] = np_where((players_only['Prop'] - players_only['Mean_Outcome']) > 0, 1, (players_only['Prop'] / players_only['Mean_Outcome']))564                        players_only['poisson_var'] = players_only.apply(calculate_poisson, axis=1)565                        players_only['10%'] = overall_file.quantile(0.1, axis=1)566                        players_only['90%'] = overall_file.quantile(0.9, axis=1)567                        players_only['Over'] = np_where(players_only['Prop'] <= 3, players_only['poisson_var'], prop_check[prop_check > 0].count(axis=1)/float(total_sims))568                        players_only['Imp Over'] = players_only['Player'].map(over_dict)569                        players_only['Over%'] = players_only[["Over", "Imp Over", "Trending Over"]].mean(axis=1)570                        players_only['Under'] = np_where(players_only['Prop'] <= 3, 1 - players_only['poisson_var'], prop_check[prop_check < 0].count(axis=1)/float(total_sims))571                        players_only['Imp Under'] = players_only['Player'].map(under_dict)572                        players_only['Under%'] = players_only[["Under", "Imp Under", "Trending Under"]].mean(axis=1)573                        players_only['Prop_avg'] = players_only['Prop'].mean() / 100574                        players_only['prop_threshold'] = .10575                        players_only = players_only[players_only['Mean_Outcome'] > 0]576                        players_only['Over_diff'] = players_only['Over%'] - players_only['Imp Over']577                        players_only['Under_diff'] = players_only['Under%'] - players_only['Imp Under']578                        players_only['Bet_check'] = np.where(players_only['Over_diff'] > players_only['Under_diff'], players_only['Over_diff'] * players_only['over_adj'], players_only['Under_diff'] * players_only['under_adj'])579                        players_only['Bet_suggest'] = np.where(players_only['Over_diff'] > players_only['Under_diff'], "Over" , "Under")580                        players_only['Bet?'] = np.where(players_only['Bet_check'] >= players_only['prop_threshold'], players_only['Bet_suggest'], "No Bet")581                        players_only['Edge'] = players_only['Bet_check']582                        players_only['Prop Type'] = prop583 584                        players_only['Player'] = hold_file[['Player']]585                        players_only['Team'] = players_only['Player'].map(team_dict)586 587                        leg_outcomes = players_only[['Player', 'Team', 'Book', 'Prop Type', 'Prop', 'Mean_Outcome', 'Imp Over', 'Trending Over', 'Over%', 'Imp Under', 'Trending Under', 'Under%', 'Bet?', 'Edge']]588                        sim_all_hold = pd.concat([sim_all_hold, leg_outcomes], ignore_index=True)589                        590                        final_outcomes = sim_all_hold591                        st.write(f'finished {prop} for {books}')592                    593            elif prop_type_var != 'All Props':594                595                player_df = player_stats.copy()596                597                if game_select_var == 'Aggregate':598                    prop_df_raw = prop_frame[['Player', 'book', 'over_prop', 'over_line', 'under_line', 'prop_type', 'Trending Over', 'Trending Under']]599                elif game_select_var == 'Pick6':600                    prop_df_raw = pick_frame[['Player', 'book', 'over_prop', 'over_line', 'under_line', 'prop_type', 'Trending Over', 'Trending Under']]601                    602                for books in book_selections:603                    prop_df = prop_df_raw[prop_df_raw['book'] == books]604 605                    if prop_type_var == "NBA_GAME_PLAYER_POINTS":606                        prop_df = prop_df[prop_df['prop_type'] == 'NBA_GAME_PLAYER_POINTS']607                    elif prop_type_var == "Points":608                        prop_df = prop_df[prop_df['prop_type'] == 'Points']609                    elif prop_type_var == "NBA_GAME_PLAYER_REBOUNDS":610                        prop_df = prop_df[prop_df['prop_type'] == 'NBA_GAME_PLAYER_REBOUNDS']611                    elif prop_type_var == "Rebounds":612                        prop_df = prop_df[prop_df['prop_type'] == 'Rebounds']613                    elif prop_type_var == "NBA_GAME_PLAYER_ASSISTS":614                        prop_df = prop_df[prop_df['prop_type'] == 'NBA_GAME_PLAYER_ASSISTS']615                    elif prop_type_var == "Assists":616                        prop_df = prop_df[prop_df['prop_type'] == 'Assists']617                    elif prop_type_var == "NBA_GAME_PLAYER_3_POINTERS_MADE":618                        prop_df = prop_df[prop_df['prop_type'] == 'NBA_GAME_PLAYER_3_POINTERS_MADE']619                    elif prop_type_var == "3-Pointers Made":620                        prop_df = prop_df[prop_df['prop_type'] == '3-Pointers Made']621                    elif prop_type_var == "NBA_GAME_PLAYER_POINTS_REBOUNDS_ASSISTS":622                        prop_df = prop_df[prop_df['prop_type'] == 'NBA_GAME_PLAYER_POINTS_REBOUNDS_ASSISTS']623                    elif prop_type_var == "Points + Assists + Rebounds":624                        prop_df = prop_df[prop_df['prop_type'] == 'Points + Assists + Rebounds']625                    elif prop_type_var == "NBA_GAME_PLAYER_POINTS_REBOUNDS":626                        prop_df = prop_df[prop_df['prop_type'] == 'NBA_GAME_PLAYER_POINTS_REBOUNDS']627                    elif prop_type_var == "Points + Rebounds":628                        prop_df = prop_df[prop_df['prop_type'] == 'Points + Rebounds']629                    elif prop_type_var == "NBA_GAME_PLAYER_POINTS_ASSISTS":630                        prop_df = prop_df[prop_df['prop_type'] == 'NBA_GAME_PLAYER_POINTS_ASSISTS']631                    elif prop_type_var == "Points + Assists":632                        prop_df = prop_df[prop_df['prop_type'] == 'Points + Assists']633                    elif prop_type_var == "NBA_GAME_PLAYER_REBOUNDS_ASSISTS":634                        prop_df = prop_df[prop_df['prop_type'] == 'NBA_GAME_PLAYER_REBOUNDS_ASSISTS']635                    elif prop_type_var == "Assists + Rebounds":636                        prop_df = prop_df[prop_df['prop_type'] == 'Assists + Rebounds']637 638                    prop_df = prop_df[['Player', 'book', 'over_prop', 'over_line', 'under_line', 'prop_type', 'Trending Over', 'Trending Under']]639                    prop_df = prop_df.rename(columns={"over_prop": "Prop"})640                    prop_df['Over'] = 1 / prop_df['over_line']641                    prop_df['Under'] = 1 / prop_df['under_line']642 643                    prop_dict = dict(zip(prop_df.Player, prop_df.Prop))644                    prop_type_dict = dict(zip(prop_df.Player, prop_df.prop_type))645                    book_dict = dict(zip(prop_df.Player, prop_df.book))646                    over_dict = dict(zip(prop_df.Player, prop_df.Over))647                    under_dict = dict(zip(prop_df.Player, prop_df.Under))648                    trending_over_dict = dict(zip(prop_df.Player, prop_df['Trending Over']))649                    trending_under_dict = dict(zip(prop_df.Player, prop_df['Trending Under']))650 651                    player_df['book'] = player_df['Player'].map(book_dict)652                    player_df['Prop'] = player_df['Player'].map(prop_dict)653                    player_df['prop_type'] = player_df['Player'].map(prop_type_dict)654                    player_df['Trending Over'] = player_df['Player'].map(trending_over_dict)655                    player_df['Trending Under'] = player_df['Player'].map(trending_under_dict)656 657                    df = player_df.reset_index(drop=True)658 659                    team_dict = dict(zip(df.Player, df.Team))660                    661                    total_sims = 1000662 663                    df.replace("", 0, inplace=True)664                    665                    if prop_type_var == "NBA_GAME_PLAYER_POINTS" or prop_type_var == "Points":666                        df['Median'] = pd.to_numeric(df['Points'], errors='coerce')667                    elif prop_type_var == "NBA_GAME_PLAYER_REBOUNDS" or prop_type_var == "Rebounds":668                        df['Median'] = pd.to_numeric(df['Rebounds'], errors='coerce')669                    elif prop_type_var == "NBA_GAME_PLAYER_ASSISTS" or prop_type_var == "Assists":670                        df['Median'] = pd.to_numeric(df['Assists'], errors='coerce')671                    elif prop_type_var == "NBA_GAME_PLAYER_3_POINTERS_MADE" or prop_type_var == "3-Pointers Made":672                        df['Median'] = pd.to_numeric(df['3P'], errors='coerce')673                    elif prop_type_var == "NBA_GAME_PLAYER_POINTS_REBOUNDS_ASSISTS" or prop_type_var == "Points + Assists + Rebounds":674                        df['Median'] = pd.to_numeric(df['Points'], errors='coerce') + pd.to_numeric(df['Rebounds'], errors='coerce') + pd.to_numeric(df['Assists'], errors='coerce')675                    elif prop_type_var == "NBA_GAME_PLAYER_POINTS_REBOUNDS" or prop_type_var == "Points + Rebounds":676                        df['Median'] = pd.to_numeric(df['Points'], errors='coerce') + pd.to_numeric(df['Rebounds'], errors='coerce')677                    elif prop_type_var == "NBA_GAME_PLAYER_POINTS_ASSISTS" or prop_type_var == "Points + Assists":678                        df['Median'] = pd.to_numeric(df['Points'], errors='coerce') + pd.to_numeric(df['Assists'], errors='coerce')679                    elif prop_type_var == "NBA_GAME_PLAYER_REBOUNDS_ASSISTS" or prop_type_var == "Assists + Rebounds":680                        df['Median'] = pd.to_numeric(df['Rebounds'], errors='coerce') + pd.to_numeric(df['Assists'], errors='coerce')681                    682                    flex_file = df.copy()683                    flex_file['Floor'] = flex_file['Median'] * .25684                    flex_file['Ceiling'] = flex_file['Median'] + (flex_file['Median'] * 1.75)685                    flex_file['STD'] = flex_file['Median'] / 4686                    flex_file['Prop'] = flex_file['Player'].map(prop_dict)687                    flex_file = flex_file[['Player', 'book', 'Prop', 'Floor', 'Median', 'Ceiling', 'STD']]688 689                    hold_file = flex_file.copy()690                    overall_file = flex_file.copy()691                    prop_file = flex_file.copy()692                            693                    overall_players = overall_file[['Player']]694 695                    for x in range(0,total_sims):    696                        prop_file[x] = prop_file['Prop']697 698                    prop_file = prop_file.drop(['Player', 'book', 'Prop', 'Floor', 'Median', 'Ceiling', 'STD'], axis=1)699 700                    for x in range(0,total_sims):701                        overall_file[x] = np.random.normal(overall_file['Median'],overall_file['STD'])702 703                    overall_file=overall_file.drop(['Player', 'book', 'Prop', 'Floor', 'Median', 'Ceiling', 'STD'], axis=1)704 705                    players_only = hold_file[['Player']]706 707                    player_outcomes = pd.merge(players_only, overall_file, left_index=True, right_index=True)708 709                    prop_check = (overall_file - prop_file)710 711                    players_only['Mean_Outcome'] = overall_file.mean(axis=1)712                    players_only['Book'] = players_only['Player'].map(book_dict)713                    players_only['Prop'] = players_only['Player'].map(prop_dict)714                    players_only['Trending Over'] = players_only['Player'].map(trending_over_dict)715                    players_only['Trending Under'] = players_only['Player'].map(trending_under_dict)716                    players_only['over_adj'] = np_where((players_only['Mean_Outcome'] - players_only['Prop']) > 0, 1, (players_only['Mean_Outcome'] / players_only['Prop']))717                    players_only['under_adj'] = np_where((players_only['Prop'] - players_only['Mean_Outcome']) > 0, 1, (players_only['Prop'] / players_only['Mean_Outcome']))718                    players_only['poisson_var'] = players_only.apply(calculate_poisson, axis=1)719                    players_only['10%'] = overall_file.quantile(0.1, axis=1)720                    players_only['90%'] = overall_file.quantile(0.9, axis=1)721                    players_only['Over'] = np_where(players_only['Prop'] <= 3, players_only['poisson_var'], prop_check[prop_check > 0].count(axis=1)/float(total_sims))722                    players_only['Imp Over'] = players_only['Player'].map(over_dict)723                    players_only['Over%'] = players_only[["Over", "Imp Over", "Trending Over"]].mean(axis=1)724                    players_only['Under'] = np_where(players_only['Prop'] <= 3, 1 - players_only['poisson_var'], prop_check[prop_check < 0].count(axis=1)/float(total_sims))725                    players_only['Imp Under'] = players_only['Player'].map(under_dict)726                    players_only['Under%'] = players_only[["Under", "Imp Under", "Trending Under"]].mean(axis=1)727                    players_only['Prop_avg'] = players_only['Prop'].mean() / 100728                    players_only['prop_threshold'] = .10729                    players_only = players_only[players_only['Mean_Outcome'] > 0]730                    players_only['Over_diff'] = players_only['Over%'] - players_only['Imp Over']731                    players_only['Under_diff'] = players_only['Under%'] - players_only['Imp Under']732                    players_only['Bet_check'] = np.where(players_only['Over_diff'] > players_only['Under_diff'], players_only['Over_diff'] * players_only['over_adj'], players_only['Under_diff'] * players_only['under_adj'])733                    players_only['Bet_suggest'] = np.where(players_only['Over_diff'] > players_only['Under_diff'], "Over" , "Under")734                    players_only['Bet?'] = np.where(players_only['Bet_check'] >= players_only['prop_threshold'], players_only['Bet_suggest'], "No Bet")735                    players_only['Edge'] = players_only['Bet_check']736                    players_only['Prop Type'] = prop_type_var737 738                    players_only['Player'] = hold_file[['Player']]739                    players_only['Team'] = players_only['Player'].map(team_dict)740 741                    leg_outcomes = players_only[['Player', 'Team', 'Book', 'Prop Type', 'Prop', 'Mean_Outcome', 'Imp Over', 'Trending Over', 'Over%', 'Imp Under', 'Trending Under', 'Under%', 'Bet?', 'Edge']]742                    sim_all_hold = pd.concat([sim_all_hold, leg_outcomes], ignore_index=True)743                    744                    final_outcomes = sim_all_hold745                    st.write(f'finished {prop_type_var} for {books}')746            747            final_outcomes = final_outcomes.dropna()748            if game_select_var == 'Pick6':749                final_outcomes = final_outcomes.drop_duplicates(subset=['Player', 'Prop Type'])750            final_outcomes = final_outcomes.sort_values(by='Edge', ascending=False)751 752            with df_hold_container:753                df_hold_container = st.empty()754                st.dataframe(final_outcomes.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(sim_format, precision=2), height=500, use_container_width = True)755            with export_container:756                export_container = st.empty()757                st.download_button(758                    label="Export Projections",759                    data=convert_df_to_csv(final_outcomes),760                    file_name='NBA_prop_proj.csv',761                    mime='text/csv',762                    key='prop_proj',763                )