TrueDFS/NHL_DFS_Contest_Sims_Origin
0
1import streamlit as st2st.set_page_config(layout="wide")3import numpy as np4import pandas as pd5import pymongo6 7@st.cache_resource8def init_conn():9 10 uri = st.secrets['mongo_uri']11 client = pymongo.MongoClient(uri, retryWrites=True, serverSelectionTimeoutMS=500000)12 db = client["NHL_Database"]13 14 return db15 16db = init_conn()17 18percentages_format = {'Exposure': '{:.2%}'}19freq_format = {'Exposure': '{:.2%}', 'Proj Own': '{:.2%}', 'Edge': '{:.2%}'}20dk_columns = ['C1', 'C2', 'W1', 'W2', 'W3', 'D1', 'D2', 'G', 'FLEX', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']21fd_columns = ['C1', 'C2', 'W1', 'W2', 'D1', 'D2', 'FLEX1', 'FLEX2', 'G', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']22 23@st.cache_data(ttl = 600)24def init_DK_seed_frames(sharp_split, slate_var): 25 26 if slate_var == 'Main Slate':27 collection = db['DK_NHL_seed_frame_Main Slate']28 elif slate_var == 'Secondary Slate':29 collection = db['DK_NHL_seed_frame_Secondary Slate']30 elif slate_var == 'Auxiliary Slate':31 collection = db['DK_NHL_seed_frame_Auxiliary Slate']32 33 cursor = collection.find().limit(sharp_split)34 35 raw_display = pd.DataFrame(list(cursor))36 raw_display = raw_display[['C1', 'C2', 'W1', 'W2', 'W3', 'D1', 'D2', 'G', 'FLEX', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']]37 DK_seed = raw_display.to_numpy()38 39 return DK_seed40 41@st.cache_data(ttl = 599)42def init_FD_seed_frames(sharp_split, slate_var): 43 44 if slate_var == 'Main Slate':45 collection = db['FD_NHL_seed_frame_Main Slate']46 elif slate_var == 'Secondary Slate':47 collection = db['FD_NHL_seed_frame_Secondary Slate']48 elif slate_var == 'Auxiliary Slate':49 collection = db['FD_NHL_seed_frame_Auxiliary Slate']50 51 cursor = collection.find().limit(sharp_split)52 53 raw_display = pd.DataFrame(list(cursor))54 raw_display = raw_display[['C1', 'C2', 'W1', 'W2', 'D1', 'D2', 'FLEX1', 'FLEX2', 'G', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']]55 FD_seed = raw_display.to_numpy()56 57 return FD_seed58 59@st.cache_data(ttl = 599)60def init_baselines():61 collection = db["Player_Level_ROO"] 62 cursor = collection.find()63 64 raw_display = pd.DataFrame(list(cursor))65 load_display = raw_display[['Player', 'Position', 'Team', 'Opp', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '2x%', '3x%', '4x%', 'Own',66 'Small Field Own%', 'Large Field Own%', 'Cash Own%', 'CPT_Own', 'Site', 'Type', 'Slate', 'player_id', 'timestamp']]67 load_display['STDev'] = load_display['Median'] / 368 DK_load_display = load_display[load_display['Site'] == 'Draftkings']69 DK_load_display = DK_load_display.drop_duplicates(subset=['Player'], keep='first')70 71 dk_raw = DK_load_display.dropna(subset=['Median'])72 dk_raw['Team'] = dk_raw['Team'].replace(['TB', 'SJ', 'LA'], ['TBL', 'SJS', 'LAK'])73 74 FD_load_display = load_display[load_display['Site'] == 'Fanduel']75 FD_load_display = FD_load_display.drop_duplicates(subset=['Player'], keep='first')76 77 fd_raw = FD_load_display.dropna(subset=['Median'])78 fd_raw['Team'] = fd_raw['Team'].replace(['TB', 'SJ', 'LA'], ['TBL', 'SJS', 'LAK'])79 80 teams_playing_count = len(dk_raw.Team.unique())81 82 return dk_raw, fd_raw, teams_playing_count83 84@st.cache_data85def convert_df(array):86 array = pd.DataFrame(array, columns=column_names)87 return array.to_csv().encode('utf-8')88 89@st.cache_data90def calculate_DK_value_frequencies(np_array):91 unique, counts = np.unique(np_array[:, :9], return_counts=True)92 frequencies = counts / len(np_array) # Normalize by the number of rows 93 combined_array = np.column_stack((unique, frequencies)) 94 return combined_array 95 96@st.cache_data97def calculate_FD_value_frequencies(np_array):98 unique, counts = np.unique(np_array[:, :9], return_counts=True)99 frequencies = counts / len(np_array) # Normalize by the number of rows 100 combined_array = np.column_stack((unique, frequencies)) 101 return combined_array102 103@st.cache_data104def sim_contest(Sim_size, seed_frame, maps_dict, Contest_Size, teams_playing_count):105 SimVar = 1106 Sim_Winners = []107 fp_array = seed_frame.copy()108 # Pre-vectorize functions109 vec_projection_map = np.vectorize(maps_dict['Projection_map'].__getitem__)110 vec_stdev_map = np.vectorize(maps_dict['STDev_map'].__getitem__)111 112 st.write('Simulating contest on frames')113 114 while SimVar <= Sim_size:115 fp_random = fp_array[np.random.choice(fp_array.shape[0], Contest_Size)]116 117 # Calculate stack multipliers first118 stack_multiplier = np.ones(fp_random.shape[0]) # Start with no bonus119 stack_multiplier += np.minimum(0.10, np.where(fp_random[:, 12] == 4, 0.025 * (teams_playing_count - 8), 0))120 stack_multiplier += np.minimum(0.15, np.where(fp_random[:, 12] >= 5, 0.025 * (teams_playing_count - 12), 0))121 122 # Apply multipliers to both loc and scale in the normal distribution123 base_projections = np.sum(np.random.normal(124 loc=vec_projection_map(fp_random[:, :-7]) * stack_multiplier[:, np.newaxis],125 scale=vec_stdev_map(fp_random[:, :-7]) * stack_multiplier[:, np.newaxis]),126 axis=1)127 128 final_projections = base_projections129 130 sample_arrays = np.c_[fp_random, final_projections]131 132 final_array = sample_arrays[sample_arrays[:, 10].argsort()[::-1]]133 best_lineup = final_array[final_array[:, -1].argsort(kind='stable')[::-1][:1]]134 Sim_Winners.append(best_lineup)135 SimVar += 1136 137 return Sim_Winners138 139dk_raw, fd_raw, teams_playing_count = init_baselines()140dk_id_dict = dict(zip(dk_raw.Player, dk_raw.player_id))141fd_id_dict = dict(zip(fd_raw.Player, fd_raw.player_id))142 143tab1, tab2 = st.tabs(['Contest Sims', 'Data Export'])144 145with tab1:146 with st.expander("Info and Filters"):147 if st.button("Load/Reset Data", key='reset2'):148 st.cache_data.clear()149 for key in st.session_state.keys():150 del st.session_state[key]151 DK_seed = init_DK_seed_frames(10000, 'Main Slate')152 FD_seed = init_FD_seed_frames(10000, 'Main Slate')153 dk_raw, fd_raw, teams_playing_count = init_baselines()154 dk_id_dict = dict(zip(dk_raw.Player, dk_raw.player_id))155 fd_id_dict = dict(zip(fd_raw.Player, fd_raw.player_id))156 157 sim_slate_var1 = st.radio("Which data are you loading?", ('Main Slate', 'Secondary Slate', 'Auxiliary Slate'), key='sim_slate_var1')158 sim_site_var1 = st.radio("What site are you working with?", ('Draftkings', 'Fanduel'), key='sim_site_var1')159 160 contest_var1 = st.selectbox("What contest size are you simulating?", ('Small', 'Medium', 'Large', 'Custom'))161 if contest_var1 == 'Small':162 Contest_Size = 1000163 elif contest_var1 == 'Medium':164 Contest_Size = 5000165 elif contest_var1 == 'Large':166 Contest_Size = 10000167 elif contest_var1 == 'Custom':168 Contest_Size = st.number_input("Insert contest size", value=100, placeholder="Type a number under 10,000...")169 strength_var1 = st.selectbox("How sharp is the field in the contest?", ('Very', 'Above Average', 'Average', 'Below Average', 'Not Very'))170 if strength_var1 == 'Not Very':171 sharp_split = 500000172 elif strength_var1 == 'Below Average':173 sharp_split = 250000174 elif strength_var1 == 'Average':175 sharp_split = 100000176 elif strength_var1 == 'Above Average':177 sharp_split = 50000178 elif strength_var1 == 'Very':179 sharp_split = 10000180 181 if st.button("Run Contest Sim"):182 if 'working_seed' in st.session_state:183 st.session_state.maps_dict = {184 'Projection_map':dict(zip(raw_baselines.Player,raw_baselines.Median)),185 'Salary_map':dict(zip(raw_baselines.Player,raw_baselines.Salary)),186 'Pos_map':dict(zip(raw_baselines.Player,raw_baselines.Position)),187 'Own_map':dict(zip(raw_baselines.Player,raw_baselines['Own'])),188 'Team_map':dict(zip(raw_baselines.Player,raw_baselines.Team)),189 'STDev_map':dict(zip(raw_baselines.Player,raw_baselines.STDev))190 }191 Sim_Winners = sim_contest(1000, st.session_state.working_seed, st.session_state.maps_dict, Contest_Size, teams_playing_count)192 Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners))193 194 #st.table(Sim_Winner_Frame)195 196 # Initial setup197 Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners), columns=column_names + ['Fantasy'])198 Sim_Winner_Frame['GPP_Proj'] = (Sim_Winner_Frame['proj'] + Sim_Winner_Frame['Fantasy']) / 2199 Sim_Winner_Frame['unique_id'] = Sim_Winner_Frame['proj'].astype(str) + Sim_Winner_Frame['salary'].astype(str) + Sim_Winner_Frame['Team'].astype(str) + Sim_Winner_Frame['Secondary'].astype(str)200 Sim_Winner_Frame = Sim_Winner_Frame.assign(win_count=Sim_Winner_Frame['unique_id'].map(Sim_Winner_Frame['unique_id'].value_counts()))201 202 # Type Casting203 type_cast_dict = {'salary': int, 'proj': np.float16, 'Fantasy': np.float16, 'GPP_Proj': np.float32, 'Own': np.float32}204 Sim_Winner_Frame = Sim_Winner_Frame.astype(type_cast_dict)205 206 # Sorting207 st.session_state.Sim_Winner_Frame = Sim_Winner_Frame.sort_values(by=['win_count', 'GPP_Proj'], ascending= [False, False]).copy().drop_duplicates(subset='unique_id').head(100)208 st.session_state.Sim_Winner_Frame.drop(columns='unique_id', inplace=True)209 210 # Data Copying211 st.session_state.Sim_Winner_Export = Sim_Winner_Frame.copy()212 for col in st.session_state.Sim_Winner_Export.iloc[:, 0:9].columns:213 st.session_state.Sim_Winner_Export[col] = st.session_state.Sim_Winner_Export[col].map(dk_id_dict)214 st.session_state.Sim_Winner_Export = st.session_state.Sim_Winner_Export.drop_duplicates(subset=['Team', 'Secondary', 'salary', 'unique_id'])215 216 # Data Copying217 st.session_state.Sim_Winner_Display = Sim_Winner_Frame.copy()218 219 else:220 if sim_site_var1 == 'Draftkings':221 st.session_state.working_seed = init_DK_seed_frames(sharp_split, sim_slate_var1)222 dk_id_dict = dict(zip(dk_raw.Player, dk_raw.player_id))223 raw_baselines = dk_raw224 column_names = dk_columns225 elif sim_site_var1 == 'Fanduel':226 st.session_state.working_seed = init_FD_seed_frames(sharp_split, sim_slate_var1)227 fd_id_dict = dict(zip(fd_raw.Player, fd_raw.player_id))228 raw_baselines = fd_raw229 column_names = fd_columns230 231 st.session_state.maps_dict = {232 'Projection_map':dict(zip(raw_baselines.Player,raw_baselines.Median)),233 'Salary_map':dict(zip(raw_baselines.Player,raw_baselines.Salary)),234 'Pos_map':dict(zip(raw_baselines.Player,raw_baselines.Position)),235 'Own_map':dict(zip(raw_baselines.Player,raw_baselines['Own'])),236 'Team_map':dict(zip(raw_baselines.Player,raw_baselines.Team)),237 'STDev_map':dict(zip(raw_baselines.Player,raw_baselines.STDev))238 }239 Sim_Winners = sim_contest(1000, st.session_state.working_seed, st.session_state.maps_dict, Contest_Size, teams_playing_count)240 Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners))241 242 #st.table(Sim_Winner_Frame)243 244 # Initial setup245 Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners), columns=column_names + ['Fantasy'])246 Sim_Winner_Frame['GPP_Proj'] = (Sim_Winner_Frame['proj'] + Sim_Winner_Frame['Fantasy']) / 2247 Sim_Winner_Frame['unique_id'] = Sim_Winner_Frame['proj'].astype(str) + Sim_Winner_Frame['salary'].astype(str) + Sim_Winner_Frame['Team'].astype(str) + Sim_Winner_Frame['Secondary'].astype(str)248 Sim_Winner_Frame = Sim_Winner_Frame.assign(win_count=Sim_Winner_Frame['unique_id'].map(Sim_Winner_Frame['unique_id'].value_counts()))249 250 # Type Casting251 type_cast_dict = {'salary': int, 'proj': np.float16, 'Fantasy': np.float16, 'GPP_Proj': np.float32, 'Own': np.float32}252 Sim_Winner_Frame = Sim_Winner_Frame.astype(type_cast_dict)253 254 # Sorting255 st.session_state.Sim_Winner_Frame = Sim_Winner_Frame.sort_values(by=['win_count', 'GPP_Proj'], ascending= [False, False]).copy().drop_duplicates(subset='unique_id').head(100)256 st.session_state.Sim_Winner_Frame.drop(columns='unique_id', inplace=True)257 258 # Data Copying259 st.session_state.Sim_Winner_Export = Sim_Winner_Frame.copy()260 for col in st.session_state.Sim_Winner_Export.iloc[:, 0:9].columns:261 st.session_state.Sim_Winner_Export[col] = st.session_state.Sim_Winner_Export[col].map(dk_id_dict)262 st.session_state.Sim_Winner_Export = st.session_state.Sim_Winner_Export.drop_duplicates(subset=['Team', 'Secondary', 'salary', 'unique_id'])263 264 # Data Copying265 st.session_state.Sim_Winner_Display = Sim_Winner_Frame.copy()266 st.session_state.freq_copy = st.session_state.Sim_Winner_Display267 268 if sim_site_var1 == 'Draftkings':269 freq_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,0:9].values, return_counts=True)),270 columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)271 elif sim_site_var1 == 'Fanduel':272 freq_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,0:9].values, return_counts=True)),273 columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)274 freq_working['Freq'] = freq_working['Freq'].astype(int)275 freq_working['Position'] = freq_working['Player'].map(st.session_state.maps_dict['Pos_map'])276 freq_working['Salary'] = freq_working['Player'].map(st.session_state.maps_dict['Salary_map'])277 freq_working['Proj Own'] = freq_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100278 freq_working['Exposure'] = freq_working['Freq']/(1000)279 freq_working['Edge'] = freq_working['Exposure'] - freq_working['Proj Own']280 freq_working['Team'] = freq_working['Player'].map(st.session_state.maps_dict['Team_map'])281 st.session_state.player_freq = freq_working.copy()282 283 if sim_site_var1 == 'Draftkings':284 center_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,0:2].values, return_counts=True)),285 columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)286 elif sim_site_var1 == 'Fanduel':287 center_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,0:2].values, return_counts=True)),288 columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)289 center_working['Freq'] = center_working['Freq'].astype(int)290 center_working['Position'] = center_working['Player'].map(st.session_state.maps_dict['Pos_map'])291 center_working['Salary'] = center_working['Player'].map(st.session_state.maps_dict['Salary_map'])292 center_working['Proj Own'] = center_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100293 center_working['Exposure'] = center_working['Freq']/(1000)294 center_working['Edge'] = center_working['Exposure'] - center_working['Proj Own']295 center_working['Team'] = center_working['Player'].map(st.session_state.maps_dict['Team_map'])296 st.session_state.center_freq = center_working.copy()297 298 if sim_site_var1 == 'Draftkings':299 wing_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,2:5].values, return_counts=True)),300 columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)301 elif sim_site_var1 == 'Fanduel':302 wing_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,2:4].values, return_counts=True)),303 columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)304 wing_working['Freq'] = wing_working['Freq'].astype(int)305 wing_working['Position'] = wing_working['Player'].map(st.session_state.maps_dict['Pos_map'])306 wing_working['Salary'] = wing_working['Player'].map(st.session_state.maps_dict['Salary_map'])307 wing_working['Proj Own'] = wing_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100308 wing_working['Exposure'] = wing_working['Freq']/(1000)309 wing_working['Edge'] = wing_working['Exposure'] - wing_working['Proj Own']310 wing_working['Team'] = wing_working['Player'].map(st.session_state.maps_dict['Team_map'])311 st.session_state.wing_freq = wing_working.copy()312 313 if sim_site_var1 == 'Draftkings':314 dmen_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,5:7].values, return_counts=True)),315 columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)316 elif sim_site_var1 == 'Fanduel':317 dmen_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,4:6].values, return_counts=True)),318 columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)319 dmen_working['Freq'] = dmen_working['Freq'].astype(int)320 dmen_working['Position'] = dmen_working['Player'].map(st.session_state.maps_dict['Pos_map'])321 dmen_working['Salary'] = dmen_working['Player'].map(st.session_state.maps_dict['Salary_map'])322 dmen_working['Proj Own'] = dmen_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100323 dmen_working['Exposure'] = dmen_working['Freq']/(1000)324 dmen_working['Edge'] = dmen_working['Exposure'] - dmen_working['Proj Own']325 dmen_working['Team'] = dmen_working['Player'].map(st.session_state.maps_dict['Team_map'])326 st.session_state.dmen_freq = dmen_working.copy()327 328 if sim_site_var1 == 'Draftkings':329 flex_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,8:9].values, return_counts=True)),330 columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)331 elif sim_site_var1 == 'Fanduel':332 flex_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,6:8].values, return_counts=True)),333 columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)334 flex_working['Freq'] = flex_working['Freq'].astype(int)335 flex_working['Position'] = flex_working['Player'].map(st.session_state.maps_dict['Pos_map'])336 flex_working['Salary'] = flex_working['Player'].map(st.session_state.maps_dict['Salary_map'])337 flex_working['Proj Own'] = flex_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100338 flex_working['Exposure'] = flex_working['Freq']/(1000)339 flex_working['Edge'] = flex_working['Exposure'] - flex_working['Proj Own']340 flex_working['Team'] = flex_working['Player'].map(st.session_state.maps_dict['Team_map'])341 st.session_state.flex_freq = flex_working.copy()342 343 if sim_site_var1 == 'Draftkings':344 goalie_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,7:8].values, return_counts=True)),345 columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)346 elif sim_site_var1 == 'Fanduel':347 goalie_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,8:9].values, return_counts=True)),348 columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)349 goalie_working['Freq'] = goalie_working['Freq'].astype(int)350 goalie_working['Position'] = goalie_working['Player'].map(st.session_state.maps_dict['Pos_map'])351 goalie_working['Salary'] = goalie_working['Player'].map(st.session_state.maps_dict['Salary_map'])352 goalie_working['Proj Own'] = goalie_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100353 goalie_working['Exposure'] = goalie_working['Freq']/(1000)354 goalie_working['Edge'] = goalie_working['Exposure'] - goalie_working['Proj Own']355 goalie_working['Team'] = goalie_working['Player'].map(st.session_state.maps_dict['Team_map'])356 st.session_state.goalie_freq = goalie_working.copy()357 358 if sim_site_var1 == 'Draftkings':359 team_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,11:12].values, return_counts=True)),360 columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)361 elif sim_site_var1 == 'Fanduel':362 team_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,11:12].values, return_counts=True)),363 columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)364 team_working['Freq'] = team_working['Freq'].astype(int)365 team_working['Exposure'] = team_working['Freq']/(1000)366 st.session_state.team_freq = team_working.copy()367 368 with st.container():369 if st.button("Reset Sim", key='reset_sim'):370 for key in st.session_state.keys():371 del st.session_state[key]372 if 'player_freq' in st.session_state: 373 player_split_var2 = st.radio("Are you wanting to isolate any lineups with specific players?", ('Full Players', 'Specific Players'), key='player_split_var2')374 if player_split_var2 == 'Specific Players':375 find_var2 = st.multiselect('Which players must be included in the lineups?', options = st.session_state.player_freq['Player'].unique())376 elif player_split_var2 == 'Full Players':377 find_var2 = st.session_state.player_freq.Player.values.tolist()378 379 if player_split_var2 == 'Specific Players':380 st.session_state.Sim_Winner_Display = st.session_state.Sim_Winner_Frame[np.equal.outer(st.session_state.Sim_Winner_Frame.to_numpy(), find_var2).any(axis=1).all(axis=1)]381 if player_split_var2 == 'Full Players':382 st.session_state.Sim_Winner_Display = st.session_state.Sim_Winner_Frame383 if 'Sim_Winner_Display' in st.session_state:384 st.dataframe(st.session_state.Sim_Winner_Display.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(precision=2), use_container_width = True)385 if 'Sim_Winner_Export' in st.session_state:386 st.download_button(387 388 label="Export Full Frame",389 data=st.session_state.Sim_Winner_Export.to_csv().encode('utf-8'),390 file_name='MLB_consim_export.csv',391 mime='text/csv',392 ) 393 tab1, tab2, tab3 = st.tabs(['Winning Frame Statistics', 'Flex Exposure Statistics', 'Stack Type Statistics'])394 395 with tab1:396 if 'Sim_Winner_Display' in st.session_state:397 # Create a new dataframe with summary statistics398 summary_df = pd.DataFrame({399 'Metric': ['Min', 'Average', 'Max', 'STDdev'],400 'Salary': [401 st.session_state.Sim_Winner_Display['salary'].min(),402 st.session_state.Sim_Winner_Display['salary'].mean(),403 st.session_state.Sim_Winner_Display['salary'].max(),404 st.session_state.Sim_Winner_Display['salary'].std()405 ],406 'Proj': [407 st.session_state.Sim_Winner_Display['proj'].min(),408 st.session_state.Sim_Winner_Display['proj'].mean(),409 st.session_state.Sim_Winner_Display['proj'].max(),410 st.session_state.Sim_Winner_Display['proj'].std()411 ],412 'Own': [413 st.session_state.Sim_Winner_Display['Own'].min(),414 st.session_state.Sim_Winner_Display['Own'].mean(),415 st.session_state.Sim_Winner_Display['Own'].max(),416 st.session_state.Sim_Winner_Display['Own'].std()417 ],418 'Fantasy': [419 st.session_state.Sim_Winner_Display['Fantasy'].min(),420 st.session_state.Sim_Winner_Display['Fantasy'].mean(),421 st.session_state.Sim_Winner_Display['Fantasy'].max(),422 st.session_state.Sim_Winner_Display['Fantasy'].std()423 ],424 'GPP_Proj': [425 st.session_state.Sim_Winner_Display['GPP_Proj'].min(),426 st.session_state.Sim_Winner_Display['GPP_Proj'].mean(),427 st.session_state.Sim_Winner_Display['GPP_Proj'].max(),428 st.session_state.Sim_Winner_Display['GPP_Proj'].std()429 ]430 })431 432 # Set the index of the summary dataframe as the "Metric" column433 summary_df = summary_df.set_index('Metric')434 435 # Display the summary dataframe436 st.subheader("Winning Frame Statistics")437 st.dataframe(summary_df.style.format({438 'Salary': '{:.2f}',439 'Proj': '{:.2f}',440 'Own': '{:.2f}',441 'Fantasy': '{:.2f}',442 'GPP_Proj': '{:.2f}'443 }).background_gradient(cmap='RdYlGn', axis=0, subset=['Salary', 'Proj', 'Own', 'Fantasy', 'GPP_Proj']), use_container_width=True)444 445 with tab2:446 if 'Sim_Winner_Display' in st.session_state:447 # Apply position mapping to FLEX column448 if sim_site_var1 == 'Draftkings':449 flex_positions = st.session_state.freq_copy['FLEX'].map(st.session_state.maps_dict['Pos_map'])450 elif sim_site_var1 == 'Fanduel':451 flex1_positions = st.session_state.freq_copy['FLEX1'].map(st.session_state.maps_dict['Pos_map'])452 flex2_positions = st.session_state.freq_copy['FLEX2'].map(st.session_state.maps_dict['Pos_map'])453 flex_positions = pd.concat([flex1_positions, flex2_positions])454 455 # Count occurrences of each position in FLEX456 flex_counts = flex_positions.value_counts()457 458 # Calculate average statistics for each FLEX position459 flex_stats = st.session_state.freq_copy.groupby(flex_positions).agg({460 'proj': 'mean',461 'Own': 'mean',462 'Fantasy': 'mean',463 'GPP_Proj': 'mean'464 })465 466 # Combine counts and average statistics467 flex_summary = pd.concat([flex_counts, flex_stats], axis=1)468 flex_summary.columns = ['Count', 'Avg Proj', 'Avg Own', 'Avg Fantasy', 'Avg GPP_Proj']469 flex_summary = flex_summary.reset_index()470 flex_summary.columns = ['Position', 'Count', 'Avg Proj', 'Avg Own', 'Avg Fantasy', 'Avg GPP_Proj']471 472 # Display the summary dataframe473 st.subheader("FLEX Position Statistics")474 st.dataframe(flex_summary.style.format({475 'Count': '{:.0f}',476 'Avg Proj': '{:.2f}',477 'Avg Own': '{:.2f}',478 'Avg Fantasy': '{:.2f}',479 'Avg GPP_Proj': '{:.2f}'480 }).background_gradient(cmap='RdYlGn', axis=0, subset=['Count', 'Avg Proj', 'Avg Own', 'Avg Fantasy', 'Avg GPP_Proj']), use_container_width=True)481 else:482 st.write("Simulation data or position mapping not available.")483 484 with tab3:485 if 'Sim_Winner_Display' in st.session_state:486 # Apply position mapping to FLEX column487 stack_counts = st.session_state.freq_copy['Team_count'].value_counts()488 489 # Calculate average statistics for each stack size490 stack_stats = st.session_state.freq_copy.groupby('Team_count').agg({491 'proj': 'mean',492 'Own': 'mean',493 'Fantasy': 'mean',494 'GPP_Proj': 'mean'495 })496 497 # Combine counts and average statistics498 stack_summary = pd.concat([stack_counts, stack_stats], axis=1)499 stack_summary.columns = ['Count', 'Avg Proj', 'Avg Own', 'Avg Fantasy', 'Avg GPP_Proj']500 stack_summary = stack_summary.reset_index()501 stack_summary.columns = ['Stack Size', 'Count', 'Avg Proj', 'Avg Own', 'Avg Fantasy', 'Avg GPP_Proj']502 stack_summary = stack_summary.sort_values(by='Stack Size', ascending=True)503 stack_summary = stack_summary.set_index('Stack Size')504 505 # Display the summary dataframe506 st.subheader("Stack Type Statistics")507 st.dataframe(stack_summary.style.format({508 'Count': '{:.0f}',509 'Avg Proj': '{:.2f}',510 'Avg Own': '{:.2f}',511 'Avg Fantasy': '{:.2f}',512 'Avg GPP_Proj': '{:.2f}'513 }).background_gradient(cmap='RdYlGn', axis=0, subset=['Count', 'Avg Proj', 'Avg Own', 'Avg Fantasy', 'Avg GPP_Proj']), use_container_width=True)514 else:515 st.write("Simulation data or position mapping not available.")516 517 518 with st.container():519 tab1, tab2, tab3, tab4, tab5, tab6, tab7 = st.tabs(['Overall Exposures', 'Center Exposures', 'Wing Exposures', 'Defense Exposures', 'Flex Exposures', 'Goalie Exposures', 'Team Exposures'])520 with tab1:521 if 'player_freq' in st.session_state:522 523 st.dataframe(st.session_state.player_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True)524 st.download_button(525 label="Export Exposures",526 data=st.session_state.player_freq.to_csv().encode('utf-8'),527 file_name='player_freq_export.csv',528 mime='text/csv',529 key='overall'530 )531 with tab2:532 if 'center_freq' in st.session_state:533 534 st.dataframe(st.session_state.center_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True)535 st.download_button(536 label="Export Exposures",537 data=st.session_state.center_freq.to_csv().encode('utf-8'),538 file_name='center_freq.csv',539 mime='text/csv',540 key='center'541 )542 with tab3:543 if 'wing_freq' in st.session_state:544 545 st.dataframe(st.session_state.wing_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True)546 st.download_button(547 label="Export Exposures",548 data=st.session_state.wing_freq.to_csv().encode('utf-8'),549 file_name='wing_freq.csv',550 mime='text/csv',551 key='wing'552 )553 with tab4:554 if 'dmen_freq' in st.session_state:555 556 st.dataframe(st.session_state.dmen_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True)557 st.download_button(558 label="Export Exposures",559 data=st.session_state.dmen_freq.to_csv().encode('utf-8'),560 file_name='dmen_freq.csv',561 mime='text/csv',562 key='dmen'563 )564 with tab5:565 if 'flex_freq' in st.session_state:566 567 st.dataframe(st.session_state.flex_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True)568 st.download_button(569 label="Export Exposures",570 data=st.session_state.flex_freq.to_csv().encode('utf-8'),571 file_name='flex_freq.csv',572 mime='text/csv',573 key='flex'574 )575 with tab6:576 if 'goalie_freq' in st.session_state:577 578 st.dataframe(st.session_state.goalie_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True)579 st.download_button(580 label="Export Exposures",581 data=st.session_state.goalie_freq.to_csv().encode('utf-8'),582 file_name='goalie_freq.csv',583 mime='text/csv',584 key='goalie'585 )586 with tab7:587 if 'team_freq' in st.session_state:588 589 st.dataframe(st.session_state.team_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(percentages_format, precision=2), use_container_width = True)590 st.download_button(591 label="Export Exposures",592 data=st.session_state.team_freq.to_csv().encode('utf-8'),593 file_name='team_freq.csv',594 mime='text/csv',595 key='team'596 )597 598with tab2:599 with st.expander("Info and Filters"):600 if st.button("Load/Reset Data", key='reset1'):601 st.cache_data.clear()602 for key in st.session_state.keys():603 del st.session_state[key]604 DK_seed = init_DK_seed_frames(10000)605 FD_seed = init_FD_seed_frames(10000)606 dk_raw, fd_raw, teams_playing_count = init_baselines()607 dk_id_dict = dict(zip(dk_raw.Player, dk_raw.player_id))608 fd_id_dict = dict(zip(fd_raw.Player, fd_raw.player_id))609 610 slate_var2 = st.radio("Which data are you loading?", ('Main Slate', 'Secondary Slate', 'Auxiliary Slate'))611 site_var1 = st.radio("What site are you working with?", ('Draftkings', 'Fanduel'))612 sharp_split_var = st.number_input("How many lineups do you want?", value=10000, max_value=500000, min_value=10000, step=10000)613 lineup_num_var = st.number_input("How many lineups do you want to display?", min_value=1, max_value=500, value=10, step=1)614 615 if site_var1 == 'Draftkings':616 617 team_var1 = st.radio("Do you want a frame with specific teams?", ('Full Slate', 'Specific Teams'), key='team_var1')618 if team_var1 == 'Specific Teams':619 team_var2 = st.multiselect('Which teams do you want?', options = dk_raw['Team'].unique())620 elif team_var1 == 'Full Slate':621 team_var2 = dk_raw.Team.values.tolist()622 623 stack_var1 = st.radio("Do you want a frame with specific stack sizes?", ('Full Slate', 'Specific Stack Sizes'), key='stack_var1')624 if stack_var1 == 'Specific Stack Sizes':625 stack_var2 = st.multiselect('Which stack sizes do you want?', options = [5, 4, 3, 2, 1, 0])626 elif stack_var1 == 'Full Slate':627 stack_var2 = [5, 4, 3, 2, 1, 0]628 629 raw_baselines = dk_raw630 column_names = dk_columns631 632 elif site_var1 == 'Fanduel':633 634 team_var1 = st.radio("Do you want a frame with specific teams?", ('Full Slate', 'Specific Teams'), key='team_var1')635 if team_var1 == 'Specific Teams':636 team_var2 = st.multiselect('Which teams do you want?', options = fd_raw['Team'].unique())637 elif team_var1 == 'Full Slate':638 team_var2 = fd_raw.Team.values.tolist()639 640 stack_var1 = st.radio("Do you want a frame with specific stack sizes?", ('Full Slate', 'Specific Stack Sizes'), key='stack_var1')641 if stack_var1 == 'Specific Stack Sizes':642 stack_var2 = st.multiselect('Which stack sizes do you want?', options = [5, 4, 3, 2, 1, 0])643 elif stack_var1 == 'Full Slate':644 stack_var2 = [5, 4, 3, 2, 1, 0]645 646 raw_baselines = fd_raw647 column_names = fd_columns648 649 650 if st.button("Prepare data export", key='data_export'):651 if 'working_seed' in st.session_state:652 st.session_state.working_seed = st.session_state.working_seed[np.isin(st.session_state.working_seed[:, 11], team_var2)]653 st.session_state.working_seed = st.session_state.working_seed[np.isin(st.session_state.working_seed[:, 12], stack_var2)]654 st.session_state.data_export_display = st.session_state.working_seed[0:lineup_num_var]655 elif 'working_seed' not in st.session_state:656 if site_var1 == 'Draftkings':657 st.session_state.working_seed = init_DK_seed_frames(sharp_split_var, slate_var2)658 659 dk_id_dict = dict(zip(dk_raw.Player, dk_raw.player_id))660 raw_baselines = dk_raw661 column_names = dk_columns662 663 elif site_var1 == 'Fanduel':664 st.session_state.working_seed = init_FD_seed_frames(sharp_split_var, slate_var2)665 666 fd_id_dict = dict(zip(fd_raw.Player, fd_raw.player_id))667 raw_baselines = fd_raw668 column_names = fd_columns669 st.session_state.working_seed = st.session_state.working_seed[np.isin(st.session_state.working_seed[:, 11], team_var2)]670 st.session_state.working_seed = st.session_state.working_seed[np.isin(st.session_state.working_seed[:, 12], stack_var2)]671 st.session_state.data_export_display = st.session_state.working_seed[0:lineup_num_var]672 data_export = st.session_state.working_seed.copy()673 st.download_button(674 label="Export optimals set",675 data=convert_df(data_export),676 file_name='NHL_optimals_export.csv',677 mime='text/csv',678 )679 for key in st.session_state.keys():680 del st.session_state[key]681 682 if st.button("Load Data", key='load_data'):683 if site_var1 == 'Draftkings':684 if 'working_seed' in st.session_state:685 st.session_state.working_seed = st.session_state.working_seed[np.isin(st.session_state.working_seed[:, 11], team_var2)]686 st.session_state.working_seed = st.session_state.working_seed[np.isin(st.session_state.working_seed[:, 12], stack_var2)]687 st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:lineup_num_var], columns=column_names)688 elif 'working_seed' not in st.session_state:689 if slate_var2 == 'Main Slate':690 st.session_state.working_seed = init_DK_seed_frames(sharp_split_var)691 dk_id_dict = dict(zip(dk_raw.Player, dk_raw.player_id))692 693 raw_baselines = dk_raw694 column_names = dk_columns695 696 st.session_state.working_seed = st.session_state.working_seed[np.isin(st.session_state.working_seed[:, 11], team_var2)]697 st.session_state.working_seed = st.session_state.working_seed[np.isin(st.session_state.working_seed[:, 12], stack_var2)]698 st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:lineup_num_var], columns=column_names)699 700 elif site_var1 == 'Fanduel':701 if 'working_seed' in st.session_state:702 st.session_state.working_seed = st.session_state.working_seed[np.isin(st.session_state.working_seed[:, 11], team_var2)]703 st.session_state.working_seed = st.session_state.working_seed[np.isin(st.session_state.working_seed[:, 12], stack_var2)]704 st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:lineup_num_var], columns=column_names)705 elif 'working_seed' not in st.session_state:706 if slate_var2 == 'Main Slate':707 st.session_state.working_seed = init_FD_seed_frames(sharp_split_var)708 fd_id_dict = dict(zip(fd_raw.Player, fd_raw.player_id))709 710 raw_baselines = fd_raw711 column_names = fd_columns712 st.session_state.working_seed = st.session_state.working_seed[np.isin(st.session_state.working_seed[:, 11], team_var2)]713 st.session_state.working_seed = st.session_state.working_seed[np.isin(st.session_state.working_seed[:, 12], stack_var2)]714 st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:lineup_num_var], columns=column_names)715 716 with st.container():717 if 'data_export_display' in st.session_state:718 st.dataframe(st.session_state.data_export_display.style.format(freq_format, precision=2), use_container_width = True)