TrueDFS/NFL_Betting_Models_Origin
0
1import streamlit as st2import numpy as np3from numpy import where as np_where4import pandas as pd5import plotly.express as px6import scipy.stats as stats7st.set_page_config(layout="wide")8 9from database import props_db, dfs_db10 11game_format = {'Win%': '{:.2%}', 'Vegas': '{:.2%}', 'Win% Diff': '{:.2%}'}12american_format = {'First Inning Lead Percentage': '{:.2%}', 'Fifth Inning Lead Percentage': '{:.2%}'}13 14st.markdown("""15<style>16 /* Tab styling */17 .stElementContainer [data-baseweb="button-group"] {18 gap: 2.000rem;19 padding: 4px;20 }21 .stElementContainer [kind="segmented_control"] {22 height: 2.000rem;23 white-space: pre-wrap;24 background-color: #68B1E7;25 color: white;26 border-radius: 20px;27 gap: 1px;28 padding: 10px 20px;29 font-weight: bold;30 transition: all 0.3s ease;31 }32 .stElementContainer [kind="segmented_controlActive"] {33 height: 3.000rem;34 background-color: #68B1E7;35 border: 3px solid #4FB286;36 border-radius: 10px;37 color: black;38 }39 .stElementContainer [kind="segmented_control"]:hover {40 background-color: #4FB286;41 cursor: pointer;42 }43 44 div[data-baseweb="select"] > div {45 background-color: #68B1E7;46 color: white;47 }48 49</style>""", unsafe_allow_html=True)50 51def calculate_poisson(row):52 mean_val = row['Mean_Outcome']53 threshold = row['Prop']54 cdf_value = stats.poisson.cdf(threshold, mean_val)55 probability = 1 - cdf_value56 return probability57 58@st.cache_resource(ttl=600)59def init_baselines():60 collection = dfs_db["Game_Betting_Model"] 61 cursor = collection.find()62 raw_display = pd.DataFrame(list(cursor))63 game_model = raw_display[['Team', 'Opp', 'Win%', 'Vegas', 'Win% Diff', 'Win Line', 'Vegas Line', 'Line Diff', 'PD Spread', 'Vegas Spread', 'Spread Diff']]64 65 collection = dfs_db["Player_Stats"] 66 cursor = collection.find()67 raw_display = pd.DataFrame(list(cursor))68 overall_stats = raw_display[['Player', 'Position', 'Team', 'Opp', 'rush_att', 'rec', 'dropbacks', 'rush_yards', 'rush_tds', 'rec_yards', 'rec_tds', 'pass_att', 'pass_yards', 'pass_tds', 'PPR', 'Half_PPR']]69 70 collection = dfs_db["Prop_Trends"] 71 cursor = collection.find()72 raw_display = pd.DataFrame(list(cursor))73 prop_trends = raw_display[['Player', 'over_prop', 'over_line', 'under_prop', 'under_line', 'book', 'prop_type', 'No Vig', 'Team', 'L3 Success', 'L6_Success', 'L10_success', 'L6 Avg', 'Projection',74 'Proj Diff', 'Implied Over', 'Trending Over', 'Over Edge', 'Implied Under', 'Trending Under', 'Under Edge']]75 76 collection = dfs_db["DK_NFL_ROO"] 77 cursor = collection.find()78 79 raw_display = pd.DataFrame(list(cursor))80 raw_display = raw_display[['Player', 'Position', 'Team', 'Opp', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '2x%', '3x%', '4x%',81 'Own', 'Small_Field_Own', 'Large_Field_Own', 'Cash_Field_Own', 'CPT_Own', 'LevX', 'version', 'slate', 'timestamp', 'player_ID', 'site']]82 load_display = raw_display[raw_display['Position'] != 'K']83 timestamp = load_display['timestamp'][0]84 85 collection = dfs_db["Prop_Trends"] 86 cursor = collection.find()87 raw_display = pd.DataFrame(list(cursor))88 prop_frame = raw_display[['Player', 'over_prop', 'over_line', 'under_prop', 'under_line', 'book', 'prop_type', 'No Vig', 'Team', 'L3 Success', 'L6_Success', 'L10_success', 'L6 Avg', 'Projection',89 'Proj Diff', 'Implied Over', 'Trending Over', 'Over Edge', 'Implied Under', 'Trending Under', 'Under Edge']]90 91 collection = dfs_db['Pick6_Trends']92 cursor = collection.find()93 raw_display = pd.DataFrame(list(cursor))94 pick_frame = raw_display[['Player', 'over_prop', 'over_line', 'under_prop', 'under_line', 'book', 'prop_type', 'No Vig', 'Team', 'L3 Success', 'L6_Success', 'L10_success', 'L6 Avg', 'Projection',95 'Proj Diff', 'Implied Over', 'Trending Over', 'Over Edge', 'Implied Under', 'Trending Under', 'Under Edge', 'last_name', 'P6_name', 'Full_name']]96 97 collection = props_db["NFL_Props"] 98 cursor = collection.find()99 100 raw_display = pd.DataFrame(list(cursor))101 market_props = raw_display[['Name', 'Position', 'Projection', 'PropType', 'OddsType', 'over_pay', 'under_pay']]102 market_props['over_prop'] = market_props['Projection']103 market_props['over_line'] = market_props['over_pay'].apply(lambda x: (x - 1) * 100 if x >= 2.0 else -100 / (x - 1))104 market_props['under_prop'] = market_props['Projection']105 market_props['under_line'] = market_props['under_pay'].apply(lambda x: (x - 1) * 100 if x >= 2.0 else -100 / (x - 1))106 107 return game_model, overall_stats, timestamp, prop_frame, prop_trends, pick_frame, market_props108 109def calculate_no_vig(row):110 def implied_probability(american_odds):111 if american_odds < 0:112 return (-american_odds) / ((-american_odds) + 100)113 else:114 return 100 / (american_odds + 100)115 116 over_line = row['over_line']117 under_line = row['under_line']118 over_prop = row['over_prop']119 120 over_prob = implied_probability(over_line)121 under_prob = implied_probability(under_line)122 123 total_prob = over_prob + under_prob124 no_vig_prob = (over_prob / total_prob + 0.5) * over_prop125 126 return no_vig_prob127 128def convert_df_to_csv(df):129 return df.to_csv().encode('utf-8')130 131game_model, overall_stats, timestamp, prop_frame, prop_trends, pick_frame, market_props = init_baselines()132qb_stats = overall_stats[overall_stats['Position'] == 'QB']133qb_stats = qb_stats.drop_duplicates(subset=['Player', 'Position'])134non_qb_stats = overall_stats[overall_stats['Position'] != 'QB']135non_qb_stats = non_qb_stats.drop_duplicates(subset=['Player', 'Position'])136team_dict = dict(zip(prop_frame['Player'], prop_frame['Team']))137t_stamp = f"Last Update: " + str(timestamp) + f" CST"138 139prop_table_options = ['NFL_GAME_PLAYER_PASSING_YARDS', 'NFL_GAME_PLAYER_RUSHING_YARDS', 'NFL_GAME_PLAYER_PASSING_ATTEMPTS', 'NFL_GAME_PLAYER_PASSING_TOUCHDOWNS', 'NFL_GAME_PLAYER_PASSING_COMPLETIONS', 'NFL_GAME_PLAYER_RUSHING_ATTEMPTS',140 'NFL_GAME_PLAYER_RECEIVING_RECEPTIONS', 'NFL_GAME_PLAYER_RECEIVING_YARDS', 'NFL_GAME_PLAYER_RECEIVING_TOUCHDOWNS']141prop_format = {'L3 Success': '{:.2%}', 'L6_Success': '{:.2%}', 'L10_success': '{:.2%}', 'Trending Over': '{:.2%}', 'Trending Under': '{:.2%}',142 'Implied Over': '{:.2%}', 'Implied Under': '{:.2%}', 'Over Edge': '{:.2%}', 'Under Edge': '{:.2%}'}143all_sim_vars = ['NFL_GAME_PLAYER_PASSING_YARDS', 'NFL_GAME_PLAYER_RUSHING_YARDS', 'NFL_GAME_PLAYER_PASSING_ATTEMPTS', 'NFL_GAME_PLAYER_PASSING_TOUCHDOWNS', 'NFL_GAME_PLAYER_PASSING_COMPLETIONS', 'NFL_GAME_PLAYER_RUSHING_ATTEMPTS',144 'NFL_GAME_PLAYER_RECEIVING_RECEPTIONS', 'NFL_GAME_PLAYER_RECEIVING_YARDS', 'NFL_GAME_PLAYER_RECEIVING_TOUCHDOWNS']145pick6_sim_vars = ['Rush + Rec Yards', 'Rush + Rec TDs', 'Passing Yards', 'Passing Attempts', 'Passing TDs', 'Completions', 'Rushing Yards', 'Receptions', 'Receiving Yards']146sim_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'])147 148selected_tab = st.segmented_control(149 "Select Tab",150 options=["Game Betting Model", 'Prop Market', "QB Projections", "RB/WR/TE Projections", "Player Prop Trends", "Player Prop Simulations", "Stat Specific Simulations"],151 selection_mode='single',152 default='Game Betting Model',153 width='stretch',154 label_visibility='collapsed',155 key='tab_selector'156)157 158if selected_tab == 'Game Betting Model':159 st.info(t_stamp)160 if st.button("Reset Data", key='reset1'):161 st.cache_data.clear()162 game_model, overall_stats, timestamp, prop_frame, prop_trends, pick_frame, market_props = init_baselines()163 qb_stats = overall_stats[overall_stats['Position'] == 'QB']164 qb_stats = qb_stats.drop_duplicates(subset=['Player', 'Position'])165 non_qb_stats = overall_stats[overall_stats['Position'] != 'QB']166 non_qb_stats = non_qb_stats.drop_duplicates(subset=['Player', 'Position'])167 team_dict = dict(zip(prop_frame['Player'], prop_frame['Team']))168 t_stamp = f"Last Update: " + str(timestamp) + f" CST"169 line_var1 = st.radio('How would you like to display odds?', options = ['Percentage', 'American'], key='line_var1')170 team_frame = game_model171 if line_var1 == 'Percentage':172 team_frame = team_frame[['Team', 'Opp', 'Win%', 'Vegas', 'Win% Diff', 'PD Spread', 'Vegas Spread', 'Spread Diff']]173 team_frame = team_frame.set_index('Team')174 try:175 st.dataframe(team_frame.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').background_gradient(cmap='RdYlGn_r', subset=['Spread Diff']).format(game_format, precision=2), use_container_width = True)176 except:177 st.dataframe(team_frame.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').background_gradient(cmap='RdYlGn_r', subset=['Spread Diff']).format(precision=2), use_container_width = True)178 if line_var1 == 'American':179 team_frame = team_frame[['Team', 'Opp', 'Win Line', 'Vegas Line', 'Line Diff', 'PD Spread', 'Vegas Spread', 'Spread Diff']]180 team_frame = team_frame.set_index('Team')181 st.dataframe(team_frame.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').background_gradient(cmap='RdYlGn_r', subset=['Spread Diff']).format(precision=2), height = 1000, use_container_width = True)182 183 st.download_button(184 label="Export Team Model",185 data=convert_df_to_csv(team_frame),186 file_name='NFL_team_betting_export.csv',187 mime='text/csv',188 key='team_export',189 )190 191if selected_tab == 'Prop Market':192 st.info(t_stamp)193 if st.button("Reset Data", key='reset4'):194 st.cache_data.clear()195 game_model, overall_stats, timestamp, prop_frame, prop_trends, pick_frame, market_props = init_baselines()196 qb_stats = overall_stats[overall_stats['Position'] == 'QB']197 qb_stats = qb_stats.drop_duplicates(subset=['Player', 'Position'])198 non_qb_stats = overall_stats[overall_stats['Position'] != 'QB']199 non_qb_stats = non_qb_stats.drop_duplicates(subset=['Player', 'Position'])200 team_dict = dict(zip(prop_frame['Player'], prop_frame['Team']))201 t_stamp = f"Last Update: " + str(timestamp) + f" CST"202 market_type = st.selectbox('Select type of prop are you wanting to view', options = prop_table_options, key = 'market_type_key')203 disp_market = market_props.copy()204 disp_market = disp_market[disp_market['PropType'] == market_type]205 disp_market['No_Vig_Prop'] = disp_market.apply(calculate_no_vig, axis=1)206 fanduel_frame = disp_market[disp_market['OddsType'] == 'FANDUEL']207 fanduel_dict = dict(zip(fanduel_frame['Name'], fanduel_frame['No_Vig_Prop']))208 draftkings_frame = disp_market[disp_market['OddsType'] == 'DRAFTKINGS']209 draftkings_dict = dict(zip(draftkings_frame['Name'], draftkings_frame['No_Vig_Prop']))210 mgm_frame = disp_market[disp_market['OddsType'] == 'MGM']211 mgm_dict = dict(zip(mgm_frame['Name'], mgm_frame['No_Vig_Prop']))212 bet365_frame = disp_market[disp_market['OddsType'] == 'BET_365']213 bet365_dict = dict(zip(bet365_frame['Name'], bet365_frame['No_Vig_Prop']))214 215 disp_market['FANDUEL'] = disp_market['Name'].map(fanduel_dict)216 disp_market['DRAFTKINGS'] = disp_market['Name'].map(draftkings_dict)217 disp_market['MGM'] = disp_market['Name'].map(mgm_dict)218 disp_market['BET365'] = disp_market['Name'].map(bet365_dict)219 220 disp_market = disp_market[['Name', 'Position','FANDUEL', 'DRAFTKINGS', 'MGM', 'BET365']]221 disp_market = disp_market.drop_duplicates(subset=['Name'], keep='first', ignore_index=True)222 223 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)224 st.download_button(225 label="Export Market Props",226 data=convert_df_to_csv(disp_market),227 file_name='NFL_market_props_export.csv',228 mime='text/csv',229 )230 231if selected_tab == 'QB Projections':232 st.info(t_stamp)233 if st.button("Reset Data", key='reset2'):234 st.cache_data.clear()235 game_model, overall_stats, timestamp, prop_frame, prop_trends, pick_frame, market_props = init_baselines()236 qb_stats = overall_stats[overall_stats['Position'] == 'QB']237 qb_stats = qb_stats.drop_duplicates(subset=['Player', 'Position'])238 non_qb_stats = overall_stats[overall_stats['Position'] != 'QB']239 non_qb_stats = non_qb_stats.drop_duplicates(subset=['Player', 'Position'])240 team_dict = dict(zip(prop_frame['Player'], prop_frame['Team']))241 t_stamp = f"Last Update: " + str(timestamp) + f" CST"242 split_var1 = st.radio("Would you like to view all teams or specific ones?", ('All', 'Specific Teams'), key='split_var1')243 if split_var1 == 'Specific Teams':244 team_var1 = st.multiselect('Which teams would you like to include in the tables?', options = qb_stats['Team'].unique(), key='team_var1')245 elif split_var1 == 'All':246 team_var1 = qb_stats.Team.values.tolist()247 qb_stats = qb_stats[qb_stats['Team'].isin(team_var1)]248 qb_stats_disp = qb_stats.set_index('Player')249 qb_stats_disp = qb_stats_disp.sort_values(by='PPR', ascending=False)250 st.dataframe(qb_stats_disp.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(precision=2), height = 1000, use_container_width = True)251 st.download_button(252 label="Export Prop Model",253 data=convert_df_to_csv(qb_stats_disp),254 file_name='NFL_qb_stats_export.csv',255 mime='text/csv',256 key='NFL_qb_stats_export',257 )258 259if selected_tab == 'RB/WR/TE Projections':260 st.info(t_stamp)261 if st.button("Reset Data", key='reset3'):262 st.cache_data.clear()263 game_model, overall_stats, timestamp, prop_frame, prop_trends, pick_frame, market_props = init_baselines()264 qb_stats = overall_stats[overall_stats['Position'] == 'QB']265 qb_stats = qb_stats.drop_duplicates(subset=['Player', 'Position'])266 non_qb_stats = overall_stats[overall_stats['Position'] != 'QB']267 non_qb_stats = non_qb_stats.drop_duplicates(subset=['Player', 'Position'])268 team_dict = dict(zip(prop_frame['Player'], prop_frame['Team']))269 t_stamp = f"Last Update: " + str(timestamp) + f" CST"270 split_var2 = st.radio("Would you like to view all teams or specific ones?", ('All', 'Specific Teams'), key='split_var2')271 if split_var2 == 'Specific Teams':272 team_var2 = st.multiselect('Which teams would you like to include in the tables?', options = non_qb_stats['Team'].unique(), key='team_var2')273 elif split_var2 == 'All':274 team_var2 = non_qb_stats.Team.values.tolist()275 non_qb_stats = non_qb_stats[non_qb_stats['Team'].isin(team_var2)]276 non_qb_stats_disp = non_qb_stats.set_index('Player')277 non_qb_stats_disp = non_qb_stats_disp.sort_values(by='PPR', ascending=False)278 st.dataframe(non_qb_stats_disp.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(precision=2), height = 1000, use_container_width = True)279 st.download_button(280 label="Export Prop Model",281 data=convert_df_to_csv(non_qb_stats_disp),282 file_name='NFL_nonqb_stats_export.csv',283 mime='text/csv',284 key='NFL_nonqb_stats_export',285 )286 287if selected_tab == 'Player Prop Trends':288 st.info(t_stamp)289 if st.button("Reset Data", key='reset5'):290 st.cache_data.clear()291 game_model, overall_stats, timestamp, prop_frame, prop_trends, pick_frame, market_props = init_baselines()292 qb_stats = overall_stats[overall_stats['Position'] == 'QB']293 qb_stats = qb_stats.drop_duplicates(subset=['Player', 'Position'])294 non_qb_stats = overall_stats[overall_stats['Position'] != 'QB']295 non_qb_stats = non_qb_stats.drop_duplicates(subset=['Player', 'Position'])296 team_dict = dict(zip(prop_frame['Player'], prop_frame['Team']))297 t_stamp = f"Last Update: " + str(timestamp) + f" CST"298 split_var5 = st.radio("Would you like to view all teams or specific ones?", ('All', 'Specific Teams'), key='split_var5')299 if split_var5 == 'Specific Teams':300 team_var5 = st.multiselect('Which teams would you like to include in the tables?', options = prop_trends['Team'].unique(), key='team_var5')301 elif split_var5 == 'All':302 team_var5 = prop_trends.Team.values.tolist()303 prop_type_var2 = st.selectbox('Select type of prop are you wanting to view', options = prop_table_options)304 book_var2 = st.selectbox('Select type of book do you want to view?', options = ['FANDUEL', 'BET365', 'DRAFTKINGS', 'CONSENSUS'])305 prop_frame_disp = prop_trends[prop_trends['Team'].isin(team_var5)]306 prop_frame_disp = prop_frame_disp[prop_frame_disp['book'] == book_var2]307 prop_frame_disp = prop_frame_disp[prop_frame_disp['prop_type'] == prop_type_var2]308 #prop_frame_disp = prop_frame_disp.set_index('Player')309 prop_frame_disp = prop_frame_disp.sort_values(by='Trending Over', ascending=False)310 st.dataframe(prop_frame_disp.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(prop_format, precision=2), height = 1000, use_container_width = True)311 st.download_button(312 label="Export Prop Trends Model",313 data=convert_df_to_csv(prop_frame_disp),314 file_name='NFL_prop_trends_export.csv',315 mime='text/csv',316 )317 318if selected_tab == 'Player Prop Simulations':319 st.info(t_stamp)320 if st.button("Reset Data", key='reset6'):321 st.cache_data.clear()322 game_model, overall_stats, timestamp, prop_frame, prop_trends, pick_frame, market_props = init_baselines()323 qb_stats = overall_stats[overall_stats['Position'] == 'QB']324 qb_stats = qb_stats.drop_duplicates(subset=['Player', 'Position'])325 non_qb_stats = overall_stats[overall_stats['Position'] != 'QB']326 non_qb_stats = non_qb_stats.drop_duplicates(subset=['Player', 'Position'])327 team_dict = dict(zip(prop_frame['Player'], prop_frame['Team']))328 t_stamp = f"Last Update: " + str(timestamp) + f" CST"329 col1, col2 = st.columns([1, 5])330 331 with col2:332 df_hold_container = st.empty()333 info_hold_container = st.empty()334 plot_hold_container = st.empty()335 336 with col1:337 player_check = st.selectbox('Select player to simulate props', options = overall_stats['Player'].unique())338 prop_type_var = st.selectbox('Select type of prop to simulate', options = ['Pass Yards', 'Pass TDs', 'Rush Yards', 'Rush TDs', 'Receptions', 'Rec Yards', 'Rec TDs', 'Fantasy', 'FD Fantasy', 'PrizePicks'])339 340 ou_var = st.selectbox('Select wether it is an over or under', options = ['Over', 'Under'])341 if prop_type_var == 'Pass Yards':342 prop_var = st.number_input('Type in the prop offered (i.e 5.5)', min_value = 100.0, max_value = 400.5, value = 250.5, step = .5)343 elif prop_type_var == 'Pass TDs':344 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)345 elif prop_type_var == 'Rush Yards':346 prop_var = st.number_input('Type in the prop offered (i.e 5.5)', min_value = 0.0, max_value = 155.5, value = 25.5, step = .5)347 elif prop_type_var == 'Rush TDs':348 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)349 elif prop_type_var == 'Receptions':350 prop_var = st.number_input('Type in the prop offered (i.e 5.5)', min_value = 0.0, max_value = 15.5, value = 5.5, step = .5)351 elif prop_type_var == 'Rec Yards':352 prop_var = st.number_input('Type in the prop offered (i.e 5.5)', min_value = 0.0, max_value = 155.5, value = 25.5, step = .5)353 elif prop_type_var == 'Rec TDs':354 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)355 elif prop_type_var == 'Fantasy':356 prop_var = st.number_input('Type in the prop offered (i.e 5.5)', min_value = 0.0, max_value = 50.5, value = 10.5, step = .5)357 elif prop_type_var == 'FD Fantasy':358 prop_var = st.number_input('Type in the prop offered (i.e 5.5)', min_value = 0.0, max_value = 50.5, value = 10.5, step = .5)359 elif prop_type_var == 'PrizePicks':360 prop_var = st.number_input('Type in the prop offered (i.e 5.5)', min_value = 0.0, max_value = 50.5, value = 10.5, step = .5)361 line_var = st.number_input('Type in the line on the prop (i.e. -120)', min_value = -1000, max_value = 1000, value = -150, step = 1)362 line_var = line_var + 1363 364 if st.button('Simulate Prop'):365 with col2:366 367 with df_hold_container.container():368 369 df = overall_stats370 371 total_sims = 5000372 373 df.replace("", 0, inplace=True)374 375 player_var = df[df['Player'] == player_check]376 player_var = player_var.reset_index()377 378 if prop_type_var == 'Pass Yards':379 df['Median'] = df['pass_yards']380 elif prop_type_var == 'Pass TDs':381 df['Median'] = df['pass_tds']382 elif prop_type_var == 'Rush Yards':383 df['Median'] = df['rush_yards']384 elif prop_type_var == 'Rush TDs':385 df['Median'] = df['rush_tds']386 elif prop_type_var == 'Receptions':387 df['Median'] = df['rec']388 elif prop_type_var == 'Rec Yards':389 df['Median'] = df['rec_yards']390 elif prop_type_var == 'Rec TDs':391 df['Median'] = df['rec_tds']392 elif prop_type_var == 'Fantasy':393 df['Median'] = df['PPR']394 elif prop_type_var == 'FD Fantasy':395 df['Median'] = df['Half_PPF']396 elif prop_type_var == 'PrizePicks':397 df['Median'] = df['Half_PPF']398 399 flex_file = df400 flex_file['Floor'] = flex_file['Median'] * .25401 flex_file['Ceiling'] = flex_file['Median'] + (flex_file['Median'] * 1.75)402 flex_file['STD'] = flex_file['Median'] / 4403 flex_file = flex_file[['Player', 'Floor', 'Median', 'Ceiling', 'STD']]404 405 hold_file = flex_file406 overall_file = flex_file407 salary_file = flex_file408 409 overall_players = overall_file[['Player']]410 411 for x in range(0,total_sims):412 overall_file[x] = np.random.normal(overall_file['Median'],overall_file['STD'])413 414 overall_file=overall_file.drop(['Player', 'Floor', 'Median', 'Ceiling', 'STD'], axis=1)415 overall_file.astype('int').dtypes416 417 players_only = hold_file[['Player']]418 419 player_outcomes = pd.merge(players_only, overall_file, left_index=True, right_index=True)420 421 players_only['Mean_Outcome'] = overall_file.mean(axis=1)422 players_only['Prop'] = prop_var423 players_only['poisson_var'] = players_only.apply(calculate_poisson, axis=1)424 players_only['10%'] = overall_file.quantile(0.1, axis=1)425 players_only['90%'] = overall_file.quantile(0.9, axis=1)426 if ou_var == 'Over':427 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))428 elif ou_var == 'Under':429 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)))430 431 players_only['implied_odds'] = np.where(line_var <= 0, (-(line_var)/((-(line_var))+100)), 100/(line_var+100))432 433 players_only['Player'] = hold_file[['Player']]434 435 final_outcomes = players_only[['Player', '10%', 'Mean_Outcome', '90%', 'implied_odds', 'beat_prop']]436 final_outcomes['Bet?'] = np.where(final_outcomes['beat_prop'] - final_outcomes['implied_odds'] >= .10, "Bet", "No Bet")437 final_outcomes = final_outcomes[final_outcomes['Player'] == player_check]438 player_outcomes = player_outcomes[player_outcomes['Player'] == player_check]439 player_outcomes = player_outcomes.drop(columns=['Player']).transpose()440 player_outcomes = player_outcomes.reset_index()441 player_outcomes.columns = ['Instance', 'Outcome']442 443 x1 = player_outcomes.Outcome.to_numpy()444 445 print(x1)446 447 hist_data = [x1]448 449 group_labels = ['player outcomes']450 451 fig = px.histogram(452 player_outcomes, x='Outcome')453 fig.add_vline(x=prop_var, line_dash="dash", line_color="green")454 455 with df_hold_container:456 df_hold_container = st.empty()457 format_dict = {'10%': '{:.2f}', 'Mean_Outcome': '{:.2f}','90%': '{:.2f}', 'beat_prop': '{:.2%}','implied_odds': '{:.2%}'}458 st.dataframe(final_outcomes.style.format(format_dict), use_container_width = True)459 460 with info_hold_container:461 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.')462 463 with plot_hold_container:464 st.dataframe(player_outcomes, use_container_width = True)465 plot_hold_container = st.empty()466 st.plotly_chart(fig, use_container_width=True)467 468if selected_tab == 'Stat Specific Simulations':469 st.info(t_stamp)470 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.')471 if st.button("Reset Data/Load Data", key='reset7'):472 st.cache_data.clear()473 game_model, overall_stats, timestamp, prop_frame, prop_trends, pick_frame, market_props = init_baselines()474 qb_stats = overall_stats[overall_stats['Position'] == 'QB']475 qb_stats = qb_stats.drop_duplicates(subset=['Player', 'Position'])476 non_qb_stats = overall_stats[overall_stats['Position'] != 'QB']477 non_qb_stats = non_qb_stats.drop_duplicates(subset=['Player', 'Position'])478 team_dict = dict(zip(prop_frame['Player'], prop_frame['Team']))479 t_stamp = f"Last Update: " + str(timestamp) + f" CST"480 481 settings_container = st.empty()482 df_hold_container = st.empty()483 export_container = st.empty()484 485 with settings_container.container():486 col1, col2, col3, col4 = st.columns([3, 3, 3, 3])487 with col1:488 game_select_var = st.selectbox('Select prop source', options = ['Aggregate', 'Pick6'])489 with col2:490 book_select_var = st.selectbox('Select book', options = ['ALL', 'BET_365', 'DRAFTKINGS', 'FANDUEL', 'MGM', 'UNIBET', 'WILLIAM_HILL'])491 if book_select_var == 'ALL':492 book_selections = ['BET_365', 'DRAFTKINGS', 'FANDUEL', 'MGM', 'UNIBET', 'WILLIAM_HILL']493 else:494 book_selections = [book_select_var]495 if game_select_var == 'Aggregate':496 prop_df = prop_frame[['Player', 'book', 'over_prop', 'over_line', 'under_line', 'prop_type', 'Trending Over', 'Trending Under']]497 elif game_select_var == 'Pick6':498 prop_df = pick_frame[['Player', 'book', 'over_prop', 'over_line', 'under_line', 'prop_type', 'Trending Over', 'Trending Under']]499 book_selections = ['Pick6']500 with col3:501 if game_select_var == 'Aggregate':502 prop_type_var = st.selectbox('Select prop category', options = ['All Props', 'NFL_GAME_PLAYER_PASSING_YARDS', 'NFL_GAME_PLAYER_RUSHING_YARDS', 'NFL_GAME_PLAYER_PASSING_ATTEMPTS', 'NFL_GAME_PLAYER_PASSING_TOUCHDOWNS', 'NFL_GAME_PLAYER_RUSHING_ATTEMPTS',503 'NFL_GAME_PLAYER_RECEIVING_RECEPTIONS', 'NFL_GAME_PLAYER_RECEIVING_YARDS', 'NFL_GAME_PLAYER_RECEIVING_TOUCHDOWNS'])504 elif game_select_var == 'Pick6':505 prop_type_var = st.selectbox('Select prop category', options = ['All Props', 'Rush + Rec Yards', 'Rush + Rec TDs', 'Passing Yards', 'Passing Attempts', 'Passing TDs', 'Rushing Attempts', 'Rushing Yards', 'Receptions', 'Receiving Yards', 'Receiving TDs'])506 with col4:507 st.download_button(508 label="Download Prop Source",509 data=convert_df_to_csv(prop_df),510 file_name='NFL_prop_source.csv',511 mime='text/csv',512 key='prop_source',513 )514 515 if st.button('Simulate Prop Category'):516 517 with df_hold_container.container():518 if prop_type_var == 'All Props':519 if game_select_var == 'Aggregate':520 prop_df_raw = prop_frame[['Player', 'book', 'over_prop', 'over_line', 'under_line', 'prop_type', 'Trending Over', 'Trending Under']]521 sim_vars = ['NFL_GAME_PLAYER_PASSING_YARDS', 'NFL_GAME_PLAYER_RUSHING_YARDS', 'NFL_GAME_PLAYER_PASSING_ATTEMPTS', 'NFL_GAME_PLAYER_PASSING_TOUCHDOWNS', 'NFL_GAME_PLAYER_RUSHING_ATTEMPTS',522 'NFL_GAME_PLAYER_RECEIVING_RECEPTIONS', 'NFL_GAME_PLAYER_RECEIVING_YARDS', 'NFL_GAME_PLAYER_RECEIVING_TOUCHDOWNS']523 elif game_select_var == 'Pick6':524 prop_df_raw = pick_frame[['Player', 'book', 'over_prop', 'over_line', 'under_line', 'prop_type', 'Trending Over', 'Trending Under']]525 sim_vars = ['Rush + Rec Yards', 'Rush + Rec TDs', 'Passing Yards', 'Passing Attempts', 'Passing TDs', 'Rushing Attempts', 'Rushing Yards', 'Receptions', 'Receiving Yards', 'Receiving TDs']526 527 player_df = overall_stats.copy()528 529 for prop in sim_vars:530 531 for books in book_selections:532 prop_df = prop_df_raw[prop_df_raw['book'] == books]533 prop_df = prop_df[prop_df['prop_type'] == prop]534 prop_df = prop_df[~((prop_df['over_prop'] < 15) & (prop_df['prop_type'] == 'NFL_GAME_PLAYER_RUSHING_YARDS'))]535 prop_df = prop_df[['Player', 'book', 'over_prop', 'over_line', 'under_line', 'prop_type', 'Trending Over', 'Trending Under']]536 prop_df.rename(columns={"over_prop": "Prop"}, inplace = True)537 prop_df['Over'] = 1 / prop_df['over_line']538 prop_df['Under'] = 1 / prop_df['under_line']539 540 prop_dict = dict(zip(prop_df.Player, prop_df.Prop))541 prop_type_dict = dict(zip(prop_df.Player, prop_df.prop_type))542 book_dict = dict(zip(prop_df.Player, prop_df.book))543 over_dict = dict(zip(prop_df.Player, prop_df.Over))544 under_dict = dict(zip(prop_df.Player, prop_df.Under))545 trending_over_dict = dict(zip(prop_df.Player, prop_df['Trending Over']))546 trending_under_dict = dict(zip(prop_df.Player, prop_df['Trending Under']))547 548 player_df['book'] = player_df['Player'].map(book_dict)549 player_df['Prop'] = player_df['Player'].map(prop_dict)550 player_df['prop_type'] = player_df['Player'].map(prop_type_dict)551 player_df['Trending Over'] = player_df['Player'].map(trending_over_dict)552 player_df['Trending Under'] = player_df['Player'].map(trending_under_dict)553 554 df = player_df.reset_index(drop=True)555 556 team_dict = dict(zip(df.Player, df.Team))557 558 total_sims = 1000559 560 df.replace("", 0, inplace=True)561 562 if prop == "NFL_GAME_PLAYER_PASSING_YARDS" or prop == "Passing Yards":563 df['Median'] = df['pass_yards']564 elif prop == "NFL_GAME_PLAYER_RUSHING_YARDS" or prop == "Rushing Yards":565 df['Median'] = df['rush_yards']566 elif prop == "NFL_GAME_PLAYER_PASSING_ATTEMPTS" or prop == "Passing Attempts":567 df['Median'] = df['pass_att']568 elif prop == "NFL_GAME_PLAYER_PASSING_TOUCHDOWNS" or prop == "Passing TDs":569 df['Median'] = df['pass_tds']570 elif prop == "NFL_GAME_PLAYER_RUSHING_ATTEMPTS" or prop == "Rushing Attempts":571 df['Median'] = df['rush_att']572 elif prop == "NFL_GAME_PLAYER_RECEIVING_RECEPTIONS" or prop == "Receptions":573 df['Median'] = df['rec']574 elif prop == "NFL_GAME_PLAYER_RECEIVING_YARDS" or prop == "Receiving Yards":575 df['Median'] = df['rec_yards']576 elif prop == "NFL_GAME_PLAYER_RECEIVING_TOUCHDOWNS" or prop == "Receiving TDs":577 df['Median'] = df['rec_tds']578 elif prop == "Rush + Rec Yards":579 df['Median'] = df['rush_yards'] + df['rec_yards']580 elif prop == "Rush + Rec TDs":581 df['Median'] = df['rush_tds'] + df['rec_tds']582 583 flex_file = df.copy()584 flex_file['Floor'] = flex_file['Median'] * .25585 flex_file['Ceiling'] = flex_file['Median'] + (flex_file['Median'] * 1.75)586 flex_file['STD'] = flex_file['Median'] / 4587 flex_file['Prop'] = flex_file['Player'].map(prop_dict)588 flex_file = flex_file[['Player', 'book', 'Prop', 'Floor', 'Median', 'Ceiling', 'STD']]589 590 hold_file = flex_file.copy()591 overall_file = flex_file.copy()592 prop_file = flex_file.copy()593 594 overall_players = overall_file[['Player']]595 596 for x in range(0,total_sims): 597 prop_file[x] = prop_file['Prop']598 599 prop_file = prop_file.drop(['Player', 'book', 'Prop', 'Floor', 'Median', 'Ceiling', 'STD'], axis=1)600 601 for x in range(0,total_sims):602 overall_file[x] = np.random.normal(overall_file['Median'],overall_file['STD'])603 604 overall_file=overall_file.drop(['Player', 'book', 'Prop', 'Floor', 'Median', 'Ceiling', 'STD'], axis=1)605 606 players_only = hold_file[['Player']]607 608 player_outcomes = pd.merge(players_only, overall_file, left_index=True, right_index=True)609 610 prop_check = (overall_file - prop_file)611 612 players_only['Mean_Outcome'] = overall_file.mean(axis=1)613 players_only['Book'] = players_only['Player'].map(book_dict)614 players_only['Prop'] = players_only['Player'].map(prop_dict)615 players_only['Trending Over'] = players_only['Player'].map(trending_over_dict)616 players_only['Trending Under'] = players_only['Player'].map(trending_under_dict)617 players_only['poisson_var'] = players_only.apply(calculate_poisson, axis=1)618 players_only['10%'] = overall_file.quantile(0.1, axis=1)619 players_only['90%'] = overall_file.quantile(0.9, axis=1)620 players_only['Over'] = np_where(players_only['Prop'] <= 3, players_only['poisson_var'], prop_check[prop_check > 0].count(axis=1)/float(total_sims))621 players_only['Imp Over'] = players_only['Player'].map(over_dict)622 players_only['Over%'] = players_only[["Over", "Imp Over", "Trending Over"]].mean(axis=1)623 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))624 players_only['Imp Under'] = players_only['Player'].map(under_dict)625 players_only['Under%'] = players_only[["Under", "Imp Under", "Trending Under"]].mean(axis=1)626 players_only['Prop_avg'] = players_only['Prop'].mean() / 100627 players_only['prop_threshold'] = .10628 players_only = players_only[players_only['Mean_Outcome'] > 0]629 players_only['Over_diff'] = players_only['Over%'] - players_only['Imp Over']630 players_only['Under_diff'] = players_only['Under%'] - players_only['Imp Under']631 players_only['Bet_check'] = np.where(players_only['Over_diff'] > players_only['Under_diff'], players_only['Over_diff'] , players_only['Under_diff'])632 players_only['Bet_suggest'] = np.where(players_only['Over_diff'] > players_only['Under_diff'], "Over" , "Under")633 players_only['Bet?'] = np.where(players_only['Bet_check'] >= players_only['prop_threshold'], players_only['Bet_suggest'], "No Bet")634 players_only['Edge'] = players_only['Bet_check']635 players_only['Prop Type'] = prop636 637 players_only['Player'] = hold_file[['Player']]638 players_only['Team'] = players_only['Player'].map(team_dict)639 640 leg_outcomes = players_only[['Player', 'Team', 'Book', 'Prop Type', 'Prop', 'Mean_Outcome', 'Imp Over', 'Trending Over', 'Over%', 'Imp Under', 'Trending Under', 'Under%', 'Bet?', 'Edge']]641 sim_all_hold = pd.concat([sim_all_hold, leg_outcomes], ignore_index=True)642 643 final_outcomes = sim_all_hold644 st.write(f'finished {prop} for {books}')645 646 elif prop_type_var != 'All Props':647 648 player_df = overall_stats.copy()649 650 if game_select_var == 'Aggregate':651 prop_df_raw = prop_frame[['Player', 'book', 'over_prop', 'over_line', 'under_line', 'prop_type', 'Trending Over', 'Trending Under']]652 elif game_select_var == 'Pick6':653 prop_df_raw = pick_frame[['Player', 'book', 'over_prop', 'over_line', 'under_line', 'prop_type', 'Trending Over', 'Trending Under']]654 655 for books in book_selections:656 prop_df = prop_df_raw[prop_df_raw['book'] == books]657 658 if prop_type_var == "NFL_GAME_PLAYER_PASSING_YARDS":659 prop_df = prop_df[prop_df['prop_type'] == 'NFL_GAME_PLAYER_PASSING_YARDS']660 elif prop_type_var == "Passing Yards":661 prop_df = prop_df[prop_df['prop_type'] == 'Passing Yards']662 elif prop_type_var == "NFL_GAME_PLAYER_RUSHING_YARDS":663 prop_df = prop_df[prop_df['prop_type'] == 'NFL_GAME_PLAYER_RUSHING_YARDS']664 elif prop_type_var == "Rushing Yards":665 prop_df = prop_df[prop_df['prop_type'] == 'Rushing Yards']666 elif prop_type_var == "NFL_GAME_PLAYER_PASSING_ATTEMPTS":667 prop_df = prop_df[prop_df['prop_type'] == 'NFL_GAME_PLAYER_PASSING_ATTEMPTS']668 elif prop_type_var == "Passing Attempts":669 prop_df = prop_df[prop_df['prop_type'] == 'Passing Attempts']670 elif prop_type_var == "NFL_GAME_PLAYER_PASSING_TOUCHDOWNS":671 prop_df = prop_df[prop_df['prop_type'] == 'NFL_GAME_PLAYER_PASSING_TOUCHDOWNS']672 elif prop_type_var == "Passing TDs":673 prop_df = prop_df[prop_df['prop_type'] == 'Passing TDs']674 elif prop_type_var == "NFL_GAME_PLAYER_RUSHING_ATTEMPTS":675 prop_df = prop_df[prop_df['prop_type'] == 'NFL_GAME_PLAYER_RUSHING_ATTEMPTS']676 elif prop_type_var == "Rushing Attempts":677 prop_df = prop_df[prop_df['prop_type'] == 'Rushing Attempts']678 elif prop_type_var == "NFL_GAME_PLAYER_RECEIVING_RECEPTIONS":679 prop_df = prop_df[prop_df['prop_type'] == 'NFL_GAME_PLAYER_RECEIVING_RECEPTIONS']680 elif prop_type_var == "Receptions":681 prop_df = prop_df[prop_df['prop_type'] == 'Receptions']682 elif prop_type_var == "NFL_GAME_PLAYER_RECEIVING_YARDS":683 prop_df = prop_df[prop_df['prop_type'] == 'NFL_GAME_PLAYER_RECEIVING_YARDS']684 elif prop_type_var == "Receiving Yards":685 prop_df = prop_df[prop_df['prop_type'] == 'Receiving Yards']686 elif prop_type_var == "NFL_GAME_PLAYER_RECEIVING_TOUCHDOWNS":687 prop_df = prop_df[prop_df['prop_type'] == 'NFL_GAME_PLAYER_RECEIVING_TOUCHDOWNS']688 elif prop_type_var == "Receiving TDs":689 prop_df = prop_df[prop_df['prop_type'] == 'Receiving TDs']690 elif prop_type_var == "Rush + Rec Yards":691 prop_df = prop_df[prop_df['prop_type'] == 'Rush + Rec Yards']692 elif prop_type_var == "Rush + Rec TDs":693 prop_df = prop_df[prop_df['prop_type'] == 'Rush + Rec TDs']694 695 prop_df = prop_df[['Player', 'book', 'over_prop', 'over_line', 'under_line', 'prop_type', 'Trending Over', 'Trending Under']]696 prop_df = prop_df.rename(columns={"over_prop": "Prop"})697 prop_df['Over'] = 1 / prop_df['over_line']698 prop_df['Under'] = 1 / prop_df['under_line']699 700 prop_dict = dict(zip(prop_df.Player, prop_df.Prop))701 prop_type_dict = dict(zip(prop_df.Player, prop_df.prop_type))702 book_dict = dict(zip(prop_df.Player, prop_df.book))703 over_dict = dict(zip(prop_df.Player, prop_df.Over))704 under_dict = dict(zip(prop_df.Player, prop_df.Under))705 trending_over_dict = dict(zip(prop_df.Player, prop_df['Trending Over']))706 trending_under_dict = dict(zip(prop_df.Player, prop_df['Trending Under']))707 708 player_df['book'] = player_df['Player'].map(book_dict)709 player_df['Prop'] = player_df['Player'].map(prop_dict)710 player_df['prop_type'] = player_df['Player'].map(prop_type_dict)711 player_df['Trending Over'] = player_df['Player'].map(trending_over_dict)712 player_df['Trending Under'] = player_df['Player'].map(trending_under_dict)713 714 df = player_df.reset_index(drop=True)715 716 team_dict = dict(zip(df.Player, df.Team))717 718 total_sims = 1000719 720 df.replace("", 0, inplace=True)721 722 if prop_type_var == "NFL_GAME_PLAYER_PASSING_YARDS" or prop_type_var == "Passing Yards":723 df['Median'] = df['pass_yards']724 elif prop_type_var == "NFL_GAME_PLAYER_RUSHING_YARDS" or prop_type_var == "Rushing Yards":725 df['Median'] = df['rush_yards']726 elif prop_type_var == "NFL_GAME_PLAYER_PASSING_ATTEMPTS" or prop_type_var == "Passing Attempts":727 df['Median'] = df['pass_att']728 elif prop_type_var == "NFL_GAME_PLAYER_PASSING_TOUCHDOWNS" or prop_type_var == "Passing TDs":729 df['Median'] = df['pass_tds']730 elif prop_type_var == "NFL_GAME_PLAYER_RUSHING_ATTEMPTS" or prop_type_var == "Rushing Attempts":731 df['Median'] = df['rush_att']732 elif prop_type_var == "NFL_GAME_PLAYER_RECEIVING_RECEPTIONS" or prop_type_var == "Receptions":733 df['Median'] = df['rec']734 elif prop_type_var == "NFL_GAME_PLAYER_RECEIVING_YARDS" or prop_type_var == "Receiving Yards":735 df['Median'] = df['rec_yards']736 elif prop_type_var == "NFL_GAME_PLAYER_RECEIVING_TOUCHDOWNS" or prop_type_var == "Receiving TDs":737 df['Median'] = df['rec_tds']738 elif prop_type_var == "Rush + Rec Yards":739 df['Median'] = df['rush_yards'] + df['rec_yards']740 elif prop_type_var == "Rush + Rec TDs":741 df['Median'] = df['rush_tds'] + df['rec_tds']742 743 flex_file = df.copy()744 flex_file['Floor'] = flex_file['Median'] * .25745 flex_file['Ceiling'] = flex_file['Median'] + (flex_file['Median'] * 1.75)746 flex_file['STD'] = flex_file['Median'] / 4747 flex_file['Prop'] = flex_file['Player'].map(prop_dict)748 flex_file = flex_file[['Player', 'book', 'Prop', 'Floor', 'Median', 'Ceiling', 'STD']]749 750 hold_file = flex_file.copy()751 overall_file = flex_file.copy()752 prop_file = flex_file.copy()753 754 overall_players = overall_file[['Player']]755 756 for x in range(0,total_sims): 757 prop_file[x] = prop_file['Prop']758 759 prop_file = prop_file.drop(['Player', 'book', 'Prop', 'Floor', 'Median', 'Ceiling', 'STD'], axis=1)760 761 for x in range(0,total_sims):762 overall_file[x] = np.random.normal(overall_file['Median'],overall_file['STD'])763 764 overall_file=overall_file.drop(['Player', 'book', 'Prop', 'Floor', 'Median', 'Ceiling', 'STD'], axis=1)765 766 players_only = hold_file[['Player']]767 768 player_outcomes = pd.merge(players_only, overall_file, left_index=True, right_index=True)769 770 prop_check = (overall_file - prop_file)771 772 players_only['Mean_Outcome'] = overall_file.mean(axis=1)773 players_only['Book'] = players_only['Player'].map(book_dict)774 players_only['Prop'] = players_only['Player'].map(prop_dict)775 players_only['Trending Over'] = players_only['Player'].map(trending_over_dict)776 players_only['Trending Under'] = players_only['Player'].map(trending_under_dict)777 players_only['poisson_var'] = players_only.apply(calculate_poisson, axis=1)778 players_only['10%'] = overall_file.quantile(0.1, axis=1)779 players_only['90%'] = overall_file.quantile(0.9, axis=1)780 players_only['Over'] = np_where(players_only['Prop'] <= 3, players_only['poisson_var'], prop_check[prop_check > 0].count(axis=1)/float(total_sims))781 players_only['Imp Over'] = players_only['Player'].map(over_dict)782 players_only['Over%'] = players_only[["Over", "Imp Over", "Trending Over"]].mean(axis=1)783 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))784 players_only['Imp Under'] = players_only['Player'].map(under_dict)785 players_only['Under%'] = players_only[["Under", "Imp Under", "Trending Under"]].mean(axis=1)786 players_only['Prop_avg'] = players_only['Prop'].mean() / 100787 players_only['prop_threshold'] = .10788 players_only = players_only[players_only['Mean_Outcome'] > 0]789 players_only['Over_diff'] = players_only['Over%'] - players_only['Imp Over']790 players_only['Under_diff'] = players_only['Under%'] - players_only['Imp Under']791 players_only['Bet_check'] = np.where(players_only['Over_diff'] > players_only['Under_diff'], players_only['Over_diff'] , players_only['Under_diff'])792 players_only['Bet_suggest'] = np.where(players_only['Over_diff'] > players_only['Under_diff'], "Over" , "Under")793 players_only['Bet?'] = np.where(players_only['Bet_check'] >= players_only['prop_threshold'], players_only['Bet_suggest'], "No Bet")794 players_only['Edge'] = players_only['Bet_check']795 players_only['Prop Type'] = prop_type_var796 797 players_only['Player'] = hold_file[['Player']]798 players_only['Team'] = players_only['Player'].map(team_dict)799 800 leg_outcomes = players_only[['Player', 'Team', 'Book', 'Prop Type', 'Prop', 'Mean_Outcome', 'Imp Over', 'Trending Over', 'Over%', 'Imp Under', 'Trending Under', 'Under%', 'Bet?', 'Edge']]801 sim_all_hold = pd.concat([sim_all_hold, leg_outcomes], ignore_index=True)802 803 final_outcomes = sim_all_hold804 st.write(f'finished {prop_type_var} for {books}')805 806 final_outcomes = final_outcomes.dropna()807 if game_select_var == 'Pick6':808 final_outcomes = final_outcomes.drop_duplicates(subset=['Player', 'Prop Type'])809 final_outcomes = final_outcomes.sort_values(by='Edge', ascending=False)810 811 with df_hold_container:812 df_hold_container = st.empty()813 st.dataframe(final_outcomes.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(precision=2), use_container_width = True)814 with export_container:815 export_container = st.empty()816 st.download_button(817 label="Export Projections",818 data=convert_df_to_csv(final_outcomes),819 file_name='NFL_prop_proj.csv',820 mime='text/csv',821 key='prop_proj',822 )