diff --git "a/app.py" "b/app.py" --- "a/app.py" +++ "b/app.py" @@ -1,16 +1,10 @@ -import streamlit as st -st.set_page_config(layout="wide") - -for name in dir(): - if not name.startswith('_'): - del globals()[name] - +import pulp import numpy as np import pandas as pd import streamlit as st import gspread -import random -import gc +from itertools import combinations +import time @st.cache_resource def init_conn(): @@ -30,15 +24,30 @@ def init_conn(): "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/gspread-connection%40sheets-api-connect-378620.iam.gserviceaccount.com" } - gc_con = gspread.service_account_from_dict(credentials) - - return gc_con + gc = gspread.service_account_from_dict(credentials) + return gc + +st.set_page_config(layout="wide") + +gc = init_conn() + +wrong_acro = ['WSH', 'AZ'] +right_acro = ['WAS', 'ARI'] -gcservice_account = init_conn() +game_format = {'Win Percentage': '{:.2%}','First Inning Lead Percentage': '{:.2%}', + 'Fifth Inning Lead Percentage': '{:.2%}', '8+ runs': '{:.2%}', 'DK LevX': '{:.2%}', 'FD LevX': '{:.2%}'} -freq_format = {'Proj Own': '{:.2%}', 'Exposure': '{:.2%}', 'Edge': '{:.2%}'} +team_roo_format = {'Top Score%': '{:.2%}','0 Runs': '{:.2%}', '1 Run': '{:.2%}', '2 Runs': '{:.2%}', '3 Runs': '{:.2%}', '4 Runs': '{:.2%}', + '5 Runs': '{:.2%}','6 Runs': '{:.2%}', '7 Runs': '{:.2%}', '8 Runs': '{:.2%}', '9 Runs': '{:.2%}', '10 Runs': '{:.2%}'} -@st.cache_resource(ttl=601) +player_roo_format = {'Top_finish': '{:.2%}','Top_5_finish': '{:.2%}', 'Top_10_finish': '{:.2%}', '20+%': '{:.2%}', '2x%': '{:.2%}', '3x%': '{:.2%}', + '4x%': '{:.2%}','GPP%': '{:.2%}'} + +expose_format = {'Proj Own': '{:.2%}','Exposure': '{:.2%}'} + +all_dk_player_projections = 'https://docs.google.com/spreadsheets/d/1I_1Ve3F4tftgfLQQoRKOJ351XfEG48s36OxXUKxmgS8/edit#gid=1391856348' + +@st.cache_resource(ttl=300) def init_baselines(): sh = gc.open_by_url(all_dk_player_projections) worksheet = sh.worksheet('SD_Projections') @@ -107,508 +116,179 @@ def init_baselines(): dk_roo_raw, dk_roo_raw_2, dk_roo_raw_3, fd_roo_raw, fd_roo_raw_2, fd_roo_raw_3, dkid_dict, fdid_dict = init_baselines() -static_exposure = pd.DataFrame(columns=['Player', 'count']) -overall_exposure = pd.DataFrame(columns=['Player', 'count']) - -def sim_contest(Sim_size, FinalPortfolio, CleanPortfolio, maps_dict, up_dict, insert_port): - SimVar = 1 - Sim_Winners = [] - fp_array = FinalPortfolio.values - - if insert_port == 1: - up_array = CleanPortfolio.values - - # Pre-vectorize functions - vec_projection_map = np.vectorize(maps_dict['Projection_map'].__getitem__) - vec_stdev_map = np.vectorize(maps_dict['STDev_map'].__getitem__) - - if insert_port == 1: - vec_up_projection_map = np.vectorize(up_dict['Projection_map'].__getitem__) - vec_up_stdev_map = np.vectorize(up_dict['STDev_map'].__getitem__) - - st.write('Simulating contest on frames') - - while SimVar <= Sim_size: - if insert_port == 1: - fp_random = fp_array[np.random.choice(fp_array.shape[0], Contest_Size-len(CleanPortfolio))] - elif insert_port == 0: - fp_random = fp_array[np.random.choice(fp_array.shape[0], Contest_Size)] - - sample_arrays1 = np.c_[ - fp_random, - np.sum(np.random.normal( - loc=vec_projection_map(fp_random[:, :-5]), - scale=vec_stdev_map(fp_random[:, :-5])), - axis=1) - ] - - if insert_port == 1: - sample_arrays2 = np.c_[ - up_array, - np.sum(np.random.normal( - loc=vec_up_projection_map(up_array[:, :-5]), - scale=vec_up_stdev_map(up_array[:, :-5])), - axis=1) - ] - sample_arrays = np.vstack((sample_arrays1, sample_arrays2)) - else: - sample_arrays = sample_arrays1 - - final_array = sample_arrays[sample_arrays[:, 10].argsort()[::-1]] - best_lineup = final_array[final_array[:, -1].argsort(kind='stable')[::-1][:1]] - Sim_Winners.append(best_lineup) - SimVar += 1 - - return Sim_Winners - -def run_seed_frame(seed_depth1, Strength_var, strength_grow, Teams_used, Total_Runs, field_growth): - RunsVar = 1 - seed_depth_def = seed_depth1 - Strength_var_def = Strength_var - strength_grow_def = strength_grow - Teams_used_def = Teams_used - Total_Runs_def = Total_Runs - - st.write('Creating Seed Frames') - - while RunsVar <= seed_depth_def: - if RunsVar <= 3: - FieldStrength = Strength_var_def - FinalPortfolio, maps_dict = get_correlated_portfolio_for_sim(Total_Runs_def * .25, sharp_split, field_growth) - FinalPortfolio2, maps_dict2 = get_uncorrelated_portfolio_for_sim(Total_Runs_def * .25, sharp_split, field_growth) - FinalPortfolio_init = pd.concat([FinalPortfolio, FinalPortfolio2], axis=0) - maps_dict.update(maps_dict2) - elif RunsVar > 3 and RunsVar <= 4: - FieldStrength += (strength_grow_def + ((30 - len(Teams_used_def)) * .001)) - FinalPortfolio3, maps_dict3 = get_correlated_portfolio_for_sim(Total_Runs_def * .25, sharp_split, field_growth) - FinalPortfolio4, maps_dict4 = get_uncorrelated_portfolio_for_sim(Total_Runs_def * .25, sharp_split, field_growth) - FinalPortfolio_merge_3 = pd.concat([FinalPortfolio_init, FinalPortfolio3], axis=0) - FinalPortfolio_merge_4 = pd.concat([FinalPortfolio_merge_3, FinalPortfolio4], axis=0) - FinalPortfolio_step_2 = FinalPortfolio_merge_4.drop_duplicates(subset = ['Projection', 'Own'],keep = 'last').reset_index(drop = True) - maps_dict.update(maps_dict3) - maps_dict.update(maps_dict4) - elif RunsVar > 4: - FieldStrength = 1 - FinalPortfolio5, maps_dict5 = get_correlated_portfolio_for_sim(Total_Runs_def * .25, sharp_split, field_growth) - FinalPortfolio6, maps_dict6 = get_uncorrelated_portfolio_for_sim(Total_Runs_def * .25, sharp_split, field_growth) - FinalPortfolio_merge_5 = pd.concat([FinalPortfolio_step_2, FinalPortfolio5], axis=0) - FinalPortfolio_merge_6 = pd.concat([FinalPortfolio_merge_5, FinalPortfolio6], axis=0) - FinalPortfolio_export = FinalPortfolio_merge_6.drop_duplicates(subset = ['Projection', 'Own'],keep = 'last').reset_index(drop = True) - maps_dict.update(maps_dict5) - maps_dict.update(maps_dict6) - RunsVar += 1 - - return FinalPortfolio_export, maps_dict - -def create_overall_dfs(pos_players, table_name, dict_name, pos): - pos_players = pos_players.sort_values(by='Value', ascending=False) - table_name_raw = pos_players.reset_index(drop=True) - overall_table_name = table_name_raw.head(round(len(table_name_raw))) - overall_table_name = overall_table_name.assign(Var = range(0,len(overall_table_name))) - overall_dict_name = pd.Series(overall_table_name.Player.values, index=overall_table_name.Var).to_dict() - - return overall_table_name, overall_dict_name - - -def get_overall_merged_df(): - ref_dict = { - 'pos':['FLEX'], - 'pos_dfs':['FLEX_Table'], - 'pos_dicts':['flex_dict'] - } - - for i in range(0,1): - ref_dict['pos_dfs'][i], ref_dict['pos_dicts'][i] =\ - create_overall_dfs(pos_players, ref_dict['pos_dfs'][i], ref_dict['pos_dicts'][i], ref_dict['pos'][i]) - - df_out = pd.concat(ref_dict['pos_dfs'], ignore_index=True) - - return df_out, ref_dict - -def create_random_portfolio(Total_Sample_Size, raw_baselines, field_growth): - - O_merge, full_pos_player_dict = get_overall_merged_df() - Overall_Merge = O_merge[['Var', 'Player', 'Team', 'Salary', 'Median', 'Own']].copy() - - # Calculate Floor, Ceiling, and STDev directly - Overall_Merge['Floor'] = Overall_Merge['Median'] * .25 - Overall_Merge['Ceiling'] = Overall_Merge['Median'] + Overall_Merge['Floor'] - Overall_Merge['STDev'] = Overall_Merge['Median'] / 4 - - # Calculate the flex range and generate unique range list - flex_range_var = len(Overall_Merge) - ranges_dict = {'flex_range': flex_range_var} - ranges_dict['flex_Uniques'] = list(range(0, flex_range_var)) - - # Generate random portfolios - rng = np.random.default_rng() - all_choices = rng.choice(flex_range_var, size=(Total_Sample_Size, 6)) - - # Create RandomPortfolio DataFrame - RandomPortfolio = pd.DataFrame(all_choices, columns=['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5']) - RandomPortfolio['User/Field'] = 0 - - return RandomPortfolio, maps_dict, ranges_dict, full_pos_player_dict - -def get_correlated_portfolio_for_sim(Total_Sample_Size, sharp_split, field_growth): - - sizesplit = round(Total_Sample_Size * sharp_split) - - RandomPortfolio, maps_dict, ranges_dict, full_pos_player_dict = create_random_portfolio(sizesplit, raw_baselines, field_growth) - - RandomPortfolio['CPT'] = pd.Series(list(RandomPortfolio['CPT'].map(full_pos_player_dict['pos_dicts'][0])), dtype="string[pyarrow]") - RandomPortfolio['FLEX1'] = pd.Series(list(RandomPortfolio['FLEX1'].map(full_pos_player_dict['pos_dicts'][0])), dtype="string[pyarrow]") - RandomPortfolio['FLEX2'] = pd.Series(list(RandomPortfolio['FLEX2'].map(full_pos_player_dict['pos_dicts'][0])), dtype="string[pyarrow]") - RandomPortfolio['FLEX3'] = pd.Series(list(RandomPortfolio['FLEX3'].map(full_pos_player_dict['pos_dicts'][0])), dtype="string[pyarrow]") - RandomPortfolio['FLEX4'] = pd.Series(list(RandomPortfolio['FLEX4'].map(full_pos_player_dict['pos_dicts'][0])), dtype="string[pyarrow]") - RandomPortfolio['FLEX5'] = pd.Series(list(RandomPortfolio['FLEX5'].map(full_pos_player_dict['pos_dicts'][0])), dtype="string[pyarrow]") - RandomPortfolio['plyr_list'] = RandomPortfolio[RandomPortfolio.columns.values.tolist()].values.tolist() - RandomPortfolio['plyr_count'] = RandomPortfolio['plyr_list'].apply(lambda x: len(set(x))) - RandomPortfolio = RandomPortfolio[RandomPortfolio['plyr_count'] == 7].drop(columns=['plyr_list','plyr_count']).\ - reset_index(drop=True) - - RandomPortfolio['CPTs'] = RandomPortfolio['CPT'].map(maps_dict['Salary_map']).astype(np.int32) * 1.5 - RandomPortfolio['FLEX1s'] = RandomPortfolio['FLEX1'].map(maps_dict['Salary_map']).astype(np.int32) - RandomPortfolio['FLEX2s'] = RandomPortfolio['FLEX2'].map(maps_dict['Salary_map']).astype(np.int32) - RandomPortfolio['FLEX3s'] = RandomPortfolio['FLEX3'].map(maps_dict['Salary_map']).astype(np.int32) - RandomPortfolio['FLEX4s'] = RandomPortfolio['FLEX4'].map(maps_dict['Salary_map']).astype(np.int32) - RandomPortfolio['FLEX5s'] = RandomPortfolio['FLEX5'].map(maps_dict['Salary_map']).astype(np.int32) - - RandomPortfolio['CPTp'] = RandomPortfolio['CPT'].map(maps_dict['Projection_map']).astype(np.float16) * 1.5 - RandomPortfolio['FLEX1p'] = RandomPortfolio['FLEX1'].map(maps_dict['Projection_map']).astype(np.float16) - RandomPortfolio['FLEX2p'] = RandomPortfolio['FLEX2'].map(maps_dict['Projection_map']).astype(np.float16) - RandomPortfolio['FLEX3p'] = RandomPortfolio['FLEX3'].map(maps_dict['Projection_map']).astype(np.float16) - RandomPortfolio['FLEX4p'] = RandomPortfolio['FLEX4'].map(maps_dict['Projection_map']).astype(np.float16) - RandomPortfolio['FLEX5p'] = RandomPortfolio['FLEX5'].map(maps_dict['Projection_map']).astype(np.float16) - - RandomPortfolio['CPTo'] = RandomPortfolio['CPT'].map(maps_dict['Own_map']).astype(np.float16) / 4 - RandomPortfolio['FLEX1o'] = RandomPortfolio['FLEX1'].map(maps_dict['Own_map']).astype(np.float16) - RandomPortfolio['FLEX2o'] = RandomPortfolio['FLEX2'].map(maps_dict['Own_map']).astype(np.float16) - RandomPortfolio['FLEX3o'] = RandomPortfolio['FLEX3'].map(maps_dict['Own_map']).astype(np.float16) - RandomPortfolio['FLEX4o'] = RandomPortfolio['FLEX4'].map(maps_dict['Own_map']).astype(np.float16) - RandomPortfolio['FLEX5o'] = RandomPortfolio['FLEX5'].map(maps_dict['Own_map']).astype(np.float16) - - portHeaderList = RandomPortfolio.columns.values.tolist() - portHeaderList.append('Salary') - portHeaderList.append('Projection') - portHeaderList.append('Own') - - RandomPortArray = RandomPortfolio.to_numpy() - - RandomPortArray = np.c_[RandomPortArray, np.einsum('ij->i',RandomPortArray[:,7:13].astype(int))] - RandomPortArray = np.c_[RandomPortArray, np.einsum('ij->i',RandomPortArray[:,13:19].astype(np.double))] - RandomPortArray = np.c_[RandomPortArray, np.einsum('ij->i',RandomPortArray[:,19:25].astype(np.double))] - - RandomPortArrayOut = np.delete(RandomPortArray, np.s_[7:25], axis=1) - RandomPortfolioDF = pd.DataFrame(RandomPortArrayOut, columns = ['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'User/Field', 'Salary', 'Projection', 'Own']) - RandomPortfolioDF = RandomPortfolioDF.sort_values(by=Sim_function, ascending=False) - - if insert_port == 1: - CleanPortfolio['Salary'] = sum([CleanPortfolio['CPT'].map(up_dict['Salary_map']) * 1.5, - CleanPortfolio['FLEX1'].map(up_dict['Salary_map']), - CleanPortfolio['FLEX2'].map(up_dict['Salary_map']), - CleanPortfolio['FLEX3'].map(up_dict['Salary_map']), - CleanPortfolio['FLEX4'].map(up_dict['Salary_map']), - CleanPortfolio['FLEX5'].map(up_dict['Salary_map']) - ]).astype(np.int16) - if insert_port == 1: - CleanPortfolio['Projection'] = sum([CleanPortfolio['CPT'].map(up_dict['Projection_map']) * 1.5, - CleanPortfolio['FLEX1'].map(up_dict['Projection_map']), - CleanPortfolio['FLEX2'].map(up_dict['Projection_map']), - CleanPortfolio['FLEX3'].map(up_dict['Projection_map']), - CleanPortfolio['FLEX4'].map(up_dict['Projection_map']), - CleanPortfolio['FLEX5'].map(up_dict['Projection_map']) - ]).astype(np.float16) - if insert_port == 1: - CleanPortfolio['Own'] = sum([CleanPortfolio['CPT'].map(up_dict['Own_map']) / 4, - CleanPortfolio['FLEX1'].map(up_dict['Own_map']), - CleanPortfolio['FLEX2'].map(up_dict['Own_map']), - CleanPortfolio['FLEX3'].map(up_dict['Own_map']), - CleanPortfolio['FLEX4'].map(up_dict['Own_map']), - CleanPortfolio['FLEX5'].map(up_dict['Own_map']) - ]).astype(np.float16) - - if site_var1 == 'Draftkings': - RandomPortfolioDF = RandomPortfolioDF[RandomPortfolioDF['Salary'] <= 50000].reset_index(drop=True) - RandomPortfolioDF = RandomPortfolioDF[RandomPortfolioDF['Salary'] >= 49500 - (FieldStrength * 1000)].reset_index(drop=True) - elif site_var1 == 'Fanduel': - RandomPortfolioDF = RandomPortfolioDF[RandomPortfolioDF['Salary'] <= 60000].reset_index(drop=True) - RandomPortfolioDF = RandomPortfolioDF[RandomPortfolioDF['Salary'] >= 59500 - (FieldStrength * 1000)].reset_index(drop=True) - - RandomPortfolio = RandomPortfolioDF.sort_values(by=Sim_function, ascending=False) - - RandomPortfolio = RandomPortfolio[['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'User/Field', 'Salary', 'Projection', 'Own']] - - return RandomPortfolio, maps_dict - -def get_uncorrelated_portfolio_for_sim(Total_Sample_Size, sharp_split, field_growth): - - sizesplit = round(Total_Sample_Size * (1-sharp_split)) - - RandomPortfolio, maps_dict, ranges_dict, full_pos_player_dict = create_random_portfolio(sizesplit, raw_baselines, field_growth) - - RandomPortfolio['CPT'] = pd.Series(list(RandomPortfolio['CPT'].map(full_pos_player_dict['pos_dicts'][0])), dtype="string[pyarrow]") - RandomPortfolio['FLEX1'] = pd.Series(list(RandomPortfolio['FLEX1'].map(full_pos_player_dict['pos_dicts'][0])), dtype="string[pyarrow]") - RandomPortfolio['FLEX2'] = pd.Series(list(RandomPortfolio['FLEX2'].map(full_pos_player_dict['pos_dicts'][0])), dtype="string[pyarrow]") - RandomPortfolio['FLEX3'] = pd.Series(list(RandomPortfolio['FLEX3'].map(full_pos_player_dict['pos_dicts'][0])), dtype="string[pyarrow]") - RandomPortfolio['FLEX4'] = pd.Series(list(RandomPortfolio['FLEX4'].map(full_pos_player_dict['pos_dicts'][0])), dtype="string[pyarrow]") - RandomPortfolio['FLEX5'] = pd.Series(list(RandomPortfolio['FLEX5'].map(full_pos_player_dict['pos_dicts'][0])), dtype="string[pyarrow]") - RandomPortfolio['plyr_list'] = RandomPortfolio[RandomPortfolio.columns.values.tolist()].values.tolist() - RandomPortfolio['plyr_count'] = RandomPortfolio['plyr_list'].apply(lambda x: len(set(x))) - RandomPortfolio = RandomPortfolio[RandomPortfolio['plyr_count'] == 7].drop(columns=['plyr_list','plyr_count']).\ - reset_index(drop=True) - - RandomPortfolio['CPTs'] = RandomPortfolio['CPT'].map(maps_dict['Salary_map']).astype(np.int32) * 1.5 - RandomPortfolio['FLEX1s'] = RandomPortfolio['FLEX1'].map(maps_dict['Salary_map']).astype(np.int32) - RandomPortfolio['FLEX2s'] = RandomPortfolio['FLEX2'].map(maps_dict['Salary_map']).astype(np.int32) - RandomPortfolio['FLEX3s'] = RandomPortfolio['FLEX3'].map(maps_dict['Salary_map']).astype(np.int32) - RandomPortfolio['FLEX4s'] = RandomPortfolio['FLEX4'].map(maps_dict['Salary_map']).astype(np.int32) - RandomPortfolio['FLEX5s'] = RandomPortfolio['FLEX5'].map(maps_dict['Salary_map']).astype(np.int32) - - RandomPortfolio['CPTp'] = RandomPortfolio['CPT'].map(maps_dict['Projection_map']).astype(np.float16) * 1.5 - RandomPortfolio['FLEX1p'] = RandomPortfolio['FLEX1'].map(maps_dict['Projection_map']).astype(np.float16) - RandomPortfolio['FLEX2p'] = RandomPortfolio['FLEX2'].map(maps_dict['Projection_map']).astype(np.float16) - RandomPortfolio['FLEX3p'] = RandomPortfolio['FLEX3'].map(maps_dict['Projection_map']).astype(np.float16) - RandomPortfolio['FLEX4p'] = RandomPortfolio['FLEX4'].map(maps_dict['Projection_map']).astype(np.float16) - RandomPortfolio['FLEX5p'] = RandomPortfolio['FLEX5'].map(maps_dict['Projection_map']).astype(np.float16) - - RandomPortfolio['CPTo'] = RandomPortfolio['CPT'].map(maps_dict['Own_map']).astype(np.float16) / 4 - RandomPortfolio['FLEX1o'] = RandomPortfolio['FLEX1'].map(maps_dict['Own_map']).astype(np.float16) - RandomPortfolio['FLEX2o'] = RandomPortfolio['FLEX2'].map(maps_dict['Own_map']).astype(np.float16) - RandomPortfolio['FLEX3o'] = RandomPortfolio['FLEX3'].map(maps_dict['Own_map']).astype(np.float16) - RandomPortfolio['FLEX4o'] = RandomPortfolio['FLEX4'].map(maps_dict['Own_map']).astype(np.float16) - RandomPortfolio['FLEX5o'] = RandomPortfolio['FLEX5'].map(maps_dict['Own_map']).astype(np.float16) - - portHeaderList = RandomPortfolio.columns.values.tolist() - portHeaderList.append('Salary') - portHeaderList.append('Projection') - portHeaderList.append('Own') - - RandomPortArray = RandomPortfolio.to_numpy() - - RandomPortArray = np.c_[RandomPortArray, np.einsum('ij->i',RandomPortArray[:,7:13].astype(int))] - RandomPortArray = np.c_[RandomPortArray, np.einsum('ij->i',RandomPortArray[:,13:19].astype(np.double))] - RandomPortArray = np.c_[RandomPortArray, np.einsum('ij->i',RandomPortArray[:,19:25].astype(np.double))] - - RandomPortArrayOut = np.delete(RandomPortArray, np.s_[7:25], axis=1) - RandomPortfolioDF = pd.DataFrame(RandomPortArrayOut, columns = ['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'User/Field', 'Salary', 'Projection', 'Own']) - RandomPortfolioDF = RandomPortfolioDF.sort_values(by=Sim_function, ascending=False) - - if insert_port == 1: - CleanPortfolio['Salary'] = sum([CleanPortfolio['CPT'].map(up_dict['Salary_map']) * 1.5, - CleanPortfolio['FLEX1'].map(up_dict['Salary_map']), - CleanPortfolio['FLEX2'].map(up_dict['Salary_map']), - CleanPortfolio['FLEX3'].map(up_dict['Salary_map']), - CleanPortfolio['FLEX4'].map(up_dict['Salary_map']), - CleanPortfolio['FLEX5'].map(up_dict['Salary_map']) - ]).astype(np.int16) - if insert_port == 1: - CleanPortfolio['Projection'] = sum([CleanPortfolio['CPT'].map(up_dict['Projection_map']) * 1.5, - CleanPortfolio['FLEX1'].map(up_dict['Projection_map']), - CleanPortfolio['FLEX2'].map(up_dict['Projection_map']), - CleanPortfolio['FLEX3'].map(up_dict['Projection_map']), - CleanPortfolio['FLEX4'].map(up_dict['Projection_map']), - CleanPortfolio['FLEX5'].map(up_dict['Projection_map']) - ]).astype(np.float16) - if insert_port == 1: - CleanPortfolio['Own'] = sum([CleanPortfolio['CPT'].map(up_dict['Own_map']) / 4, - CleanPortfolio['FLEX1'].map(up_dict['Own_map']), - CleanPortfolio['FLEX2'].map(up_dict['Own_map']), - CleanPortfolio['FLEX3'].map(up_dict['Own_map']), - CleanPortfolio['FLEX4'].map(up_dict['Own_map']), - CleanPortfolio['FLEX5'].map(up_dict['Own_map']) - ]).astype(np.float16) - - if site_var1 == 'Draftkings': - RandomPortfolioDF = RandomPortfolioDF[RandomPortfolioDF['Salary'] <= 50000].reset_index(drop=True) - RandomPortfolioDF = RandomPortfolioDF[RandomPortfolioDF['Salary'] >= 49500 - (FieldStrength * 1000)].reset_index(drop=True) - elif site_var1 == 'Fanduel': - RandomPortfolioDF = RandomPortfolioDF[RandomPortfolioDF['Salary'] <= 60000].reset_index(drop=True) - RandomPortfolioDF = RandomPortfolioDF[RandomPortfolioDF['Salary'] >= 59500 - (FieldStrength * 1000)].reset_index(drop=True) - - RandomPortfolio = RandomPortfolioDF.sort_values(by=Sim_function, ascending=False) - - RandomPortfolio = RandomPortfolio[['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'User/Field', 'Salary', 'Projection', 'Own']] - - return RandomPortfolio, maps_dict +@st.cache_data +def convert_df_to_csv(df): + return df.to_csv().encode('utf-8') -tab1, tab2 = st.tabs(['Uploads', 'Contest Sim']) +tab1, tab2, tab3 = st.tabs(['Uploads and Info', 'Range of Outcomes', 'Optimizer']) with tab1: - with st.container(): - st.info("The Projections file can have any columns in any order, but must contain columns explicitly named: 'Player', 'Salary', 'Position', 'Team', 'Opp', 'Median', and 'Own'. Upload your projections first to avoid an error message.") - col1, col2 = st.columns([3, 3]) + st.info("The Projections file can have any columns in any order, but must contain columns explicitly named: 'Player', 'Salary', 'Position', 'Team', 'Opp', 'rush_yards', 'rec', 'Median', and 'Own'. For the purposes of this showdown optimizer, only include FLEX positions, salaries, and medians. The optimizer logic will handle the rest!") + col1, col2 = st.columns([1, 5]) - with col1: - proj_file = st.file_uploader("Upload Projections File", key = 'proj_uploader') - - if proj_file is not None: - try: - proj_dataframe = pd.read_csv(proj_file) - proj_dataframe = proj_dataframe.dropna(subset='Median') - except: - proj_dataframe = pd.read_excel(proj_file) - proj_dataframe = proj_dataframe.dropna(subset='Median') - - player_salary_dict = dict(zip(proj_dataframe.Player, proj_dataframe.Salary)) - player_proj_dict = dict(zip(proj_dataframe.Player, proj_dataframe.Median)) - player_own_dict = dict(zip(proj_dataframe.Player, proj_dataframe.Own)) - player_team_dict = dict(zip(proj_dataframe.Player, proj_dataframe.Team)) - - with col2: - portfolio_file = st.file_uploader("Upload Portfolio File", key = 'portfolio_uploader') + with col1: + proj_file = st.file_uploader("Upload Projections File", key = 'proj_uploader') + + if proj_file is not None: + try: + proj_dataframe = pd.read_csv(proj_file) + proj_dataframe = proj_dataframe.loc[proj_dataframe['Median'] > 0] + try: + proj_dataframe['Own'] = proj_dataframe['Own'].str.replace('%', '').astype(float) + except: + pass + except: + proj_dataframe = pd.read_excel(proj_file) + proj_dataframe = proj_dataframe.loc[proj_dataframe['Median'] > 0] + try: + proj_dataframe['Own'] = proj_dataframe['Own'].str.replace('%', '').astype(float) + except: + pass + with col2: + if proj_file is not None: + st.dataframe(proj_dataframe.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(precision=2), use_container_width = True) - if portfolio_file is not None: - try: - portfolio_dataframe = pd.read_csv(portfolio_file) - except: - portfolio_dataframe = pd.read_excel(portfolio_file) - try: - try: - portfolio_dataframe.columns=["CPT", "FLEX1", "FLEX2", "FLEX3", "FLEX4", "FLEX5"] - split_portfolio = portfolio_dataframe - split_portfolio[['CPT', 'CPT_ID']] = split_portfolio.CPT.str.split("(", n=1, expand = True) - split_portfolio[['FLEX1', 'FLEX1_ID']] = split_portfolio.FLEX1.str.split("(", n=1, expand = True) - split_portfolio[['FLEX2', 'FLEX2_ID']] = split_portfolio.FLEX2.str.split("(", n=1, expand = True) - split_portfolio[['FLEX3', 'FLEX3_ID']] = split_portfolio.FLEX3.str.split("(", n=1, expand = True) - split_portfolio[['FLEX4', 'FLEX4_ID']] = split_portfolio.FLEX4.str.split("(", n=1, expand = True) - split_portfolio[['FLEX5', 'FLEX5_ID']] = split_portfolio.FLEX5.str.split("(", n=1, expand = True) - - split_portfolio['CPT'] = split_portfolio['CPT'].str.strip() - split_portfolio['FLEX1'] = split_portfolio['FLEX1'].str.strip() - split_portfolio['FLEX2'] = split_portfolio['FLEX2'].str.strip() - split_portfolio['FLEX3'] = split_portfolio['FLEX3'].str.strip() - split_portfolio['FLEX4'] = split_portfolio['FLEX4'].str.strip() - split_portfolio['FLEX5'] = split_portfolio['FLEX5'].str.strip() - - CPT_dict = dict(zip(split_portfolio.CPT, split_portfolio.CPT_ID)) - FLEX1_dict = dict(zip(split_portfolio.FLEX1, split_portfolio.FLEX1_ID)) - FLEX2_dict = dict(zip(split_portfolio.FLEX2, split_portfolio.FLEX2_ID)) - FLEX3_dict = dict(zip(split_portfolio.FLEX3, split_portfolio.FLEX3_ID)) - FLEX4_dict = dict(zip(split_portfolio.FLEX4, split_portfolio.FLEX4_ID)) - FLEX5_dict = dict(zip(split_portfolio.FLEX5, split_portfolio.FLEX5_ID)) - - split_portfolio['Salary'] = sum([split_portfolio['CPT'].map(player_salary_dict) * 1.5, - split_portfolio['FLEX1'].map(player_salary_dict), - split_portfolio['FLEX2'].map(player_salary_dict), - split_portfolio['FLEX3'].map(player_salary_dict), - split_portfolio['FLEX4'].map(player_salary_dict), - split_portfolio['FLEX5'].map(player_salary_dict)]) - - split_portfolio['Projection'] = sum([split_portfolio['CPT'].map(player_proj_dict) * 1.5, - split_portfolio['FLEX1'].map(player_proj_dict), - split_portfolio['FLEX2'].map(player_proj_dict), - split_portfolio['FLEX3'].map(player_proj_dict), - split_portfolio['FLEX4'].map(player_proj_dict), - split_portfolio['FLEX5'].map(player_proj_dict)]) - - split_portfolio['Ownership'] = sum([split_portfolio['CPT'].map(player_own_dict) / 4, - split_portfolio['FLEX1'].map(player_own_dict), - split_portfolio['FLEX2'].map(player_own_dict), - split_portfolio['FLEX3'].map(player_own_dict), - split_portfolio['FLEX4'].map(player_own_dict), - split_portfolio['FLEX5'].map(player_own_dict)]) - - except: - portfolio_dataframe.columns=["CPT", "FLEX1", "FLEX2", "FLEX3", "FLEX4", "FLEX5"] - split_portfolio = portfolio_dataframe - split_portfolio[['CPT_ID', 'CPT']] = split_portfolio.CPT.str.split(":", n=1, expand = True) - split_portfolio[['FLEX1_ID', 'FLEX1']] = split_portfolio.FLEX1.str.split(":", n=1, expand = True) - split_portfolio[['FLEX2_ID', 'FLEX2']] = split_portfolio.FLEX2.str.split(":", n=1, expand = True) - split_portfolio[['FLEX3_ID', 'FLEX3']] = split_portfolio.FLEX3.str.split(":", n=1, expand = True) - split_portfolio[['FLEX4_ID', 'FLEX4']] = split_portfolio.FLEX4.str.split(":", n=1, expand = True) - split_portfolio[['FLEX5_ID', 'FLEX5']] = split_portfolio.FLEX5.str.split(":", n=1, expand = True) - - split_portfolio['CPT'] = split_portfolio['CPT'].str.strip() - split_portfolio['FLEX1'] = split_portfolio['FLEX1'].str.strip() - split_portfolio['FLEX2'] = split_portfolio['FLEX2'].str.strip() - split_portfolio['FLEX3'] = split_portfolio['FLEX3'].str.strip() - split_portfolio['FLEX4'] = split_portfolio['FLEX4'].str.strip() - split_portfolio['FLEX5'] = split_portfolio['FLEX5'].str.strip() - - CPT_dict = dict(zip(split_portfolio.CPT, split_portfolio.CPT_ID)) - FLEX1_dict = dict(zip(split_portfolio.FLEX1, split_portfolio.FLEX1_ID)) - FLEX2_dict = dict(zip(split_portfolio.FLEX2, split_portfolio.FLEX2_ID)) - FLEX3_dict = dict(zip(split_portfolio.FLEX3, split_portfolio.FLEX3_ID)) - FLEX4_dict = dict(zip(split_portfolio.FLEX4, split_portfolio.FLEX4_ID)) - FLEX5_dict = dict(zip(split_portfolio.FLEX5, split_portfolio.FLEX5_ID)) - - split_portfolio['Salary'] = sum([split_portfolio['CPT'].map(player_salary_dict), - split_portfolio['FLEX1'].map(player_salary_dict), - split_portfolio['FLEX2'].map(player_salary_dict), - split_portfolio['FLEX3'].map(player_salary_dict), - split_portfolio['FLEX4'].map(player_salary_dict), - split_portfolio['FLEX5'].map(player_salary_dict)]) - - split_portfolio['Projection'] = sum([split_portfolio['CPT'].map(player_proj_dict) * 1.5, - split_portfolio['FLEX1'].map(player_proj_dict), - split_portfolio['FLEX2'].map(player_proj_dict), - split_portfolio['FLEX3'].map(player_proj_dict), - split_portfolio['FLEX4'].map(player_proj_dict), - split_portfolio['FLEX5'].map(player_proj_dict)]) - - split_portfolio['Ownership'] = sum([split_portfolio['CPT'].map(player_own_dict) / 4, - split_portfolio['FLEX1'].map(player_own_dict), - split_portfolio['FLEX2'].map(player_own_dict), - split_portfolio['FLEX3'].map(player_own_dict), - split_portfolio['FLEX4'].map(player_own_dict), - split_portfolio['FLEX5'].map(player_own_dict)]) - - except: - split_portfolio = portfolio_dataframe - - split_portfolio['CPT'] = split_portfolio['CPT'].str[:-6] - split_portfolio['FLEX1'] = split_portfolio['FLEX1'].str[:-6] - split_portfolio['FLEX2'] = split_portfolio['FLEX2'].str[:-6] - split_portfolio['FLEX3'] = split_portfolio['FLEX3'].str[:-6] - split_portfolio['FLEX4'] = split_portfolio['FLEX4'].str[:-6] - split_portfolio['FLEX5'] = split_portfolio['FLEX5'].str[:-6] - - split_portfolio['CPT'] = split_portfolio['CPT'].str.strip() - split_portfolio['FLEX1'] = split_portfolio['FLEX1'].str.strip() - split_portfolio['FLEX2'] = split_portfolio['FLEX2'].str.strip() - split_portfolio['FLEX3'] = split_portfolio['FLEX3'].str.strip() - split_portfolio['FLEX4'] = split_portfolio['FLEX4'].str.strip() - split_portfolio['FLEX5'] = split_portfolio['FLEX5'].str.strip() - - split_portfolio['Salary'] = sum([split_portfolio['CPT'].map(player_salary_dict) * 1.5, - split_portfolio['FLEX1'].map(player_salary_dict), - split_portfolio['FLEX2'].map(player_salary_dict), - split_portfolio['FLEX3'].map(player_salary_dict), - split_portfolio['FLEX4'].map(player_salary_dict), - split_portfolio['FLEX5'].map(player_salary_dict)]) - - split_portfolio['Projection'] = sum([split_portfolio['CPT'].map(player_proj_dict) * 1.5, - split_portfolio['FLEX1'].map(player_proj_dict), - split_portfolio['FLEX2'].map(player_proj_dict), - split_portfolio['FLEX3'].map(player_proj_dict), - split_portfolio['FLEX4'].map(player_proj_dict), - split_portfolio['FLEX5'].map(player_proj_dict)]) - - split_portfolio['Ownership'] = sum([split_portfolio['CPT'].map(player_own_dict) / 4, - split_portfolio['FLEX1'].map(player_own_dict), - split_portfolio['FLEX2'].map(player_own_dict), - split_portfolio['FLEX3'].map(player_own_dict), - split_portfolio['FLEX4'].map(player_own_dict), - split_portfolio['FLEX5'].map(player_own_dict)]) - - - gc.collect() - with tab2: - col1, col2 = st.columns([1, 7]) + col1, col2 = st.columns([1, 5]) + with col1: + if st.button("Load/Reset Data", key='reset2'): + st.cache_data.clear() + dk_roo_raw, dk_roo_raw_2, dk_roo_raw_3, fd_roo_raw, fd_roo_raw_2, fd_roo_raw_3, dkid_dict, fdid_dict = init_baselines() + slate_var2 = st.radio("Which data are you loading?", ('Paydirt (Main)', 'Paydirt (Secondary)', 'Payidrt (Third)', 'User'), key='slate_var2') + site_var2 = st.radio("What table would you like to display?", ('Draftkings', 'Fanduel'), key='site_var2') + if slate_var2 == 'User': + raw_baselines = proj_dataframe + elif slate_var2 != 'User': + if site_var2 == 'Draftkings': + if slate_var2 == 'Paydirt (Main)': + raw_baselines = dk_roo_raw + elif slate_var2 == 'Paydirt (Secondary)': + raw_baselines = dk_roo_raw_2 + elif slate_var2 == 'Paydirt (Third)': + raw_baselines = dk_roo_raw_3 + elif site_var2 == 'Fanduel': + if slate_var2 == 'Paydirt (Main)': + raw_baselines = fd_roo_raw + elif slate_var2 == 'Paydirt (Secondary)': + raw_baselines = fd_roo_raw_2 + elif slate_var2 == 'Paydirt (Third)': + raw_baselines = fd_roo_raw_3 + + with col2: + hold_container = st.empty() + if st.button('Create Range of Outcomes for Slate'): + with hold_container: + working_roo = raw_baselines + working_roo = working_roo.loc[working_roo['Median'] > 0] + if site_var2 == 'Draftkings': + working_roo.rename(columns={"name": "Player", "rush_yards": "Rush Yards", "rec": "Receptions", "Median": "Fantasy"}, inplace = True) + elif site_var2 == 'Fanduel': + working_roo.rename(columns={"name": "Player", "rush_yards": "Rush Yards", "rec": "Receptions", "Median": "Fantasy"}, inplace = True) + working_roo.replace('', 0, inplace=True) + own_dict = dict(zip(working_roo.Player, working_roo.Own)) + team_dict = dict(zip(working_roo.Player, working_roo.Team)) + opp_dict = dict(zip(working_roo.Player, working_roo.Opp)) + total_sims = 1000 + + flex_file = working_roo[['Player', 'Position', 'Salary', 'Fantasy', 'Rush Yards', 'Receptions']] + flex_file.rename(columns={"Fantasy": "Median", "Pos": "Position"}, inplace = True) + flex_file['Floor'] = np.where(flex_file['Position'] == 'QB',(flex_file['Median']*.25) + (flex_file['Rush Yards']*.01),flex_file['Median']*.25) + flex_file['Ceiling'] = np.where(flex_file['Position'] == 'QB',(flex_file['Median'] + flex_file['Floor']) + (flex_file['Rush Yards']*.01), flex_file['Median'] + flex_file['Floor'] + flex_file['Receptions']) + flex_file['Ceiling'] = flex_file['Ceiling'].fillna(15) + flex_file['STD'] = np.where(flex_file['Position'] != 'QB', (flex_file['Median']/4) + flex_file['Receptions'], (flex_file['Median']/4)) + flex_file['STD'] = flex_file['Ceiling'].fillna(5) + flex_file = flex_file[['Player', 'Position', 'Salary', 'Floor', 'Median', 'Ceiling', 'STD']] + hold_file = flex_file + overall_file = flex_file + salary_file = flex_file + + overall_players = overall_file[['Player']] + + for x in range(0,total_sims): + salary_file[x] = salary_file['Salary'] + + salary_file=salary_file.drop(['Player', 'Position', 'Salary', 'Floor', 'Median', 'Ceiling', 'STD'], axis=1) + salary_file.astype('int').dtypes + + salary_file = salary_file.div(1000) + + for x in range(0,total_sims): + overall_file[x] = np.random.normal(overall_file['Median'],overall_file['STD']) + + overall_file=overall_file.drop(['Player', 'Position', 'Salary', 'Floor', 'Median', 'Ceiling', 'STD'], axis=1) + overall_file.astype('int').dtypes + + players_only = hold_file[['Player']] + raw_lineups_file = players_only + + for x in range(0,total_sims): + maps_dict = {'proj_map':dict(zip(hold_file.Player,hold_file[x]))} + raw_lineups_file[x] = sum([raw_lineups_file['Player'].map(maps_dict['proj_map'])]) + players_only[x] = raw_lineups_file[x].rank(ascending=False) + + players_only=players_only.drop(['Player'], axis=1) + players_only.astype('int').dtypes + + salary_2x_check = (overall_file - (salary_file*2)) + salary_3x_check = (overall_file - (salary_file*3)) + salary_4x_check = (overall_file - (salary_file*4)) + + players_only['Average_Rank'] = players_only.mean(axis=1) + players_only['Top_finish'] = players_only[players_only == 1].count(axis=1)/total_sims + players_only['Top_5_finish'] = players_only[players_only <= 5].count(axis=1)/total_sims + players_only['Top_10_finish'] = players_only[players_only <= 10].count(axis=1)/total_sims + players_only['20+%'] = overall_file[overall_file >= 20].count(axis=1)/float(total_sims) + players_only['2x%'] = salary_2x_check[salary_2x_check >= 1].count(axis=1)/float(total_sims) + players_only['3x%'] = salary_3x_check[salary_3x_check >= 1].count(axis=1)/float(total_sims) + players_only['4x%'] = salary_4x_check[salary_4x_check >= 1].count(axis=1)/float(total_sims) + + players_only['Player'] = hold_file[['Player']] + + final_outcomes = players_only[['Player', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '2x%', '3x%', '4x%']] + + final_Proj = pd.merge(hold_file, final_outcomes, on="Player") + final_Proj = final_Proj[['Player', 'Position', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '2x%', '3x%', '4x%']] + final_Proj['Own'] = final_Proj['Player'].map(own_dict) + final_Proj['Team'] = final_Proj['Player'].map(team_dict) + final_Proj['Opp'] = final_Proj['Player'].map(opp_dict) + final_Proj = final_Proj[['Player', 'Position', 'Team', 'Opp', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '2x%', '3x%', '4x%', 'Own']] + final_Proj['Projection Rank'] = final_Proj.Median.rank(pct = True) + final_Proj['Own Rank'] = final_Proj.Own.rank(pct = True) + final_Proj['LevX'] = 0 + final_Proj['LevX'] = final_Proj[['Projection Rank', 'Top_5_finish']].mean(axis=1) + final_Proj['4x%'] - final_Proj['Own Rank'] + final_Proj['CPT_Own'] = final_Proj['Own'] / 4 + final_Proj['CPT_Proj'] = final_Proj['Median'] * 1.5 + final_Proj['CPT_Salary'] = final_Proj['Salary'] * 1.5 + + display_Proj = final_Proj[['Player', 'Position', 'Team', 'Opp', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '2x%', '3x%', '4x%', 'Own', 'CPT_Own', 'LevX']] + display_Proj = display_Proj.set_index('Player') + display_Proj = display_Proj.sort_values(by='Median', ascending=False) + + with hold_container: + hold_container = st.empty() + display_Proj = display_Proj + st.dataframe(display_Proj.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(player_roo_format, precision=2), use_container_width = True) + + st.download_button( + label="Export Tables", + data=convert_df_to_csv(final_Proj), + file_name='Custom_NFL_overall_export.csv', + mime='text/csv', + ) + +with tab3: + col1, col2 = st.columns([1, 5]) with col1: if st.button("Load/Reset Data", key='reset1'): st.cache_data.clear() + dk_roo_raw, dk_roo_raw_2, dk_roo_raw_3, fd_roo_raw, fd_roo_raw_2, fd_roo_raw_3, dkid_dict, fdid_dict = init_baselines() for key in st.session_state.keys(): del st.session_state[key] - dk_roo_raw, dk_roo_raw_2, dk_roo_raw_3, fd_roo_raw, fd_roo_raw_2, fd_roo_raw_3, dkid_dict, fdid_dict = init_baselines() - - slate_var1 = st.radio("Which data are you loading?", ('Paydirt (Main)', 'Paydirt (Secondary)', 'Paydirt (Third)', 'User')) - site_var1 = 'Draftkings' + slate_var1 = st.radio("Which data are you loading?", ('Paydirt (Main)', 'Paydirt (Secondary)', 'Payidrt (Third)', 'User'), key='slate_var1') + site_var1 = st.selectbox("What site is the showdown on?", ('Draftkings', 'Fanduel'), key='site_var1') if site_var1 == 'Draftkings': if slate_var1 == 'User': - raw_baselines = proj_dataframe[['Player', 'Salary', 'Position', 'Team', 'Opp', 'Median', 'Own']] + raw_baselines = proj_dataframe elif slate_var1 == 'Paydirt (Main)': raw_baselines = dk_roo_raw elif slate_var1 == 'Paydirt (Secondary)': @@ -617,365 +297,440 @@ with tab2: raw_baselines = dk_roo_raw_3 elif site_var1 == 'Fanduel': if slate_var1 == 'User': + st.info("Showdown on Fanduel sucks, you should not do that, but I understand degen's gotta degen") raw_baselines = proj_dataframe elif slate_var1 == 'Paydirt (Main)': - raw_baselines = dk_roo_raw + st.info("Showdown on Fanduel sucks, you should not do that, but I understand degen's gotta degen") + raw_baselines = fd_roo_raw elif slate_var1 == 'Paydirt (Secondary)': - raw_baselines = dk_roo_raw_2 + st.info("Showdown on Fanduel sucks, you should not do that, but I understand degen's gotta degen") + raw_baselines = fd_roo_raw_2 elif slate_var1 == 'Paydirt (Third)': - raw_baselines = dk_roo_raw_3 - - st.info("If you are uploading a portfolio, note that there is an adjustments to projections and deviation mapping to prevent 'Projection Bias' and create a fair simulation") - insert_port1 = st.selectbox("Are you uploading a portfolio?", ('No', 'Yes')) - if insert_port1 == 'Yes': - insert_port = 1 - elif insert_port1 == 'No': - insert_port = 0 - contest_var1 = st.selectbox("What contest size are you simulating?", ('Small', 'Medium', 'Large')) - if contest_var1 == 'Small': - Contest_Size = 500 - elif contest_var1 == 'Medium': - Contest_Size = 2500 - elif contest_var1 == 'Large': - Contest_Size = 5000 - strength_var1 = st.selectbox("How sharp is the field in the contest?", ('Not Very', 'Average', 'Very')) - if strength_var1 == 'Not Very': - sharp_split = .33 - Strength_var = .50 - scaling_var = 5 - elif strength_var1 == 'Average': - sharp_split = .50 - Strength_var = .25 - scaling_var = 10 - elif strength_var1 == 'Very': - sharp_split = .75 - Strength_var = .01 - scaling_var = 15 + st.info("Showdown on Fanduel sucks, you should not do that, but I understand degen's gotta degen") + raw_baselines = fd_roo_raw_3 + contest_var1 = st.selectbox("What contest type are you optimizing for?", ('Cash', 'Small Field GPP', 'Large Field GPP'), key='contest_var1') + lock_var1 = st.multiselect("Are there any players you want to use in all lineups in the CAPTAIN (Lock Button)?", options = raw_baselines['Player'].unique(), key='lock_var1') + lock_var2 = st.multiselect("Are there any players you want to use in all lineups in the FLEX (Lock Button)?", options = raw_baselines['Player'].unique(), key='lock_var2') + avoid_var1 = st.multiselect("Are there any players you want to remove from the pool (Drop Button)?", options = raw_baselines['Player'].unique(), key='avoid_var1') + trim_choice1 = st.selectbox("Allow overowned lineups?", options = ['Yes', 'No']) + linenum_var1 = st.number_input("How many lineups would you like to produce?", min_value = 1, max_value = 300, value = 20, step = 1, key='linenum_var1') + if trim_choice1 == 'Yes': + trim_var1 = 0 + elif trim_choice1 == 'No': + trim_var1 = 1 + if site_var1 == 'Draftkings': + min_sal1 = st.number_input('Min Salary', min_value = 35000, max_value = 49900, value = 49000, step = 100, key='min_sal1') + max_sal1 = st.number_input('Max Salary', min_value = 35000, max_value = 50000, value = 50000, step = 100, key='max_sal1') + elif site_var1 == 'Fanduel': + min_sal1 = st.number_input('Min Salary', min_value = 45000, max_value = 59900, value = 59000, step = 100, key='min_sal1') + max_sal1 = st.number_input('Max Salary', min_value = 45000, max_value = 60000, value = 60000, step = 100, key='max_sal1') + + if contest_var1 == 'Small Field GPP': + if site_var1 == 'Draftkings': + ownframe = raw_baselines.copy() + ownframe['Own%'] = np.where((ownframe['Position'] == 'QB') & (ownframe['Own'] - ownframe.loc[ownframe['Position'] == 'QB', 'Own'].mean() >= 0), ownframe['Own'] * (5 * (ownframe['Own'] - ownframe.loc[ownframe['Position'] == 'QB', 'Own'].mean())/100) + ownframe.loc[ownframe['Position'] == 'QB', 'Own'].mean(), ownframe['Own']) + ownframe['Own%'] = np.where((ownframe['Position'] != 'QB') & (ownframe['Own'] - ownframe.loc[ownframe['Position'] != 'QB', 'Own'].mean() >= 0), ownframe['Own'] * (5 * (ownframe['Own'] - ownframe.loc[ownframe['Position'] != 'QB', 'Own'].mean())/100) + ownframe.loc[ownframe['Position'] != 'QB', 'Own'].mean(), ownframe['Own%']) + ownframe['Own%'] = np.where(ownframe['Own%'] > 85, 85, ownframe['Own%']) + ownframe['Own'] = ownframe['Own%'] * (500 / ownframe['Own%'].sum()) + elif site_var1 == 'Fanduel': + ownframe = raw_baselines.copy() + ownframe['Own%'] = np.where((ownframe['Position'] == 'QB') & (ownframe['Own'] - ownframe.loc[ownframe['Position'] == 'QB', 'Own'].mean() >= 0), ownframe['Own'] * (5 * (ownframe['Own'] - ownframe.loc[ownframe['Position'] == 'QB', 'Own'].mean())/50) + ownframe.loc[ownframe['Position'] == 'QB', 'Own'].mean(), ownframe['Own']) + ownframe['Own%'] = np.where((ownframe['Position'] != 'QB') & (ownframe['Own'] - ownframe.loc[ownframe['Position'] != 'QB', 'Own'].mean() >= 0), ownframe['Own'] * (5 * (ownframe['Own'] - ownframe.loc[ownframe['Position'] != 'QB', 'Own'].mean())/150) + ownframe.loc[ownframe['Position'] != 'QB', 'Own'].mean(), ownframe['Own%']) + ownframe['Own%'] = np.where(ownframe['Own%'] > 75, 75, ownframe['Own%']) + ownframe['Own'] = ownframe['Own%'] * (400 / ownframe['Own%'].sum()) + elif contest_var1 == 'Large Field GPP': + if site_var1 == 'Draftkings': + ownframe = raw_baselines.copy() + ownframe['Own%'] = np.where((ownframe['Position'] == 'QB') & (ownframe['Own'] - ownframe.loc[ownframe['Position'] == 'QB', 'Own'].mean() >= 0), ownframe['Own'] * (2.5 * (ownframe['Own'] - ownframe.loc[ownframe['Position'] == 'QB', 'Own'].mean())/100) + ownframe.loc[ownframe['Position'] == 'QB', 'Own'].mean(), ownframe['Own']) + ownframe['Own%'] = np.where((ownframe['Position'] != 'QB') & (ownframe['Own'] - ownframe.loc[ownframe['Position'] != 'QB', 'Own'].mean() >= 0), ownframe['Own'] * (2.5 * (ownframe['Own'] - ownframe.loc[ownframe['Position'] != 'QB', 'Own'].mean())/100) + ownframe.loc[ownframe['Position'] != 'QB', 'Own'].mean(), ownframe['Own%']) + ownframe['Own%'] = np.where(ownframe['Own%'] > 75, 75, ownframe['Own%']) + ownframe['Own'] = ownframe['Own%'] * (500 / ownframe['Own%'].sum()) + elif site_var1 == 'Fanduel': + ownframe = raw_baselines.copy() + ownframe['Own%'] = np.where((ownframe['Position'] == 'QB') & (ownframe['Own'] - ownframe.loc[ownframe['Position'] == 'QB', 'Own'].mean() >= 0), ownframe['Own'] * (2.5 * (ownframe['Own'] - ownframe.loc[ownframe['Position'] == 'QB', 'Own'].mean())/50) + ownframe.loc[ownframe['Position'] == 'QB', 'Own'].mean(), ownframe['Own']) + ownframe['Own%'] = np.where((ownframe['Position'] != 'QB') & (ownframe['Own'] - ownframe.loc[ownframe['Position'] != 'QB', 'Own'].mean() >= 0), ownframe['Own'] * (2.5 * (ownframe['Own'] - ownframe.loc[ownframe['Position'] != 'QB', 'Own'].mean())/150) + ownframe.loc[ownframe['Position'] != 'QB', 'Own'].mean(), ownframe['Own%']) + ownframe['Own%'] = np.where(ownframe['Own%'] > 75, 75, ownframe['Own%']) + ownframe['Own'] = ownframe['Own%'] * (400 / ownframe['Own%'].sum()) + elif contest_var1 == 'Cash': + if site_var1 == 'Draftkings': + ownframe = raw_baselines.copy() + ownframe['Own%'] = np.where((ownframe['Position'] == 'QB') & (ownframe['Own'] - ownframe.loc[ownframe['Position'] == 'QB', 'Own'].mean() >= 0), ownframe['Own'] * (6 * (ownframe['Own'] - ownframe.loc[ownframe['Position'] == 'QB', 'Own'].mean())/100) + ownframe.loc[ownframe['Position'] == 'QB', 'Own'].mean(), ownframe['Own']) + ownframe['Own%'] = np.where((ownframe['Position'] != 'QB') & (ownframe['Own'] - ownframe.loc[ownframe['Position'] != 'QB', 'Own'].mean() >= 0), ownframe['Own'] * (6 * (ownframe['Own'] - ownframe.loc[ownframe['Position'] != 'QB', 'Own'].mean())/100) + ownframe.loc[ownframe['Position'] != 'QB', 'Own'].mean(), ownframe['Own%']) + ownframe['Own%'] = np.where(ownframe['Own%'] > 90, 90, ownframe['Own%']) + ownframe['Own'] = ownframe['Own%'] * (500 / ownframe['Own%'].sum()) + elif site_var1 == 'Fanduel': + ownframe = raw_baselines.copy() + ownframe['Own%'] = np.where((ownframe['Position'] == 'QB') & (ownframe['Own'] - ownframe.loc[ownframe['Position'] == 'QB', 'Own'].mean() >= 0), ownframe['Own'] * (6 * (ownframe['Own'] - ownframe.loc[ownframe['Position'] == 'QB', 'Own'].mean())/50) + ownframe.loc[ownframe['Position'] == 'QB', 'Own'].mean(), ownframe['Own']) + ownframe['Own%'] = np.where((ownframe['Position'] != 'QB') & (ownframe['Own'] - ownframe.loc[ownframe['Position'] != 'QB', 'Own'].mean() >= 0), ownframe['Own'] * (6 * (ownframe['Own'] - ownframe.loc[ownframe['Position'] != 'QB', 'Own'].mean())/150) + ownframe.loc[ownframe['Position'] != 'QB', 'Own'].mean(), ownframe['Own%']) + ownframe['Own%'] = np.where(ownframe['Own%'] > 75, 75, ownframe['Own%']) + ownframe['Own'] = ownframe['Own%'] * (400 / ownframe['Own%'].sum()) + export_baselines = ownframe[['Player', 'Salary', 'Position', 'Team', 'Opp', 'Median', 'Own']] + export_baselines['CPT_Proj'] = export_baselines['Median'] * 1.5 + export_baselines['CPT_Salary'] = export_baselines['Salary'] * 1.5 + display_baselines = ownframe[['Player', 'Salary', 'Position', 'Team', 'Opp', 'Median', 'Own']] + display_baselines['CPT Own'] = display_baselines['Own'] / 4 + display_baselines = display_baselines.sort_values(by='Median', ascending=False) + display_baselines['cpt_lock'] = np.where(display_baselines['Player'].isin(lock_var1), 1, 0) + display_baselines['lock'] = np.where(display_baselines['Player'].isin(lock_var2), 1, 0) + + st.session_state.display_baselines = display_baselines.copy() + st.session_state.export_baselines = export_baselines.copy() - Sort_function = 'Median' - Sim_function = 'Projection' + index_check = pd.DataFrame() + flex_proj = pd.DataFrame() + cpt_proj = pd.DataFrame() - if Contest_Size <= 1000: - strength_grow = .01 - elif Contest_Size > 1000 and Contest_Size <= 2500: - strength_grow = .025 - elif Contest_Size > 2500 and Contest_Size <= 5000: - strength_grow = .05 - elif Contest_Size > 5000 and Contest_Size <= 20000: - strength_grow = .075 - elif Contest_Size > 20000: - strength_grow = .1 + if site_var1 == 'Draftkings': + cpt_proj['Player'] = display_baselines['Player'] + cpt_proj['Salary'] = display_baselines['Salary'] * 1.5 + cpt_proj['Position'] = display_baselines['Position'] + cpt_proj['Team'] = display_baselines['Team'] + cpt_proj['Opp'] = display_baselines['Opp'] + cpt_proj['Median'] = display_baselines['Median'] * 1.5 + cpt_proj['Own'] = display_baselines['CPT Own'] + cpt_proj['lock'] = display_baselines['cpt_lock'] + cpt_proj['roster'] = 'CPT' + if len(lock_var1) > 0: + cpt_proj = cpt_proj[cpt_proj['lock'] == 1] + if len(lock_var2) > 0: + cpt_proj = cpt_proj[~cpt_proj['Player'].isin(lock_var2)] - field_growth = 100 * strength_grow + flex_proj['Player'] = display_baselines['Player'] + flex_proj['Salary'] = display_baselines['Salary'] + flex_proj['Position'] = display_baselines['Position'] + flex_proj['Team'] = display_baselines['Team'] + flex_proj['Opp'] = display_baselines['Opp'] + flex_proj['Median'] = display_baselines['Median'] + flex_proj['Own'] = display_baselines['Own'] + flex_proj['lock'] = display_baselines['lock'] + flex_proj['roster'] = 'FLEX' + elif site_var1 == 'Fanduel': + cpt_proj['Player'] = display_baselines['Player'] + cpt_proj['Salary'] = display_baselines['Salary'] + cpt_proj['Position'] = display_baselines['Position'] + cpt_proj['Team'] = display_baselines['Team'] + cpt_proj['Opp'] = display_baselines['Opp'] + cpt_proj['Median'] = display_baselines['Median'] * 1.5 + cpt_proj['Own'] = display_baselines['CPT Own'] *.75 + cpt_proj['lock'] = display_baselines['cpt_lock'] + cpt_proj['roster'] = 'CPT' + flex_proj['Player'] = display_baselines['Player'] + flex_proj['Salary'] = display_baselines['Salary'] + flex_proj['Position'] = display_baselines['Position'] + flex_proj['Team'] = display_baselines['Team'] + flex_proj['Opp'] = display_baselines['Opp'] + flex_proj['Median'] = display_baselines['Median'] + flex_proj['Own'] = display_baselines['Own'] + flex_proj['lock'] = display_baselines['lock'] + flex_proj['roster'] = 'FLEX' + + combo_file = pd.concat([cpt_proj, flex_proj], ignore_index=True) + with col2: - with st.container(): - if st.button("Simulate Contest", key='sim1'): - with st.container(): - for key in st.session_state.keys(): - del st.session_state[key] - - if slate_var1 == 'User': - initial_proj = proj_dataframe[['Player', 'Team', 'Position', 'Median', 'Own', 'Salary']] - - # Define the calculation to be applied - def calculate_own(position, own, mean_own, factor, max_own=75): - return np.where((position == 'QB') & (own - mean_own >= 0), - own * (factor * (own - mean_own) / 100) + mean_own, - own) - - # Set the factors based on the contest_var1 - factor_qb, factor_other = { - 'Small': (8, 10), - 'Medium': (5, 5), - 'Large': (1.5, 1.5), - }[contest_var1] - - # Apply the calculation to the DataFrame - initial_proj['Own%'] = initial_proj.apply(lambda row: calculate_own(row['Position'], row['Own'], initial_proj.loc[initial_proj['Position'] == row['Position'], 'Own'].mean(), factor_qb if row['Position'] == 'QB' else factor_other), axis=1) - initial_proj['Own%'] = initial_proj['Own%'].clip(upper=75) - initial_proj['Own'] = initial_proj['Own%'] * (600 / initial_proj['Own%'].sum()) - - # Drop unnecessary columns and create the final DataFrame - Overall_Proj = initial_proj[['Player', 'Team', 'Position', 'Median', 'Own', 'Salary']] - - elif slate_var1 != 'User': - # Copy only the necessary columns - initial_proj = raw_baselines[['Player', 'Team', 'Position', 'Median', 'Own', 'Salary']] - - # Define the calculation to be applied - def calculate_own(position, own, mean_own, factor, max_own=75): - return np.where((position == 'QB') & (own - mean_own >= 0), - own * (factor * (own - mean_own) / 100) + mean_own, - own) + display_container = st.empty() + display_dl_container = st.empty() + optimize_container = st.empty() + download_container = st.empty() + freq_container = st.empty() + if st.button('Optimize'): + for key in st.session_state.keys(): + del st.session_state[key] + max_proj = 1000 + max_own = 1000 + total_proj = 0 + total_own = 0 + display_container = st.empty() + display_dl_container = st.empty() + optimize_container = st.empty() + download_container = st.empty() + freq_container = st.empty() + lineup_display = [] + check_list = [] + lineups = [] + portfolio = pd.DataFrame() + x = 1 + + with st.spinner('Wait for it...'): + with optimize_container: + + while x <= linenum_var1: + sorted_lineup = [] + p_used = [] + + raw_proj_file = combo_file + raw_flex_file = raw_proj_file.dropna(how='all') + raw_flex_file = raw_flex_file.loc[raw_flex_file['Median'] > 0] + flex_file = raw_flex_file + flex_file.rename(columns={"Own": "Proj DK Own%"}, inplace = True) + flex_file['name_var'] = flex_file['Player'] + flex_file['lock'] = np.where(flex_file['Player'].isin(lock_var2), 1, 0) + flex_file = flex_file[~flex_file['Player'].isin(avoid_var1)] + flex_file['Player'] = np.where(flex_file['roster'] == 'CPT', flex_file['Player'] + ' - CPT', flex_file['Player'] + ' - FLEX') + player_ids = flex_file.index + + overall_players = flex_file[['Player']] + overall_players['player_var_add'] = flex_file.index + overall_players['player_var'] = 'player_vars_' + overall_players['player_var_add'].astype(str) + + player_vars = pulp.LpVariable.dicts("player_vars", flex_file.index, 0, 1, pulp.LpInteger) + total_score = pulp.LpProblem("Fantasy_Points_Problem", pulp.LpMaximize) + player_match = dict(zip(overall_players['player_var'], overall_players['Player'])) + player_index_match = dict(zip(overall_players['player_var'], overall_players['player_var_add'])) + + player_own = dict(zip(flex_file['Player'], flex_file['Proj DK Own%'])) + player_team = dict(zip(flex_file['Player'], flex_file['Team'])) + player_pos = dict(zip(flex_file['Player'], flex_file['Position'])) + player_sal = dict(zip(flex_file['Player'], flex_file['Salary'])) + player_proj = dict(zip(flex_file['Player'], flex_file['Median'])) + + obj_points = {idx: (flex_file['Median'][idx]) for idx in flex_file.index} + total_score += sum([player_vars[idx]*obj_points[idx] for idx in flex_file.index]) + + obj_points_max = {idx: (flex_file['Median'][idx]) for idx in flex_file.index} + obj_own_max = {idx: (flex_file['Proj DK Own%'][idx]) for idx in flex_file.index} + + obj_salary = {idx: (flex_file['Salary'][idx]) for idx in flex_file.index} + total_score += pulp.lpSum([player_vars[idx]*obj_salary[idx] for idx in flex_file.index]) <= max_sal1 + total_score += pulp.lpSum([player_vars[idx]*obj_salary[idx] for idx in flex_file.index]) >= min_sal1 + + if site_var1 == 'Draftkings': + + for flex in flex_file['lock'].unique(): + sub_idx = flex_file[flex_file['lock'] == 1].index + total_score += pulp.lpSum([player_vars[idx] for idx in sub_idx]) == len(lock_var2) + + for flex in flex_file['roster'].unique(): + sub_idx = flex_file[flex_file['roster'] == "CPT"].index + total_score += pulp.lpSum([player_vars[idx] for idx in sub_idx]) == 1 + + for flex in flex_file['roster'].unique(): + sub_idx = flex_file[flex_file['roster'] == "FLEX"].index + total_score += pulp.lpSum([player_vars[idx] for idx in sub_idx]) == 5 + + for playerid in player_ids: + total_score += pulp.lpSum([player_vars[i] for i in player_ids if + (flex_file['name_var'][i] == flex_file['name_var'][playerid])]) <= 1 + + elif site_var1 == 'Fanduel': + + for flex in flex_file['lock'].unique(): + sub_idx = flex_file[flex_file['lock'] == 1].index + total_score += pulp.lpSum([player_vars[idx] for idx in sub_idx]) == len(lock_var2) + + for flex in flex_file['Position'].unique(): + sub_idx = flex_file[flex_file['Position'] != "Var"].index + total_score += pulp.lpSum([player_vars[idx] for idx in sub_idx]) == 5 + + for flex in flex_file['roster'].unique(): + sub_idx = flex_file[flex_file['roster'] == "CPT"].index + total_score += pulp.lpSum([player_vars[idx] for idx in sub_idx]) == 1 + + for playerid in player_ids: + total_score += pulp.lpSum([player_vars[i] for i in player_ids if + (flex_file['name_var'][i] == flex_file['name_var'][playerid])]) <= 1 + + player_count = [] + player_trim = [] + lineup_list = [] + + if contest_var1 == 'Cash': + obj_points = {idx: (flex_file['Proj DK Own%'][idx]) for idx in flex_file.index} + total_score += sum([player_vars[idx]*obj_points[idx] for idx in flex_file.index]) + total_score += pulp.lpSum([player_vars[idx]*obj_points[idx] for idx in flex_file.index]) <= max_own - .001 + elif contest_var1 != 'Cash': + obj_points = {idx: (flex_file['Median'][idx]) for idx in flex_file.index} + total_score += sum([player_vars[idx]*obj_points[idx] for idx in flex_file.index]) + total_score += pulp.lpSum([player_vars[idx]*obj_points[idx] for idx in flex_file.index]) <= max_proj - .01 + if trim_var1 == 1: + total_score += pulp.lpSum([player_vars[idx]*obj_own_max[idx] for idx in flex_file.index]) <= max_own - .001 + + total_score.solve() + for v in total_score.variables(): + if v.varValue > 0: + lineup_list.append(v.name) + df = pd.DataFrame(lineup_list) + df['Names'] = df[0].map(player_match) + df['Cost'] = df['Names'].map(player_sal) + df['Proj'] = df['Names'].map(player_proj) + df['Own'] = df['Names'].map(player_own) + total_cost = sum(df['Cost']) + total_own = sum(df['Own']) + total_proj = sum(df['Proj']) + lineup_raw = pd.DataFrame(lineup_list) + lineup_raw['Names'] = lineup_raw[0].map(player_match) + lineup_raw['value'] = lineup_raw[0].map(player_index_match) + lineup_final = lineup_raw.sort_values(by=['value']) + del lineup_final[lineup_final.columns[0]] + del lineup_final[lineup_final.columns[1]] + lineup_final['Team'] = lineup_final['Names'].map(player_team) + lineup_final['Position'] = lineup_final['Names'].map(player_pos) + lineup_final['Salary'] = lineup_final['Names'].map(player_sal) + lineup_final['Proj'] = lineup_final['Names'].map(player_proj) + lineup_final['Own'] = lineup_final['Names'].map(player_own) + lineup_final.loc['Column_Total'] = lineup_final.sum(numeric_only=True, axis=0) + lineup_final = lineup_final.reset_index(drop=True) + + max_proj = total_proj + max_own = total_own + + if site_var1 == 'Draftkings': + if len(lineup_final) == 7: + port_display = pd.DataFrame(lineup_final['Names'][:-1].values.reshape(1, -1)) + + port_display['Cost'] = total_cost + port_display['Proj'] = total_proj + port_display['Own'] = total_own + st.table(port_display) + + portfolio = pd.concat([portfolio, port_display], ignore_index = True) + elif site_var1 == 'Fanduel': + if len(lineup_final) == 6: + port_display = pd.DataFrame(lineup_final['Names'][:-1].values.reshape(1, -1)) + + port_display['Cost'] = total_cost + port_display['Proj'] = total_proj + port_display['Own'] = total_own + st.table(port_display) + + portfolio = pd.concat([portfolio, port_display], ignore_index = True) + + x += 1 + + if site_var1 == 'Draftkings': + portfolio.rename(columns={0: "CPT", 1: "FLEX1", 2: "FLEX2", 3: "FLEX3", 4: "FLEX4", 5: "FLEX5"}, inplace = True) + elif site_var1 == 'Fanduel': + portfolio.rename(columns={0: "MVP", 1: "FLEX1", 2: "FLEX2", 3: "FLEX3", 4: "FLEX4"}, inplace = True) + portfolio = portfolio.dropna() + portfolio = portfolio.reset_index() + portfolio['Lineup_num'] = portfolio['index'] + 1 + portfolio.rename(columns={'Lineup_num': "Lineup"}, inplace = True) + portfolio = portfolio.set_index('Lineup') + portfolio = portfolio.drop(columns=['index']) + st.session_state.portfolio = portfolio.drop_duplicates() + + final_outcomes = portfolio + st.session_state.final_outcomes = portfolio - # Set the factors based on the contest_var1 - factor_qb, factor_other = { - 'Small': (8, 10), - 'Medium': (5, 5), - 'Large': (1.5, 1.5), - }[contest_var1] + player_freq = pd.DataFrame(np.column_stack(np.unique(st.session_state.portfolio.iloc[:,0:5].values, return_counts=True)), + columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True) + player_freq['Freq'] = player_freq['Freq'].astype(int) + player_freq['Position'] = player_freq['Player'].map(player_pos) + player_freq['Salary'] = player_freq['Player'].map(player_sal) + player_freq['Proj Own'] = player_freq['Player'].map(player_own) / 100 + player_freq['Exposure'] = player_freq['Freq']/(linenum_var1) + player_freq['Team'] = player_freq['Player'].map(player_team) - # Apply the calculation to the DataFrame - initial_proj['Own%'] = initial_proj.apply(lambda row: calculate_own(row['Position'], row['Own'], initial_proj.loc[initial_proj['Position'] == row['Position'], 'Own'].mean(), factor_qb if row['Position'] == 'QB' else factor_other), axis=1) - initial_proj['Own%'] = initial_proj['Own%'].clip(upper=75) - initial_proj['Own'] = initial_proj['Own%'] * (600 / initial_proj['Own%'].sum()) + final_outcomes_export = pd.DataFrame() + split_portfolio = pd.DataFrame() - # Drop unnecessary columns and create the final DataFrame - Overall_Proj = initial_proj[['Player', 'Team', 'Position', 'Median', 'Own', 'Salary']] - - if insert_port == 1: - UserPortfolio = portfolio_dataframe[['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5']] - elif insert_port == 0: - UserPortfolio = pd.DataFrame(columns = ['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5']) - - Overall_Proj.replace('', np.nan, inplace=True) - Overall_Proj = Overall_Proj.dropna(subset=['Median']) - Overall_Proj = Overall_Proj.assign(Value=lambda x: (x.Median / (x.Salary / 1000))) - Overall_Proj['Sort_var'] = (Overall_Proj['Median'].rank(ascending=False) + Overall_Proj['Value'].rank(ascending=False)) / 2 - Overall_Proj = Overall_Proj.sort_values(by='Sort_var', ascending=False) - Overall_Proj['Own'] = np.where((Overall_Proj['Median'] > 0) & (Overall_Proj['Own'] == 0), 1, Overall_Proj['Own']) - Overall_Proj = Overall_Proj.loc[Overall_Proj['Own'] > 0] - - Overall_Proj['Floor'] = np.where(Overall_Proj['Position'] == 'QB', Overall_Proj['Median'] * .5, Overall_Proj['Median'] * .25) - Overall_Proj['Ceiling'] = np.where(Overall_Proj['Position'] == 'WR', Overall_Proj['Median'] + Overall_Proj['Median'], Overall_Proj['Median'] + Overall_Proj['Floor']) - Overall_Proj['STDev'] = Overall_Proj['Median'] / 4 - - Teams_used = Overall_Proj['Team'].drop_duplicates().reset_index(drop=True) - Teams_used = Teams_used.reset_index() - Teams_used['team_item'] = Teams_used['index'] + 1 - Teams_used = Teams_used.drop(columns=['index']) - Teams_used_dictraw = Teams_used.drop(columns=['team_item']) - - team_list = Teams_used['Team'].to_list() - item_list = Teams_used['team_item'].to_list() - - FieldStrength_raw = Strength_var + ((30 - len(Teams_used)) * .01) - FieldStrength = FieldStrength_raw - (FieldStrength_raw * (20000 / Contest_Size)) - - if FieldStrength < 0: - FieldStrength = Strength_var - field_split = Strength_var - - for checkVar in range(len(team_list)): - Overall_Proj['Team'] = Overall_Proj['Team'].replace(team_list, item_list) - - flex_raw = Overall_Proj - flex_raw.dropna(subset=['Median']).reset_index(drop=True) - flex_raw = flex_raw.reset_index(drop=True) - flex_raw = flex_raw.sort_values(by='Own', ascending=False) - - pos_players = flex_raw - pos_players.dropna(subset=['Median']).reset_index(drop=True) - pos_players = pos_players.reset_index(drop=True) - - if insert_port == 1: - try: - # Initialize an empty DataFrame to store raw portfolio data - Raw_Portfolio = pd.DataFrame() + if site_var1 == 'Draftkings': - # Split each portfolio column and concatenate to Raw_Portfolio - columns_to_process = ['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5'] - for col in columns_to_process: - temp_df = UserPortfolio[col].str.split("(", n=1, expand=True) - temp_df.columns = [col, 'Drop'] - Raw_Portfolio = pd.concat([Raw_Portfolio, temp_df], axis=1) + split_portfolio[['CPT', 'CPT_ID']] = final_outcomes.CPT.str.split("-", n=1, expand = True) + split_portfolio[['FLEX1', 'FLEX1_ID']] = final_outcomes.FLEX1.str.split("-", n=1, expand = True) + split_portfolio[['FLEX2', 'FLEX2_ID']] = final_outcomes.FLEX2.str.split("-", n=1, expand = True) + split_portfolio[['FLEX3', 'FLEX3_ID']] = final_outcomes.FLEX3.str.split("-", n=1, expand = True) + split_portfolio[['FLEX4', 'FLEX4_ID']] = final_outcomes.FLEX4.str.split("-", n=1, expand = True) + split_portfolio[['FLEX5', 'FLEX5_ID']] = final_outcomes.FLEX5.str.split("-", n=1, expand = True) + + split_portfolio['CPT'] = split_portfolio['CPT'].str.strip() + split_portfolio['FLEX1'] = split_portfolio['FLEX1'].str.strip() + split_portfolio['FLEX2'] = split_portfolio['FLEX2'].str.strip() + split_portfolio['FLEX3'] = split_portfolio['FLEX3'].str.strip() + split_portfolio['FLEX4'] = split_portfolio['FLEX4'].str.strip() + split_portfolio['FLEX5'] = split_portfolio['FLEX5'].str.strip() - # Keep only required variables and remove whitespace - keep_vars = columns_to_process - CleanPortfolio = Raw_Portfolio[keep_vars] - CleanPortfolio = CleanPortfolio.apply(lambda x: x.str.strip()) + final_outcomes_export['CPT'] = split_portfolio['CPT'] + final_outcomes_export['FLEX1'] = split_portfolio['FLEX1'] + final_outcomes_export['FLEX2'] = split_portfolio['FLEX2'] + final_outcomes_export['FLEX3'] = split_portfolio['FLEX3'] + final_outcomes_export['FLEX4'] = split_portfolio['FLEX4'] + final_outcomes_export['FLEX5'] = split_portfolio['FLEX5'] - # Reset index and clean up the DataFrame - CleanPortfolio.reset_index(inplace=True) - CleanPortfolio['User/Field'] = CleanPortfolio['index'] + 1 - CleanPortfolio.drop(columns=['index'], inplace=True) - CleanPortfolio.replace('', np.nan, inplace=True) - CleanPortfolio.dropna(subset=['CPT'], inplace=True) + final_outcomes_export['CPT'].replace(dkid_dict, inplace=True) + final_outcomes_export['FLEX1'].replace(dkid_dict, inplace=True) + final_outcomes_export['FLEX2'].replace(dkid_dict, inplace=True) + final_outcomes_export['FLEX3'].replace(dkid_dict, inplace=True) + final_outcomes_export['FLEX4'].replace(dkid_dict, inplace=True) + final_outcomes_export['FLEX5'].replace(dkid_dict, inplace=True) + final_outcomes_export['Salary'] = final_outcomes['Cost'] + final_outcomes_export['Own'] = final_outcomes['Own'] + final_outcomes_export['Proj'] = final_outcomes['Proj'] - # Create cleaport_players DataFrame - unique_vals, counts = np.unique(CleanPortfolio.iloc[:, 0:6].values, return_counts=True) - cleaport_players = pd.DataFrame(np.column_stack([unique_vals, counts]), columns=['Player', 'Freq']).astype({'Freq': int}).sort_values('Freq', ascending=False).reset_index(drop=True) + st.session_state.final_outcomes_export = final_outcomes_export.copy() - # Merge and update nerf_frame DataFrame - nerf_frame = pd.merge(cleaport_players, Overall_Proj, on='Player', how='left') - nerf_frame[['Median', 'Floor', 'Ceiling', 'STDev']] *= .9 + elif site_var1 == 'Fanduel': - del Raw_Portfolio - except: - # Reset index and perform column-wise operations - CleanPortfolio = UserPortfolio.reset_index(drop=True) - CleanPortfolio['User/Field'] = CleanPortfolio.index + 1 - CleanPortfolio.replace('', np.nan, inplace=True) - CleanPortfolio.dropna(subset=['CPT'], inplace=True) + split_portfolio[['MVP', 'CPT_ID']] = final_outcomes.MVP.str.split("-", n=1, expand = True) + split_portfolio[['FLEX1', 'FLEX1_ID']] = final_outcomes.FLEX1.str.split("-", n=1, expand = True) + split_portfolio[['FLEX2', 'FLEX2_ID']] = final_outcomes.FLEX2.str.split("-", n=1, expand = True) + split_portfolio[['FLEX3', 'FLEX3_ID']] = final_outcomes.FLEX3.str.split("-", n=1, expand = True) + split_portfolio[['FLEX4', 'FLEX4_ID']] = final_outcomes.FLEX4.str.split("-", n=1, expand = True) + + split_portfolio['MVP'] = split_portfolio['MVP'].str.strip() + split_portfolio['FLEX1'] = split_portfolio['FLEX1'].str.strip() + split_portfolio['FLEX2'] = split_portfolio['FLEX2'].str.strip() + split_portfolio['FLEX3'] = split_portfolio['FLEX3'].str.strip() + split_portfolio['FLEX4'] = split_portfolio['FLEX4'].str.strip() - # Create cleaport_players DataFrame - unique_vals, counts = np.unique(CleanPortfolio.iloc[:, 0:6].values, return_counts=True) - cleaport_players = pd.DataFrame({'Player': unique_vals, 'Freq': counts}).sort_values('Freq', ascending=False).reset_index(drop=True).astype({'Freq': int}) + final_outcomes_export['MVP'] = split_portfolio['MVP'] + final_outcomes_export['FLEX1'] = split_portfolio['FLEX1'] + final_outcomes_export['FLEX2'] = split_portfolio['FLEX2'] + final_outcomes_export['FLEX3'] = split_portfolio['FLEX3'] + final_outcomes_export['FLEX4'] = split_portfolio['FLEX4'] - # Merge and update nerf_frame DataFrame - nerf_frame = pd.merge(cleaport_players, Overall_Proj, on='Player', how='left') - nerf_frame[['Median', 'Floor', 'Ceiling', 'STDev']] *= .9 + final_outcomes_export['MVP'].replace(fdid_dict, inplace=True) + final_outcomes_export['FLEX1'].replace(fdid_dict, inplace=True) + final_outcomes_export['FLEX2'].replace(fdid_dict, inplace=True) + final_outcomes_export['FLEX3'].replace(fdid_dict, inplace=True) + final_outcomes_export['FLEX4'].replace(fdid_dict, inplace=True) + final_outcomes_export['Salary'] = final_outcomes['Cost'] + final_outcomes_export['Own'] = final_outcomes['Own'] + final_outcomes_export['Proj'] = final_outcomes['Proj'] - st.table(nerf_frame) - - elif insert_port == 0: - CleanPortfolio = UserPortfolio - cleaport_players = pd.DataFrame(np.column_stack(np.unique(CleanPortfolio.iloc[:,0:6].values, return_counts=True)), - columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True) - cleaport_players['Freq'] = cleaport_players['Freq'].astype(int) - nerf_frame = Overall_Proj - - ref_dict = { - 'pos':['FLEX'], - 'pos_dfs':['FLEX_Table'], - 'pos_dicts':['flex_dict'] - } - - maps_dict = { - 'Floor_map':dict(zip(Overall_Proj.Player,Overall_Proj.Floor)), - 'Projection_map':dict(zip(Overall_Proj.Player,Overall_Proj.Median)), - 'Ceiling_map':dict(zip(Overall_Proj.Player,Overall_Proj.Ceiling)), - 'Salary_map':dict(zip(Overall_Proj.Player,Overall_Proj.Salary)), - 'Pos_map':dict(zip(Overall_Proj.Player,Overall_Proj.Position)), - 'Own_map':dict(zip(Overall_Proj.Player,Overall_Proj.Own)), - 'Team_map':dict(zip(Overall_Proj.Player,Overall_Proj.Team)), - 'STDev_map':dict(zip(Overall_Proj.Player,Overall_Proj.STDev)), - 'team_check_map':dict(zip(Overall_Proj.Player,Overall_Proj.Team)) - } - - up_dict = { - 'Floor_map':dict(zip(cleaport_players.Player,nerf_frame.Floor)), - 'Projection_map':dict(zip(cleaport_players.Player,nerf_frame.Median)), - 'Ceiling_map':dict(zip(cleaport_players.Player,nerf_frame.Ceiling)), - 'Salary_map':dict(zip(cleaport_players.Player,nerf_frame.Salary)), - 'Pos_map':dict(zip(cleaport_players.Player,nerf_frame.Position)), - 'Own_map':dict(zip(cleaport_players.Player,nerf_frame.Own)), - 'Team_map':dict(zip(cleaport_players.Player,nerf_frame.Team)), - 'STDev_map':dict(zip(cleaport_players.Player,nerf_frame.STDev)), - 'team_check_map':dict(zip(cleaport_players.Player,nerf_frame.Team)) - } - - FinalPortfolio, maps_dict = run_seed_frame(5, Strength_var, strength_grow, Teams_used, 1000000, field_growth) - - Sim_Winners = sim_contest(5000, FinalPortfolio, CleanPortfolio, maps_dict, up_dict, insert_port) - - # Initial setup - Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners), columns=FinalPortfolio.columns.tolist() + ['Fantasy']) - Sim_Winner_Frame['GPP_Proj'] = (Sim_Winner_Frame['Projection'] + Sim_Winner_Frame['Fantasy']) / 2 - Sim_Winner_Frame['unique_id'] = Sim_Winner_Frame['Projection'].astype(str) + Sim_Winner_Frame['Salary'].astype(str) + Sim_Winner_Frame['Own'].astype(str) - Sim_Winner_Frame = Sim_Winner_Frame.assign(win_count=Sim_Winner_Frame['unique_id'].map(Sim_Winner_Frame['unique_id'].value_counts())) - - # Type Casting - type_cast_dict = {'Salary': int, 'Projection': np.float16, 'Fantasy': np.float16, 'GPP_Proj': np.float32} - Sim_Winner_Frame = Sim_Winner_Frame.astype(type_cast_dict) - - del FinalPortfolio, insert_port, type_cast_dict - - # Sorting - 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) - st.session_state.Sim_Winner_Frame.drop(columns='unique_id', inplace=True) - - # Data Copying - st.session_state.Sim_Winner_Export = Sim_Winner_Frame.copy() - - # Data Copying - st.session_state.Sim_Winner_Display = Sim_Winner_Frame.copy() - - del Sim_Winner_Frame, Sim_Winners - - st.session_state.player_freq = pd.DataFrame(np.column_stack(np.unique(st.session_state.Sim_Winner_Display.iloc[:,0:6].values, return_counts=True)), - columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True) - st.session_state.player_freq['Freq'] = st.session_state.player_freq['Freq'].astype(int) - st.session_state.player_freq['Position'] = st.session_state.player_freq['Player'].map(maps_dict['Pos_map']) - st.session_state.player_freq['Salary'] = st.session_state.player_freq['Player'].map(maps_dict['Salary_map']) - st.session_state.player_freq['Proj Own'] = st.session_state.player_freq['Player'].map(maps_dict['Own_map']) / 100 - st.session_state.player_freq['Exposure'] = st.session_state.player_freq['Freq']/(5000) - st.session_state.player_freq['Edge'] = st.session_state.player_freq['Exposure'] - st.session_state.player_freq['Proj Own'] - st.session_state.player_freq['Team'] = st.session_state.player_freq['Player'].map(maps_dict['Team_map']) - for checkVar in range(len(team_list)): - st.session_state.player_freq['Team'] = st.session_state.player_freq['Team'].replace(item_list, team_list) - - st.session_state.cpt_freq = pd.DataFrame(np.column_stack(np.unique(st.session_state.Sim_Winner_Display.iloc[:,0:1].values, return_counts=True)), - columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True) - st.session_state.cpt_freq['Freq'] = st.session_state.cpt_freq['Freq'].astype(int) - st.session_state.cpt_freq['Position'] = st.session_state.cpt_freq['Player'].map(maps_dict['Pos_map']) - st.session_state.cpt_freq['Salary'] = st.session_state.cpt_freq['Player'].map(maps_dict['Salary_map']) - st.session_state.cpt_freq['Proj Own'] = (st.session_state.cpt_freq['Player'].map(maps_dict['Own_map']) / 4) / 100 - st.session_state.cpt_freq['Exposure'] = st.session_state.cpt_freq['Freq']/5000 - st.session_state.cpt_freq['Edge'] = st.session_state.cpt_freq['Exposure'] - st.session_state.cpt_freq['Proj Own'] - st.session_state.cpt_freq['Team'] = st.session_state.cpt_freq['Player'].map(maps_dict['Team_map']) - for checkVar in range(len(team_list)): - st.session_state.cpt_freq['Team'] = st.session_state.cpt_freq['Team'].replace(item_list, team_list) - - st.session_state.flex_freq = pd.DataFrame(np.column_stack(np.unique(st.session_state.Sim_Winner_Display.iloc[:,[1, 2, 3, 4, 5]].values, return_counts=True)), - columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True) - st.session_state.flex_freq['Freq'] = st.session_state.flex_freq['Freq'].astype(int) - st.session_state.flex_freq['Position'] = st.session_state.flex_freq['Player'].map(maps_dict['Pos_map']) - st.session_state.flex_freq['Salary'] = st.session_state.flex_freq['Player'].map(maps_dict['Salary_map']) - st.session_state.flex_freq['Proj Own'] = (st.session_state.flex_freq['Player'].map(maps_dict['Own_map']) / 100) - ((st.session_state.flex_freq['Player'].map(maps_dict['Own_map']) / 4) / 100) - st.session_state.flex_freq['Exposure'] = st.session_state.flex_freq['Freq']/5000 - st.session_state.flex_freq['Edge'] = st.session_state.flex_freq['Exposure'] - st.session_state.flex_freq['Proj Own'] - st.session_state.flex_freq['Team'] = st.session_state.flex_freq['Player'].map(maps_dict['Team_map']) - for checkVar in range(len(team_list)): - st.session_state.flex_freq['Team'] = st.session_state.flex_freq['Team'].replace(item_list, team_list) - - with st.container(): - if 'player_freq' in st.session_state: - player_split_var2 = st.radio("Are you wanting to isolate any lineups with specific players?", ('Full Players', 'Specific Players'), key='player_split_var2') - if player_split_var2 == 'Specific Players': - find_var2 = st.multiselect('Which players must be included in the lineups?', options = st.session_state.player_freq['Player'].unique()) - elif player_split_var2 == 'Full Players': - find_var2 = st.session_state.player_freq.Player.values.tolist() - - if player_split_var2 == 'Specific Players': - st.session_state.Sim_Winner_Display = st.session_state.Sim_Winner_Frame[np.equal.outer(st.session_state.Sim_Winner_Frame.to_numpy(copy=False), find_var2).any(axis=1).all(axis=1)] - if player_split_var2 == 'Full Players': - st.session_state.Sim_Winner_Display = st.session_state.Sim_Winner_Frame - if 'Sim_Winner_Display' in st.session_state: - st.dataframe(st.session_state.Sim_Winner_Display.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').background_gradient(cmap='RdYlGn_r', subset=['Own']).format(precision=2), use_container_width = True) - if 'Sim_Winner_Export' in st.session_state: - st.download_button( - label="Export Full Frame", - data=st.session_state.Sim_Winner_Export.to_csv().encode('utf-8'), - file_name='NFL_consim_export.csv', - mime='text/csv', - ) + st.session_state.FD_final_outcomes_export = final_outcomes_export.copy() + + st.session_state.player_freq = player_freq[['Player', 'Position', 'Team', 'Salary', 'Proj Own', 'Exposure']] + with display_container: + display_container = st.empty() + if 'display_baselines' in st.session_state: + st.dataframe(st.session_state.display_baselines.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(precision=2), use_container_width = True) - with st.container(): - tab1, tab2, tab3 = st.tabs(['Overall Exposures', 'CPT Exposures', 'FLEX Exposures']) - with tab1: - if 'player_freq' in st.session_state: - 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) + with display_dl_container: + display_dl_container = st.empty() + if 'export_baselines' in st.session_state: st.download_button( - label="Export Exposures", - data=st.session_state.player_freq.to_csv().encode('utf-8'), - file_name='player_freq_export.csv', + label="Export Projections", + data=convert_df_to_csv(st.session_state.export_baselines), + file_name='showdown_proj_export.csv', mime='text/csv', - ) - with tab2: - if 'player_freq' in st.session_state: - st.dataframe(st.session_state.cpt_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True) - st.download_button( - label="Export Exposures", - data=st.session_state.cpt_freq.to_csv().encode('utf-8'), - file_name='cpt_freq_export.csv', - mime='text/csv', - ) - with tab3: - if 'player_freq' in st.session_state: - 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) - st.download_button( - label="Export Exposures", - data=st.session_state.flex_freq.to_csv().encode('utf-8'), - file_name='flex_freq_export.csv', - mime='text/csv', - ) -del gcservice_account -del dk_roo_raw, dk_roo_raw_2, fd_roo_raw, fd_roo_raw_2 -del static_exposure, overall_exposure -del insert_port1, Contest_Size, sharp_split, Strength_var, scaling_var, Sort_function, Sim_function, strength_grow, field_growth -del raw_baselines -del freq_format - -gc.collect() \ No newline at end of file + ) + + with optimize_container: + optimize_container = st.empty() + if 'final_outcomes' in st.session_state: + st.dataframe(st.session_state.final_outcomes.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(precision=2), use_container_width = True) + + with download_container: + download_container = st.empty() + if site_var1 == 'Draftkings': + if 'final_outcomes_export' in st.session_state: + st.download_button( + label="Export Optimals", + data=convert_df_to_csv(st.session_state.final_outcomes_export), + file_name='NFL_optimals_export.csv', + mime='text/csv', + ) + elif site_var1 == 'Fanduel': + if 'FD_final_outcomes_export' in st.session_state: + st.download_button( + label="Export Optimals", + data=convert_df_to_csv(st.session_state.FD_final_outcomes_export), + file_name='FD_NFL_optimals_export.csv', + mime='text/csv', + ) + + with freq_container: + freq_container = st.empty() + if 'player_freq' in st.session_state: + st.dataframe(st.session_state.player_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(expose_format, precision=2), use_container_width = True) \ No newline at end of file