James McCool commited on
Commit
f7a9234
·
1 Parent(s): 08413f9

copying structure from NFL

Browse files
.streamlit/secrets.toml ADDED
@@ -0,0 +1 @@
 
 
1
+ mongo_uri = "mongodb+srv://multichem:Xr1q5wZdXPbxdUmJ@testcluster.lgwtp5i.mongodb.net/?retryWrites=true&w=majority&appName=TestCluster"
Dockerfile CHANGED
@@ -5,11 +5,24 @@ WORKDIR /app
5
  RUN apt-get update && apt-get install -y \
6
  build-essential \
7
  curl \
 
8
  git \
9
  && rm -rf /var/lib/apt/lists/*
10
 
11
  COPY requirements.txt ./
12
  COPY src/ ./src/
 
 
 
 
 
 
 
 
 
 
 
 
13
 
14
  RUN pip3 install -r requirements.txt
15
 
 
5
  RUN apt-get update && apt-get install -y \
6
  build-essential \
7
  curl \
8
+ software-properties-common \
9
  git \
10
  && rm -rf /var/lib/apt/lists/*
11
 
12
  COPY requirements.txt ./
13
  COPY src/ ./src/
14
+ COPY .streamlit/ ./.streamlit/
15
+
16
+
17
+
18
+ ENV MONGO_URI="mongodb+srv://multichem:Xr1q5wZdXPbxdUmJ@testcluster.lgwtp5i.mongodb.net/?retryWrites=true&w=majority&appName=TestCluster"
19
+ RUN useradd -m -u 1000 user
20
+ USER user
21
+ ENV HOME=/home/user\
22
+ PATH=/home/user/.local/bin:$PATH
23
+ WORKDIR $HOME/app
24
+ RUN pip install --no-cache-dir --upgrade pip
25
+ COPY --chown=user . $HOME/app
26
 
27
  RUN pip3 install -r requirements.txt
28
 
requirements.txt CHANGED
@@ -1,3 +1,8 @@
1
- altair
2
- pandas
3
- streamlit
 
 
 
 
 
 
1
+ streamlit
2
+ openpyxl
3
+ matplotlib
4
+ pulp
5
+ docker
6
+ plotly
7
+ scipy
8
+ pymongo
src/database.py ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pymongo
3
+ import os
4
+
5
+ @st.cache_resource
6
+ def init_conn():
7
+ uri = os.getenv('MONGO_URI')
8
+ if not uri:
9
+ uri = st.secrets['mongo_uri']
10
+ client = pymongo.MongoClient(uri, retryWrites=True, serverSelectionTimeoutMS=500000)
11
+ db = client["NFL_Database"]
12
+ return db
13
+
14
+ # Initialize the database connection
15
+ db = init_conn()
src/sim_func_hold/regular_functions.py ADDED
@@ -0,0 +1,147 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ import numpy as np
4
+ from pymongo import MongoClient
5
+ from database import db
6
+
7
+ @st.cache_data(ttl = 600)
8
+ def init_DK_seed_frames(slate_var, sharp_split):
9
+
10
+
11
+ if slate_var == 'Main Slate':
12
+ collection = db['DK_NFL_name_map']
13
+ cursor = collection.find()
14
+ raw_data = pd.DataFrame(list(cursor))
15
+ names_dict = dict(zip(raw_data['key'], raw_data['value']))
16
+ collection = db[f"DK_NFL_seed_frame_Main Slate"]
17
+ elif slate_var == 'Secondary Slate':
18
+ collection = db['DK_NFL_Secondary_name_map']
19
+ cursor = collection.find()
20
+ raw_data = pd.DataFrame(list(cursor))
21
+ names_dict = dict(zip(raw_data['key'], raw_data['value']))
22
+ collection = db[f"DK_NFL_seed_frame_Secondary Slate"]
23
+ elif slate_var == 'Late Slate':
24
+ collection = db['DK_NFL_Late_name_map']
25
+ cursor = collection.find()
26
+ raw_data = pd.DataFrame(list(cursor))
27
+ names_dict = dict(zip(raw_data['key'], raw_data['value']))
28
+ collection = db[f"DK_NFL_seed_frame_Late Slate"]
29
+
30
+ cursor = collection.find().limit(sharp_split)
31
+
32
+ raw_display = pd.DataFrame(list(cursor))
33
+ raw_display = raw_display[['QB', 'RB1', 'RB2', 'WR1', 'WR2', 'WR3', 'TE', 'FLEX', 'DST', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']]
34
+ dict_columns = ['QB', 'RB1', 'RB2', 'WR1', 'WR2', 'WR3', 'TE', 'FLEX', 'DST']
35
+ for col in dict_columns:
36
+ raw_display[col] = raw_display[col].map(names_dict)
37
+ DK_seed = raw_display.to_numpy()
38
+
39
+ return DK_seed
40
+
41
+ @st.cache_data(ttl = 599)
42
+ def init_FD_seed_frames(slate_var, sharp_split):
43
+
44
+ if slate_var == 'Main Slate':
45
+ collection = db['FD_NFL_name_map']
46
+ cursor = collection.find()
47
+ raw_data = pd.DataFrame(list(cursor))
48
+ names_dict = dict(zip(raw_data['key'], raw_data['value']))
49
+ collection = db[f"FD_NFL_seed_frame_Main Slate"]
50
+ cursor = collection.find().limit(sharp_split)
51
+ elif slate_var == 'Secondary Slate':
52
+ collection = db['FD_NFL_Secondary_name_map']
53
+ cursor = collection.find()
54
+ raw_data = pd.DataFrame(list(cursor))
55
+ names_dict = dict(zip(raw_data['key'], raw_data['value']))
56
+ collection = db[f"FD_NFL_seed_frame_Secondary Slate"]
57
+ cursor = collection.find().limit(sharp_split)
58
+ elif slate_var == 'Late Slate':
59
+ collection = db['FD_NFL_Late_name_map']
60
+ cursor = collection.find()
61
+ raw_data = pd.DataFrame(list(cursor))
62
+ names_dict = dict(zip(raw_data['key'], raw_data['value']))
63
+ collection = db[f"FD_NFL_seed_frame_Late Slate"]
64
+ cursor = collection.find().limit(sharp_split)
65
+
66
+ raw_display = pd.DataFrame(list(cursor))
67
+ raw_display = raw_display[['QB', 'RB1', 'RB2', 'WR1', 'WR2', 'WR3', 'TE', 'FLEX', 'DST', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']]
68
+ dict_columns = ['QB', 'RB1', 'RB2', 'WR1', 'WR2', 'WR3', 'TE', 'FLEX', 'DST']
69
+ for col in dict_columns:
70
+ raw_display[col] = raw_display[col].map(names_dict)
71
+ FD_seed = raw_display.to_numpy()
72
+
73
+ return FD_seed
74
+
75
+ @st.cache_data(ttl = 599)
76
+ def init_baselines(slate_var):
77
+ collection = db["DK_NFL_ROO"]
78
+ cursor = collection.find()
79
+
80
+ raw_display = pd.DataFrame(list(cursor))
81
+ raw_display = raw_display[raw_display['slate'] == slate_var]
82
+ raw_display = raw_display[raw_display['version'] == 'overall']
83
+ dk_raw = raw_display[['Player', 'Position', 'Team', 'Opp', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '2x%', '3x%', '4x%',
84
+ 'Own', 'Small_Field_Own', 'Large_Field_Own', 'Cash_Field_Own', 'CPT_Own', 'LevX', 'version', 'slate', 'timestamp', 'player_ID', 'site']]
85
+ dk_raw['STDev'] = (dk_raw['Ceiling'] - dk_raw['Floor']) / 4
86
+
87
+ collection = db["FD_NFL_ROO"]
88
+ cursor = collection.find()
89
+
90
+ raw_display = pd.DataFrame(list(cursor))
91
+ raw_display = raw_display[raw_display['slate'] == slate_var]
92
+ raw_display = raw_display[raw_display['version'] == 'overall']
93
+ fd_raw = raw_display[['Player', 'Position', 'Team', 'Opp', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '2x%', '3x%', '4x%',
94
+ 'Own', 'Small_Field_Own', 'Large_Field_Own', 'Cash_Field_Own', 'CPT_Own', 'LevX', 'version', 'slate', 'timestamp', 'player_ID', 'site']]
95
+ fd_raw['STDev'] = (fd_raw['Ceiling'] - fd_raw['Floor']) / 4
96
+
97
+ return dk_raw, fd_raw
98
+
99
+ @st.cache_data
100
+ def convert_df(array):
101
+ array = pd.DataFrame(array, columns=column_names)
102
+ return array.to_csv().encode('utf-8')
103
+
104
+ @st.cache_data
105
+ def calculate_DK_value_frequencies(np_array):
106
+ unique, counts = np.unique(np_array[:, :9], return_counts=True)
107
+ frequencies = counts / len(np_array) # Normalize by the number of rows
108
+ combined_array = np.column_stack((unique, frequencies))
109
+ return combined_array
110
+
111
+ @st.cache_data
112
+ def calculate_FD_value_frequencies(np_array):
113
+ unique, counts = np.unique(np_array[:, :9], return_counts=True)
114
+ frequencies = counts / len(np_array) # Normalize by the number of rows
115
+ combined_array = np.column_stack((unique, frequencies))
116
+ return combined_array
117
+
118
+ @st.cache_data
119
+ def sim_contest(Sim_size, seed_frame, maps_dict, Contest_Size):
120
+ SimVar = 1
121
+ Sim_Winners = []
122
+ fp_array = seed_frame.copy()
123
+ # Pre-vectorize functions
124
+ vec_projection_map = np.vectorize(maps_dict['Projection_map'].__getitem__)
125
+ vec_stdev_map = np.vectorize(maps_dict['STDev_map'].__getitem__)
126
+
127
+ st.write('Simulating contest on frames')
128
+
129
+ while SimVar <= Sim_size:
130
+ fp_random = fp_array[np.random.choice(fp_array.shape[0], Contest_Size)]
131
+
132
+ sample_arrays1 = np.c_[
133
+ fp_random,
134
+ np.sum(np.random.normal(
135
+ loc=vec_projection_map(fp_random[:, :-7]),
136
+ scale=vec_stdev_map(fp_random[:, :-7])),
137
+ axis=1)
138
+ ]
139
+
140
+ sample_arrays = sample_arrays1
141
+
142
+ final_array = sample_arrays[sample_arrays[:, 10].argsort()[::-1]]
143
+ best_lineup = final_array[final_array[:, -1].argsort(kind='stable')[::-1][:1]]
144
+ Sim_Winners.append(best_lineup)
145
+ SimVar += 1
146
+
147
+ return Sim_Winners
src/sim_func_hold/showdown_functions.py ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ import numpy as np
4
+ from pymongo import MongoClient
5
+ from database import db
6
+
7
+ @st.cache_data(ttl = 599)
8
+ def init_DK_SD_seed_frames(slate, split, translation_dict):
9
+ # Now dynamic
10
+ collection = db[translation_dict[slate]]
11
+ cursor = collection.find().limit(split)
12
+
13
+ raw_display = pd.DataFrame(list(cursor))
14
+ raw_display = raw_display[['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']]
15
+ DK_seed = raw_display.to_numpy()
16
+
17
+ return DK_seed
18
+
19
+ @st.cache_data(ttl = 599)
20
+ def init_FD_SD_seed_frames(slate, split, translation_dict):
21
+ # Now dynamic
22
+ collection = db[translation_dict[slate]]
23
+ cursor = collection.find().limit(split)
24
+
25
+ raw_display = pd.DataFrame(list(cursor))
26
+ raw_display = raw_display[['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']]
27
+ FD_seed = raw_display.to_numpy()
28
+
29
+ return FD_seed
30
+
31
+ @st.cache_data(ttl = 599)
32
+ def init_SD_baselines(slate_var):
33
+ collection = db['DK_SD_NFL_ROO']
34
+ cursor = collection.find()
35
+
36
+ raw_display = pd.DataFrame(list(cursor))
37
+ raw_display = raw_display[raw_display['version'] == 'overall']
38
+ raw_display = raw_display[['Player', 'Position', 'Team', 'Opp', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '2x%', '3x%', '4x%',
39
+ 'Own', 'Small_Field_Own', 'Large_Field_Own', 'Cash_Field_Own', 'CPT_Own', 'LevX', 'version', 'slate', 'timestamp', 'player_id', 'site']]
40
+ raw_display = raw_display.rename(columns={'player_id': 'player_ID'})
41
+ raw_display['Small_Field_Own'] = raw_display['Large_Field_Own']
42
+ raw_display['small_CPT_Own_raw'] = (raw_display['Small_Field_Own'] / 2) * ((100 - (100-raw_display['Small_Field_Own']))/100)
43
+ small_cpt_own_var = 300 / raw_display['small_CPT_Own_raw'].sum()
44
+ raw_display['small_CPT_Own'] = raw_display['small_CPT_Own_raw'] * small_cpt_own_var
45
+ raw_display['cpt_Median'] = raw_display['Median'] * 1.25
46
+ raw_display['STDev'] = raw_display['Median'] / 4
47
+ raw_display['CPT_STDev'] = raw_display['cpt_Median'] / 4
48
+
49
+ dk_raw = raw_display.dropna(subset=['Median'])
50
+
51
+ collection = db['FD_SD_NFL_ROO']
52
+ cursor = collection.find()
53
+
54
+ raw_display = pd.DataFrame(list(cursor))
55
+ raw_display = raw_display[raw_display['version'] == 'overall']
56
+ raw_display = raw_display[['Player', 'Position', 'Team', 'Opp', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '2x%', '3x%', '4x%',
57
+ 'Own', 'Small_Field_Own', 'Large_Field_Own', 'Cash_Field_Own', 'CPT_Own', 'LevX', 'version', 'slate', 'timestamp', 'player_id', 'site']]
58
+ raw_display = raw_display.rename(columns={'player_id': 'player_ID'})
59
+ raw_display['Small_Field_Own'] = raw_display['Large_Field_Own']
60
+ raw_display['small_CPT_Own_raw'] = (raw_display['Small_Field_Own'] / 2) * ((100 - (100-raw_display['Small_Field_Own']))/100)
61
+ small_cpt_own_var = 300 / raw_display['small_CPT_Own_raw'].sum()
62
+ raw_display['small_CPT_Own'] = raw_display['small_CPT_Own_raw'] * small_cpt_own_var
63
+ raw_display['cpt_Median'] = raw_display['Median'] * 1.25
64
+ raw_display['STDev'] = raw_display['Median'] / 4
65
+ raw_display['CPT_STDev'] = raw_display['cpt_Median'] / 4
66
+
67
+ fd_raw = raw_display.dropna(subset=['Median'])
68
+
69
+ return dk_raw, fd_raw
70
+
71
+ @st.cache_data
72
+ def convert_df(array):
73
+ array = pd.DataFrame(array, columns=column_names)
74
+ return array.to_csv().encode('utf-8')
75
+
76
+ @st.cache_data
77
+ def calculate_SD_value_frequencies(np_array):
78
+ unique, counts = np.unique(np_array[:, :6], return_counts=True)
79
+ frequencies = counts / len(np_array) # Normalize by the number of rows
80
+ combined_array = np.column_stack((unique, frequencies))
81
+ return combined_array
82
+
83
+ @st.cache_data
84
+ def sim_SD_contest(Sim_size, seed_frame, maps_dict, Contest_Size):
85
+ SimVar = 1
86
+ Sim_Winners = []
87
+
88
+ # Pre-vectorize functions
89
+ vec_projection_map = np.vectorize(maps_dict['Projection_map'].__getitem__)
90
+ vec_cpt_projection_map = np.vectorize(maps_dict['cpt_projection_map'].__getitem__)
91
+ vec_stdev_map = np.vectorize(maps_dict['STDev_map'].__getitem__)
92
+ vec_cpt_stdev_map = np.vectorize(maps_dict['cpt_STDev_map'].__getitem__)
93
+
94
+ st.write('Simulating contest on frames')
95
+
96
+ while SimVar <= Sim_size:
97
+ fp_random = seed_frame[np.random.choice(seed_frame.shape[0], Contest_Size)]
98
+
99
+ sample_arrays1 = np.c_[
100
+ fp_random,
101
+ np.sum(np.random.normal(
102
+ loc=np.concatenate([
103
+ vec_cpt_projection_map(fp_random[:, 0:1]), # Apply cpt_projection_map to first column
104
+ vec_projection_map(fp_random[:, 1:-7]) # Apply original projection to remaining columns
105
+ ], axis=1),
106
+ scale=np.concatenate([
107
+ vec_cpt_stdev_map(fp_random[:, 0:1]), # Apply cpt_projection_map to first column
108
+ vec_stdev_map(fp_random[:, 1:-7]) # Apply original projection to remaining columns
109
+ ], axis=1)),
110
+ axis=1)
111
+ ]
112
+
113
+ sample_arrays = sample_arrays1
114
+
115
+ final_array = sample_arrays[sample_arrays[:, 7].argsort()[::-1]]
116
+ best_lineup = final_array[final_array[:, -1].argsort(kind='stable')[::-1][:1]]
117
+ Sim_Winners.append(best_lineup)
118
+ SimVar += 1
119
+
120
+ return Sim_Winners
src/streamlit_app.py CHANGED
@@ -1,40 +1,850 @@
1
- import altair as alt
2
  import numpy as np
3
  import pandas as pd
4
- import streamlit as st
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
- """
7
- # Welcome to Streamlit!
8
-
9
- Edit `/streamlit_app.py` to customize this app to your heart's desire :heart:.
10
- If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community
11
- forums](https://discuss.streamlit.io).
12
-
13
- In the meantime, below is an example of what you can do with just a few lines of code:
14
- """
15
-
16
- num_points = st.slider("Number of points in spiral", 1, 10000, 1100)
17
- num_turns = st.slider("Number of turns in spiral", 1, 300, 31)
18
-
19
- indices = np.linspace(0, 1, num_points)
20
- theta = 2 * np.pi * num_turns * indices
21
- radius = indices
22
-
23
- x = radius * np.cos(theta)
24
- y = radius * np.sin(theta)
25
-
26
- df = pd.DataFrame({
27
- "x": x,
28
- "y": y,
29
- "idx": indices,
30
- "rand": np.random.randn(num_points),
31
- })
32
-
33
- st.altair_chart(alt.Chart(df, height=700, width=700)
34
- .mark_point(filled=True)
35
- .encode(
36
- x=alt.X("x", axis=None),
37
- y=alt.Y("y", axis=None),
38
- color=alt.Color("idx", legend=None, scale=alt.Scale()),
39
- size=alt.Size("rand", legend=None, scale=alt.Scale(range=[1, 150])),
40
- ))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
  import numpy as np
3
  import pandas as pd
4
+ import pymongo
5
+ import re
6
+ import os
7
+ from itertools import combinations
8
+
9
+
10
+ st.set_page_config(layout="wide")
11
+
12
+ from database import db
13
+ from sim_func_hold.regular_functions import *
14
+ from sim_func_hold.showdown_functions import *
15
+
16
+ percentages_format = {'Exposure': '{:.2%}'}
17
+ freq_format = {'Exposure': '{:.2%}', 'Proj Own': '{:.2%}', 'Edge': '{:.2%}'}
18
+ dk_columns = ['QB', 'RB1', 'RB2', 'WR1', 'WR2', 'WR3', 'TE', 'FLEX', 'DST', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']
19
+ fd_columns = ['QB', 'RB1', 'RB2', 'WR1', 'WR2', 'WR3', 'TE', 'FLEX', 'DST', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']
20
+ dk_sd_columns = ['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']
21
+ fd_sd_columns = ['CPT', 'FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']
22
+
23
+ showdown_selections = ['Showdown #1', 'Showdown #2', 'Showdown #3', 'Showdown #4', 'Showdown #5', 'Showdown #6', 'Showdown #7', 'Showdown #8', 'Showdown #9', 'Showdown #10', 'Showdown #11', 'Showdown #12', 'Showdown #13', 'Showdown #14', 'Showdown #15']
24
+ dk_db_showdown_selections = ['DK_NFL_SD_seed_frame_Showdown #1', 'DK_NFL_SD_seed_frame_Showdown #2', 'DK_NFL_SD_seed_frame_Showdown #3', 'DK_NFL_SD_seed_frame_Showdown #4', 'DK_NFL_SD_seed_frame_Showdown #5', 'DK_NFL_SD_seed_frame_Showdown #6',
25
+ 'DK_NFL_SD_seed_frame_Showdown #7', 'DK_NFL_SD_seed_frame_Showdown #8', 'DK_NFL_SD_seed_frame_Showdown #9', 'DK_NFL_SD_seed_frame_Showdown #10', 'DK_NFL_SD_seed_frame_Showdown #11', 'DK_NFL_SD_seed_frame_Showdown #12', 'DK_NFL_SD_seed_frame_Showdown #13',
26
+ 'DK_NFL_SD_seed_frame_Showdown #14', 'DK_NFL_SD_seed_frame_Showdown #15']
27
+ fd_db_showdown_selections = ['FD_NFL_SD_seed_frame_Showdown #1', 'FD_NFL_SD_seed_frame_Showdown #2', 'FD_NFL_SD_seed_frame_Showdown #3', 'FD_NFL_SD_seed_frame_Showdown #4', 'FD_NFL_SD_seed_frame_Showdown #5', 'FD_NFL_SD_seed_frame_Showdown #6',
28
+ 'FD_NFL_SD_seed_frame_Showdown #7', 'FD_NFL_SD_seed_frame_Showdown #8', 'FD_NFL_SD_seed_frame_Showdown #9', 'FD_NFL_SD_seed_frame_Showdown #10', 'FD_NFL_SD_seed_frame_Showdown #11', 'FD_NFL_SD_seed_frame_Showdown #12', 'FD_NFL_SD_seed_frame_Showdown #13',
29
+ 'FD_NFL_SD_seed_frame_Showdown #14', 'FD_NFL_SD_seed_frame_Showdown #15']
30
+
31
+ dk_showdown_db_translation = dict(zip(showdown_selections, dk_db_showdown_selections))
32
+ fd_showdown_db_translation = dict(zip(showdown_selections, fd_db_showdown_selections))
33
+
34
+ # Probably should have done this in a dictionary to start with
35
+ wrong_team_names = ['Denver Broncos', 'Washington Commanders', 'Cincinnati Bengals', 'Arizona Cardinals', 'Los Angeles Rams', 'Pittsburgh Steelers',
36
+ 'Jacksonville Jaguars', 'New England Patriots', 'Tampa Bay Buccaneers', 'San Francisco 49ers', 'Green Bay Packers', 'New York Jets',
37
+ 'Indianapolis Colts', 'Miami Dolphins', 'Detroit Lions', 'Las Vegas Raiders', 'Atlanta Falcons', 'Seattle Seahawks', 'Houston Texans',
38
+ 'New Orleans Saints', 'Carolina Panthers', 'New York Giants', 'Cleveland Browns', 'Tennessee Titans', 'Philadelphia Eagles', 'Dallas Cowboys',
39
+ 'Kansas City Chiefs', 'Los Angeles Chargers', 'Baltimore Ravens', 'Buffalo Bills', 'Minnesota Vikings', 'Chicago Bears']
40
+ right_name_teams = ['Broncos', 'Commanders', 'Bengals', 'Cardinals', 'Rams', 'Steelers', 'Jaguars', 'Patriots', 'Buccaneers', '49ers', 'Packers',
41
+ 'Jets', 'Colts', 'Dolphins', 'Lions', 'Raiders', 'Falcons', 'Seahawks', 'Texans', 'Saints', 'Panthers', 'Giants', 'Browns', 'Titans', 'Eagles', 'Cowboys',
42
+ 'Chiefs', 'Chargers', 'Ravens', 'Bills', 'Vikings', 'Bears']
43
+
44
+ st.markdown("""
45
+ <style>
46
+ /* Tab styling */
47
+ .stElementContainer [data-baseweb="button-group"] {
48
+ gap: 2.000rem;
49
+ padding: 4px;
50
+ }
51
+ .stElementContainer [kind="segmented_control"] {
52
+ height: 2.000rem;
53
+ white-space: pre-wrap;
54
+ background-color: #DAA520;
55
+ color: white;
56
+ border-radius: 20px;
57
+ gap: 1px;
58
+ padding: 10px 20px;
59
+ font-weight: bold;
60
+ transition: all 0.3s ease;
61
+ }
62
+ .stElementContainer [kind="segmented_controlActive"] {
63
+ height: 3.000rem;
64
+ background-color: #DAA520;
65
+ border: 3px solid #FFD700;
66
+ border-radius: 10px;
67
+ color: black;
68
+ }
69
+ .stElementContainer [kind="segmented_control"]:hover {
70
+ background-color: #FFD700;
71
+ cursor: pointer;
72
+ }
73
+
74
+ div[data-baseweb="select"] > div {
75
+ background-color: #DAA520;
76
+ color: white;
77
+ }
78
+
79
+ </style>""", unsafe_allow_html=True)
80
+
81
+ @st.cache_resource(ttl=60)
82
+ def define_dk_showdown_slates():
83
+ collection = db["DK_SD_NFL_ROO"]
84
+ cursor = collection.find()
85
+ raw_display = pd.DataFrame(list(cursor))
86
+ unique_slates = raw_display['slate'].unique()
87
+
88
+ slate_names = []
89
+
90
+ for slate in unique_slates:
91
+ slate_data = raw_display[raw_display['slate'] == slate]
92
+ slate_name = slate_data.iloc[0]['Team'] + ' vs. ' + slate_data.iloc[0]['Opp']
93
+ slate_names.append(slate_name)
94
+
95
+ slate_name_lookup = dict(zip(slate_names, unique_slates))
96
+ return slate_names, slate_name_lookup
97
+
98
+ @st.cache_resource(ttl=60)
99
+ def define_fd_showdown_slates():
100
+ collection = db["FD_SD_NFL_ROO"]
101
+ cursor = collection.find()
102
+ raw_display = pd.DataFrame(list(cursor))
103
+ unique_slates = raw_display['slate'].unique()
104
+
105
+ slate_names = []
106
+
107
+ for slate in unique_slates:
108
+ slate_data = raw_display[raw_display['slate'] == slate]
109
+ slate_name = slate_data.iloc[0]['Team'] + ' vs. ' + slate_data.iloc[0]['Opp']
110
+ slate_names.append(slate_name)
111
+
112
+ slate_name_lookup = dict(zip(slate_names, unique_slates))
113
+ return slate_names, slate_name_lookup
114
+
115
+ slate_names_dk, slate_name_lookup_dk = define_dk_showdown_slates()
116
+ slate_names_fd, slate_name_lookup_fd = define_fd_showdown_slates()
117
+
118
+ if st.button("Load/Reset Data", key='reset2'):
119
+ st.cache_data.clear()
120
+ for key in st.session_state.keys():
121
+ del st.session_state[key]
122
+ slate_names_dk, slate_name_lookup_dk = define_dk_showdown_slates()
123
+ slate_names_fd, slate_name_lookup_fd = define_fd_showdown_slates()
124
+ DK_seed = init_DK_seed_frames('Main Slate', 10000)
125
+ DK_sd_seed = init_DK_SD_seed_frames("Showdown #1", 10000, dk_showdown_db_translation)
126
+ FD_seed = init_FD_seed_frames('Main Slate', 10000)
127
+ FD_sd_seed = init_FD_SD_seed_frames("Showdown #1", 10000, fd_showdown_db_translation)
128
+ dk_raw, fd_raw = init_baselines('Main Slate')
129
+ dk_sd_raw, fd_sd_raw = init_SD_baselines('Showdown #1')
130
+ dk_id_dict = dict(zip(dk_raw.Player, dk_raw.player_ID))
131
+ dk_sd_id_dict = dict(zip(dk_sd_raw.Player, dk_sd_raw.player_ID))
132
+ fd_id_dict = dict(zip(fd_raw.Player, fd_raw.player_ID))
133
+ fd_sd_id_dict = dict(zip(fd_sd_raw.Player, fd_sd_raw.player_ID))
134
+
135
+ selected_tab = st.segmented_control(
136
+ "Select Tab",
137
+ options=["Regular Slate Contest Sims", "Showdown Contest Sims"],
138
+ selection_mode='single',
139
+ default='Regular Slate Contest Sims',
140
+ width='stretch',
141
+ label_visibility='collapsed',
142
+ key='tab_selector'
143
+ )
144
+
145
+ if selected_tab == "Regular Slate Contest Sims":
146
+ dk_raw, fd_raw = init_baselines('Main Slate')
147
+ raw_baselines = dk_raw
148
+ column_names = dk_columns
149
+ with st.expander("Info and Filters"):
150
+ site_data_col, slate_data_col, contest_size_col, contest_sharpness_col = st.columns([1, 1, 1, 1])
151
+ with site_data_col:
152
+ sim_site_var1 = st.radio("What site are you working with?", ('Draftkings', 'Fanduel'), key='sim_site_var1')
153
+
154
+ with slate_data_col:
155
+ sim_slate_var1 = st.radio("Which data are you loading?", ('Main Slate', 'Secondary Slate', 'Late Slate'), key='sim_slate_var1')
156
+
157
+ with contest_size_col:
158
+ contest_var1 = st.selectbox("What contest size are you simulating?", ('Small', 'Medium', 'Large'))
159
+ if contest_var1 == 'Small':
160
+ Contest_Size = 1000
161
+ elif contest_var1 == 'Medium':
162
+ Contest_Size = 5000
163
+ elif contest_var1 == 'Large':
164
+ Contest_Size = 10000
165
+ elif contest_var1 == 'Custom':
166
+ Contest_Size = st.number_input("Insert contest size", value=100, placeholder="Type a number under 10,000...")
167
+ with contest_sharpness_col:
168
+ strength_var1 = st.selectbox("How sharp is the field in the contest?", ('Very', 'Above Average', 'Average', 'Below Average', 'Not Very'))
169
+ if strength_var1 == 'Not Very':
170
+ sharp_split = 500000
171
+ elif strength_var1 == 'Below Average':
172
+ sharp_split = 250000
173
+ elif strength_var1 == 'Average':
174
+ sharp_split = 100000
175
+ elif strength_var1 == 'Above Average':
176
+ sharp_split = 50000
177
+ elif strength_var1 == 'Very':
178
+ sharp_split = 10000
179
+
180
+ if st.button("Run Contest Sim"):
181
+
182
+ if 'working_seed' not in st.session_state:
183
+ if sim_site_var1 == 'Draftkings':
184
+ st.session_state.working_seed = init_DK_seed_frames(sim_slate_var1, sharp_split)
185
+ dk_raw, fd_raw = init_baselines(sim_slate_var1)
186
+ dk_id_dict = dict(zip(dk_raw.Player, dk_raw.player_ID))
187
+
188
+ raw_baselines = dk_raw
189
+ column_names = dk_columns
190
+ elif sim_site_var1 == 'Fanduel':
191
+ st.session_state.working_seed = init_FD_seed_frames(sim_slate_var1, sharp_split)
192
+ dk_raw, fd_raw = init_baselines(sim_slate_var1)
193
+ fd_id_dict = dict(zip(fd_raw.Player, fd_raw.player_ID))
194
+
195
+ raw_baselines = fd_raw
196
+ column_names = fd_columns
197
+ st.session_state.maps_dict = {
198
+ 'Projection_map':dict(zip(raw_baselines.Player,raw_baselines.Median)),
199
+ 'Salary_map':dict(zip(raw_baselines.Player,raw_baselines.Salary)),
200
+ 'Pos_map':dict(zip(raw_baselines.Player,raw_baselines.Position)),
201
+ 'Own_map':dict(zip(raw_baselines.Player,raw_baselines['Own'])),
202
+ 'Team_map':dict(zip(raw_baselines.Player,raw_baselines.Team)),
203
+ 'STDev_map':dict(zip(raw_baselines.Player,raw_baselines.STDev))
204
+ }
205
+
206
+ Sim_Winners = sim_contest(1000, st.session_state.working_seed, st.session_state.maps_dict, Contest_Size)
207
+ Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners))
208
+
209
+ #st.table(Sim_Winner_Frame)
210
+
211
+ # Initial setup
212
+ Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners), columns=column_names + ['Fantasy'])
213
+ Sim_Winner_Frame['GPP_Proj'] = (Sim_Winner_Frame['proj'] + Sim_Winner_Frame['Fantasy']) / 2
214
+ 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)
215
+ Sim_Winner_Frame = Sim_Winner_Frame.assign(win_count=Sim_Winner_Frame['unique_id'].map(Sim_Winner_Frame['unique_id'].value_counts()))
216
+
217
+ # Type Casting
218
+ type_cast_dict = {'salary': int, 'proj': np.float16, 'Fantasy': np.float16, 'GPP_Proj': np.float32, 'Own': np.float32}
219
+ Sim_Winner_Frame = Sim_Winner_Frame.astype(type_cast_dict)
220
+
221
+ # Sorting
222
+ 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)
223
+ st.session_state.Sim_Winner_Frame.drop(columns='unique_id', inplace=True)
224
+
225
+ # Data Copying
226
+ st.session_state.Sim_Winner_Export = Sim_Winner_Frame.copy()
227
+ if sim_site_var1 == 'Draftkings':
228
+ for col in st.session_state.Sim_Winner_Export.iloc[:, 0:9].columns:
229
+ st.session_state.Sim_Winner_Export[col] = st.session_state.Sim_Winner_Export[col].map(dk_id_dict)
230
+ elif sim_site_var1 == 'Fanduel':
231
+ for col in st.session_state.Sim_Winner_Export.iloc[:, 0:9].columns:
232
+ st.session_state.Sim_Winner_Export[col] = st.session_state.Sim_Winner_Export[col].map(fd_id_dict)
233
+
234
+ # Data Copying
235
+ st.session_state.Sim_Winner_Display = Sim_Winner_Frame.copy()
236
+ st.session_state.freq_copy = st.session_state.Sim_Winner_Display
237
+ else:
238
+ st.session_state.maps_dict = {
239
+ 'Projection_map':dict(zip(raw_baselines.Player,raw_baselines.Median)),
240
+ 'Salary_map':dict(zip(raw_baselines.Player,raw_baselines.Salary)),
241
+ 'Pos_map':dict(zip(raw_baselines.Player,raw_baselines.Position)),
242
+ 'Own_map':dict(zip(raw_baselines.Player,raw_baselines['Own'])),
243
+ 'Team_map':dict(zip(raw_baselines.Player,raw_baselines.Team)),
244
+ 'STDev_map':dict(zip(raw_baselines.Player,raw_baselines.STDev))
245
+ }
246
+
247
+ Sim_Winners = sim_contest(1000, st.session_state.working_seed, st.session_state.maps_dict, Contest_Size)
248
+ Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners))
249
+
250
+ # Initial setup
251
+ Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners), columns=column_names + ['Fantasy'])
252
+ Sim_Winner_Frame['GPP_Proj'] = (Sim_Winner_Frame['proj'] + Sim_Winner_Frame['Fantasy']) / 2
253
+ 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)
254
+ Sim_Winner_Frame = Sim_Winner_Frame.assign(win_count=Sim_Winner_Frame['unique_id'].map(Sim_Winner_Frame['unique_id'].value_counts()))
255
+
256
+ # Type Casting
257
+ type_cast_dict = {'salary': int, 'proj': np.float16, 'Fantasy': np.float16, 'GPP_Proj': np.float32, 'Own': np.float32}
258
+ Sim_Winner_Frame = Sim_Winner_Frame.astype(type_cast_dict)
259
+
260
+ # Sorting
261
+ 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)
262
+ st.session_state.Sim_Winner_Frame.drop(columns='unique_id', inplace=True)
263
+
264
+ # Data Copying
265
+ st.session_state.Sim_Winner_Export = Sim_Winner_Frame.copy()
266
+
267
+ # Data Copying
268
+ st.session_state.Sim_Winner_Display = Sim_Winner_Frame.copy()
269
+
270
+ if sim_site_var1 == 'Draftkings':
271
+ freq_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,0:9].values, return_counts=True)),
272
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
273
+ elif sim_site_var1 == 'Fanduel':
274
+ freq_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,0:9].values, return_counts=True)),
275
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
276
+ freq_working['Freq'] = freq_working['Freq'].astype(int)
277
+ freq_working['Position'] = freq_working['Player'].map(st.session_state.maps_dict['Pos_map'])
278
+ freq_working['Salary'] = freq_working['Player'].map(st.session_state.maps_dict['Salary_map'])
279
+ freq_working['Proj Own'] = freq_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100
280
+ freq_working['Exposure'] = freq_working['Freq']/(1000)
281
+ freq_working['Edge'] = freq_working['Exposure'] - freq_working['Proj Own']
282
+ freq_working['Team'] = freq_working['Player'].map(st.session_state.maps_dict['Team_map'])
283
+ st.session_state.player_freq = freq_working.copy()
284
+
285
+ if sim_site_var1 == 'Draftkings':
286
+ qb_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,0:1].values, return_counts=True)),
287
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
288
+ elif sim_site_var1 == 'Fanduel':
289
+ qb_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,0:1].values, return_counts=True)),
290
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
291
+ qb_working['Freq'] = qb_working['Freq'].astype(int)
292
+ qb_working['Position'] = qb_working['Player'].map(st.session_state.maps_dict['Pos_map'])
293
+ qb_working['Salary'] = qb_working['Player'].map(st.session_state.maps_dict['Salary_map'])
294
+ qb_working['Proj Own'] = qb_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100
295
+ qb_working['Exposure'] = qb_working['Freq']/(1000)
296
+ qb_working['Edge'] = qb_working['Exposure'] - qb_working['Proj Own']
297
+ qb_working['Team'] = qb_working['Player'].map(st.session_state.maps_dict['Team_map'])
298
+ st.session_state.qb_freq = qb_working.copy()
299
+
300
+ if sim_site_var1 == 'Draftkings':
301
+ rbwrte_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,1:7].values, return_counts=True)),
302
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
303
+ elif sim_site_var1 == 'Fanduel':
304
+ rbwrte_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,1:7].values, return_counts=True)),
305
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
306
+ rbwrte_working['Freq'] = rbwrte_working['Freq'].astype(int)
307
+ rbwrte_working['Position'] = rbwrte_working['Player'].map(st.session_state.maps_dict['Pos_map'])
308
+ rbwrte_working['Salary'] = rbwrte_working['Player'].map(st.session_state.maps_dict['Salary_map'])
309
+ rbwrte_working['Proj Own'] = rbwrte_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100
310
+ rbwrte_working['Exposure'] = rbwrte_working['Freq']/(1000)
311
+ rbwrte_working['Edge'] = rbwrte_working['Exposure'] - rbwrte_working['Proj Own']
312
+ rbwrte_working['Team'] = rbwrte_working['Player'].map(st.session_state.maps_dict['Team_map'])
313
+ st.session_state.rbwrte_freq = rbwrte_working.copy()
314
+
315
+ if sim_site_var1 == 'Draftkings':
316
+ rb_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,1:3].values, return_counts=True)),
317
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
318
+ elif sim_site_var1 == 'Fanduel':
319
+ rb_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,1:3].values, return_counts=True)),
320
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
321
+ rb_working['Freq'] = rb_working['Freq'].astype(int)
322
+ rb_working['Position'] = rb_working['Player'].map(st.session_state.maps_dict['Pos_map'])
323
+ rb_working['Salary'] = rb_working['Player'].map(st.session_state.maps_dict['Salary_map'])
324
+ rb_working['Proj Own'] = rb_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100
325
+ rb_working['Exposure'] = rb_working['Freq']/(1000)
326
+ rb_working['Edge'] = rb_working['Exposure'] - rb_working['Proj Own']
327
+ rb_working['Team'] = rb_working['Player'].map(st.session_state.maps_dict['Team_map'])
328
+ st.session_state.rb_freq = rb_working.copy()
329
+
330
+ if sim_site_var1 == 'Draftkings':
331
+ wr_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,3:6].values, return_counts=True)),
332
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
333
+ elif sim_site_var1 == 'Fanduel':
334
+ wr_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,3:6].values, return_counts=True)),
335
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
336
+ wr_working['Freq'] = wr_working['Freq'].astype(int)
337
+ wr_working['Position'] = wr_working['Player'].map(st.session_state.maps_dict['Pos_map'])
338
+ wr_working['Salary'] = wr_working['Player'].map(st.session_state.maps_dict['Salary_map'])
339
+ wr_working['Proj Own'] = wr_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100
340
+ wr_working['Exposure'] = wr_working['Freq']/(1000)
341
+ wr_working['Edge'] = wr_working['Exposure'] - wr_working['Proj Own']
342
+ wr_working['Team'] = wr_working['Player'].map(st.session_state.maps_dict['Team_map'])
343
+ st.session_state.wr_freq = wr_working.copy()
344
+
345
+ if sim_site_var1 == 'Draftkings':
346
+ te_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,6:7].values, return_counts=True)),
347
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
348
+ elif sim_site_var1 == 'Fanduel':
349
+ te_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,6:7].values, return_counts=True)),
350
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
351
+ te_working['Freq'] = te_working['Freq'].astype(int)
352
+ te_working['Position'] = te_working['Player'].map(st.session_state.maps_dict['Pos_map'])
353
+ te_working['Salary'] = te_working['Player'].map(st.session_state.maps_dict['Salary_map'])
354
+ te_working['Proj Own'] = te_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100
355
+ te_working['Exposure'] = te_working['Freq']/(1000)
356
+ te_working['Edge'] = te_working['Exposure'] - te_working['Proj Own']
357
+ te_working['Team'] = te_working['Player'].map(st.session_state.maps_dict['Team_map'])
358
+ st.session_state.te_freq = te_working.copy()
359
+
360
+ if sim_site_var1 == 'Draftkings':
361
+ flex_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,7:8].values, return_counts=True)),
362
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
363
+ elif sim_site_var1 == 'Fanduel':
364
+ flex_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,7:8].values, return_counts=True)),
365
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
366
+ flex_working['Freq'] = flex_working['Freq'].astype(int)
367
+ flex_working['Position'] = flex_working['Player'].map(st.session_state.maps_dict['Pos_map'])
368
+ flex_working['Salary'] = flex_working['Player'].map(st.session_state.maps_dict['Salary_map'])
369
+ flex_working['Proj Own'] = flex_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100
370
+ flex_working['Exposure'] = flex_working['Freq']/(1000)
371
+ flex_working['Edge'] = flex_working['Exposure'] - flex_working['Proj Own']
372
+ flex_working['Team'] = flex_working['Player'].map(st.session_state.maps_dict['Team_map'])
373
+ st.session_state.flex_freq = flex_working.copy()
374
+
375
+ if sim_site_var1 == 'Draftkings':
376
+ dst_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,8:9].values, return_counts=True)),
377
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
378
+ elif sim_site_var1 == 'Fanduel':
379
+ dst_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,8:9].values, return_counts=True)),
380
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
381
+ dst_working['Freq'] = dst_working['Freq'].astype(int)
382
+ dst_working['Position'] = dst_working['Player'].map(st.session_state.maps_dict['Pos_map'])
383
+ dst_working['Salary'] = dst_working['Player'].map(st.session_state.maps_dict['Salary_map'])
384
+ dst_working['Proj Own'] = dst_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100
385
+ dst_working['Exposure'] = dst_working['Freq']/(1000)
386
+ dst_working['Edge'] = dst_working['Exposure'] - dst_working['Proj Own']
387
+ dst_working['Team'] = dst_working['Player'].map(st.session_state.maps_dict['Team_map'])
388
+ st.session_state.dst_freq = dst_working.copy()
389
+
390
+ if sim_site_var1 == 'Draftkings':
391
+ team_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,11:12].values, return_counts=True)),
392
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
393
+ elif sim_site_var1 == 'Fanduel':
394
+ team_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,11:12].values, return_counts=True)),
395
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
396
+ team_working['Freq'] = team_working['Freq'].astype(int)
397
+ team_working['Exposure'] = team_working['Freq']/(1000)
398
+ st.session_state.team_freq = team_working.copy()
399
+
400
+ with st.container():
401
+ if st.button("Reset Sim", key='reset_sim'):
402
+ for key in st.session_state.keys():
403
+ del st.session_state[key]
404
+ if 'player_freq' in st.session_state:
405
+ player_split_var2 = st.radio("Are you wanting to isolate any lineups with specific players?", ('Full Players', 'Specific Players'), key='player_split_var2')
406
+ if player_split_var2 == 'Specific Players':
407
+ find_var2 = st.multiselect('Which players must be included in the lineups?', options = st.session_state.player_freq['Player'].unique())
408
+ elif player_split_var2 == 'Full Players':
409
+ find_var2 = st.session_state.player_freq.Player.values.tolist()
410
+
411
+ if player_split_var2 == 'Specific Players':
412
+ 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)]
413
+ if player_split_var2 == 'Full Players':
414
+ st.session_state.Sim_Winner_Display = st.session_state.Sim_Winner_Frame
415
+ if 'Sim_Winner_Display' in st.session_state:
416
+ st.dataframe(st.session_state.Sim_Winner_Display.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(precision=2), use_container_width = True)
417
+ if 'Sim_Winner_Export' in st.session_state:
418
+ st.download_button(
419
+ label="Export Full Frame",
420
+ data=st.session_state.Sim_Winner_Export.to_csv().encode('utf-8'),
421
+ file_name='MLB_consim_export.csv',
422
+ mime='text/csv',
423
+ )
424
+ tab1, tab2 = st.tabs(['Winning Frame Statistics', 'Flex Exposure Statistics'])
425
+
426
+ with tab1:
427
+ if 'Sim_Winner_Display' in st.session_state:
428
+ # Create a new dataframe with summary statistics
429
+ summary_df = pd.DataFrame({
430
+ 'Metric': ['Min', 'Average', 'Max', 'STDdev'],
431
+ 'Salary': [
432
+ st.session_state.Sim_Winner_Display['salary'].min(),
433
+ st.session_state.Sim_Winner_Display['salary'].mean(),
434
+ st.session_state.Sim_Winner_Display['salary'].max(),
435
+ st.session_state.Sim_Winner_Display['salary'].std()
436
+ ],
437
+ 'Proj': [
438
+ st.session_state.Sim_Winner_Display['proj'].min(),
439
+ st.session_state.Sim_Winner_Display['proj'].mean(),
440
+ st.session_state.Sim_Winner_Display['proj'].max(),
441
+ st.session_state.Sim_Winner_Display['proj'].std()
442
+ ],
443
+ 'Own': [
444
+ st.session_state.Sim_Winner_Display['Own'].min(),
445
+ st.session_state.Sim_Winner_Display['Own'].mean(),
446
+ st.session_state.Sim_Winner_Display['Own'].max(),
447
+ st.session_state.Sim_Winner_Display['Own'].std()
448
+ ],
449
+ 'Fantasy': [
450
+ st.session_state.Sim_Winner_Display['Fantasy'].min(),
451
+ st.session_state.Sim_Winner_Display['Fantasy'].mean(),
452
+ st.session_state.Sim_Winner_Display['Fantasy'].max(),
453
+ st.session_state.Sim_Winner_Display['Fantasy'].std()
454
+ ],
455
+ 'GPP_Proj': [
456
+ st.session_state.Sim_Winner_Display['GPP_Proj'].min(),
457
+ st.session_state.Sim_Winner_Display['GPP_Proj'].mean(),
458
+ st.session_state.Sim_Winner_Display['GPP_Proj'].max(),
459
+ st.session_state.Sim_Winner_Display['GPP_Proj'].std()
460
+ ]
461
+ })
462
+
463
+ # Set the index of the summary dataframe as the "Metric" column
464
+ summary_df = summary_df.set_index('Metric')
465
+
466
+ # Display the summary dataframe
467
+ st.subheader("Winning Frame Statistics")
468
+ st.dataframe(summary_df.style.format({
469
+ 'Salary': '{:.2f}',
470
+ 'Proj': '{:.2f}',
471
+ 'Fantasy': '{:.2f}',
472
+ 'GPP_Proj': '{:.2f}'
473
+ }).background_gradient(cmap='RdYlGn', axis=0, subset=['Salary', 'Proj', 'Own', 'Fantasy', 'GPP_Proj']), use_container_width=True)
474
+
475
+ with tab2:
476
+ if 'Sim_Winner_Display' in st.session_state:
477
+ # Apply position mapping to FLEX column
478
+ flex_positions = st.session_state.freq_copy['FLEX'].map(st.session_state.maps_dict['Pos_map'])
479
+
480
+ # Count occurrences of each position in FLEX
481
+ flex_counts = flex_positions.value_counts()
482
+
483
+ # Calculate average statistics for each FLEX position
484
+ flex_stats = st.session_state.freq_copy.groupby(flex_positions).agg({
485
+ 'proj': 'mean',
486
+ 'Own': 'mean',
487
+ 'Fantasy': 'mean',
488
+ 'GPP_Proj': 'mean'
489
+ })
490
+
491
+ # Combine counts and average statistics
492
+ flex_summary = pd.concat([flex_counts, flex_stats], axis=1)
493
+ flex_summary.columns = ['Count', 'Avg Proj', 'Avg Own', 'Avg Fantasy', 'Avg GPP_Proj']
494
+ flex_summary = flex_summary.reset_index()
495
+ flex_summary.columns = ['Position', 'Count', 'Avg Proj', 'Avg Own', 'Avg Fantasy', 'Avg GPP_Proj']
496
+
497
+ # Display the summary dataframe
498
+ st.subheader("FLEX Position Statistics")
499
+ st.dataframe(flex_summary.style.format({
500
+ 'Count': '{:.0f}',
501
+ 'Avg Proj': '{:.2f}',
502
+ 'Avg Fantasy': '{:.2f}',
503
+ 'Avg GPP_Proj': '{:.2f}'
504
+ }).background_gradient(cmap='RdYlGn', axis=0, subset=['Count', 'Avg Proj', 'Avg Own', 'Avg Fantasy', 'Avg GPP_Proj']), use_container_width=True)
505
+
506
+ else:
507
+ st.write("Simulation data or position mapping not available.")
508
+ with st.container():
509
+ tab1, tab2, tab3, tab4, tab5, tab6, tab7, tab8, tab9 = st.tabs(['Overall Exposures', 'QB Exposures', 'RB-WR-TE Exposures', 'RB Exposures', 'WR Exposures', 'TE Exposures', 'FLEX Exposures', 'DST Exposures', 'Team Exposures'])
510
+ with tab1:
511
+ if 'player_freq' in st.session_state:
512
+
513
+ 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)
514
+ st.download_button(
515
+ label="Export Exposures",
516
+ data=st.session_state.player_freq.to_csv().encode('utf-8'),
517
+ file_name='player_freq_export.csv',
518
+ mime='text/csv',
519
+ key='overall'
520
+ )
521
+ with tab2:
522
+ if 'qb_freq' in st.session_state:
523
+
524
+ st.dataframe(st.session_state.qb_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True)
525
+ st.download_button(
526
+ label="Export Exposures",
527
+ data=st.session_state.qb_freq.to_csv().encode('utf-8'),
528
+ file_name='qb_freq.csv',
529
+ mime='text/csv',
530
+ key='qb'
531
+ )
532
+ with tab3:
533
+ if 'rbwrte_freq' in st.session_state:
534
+
535
+ st.dataframe(st.session_state.rbwrte_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True)
536
+ st.download_button(
537
+ label="Export Exposures",
538
+ data=st.session_state.rbwrte_freq.to_csv().encode('utf-8'),
539
+ file_name='rbwrte_freq.csv',
540
+ mime='text/csv',
541
+ key='rbwrte'
542
+ )
543
+ with tab4:
544
+ if 'rb_freq' in st.session_state:
545
+
546
+ st.dataframe(st.session_state.rb_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True)
547
+ st.download_button(
548
+ label="Export Exposures",
549
+ data=st.session_state.rb_freq.to_csv().encode('utf-8'),
550
+ file_name='rb_freq.csv',
551
+ mime='text/csv',
552
+ key='rb'
553
+ )
554
+ with tab5:
555
+ if 'wr_freq' in st.session_state:
556
+
557
+ st.dataframe(st.session_state.wr_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True)
558
+ st.download_button(
559
+ label="Export Exposures",
560
+ data=st.session_state.wr_freq.to_csv().encode('utf-8'),
561
+ file_name='wr_freq.csv',
562
+ mime='text/csv',
563
+ key='wr'
564
+ )
565
+ with tab6:
566
+ if 'te_freq' in st.session_state:
567
+
568
+ st.dataframe(st.session_state.te_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True)
569
+ st.download_button(
570
+ label="Export Exposures",
571
+ data=st.session_state.te_freq.to_csv().encode('utf-8'),
572
+ file_name='te_freq.csv',
573
+ mime='text/csv',
574
+ key='te'
575
+ )
576
+ with tab7:
577
+ if 'flex_freq' in st.session_state:
578
+
579
+ 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)
580
+ st.download_button(
581
+ label="Export Exposures",
582
+ data=st.session_state.flex_freq.to_csv().encode('utf-8'),
583
+ file_name='flex_freq.csv',
584
+ mime='text/csv',
585
+ key='flex'
586
+ )
587
+ with tab8:
588
+ if 'dst_freq' in st.session_state:
589
+
590
+ st.dataframe(st.session_state.dst_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True)
591
+ st.download_button(
592
+ label="Export Exposures",
593
+ data=st.session_state.dst_freq.to_csv().encode('utf-8'),
594
+ file_name='dst_freq.csv',
595
+ mime='text/csv',
596
+ key='dst'
597
+ )
598
+ with tab9:
599
+ if 'team_freq' in st.session_state:
600
+
601
+ 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)
602
+ st.download_button(
603
+ label="Export Exposures",
604
+ data=st.session_state.team_freq.to_csv().encode('utf-8'),
605
+ file_name='team_freq.csv',
606
+ mime='text/csv',
607
+ key='team'
608
+ )
609
+
610
+ if selected_tab == "Showdown Contest Sims":
611
+ dk_sd_raw, fd_sd_raw = init_SD_baselines('Showdown #1')
612
+ raw_baselines = dk_sd_raw
613
+ column_names = dk_sd_columns
614
+ with st.expander("Info and Filters"):
615
+ site_data_col, slate_data_col, contest_size_col, contest_sharpness_col = st.columns([1, 1, 1, 1])
616
+ with site_data_col:
617
+ sim_site_var2 = st.radio("What site are you working with?", ('Draftkings', 'Fanduel'), key='sim_site_var2')
618
+
619
+ with slate_data_col:
620
+ sim_slate_var2 = st.radio("Which data are you loading?", slate_names_dk if sim_site_var2 == 'Draftkings' else slate_names_fd, key='sim_slate_var2')
621
+
622
+ with contest_size_col:
623
+ contest_var2 = st.selectbox("What contest size are you simulating?", ('Small', 'Medium', 'Large'), key='contest_var2')
624
+ if contest_var2 == 'Small':
625
+ Contest_Size = 1000
626
+ elif contest_var2 == 'Medium':
627
+ Contest_Size = 5000
628
+ elif contest_var2 == 'Large':
629
+ Contest_Size = 10000
630
+ elif contest_var2 == 'Custom':
631
+ Contest_Size = st.number_input("Insert contest size", value=100, placeholder="Type a number under 10,000...")
632
+ with contest_sharpness_col:
633
+ strength_var2 = st.selectbox("How sharp is the field in the contest?", ('Very', 'Above Average', 'Average', 'Below Average', 'Not Very'), key='strength_var2')
634
+ if strength_var2 == 'Not Very':
635
+ sharp_split = 500000
636
+ elif strength_var2 == 'Below Average':
637
+ sharp_split = 250000
638
+ elif strength_var2 == 'Average':
639
+ sharp_split = 100000
640
+ elif strength_var2 == 'Above Average':
641
+ sharp_split = 50000
642
+ elif strength_var2 == 'Very':
643
+ sharp_split = 10000
644
+
645
+ if st.button("Run Contest Sim"):
646
+
647
+ if 'sd_working_seed' not in st.session_state:
648
+ if sim_site_var2 == 'Draftkings':
649
+ st.session_state.sd_working_seed = init_DK_SD_seed_frames(slate_name_lookup_dk[sim_slate_var2], sharp_split, dk_showdown_db_translation)
650
+ export_id_dict = dict(zip(dk_sd_raw.Player, dk_sd_raw.player_ID))
651
+ raw_baselines = dk_sd_raw
652
+ column_names = dk_sd_columns
653
+ elif sim_site_var2 == 'Fanduel':
654
+ st.session_state.sd_working_seed = init_FD_SD_seed_frames(slate_name_lookup_fd[sim_slate_var2], sharp_split, fd_showdown_db_translation)
655
+ export_id_dict = dict(zip(fd_sd_raw.Player, fd_sd_raw.player_ID))
656
+ raw_baselines = fd_sd_raw
657
+ column_names = fd_sd_columns
658
+ maps_dict = {
659
+ 'Projection_map':dict(zip(raw_baselines.Player,raw_baselines.Median)),
660
+ 'cpt_projection_map':dict(zip(raw_baselines.Player,raw_baselines.cpt_Median)),
661
+ 'Salary_map':dict(zip(raw_baselines.Player,raw_baselines.Salary)),
662
+ 'Pos_map':dict(zip(raw_baselines.Player,raw_baselines.Position)),
663
+ 'Own_map':dict(zip(raw_baselines.Player,raw_baselines['Own'])),
664
+ 'cpt_Own_map':dict(zip(raw_baselines.Player,raw_baselines['CPT_Own'])),
665
+ 'Team_map':dict(zip(raw_baselines.Player,raw_baselines.Team)),
666
+ 'STDev_map':dict(zip(raw_baselines.Player,raw_baselines.STDev)),
667
+ 'cpt_STDev_map':dict(zip(raw_baselines.Player,raw_baselines['CPT_STDev']))
668
+ }
669
+ Sim_Winners = sim_SD_contest(1000, st.session_state.sd_working_seed, maps_dict, Contest_Size)
670
+ Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners))
671
+
672
+ #st.table(Sim_Winner_Frame)
673
+
674
+ # Initial setup
675
+ Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners), columns=column_names + ['Fantasy'])
676
+ Sim_Winner_Frame['GPP_Proj'] = (Sim_Winner_Frame['proj'] + Sim_Winner_Frame['Fantasy']) / 2
677
+ 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)
678
+
679
+ Sim_Winner_Frame = Sim_Winner_Frame.assign(win_count=Sim_Winner_Frame['unique_id'].map(Sim_Winner_Frame['unique_id'].value_counts()))
680
+
681
+ # Type Casting
682
+ type_cast_dict = {'salary': int, 'proj': np.float16, 'Fantasy': np.float16, 'GPP_Proj': np.float32, 'Own': np.float32}
683
+ Sim_Winner_Frame = Sim_Winner_Frame.astype(type_cast_dict)
684
+
685
+ # Sorting
686
+ 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)
687
+ st.session_state.Sim_Winner_Frame = st.session_state.Sim_Winner_Frame.drop(columns=['unique_id', 'win_count'])
688
+
689
+ # Data Copying
690
+ st.session_state.Sim_Winner_Export = Sim_Winner_Frame.copy()
691
+ st.session_state.Sim_Winner_Export.iloc[:, 0:6] = st.session_state.Sim_Winner_Export.iloc[:, 0:6].apply(lambda x: x.map(export_id_dict))
692
+
693
+ # Data Copying
694
+ st.session_state.Sim_Winner_Display = Sim_Winner_Frame.copy()
695
+ freq_copy = st.session_state.Sim_Winner_Display
696
+
697
+ else:
698
+ maps_dict = {
699
+ 'Projection_map':dict(zip(raw_baselines.Player,raw_baselines.Median)),
700
+ 'cpt_projection_map':dict(zip(raw_baselines.Player,raw_baselines.cpt_Median)),
701
+ 'Salary_map':dict(zip(raw_baselines.Player,raw_baselines.Salary)),
702
+ 'Pos_map':dict(zip(raw_baselines.Player,raw_baselines.Position)),
703
+ 'Own_map':dict(zip(raw_baselines.Player,raw_baselines['Own'])),
704
+ 'cpt_Own_map':dict(zip(raw_baselines.Player,raw_baselines['CPT_Own'])),
705
+ 'Team_map':dict(zip(raw_baselines.Player,raw_baselines.Team)),
706
+ 'STDev_map':dict(zip(raw_baselines.Player,raw_baselines.STDev)),
707
+ 'cpt_STDev_map':dict(zip(raw_baselines.Player,raw_baselines['CPT_STDev']))
708
+ }
709
+ Sim_Winners = sim_SD_contest(1000, st.session_state.sd_working_seed, maps_dict, Contest_Size)
710
+ Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners))
711
+
712
+ #st.table(Sim_Winner_Frame)
713
+
714
+ # Initial setup
715
+ Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners), columns=column_names + ['Fantasy'])
716
+ Sim_Winner_Frame['GPP_Proj'] = (Sim_Winner_Frame['proj'] + Sim_Winner_Frame['Fantasy']) / 2
717
+ 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)
718
+ Sim_Winner_Frame = Sim_Winner_Frame.assign(win_count=Sim_Winner_Frame['unique_id'].map(Sim_Winner_Frame['unique_id'].value_counts()))
719
+
720
+ # Type Casting
721
+ type_cast_dict = {'salary': int, 'proj': np.float16, 'Fantasy': np.float16, 'GPP_Proj': np.float32, 'Own': np.float32}
722
+ Sim_Winner_Frame = Sim_Winner_Frame.astype(type_cast_dict)
723
+
724
+ # Sorting
725
+ 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)
726
+ st.session_state.Sim_Winner_Frame = st.session_state.Sim_Winner_Frame.drop(columns=['unique_id', 'win_count'])
727
+
728
+ # Data Copying
729
+ st.session_state.Sim_Winner_Export = Sim_Winner_Frame.copy()
730
+ st.session_state.Sim_Winner_Export.iloc[:, 0:6] = st.session_state.Sim_Winner_Export.iloc[:, 0:6].apply(lambda x: x.map(export_id_dict))
731
+
732
+ # Data Copying
733
+ st.session_state.Sim_Winner_Display = Sim_Winner_Frame.copy()
734
+ freq_copy = st.session_state.Sim_Winner_Display
735
+
736
+ if sim_site_var2 == 'Draftkings':
737
+ freq_working = pd.DataFrame(np.column_stack(np.unique(freq_copy.iloc[:,0:6].values, return_counts=True)),
738
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
739
+ elif sim_site_var2 == 'Fanduel':
740
+ freq_working = pd.DataFrame(np.column_stack(np.unique(freq_copy.iloc[:,0:6].values, return_counts=True)),
741
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
742
+ freq_working['Freq'] = freq_working['Freq'].astype(int)
743
+ freq_working['Position'] = freq_working['Player'].map(maps_dict['Pos_map'])
744
+ freq_working['Salary'] = freq_working['Player'].map(maps_dict['Salary_map']) / 1.5
745
+ freq_working['Proj Own'] = freq_working['Player'].map(maps_dict['Own_map']) / 100
746
+ freq_working['Exposure'] = freq_working['Freq']/(1000)
747
+ freq_working['Edge'] = freq_working['Exposure'] - freq_working['Proj Own']
748
+ freq_working['Team'] = freq_working['Player'].map(maps_dict['Team_map'])
749
+ st.session_state.player_freq = freq_working.copy()
750
+
751
+ cpt_working = pd.DataFrame(np.column_stack(np.unique(freq_copy.iloc[:,0:1].values, return_counts=True)),
752
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
753
+ cpt_working['Freq'] = cpt_working['Freq'].astype(int)
754
+ cpt_working['Position'] = cpt_working['Player'].map(maps_dict['Pos_map'])
755
+ cpt_working['Salary'] = cpt_working['Player'].map(maps_dict['Salary_map'])
756
+ cpt_working['Proj Own'] = cpt_working['Player'].map(maps_dict['cpt_Own_map']) / 100
757
+ cpt_working['Exposure'] = cpt_working['Freq']/(1000)
758
+ cpt_working['Edge'] = cpt_working['Exposure'] - cpt_working['Proj Own']
759
+ cpt_working['Team'] = cpt_working['Player'].map(maps_dict['Team_map'])
760
+ st.session_state.sp_freq = cpt_working.copy()
761
+
762
+ flex_working = pd.DataFrame(np.column_stack(np.unique(freq_copy.iloc[:,1:6].values, return_counts=True)),
763
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
764
+ cpt_own_div = 600
765
+ flex_working['Freq'] = flex_working['Freq'].astype(int)
766
+ flex_working['Position'] = flex_working['Player'].map(maps_dict['Pos_map'])
767
+ flex_working['Salary'] = flex_working['Player'].map(maps_dict['Salary_map']) / 1.5
768
+ flex_working['Proj Own'] = (flex_working['Player'].map(maps_dict['Own_map']) / 100) - (flex_working['Player'].map(maps_dict['cpt_Own_map']) / 100)
769
+ flex_working['Exposure'] = flex_working['Freq']/(1000)
770
+ flex_working['Edge'] = flex_working['Exposure'] - flex_working['Proj Own']
771
+ flex_working['Team'] = flex_working['Player'].map(maps_dict['Team_map'])
772
+ st.session_state.flex_freq = flex_working.copy()
773
 
774
+ team_working = pd.DataFrame(np.column_stack(np.unique(freq_copy.iloc[:,8:9].values, return_counts=True)),
775
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
776
+ team_working['Freq'] = team_working['Freq'].astype(int)
777
+ team_working['Exposure'] = team_working['Freq']/(1000)
778
+ st.session_state.team_freq = team_working.copy()
779
+
780
+ with st.container():
781
+ if st.button("Reset Sim", key='reset_sim'):
782
+ for key in st.session_state.keys():
783
+ del st.session_state[key]
784
+ if 'player_freq' in st.session_state:
785
+ player_split_var2 = st.radio("Are you wanting to isolate any lineups with specific players?", ('Full Players', 'Specific Players'), key='player_split_var2')
786
+ if player_split_var2 == 'Specific Players':
787
+ find_var2 = st.multiselect('Which players must be included in the lineups?', options = st.session_state.player_freq['Player'].unique())
788
+ elif player_split_var2 == 'Full Players':
789
+ find_var2 = st.session_state.player_freq.Player.values.tolist()
790
+
791
+ if player_split_var2 == 'Specific Players':
792
+ 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)]
793
+ if player_split_var2 == 'Full Players':
794
+ st.session_state.Sim_Winner_Display = st.session_state.Sim_Winner_Frame
795
+ if 'Sim_Winner_Display' in st.session_state:
796
+ st.dataframe(st.session_state.Sim_Winner_Display.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(precision=2), use_container_width = True)
797
+ if 'Sim_Winner_Export' in st.session_state:
798
+ st.download_button(
799
+ label="Export Full Frame",
800
+ data=st.session_state.Sim_Winner_Export.to_csv().encode('utf-8'),
801
+ file_name='NFL_SD_consim_export.csv',
802
+ mime='text/csv',
803
+ )
804
+
805
+ with st.container():
806
+ tab1, tab2, tab3, tab4 = st.tabs(['Overall Exposures', 'CPT Exposures', 'FLEX Exposures', 'Team Exposures'])
807
+ with tab1:
808
+ if 'player_freq' in st.session_state:
809
+
810
+ 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)
811
+ st.download_button(
812
+ label="Export Exposures",
813
+ data=st.session_state.player_freq.to_csv().encode('utf-8'),
814
+ file_name='player_freq_export.csv',
815
+ mime='text/csv',
816
+ key='overall'
817
+ )
818
+ with tab2:
819
+ if 'sp_freq' in st.session_state:
820
+
821
+ st.dataframe(st.session_state.sp_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True)
822
+ st.download_button(
823
+ label="Export Exposures",
824
+ data=st.session_state.sp_freq.to_csv().encode('utf-8'),
825
+ file_name='cpt_freq.csv',
826
+ mime='text/csv',
827
+ key='sp'
828
+ )
829
+ with tab3:
830
+ if 'flex_freq' in st.session_state:
831
+
832
+ 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)
833
+ st.download_button(
834
+ label="Export Exposures",
835
+ data=st.session_state.flex_freq.to_csv().encode('utf-8'),
836
+ file_name='flex_freq.csv',
837
+ mime='text/csv',
838
+ key='flex'
839
+ )
840
+ with tab4:
841
+ if 'team_freq' in st.session_state:
842
+
843
+ 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)
844
+ st.download_button(
845
+ label="Export Exposures",
846
+ data=st.session_state.team_freq.to_csv().encode('utf-8'),
847
+ file_name='team_freq.csv',
848
+ mime='text/csv',
849
+ key='team'
850
+ )