James McCool commited on
Commit
ceb1f25
·
1 Parent(s): 2b28c7d

Implement comprehensive contest simulation functionality with dynamic sport, site, and slate selection

Browse files
Files changed (1) hide show
  1. app.py +384 -386
app.py CHANGED
@@ -281,6 +281,389 @@ except:
281
  dk_raw, fd_raw = init_baselines('NBA')
282
 
283
  tab1, tab2 = st.tabs(['Contest Sims', 'Data Export'])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
284
  with tab2:
285
  with st.expander("Info and Filters"):
286
  if st.button("Load/Reset Data", key='reset1'):
@@ -440,389 +823,4 @@ with tab2:
440
 
441
  with st.container():
442
  if 'data_export_display' in st.session_state:
443
- st.dataframe(st.session_state.data_export_display.style.format(freq_format, precision=2), use_container_width = True)
444
-
445
- with tab1:
446
- col1, col2 = st.columns([1, 7])
447
- with col1:
448
- if st.button("Load/Reset Data", key='reset2'):
449
- st.cache_data.clear()
450
- for key in st.session_state.keys():
451
- del st.session_state[key]
452
- dk_raw, fd_raw = init_baselines('NFL')
453
- sim_sport_var1 = st.radio("What sport are you working with?", ('NBA', 'NFL'), key='sim_sport_var1')
454
- dk_raw, fd_raw = init_baselines(sim_sport_var1)
455
- sim_slate_var1 = st.radio("Which data are you loading?", ('Showdown', 'Secondary Showdown', 'Auxiliary Showdown'), key='sim_slate_var1')
456
- sim_site_var1 = st.radio("What site are you working with?", ('Draftkings', 'Fanduel'), key='sim_site_var1')
457
- if sim_site_var1 == 'Draftkings':
458
- raw_baselines = dk_raw
459
- column_names = dk_columns
460
- elif sim_site_var1 == 'Fanduel':
461
- raw_baselines = fd_raw
462
- column_names = fd_columns
463
- contest_var1 = st.selectbox("What contest size are you simulating?", ('Small', 'Medium', 'Large', 'Custom'))
464
- if contest_var1 == 'Small':
465
- Contest_Size = 1000
466
- st.write("Small field size is 1,000 entrants.")
467
- raw_baselines['Own'] = raw_baselines['Small_Field_Own']
468
- raw_baselines['CPT_Own'] = raw_baselines['small_CPT_Own']
469
- elif contest_var1 == 'Medium':
470
- Contest_Size = 5000
471
- st.write("Medium field size is 5,000 entrants.")
472
- elif contest_var1 == 'Large':
473
- Contest_Size = 10000
474
- st.write("Large field size is 10,000 entrants.")
475
- elif contest_var1 == 'Custom':
476
- Contest_Size = st.number_input("Insert contest size", value=100, min_value=1, max_value=100000)
477
- strength_var1 = st.selectbox("How sharp is the field in the contest?", ('Very', 'Above Average', 'Average', 'Below Average', 'Not Very'))
478
- if strength_var1 == 'Not Very':
479
- sharp_split = 500000
480
- elif strength_var1 == 'Below Average':
481
- sharp_split = 400000
482
- elif strength_var1 == 'Average':
483
- sharp_split = 300000
484
- elif strength_var1 == 'Above Average':
485
- sharp_split = 200000
486
- elif strength_var1 == 'Very':
487
- sharp_split = 100000
488
-
489
-
490
- with col2:
491
- if st.button("Run Contest Sim"):
492
- if 'working_seed' in st.session_state:
493
- maps_dict = {
494
- 'Projection_map':dict(zip(raw_baselines.Player,raw_baselines.Median)),
495
- 'cpt_projection_map':dict(zip(raw_baselines.Player,raw_baselines.cpt_Median)),
496
- 'Salary_map':dict(zip(raw_baselines.Player,raw_baselines.Salary)),
497
- 'Pos_map':dict(zip(raw_baselines.Player,raw_baselines.Position)),
498
- 'Own_map':dict(zip(raw_baselines.Player,raw_baselines['Own'])),
499
- 'cpt_Own_map':dict(zip(raw_baselines.Player,raw_baselines['CPT_Own'])),
500
- 'Team_map':dict(zip(raw_baselines.Player,raw_baselines.Team)),
501
- 'STDev_map':dict(zip(raw_baselines.Player,raw_baselines.STDev)),
502
- 'cpt_STDev_map':dict(zip(raw_baselines.Player,raw_baselines['CPT_STDev']))
503
- }
504
- Sim_Winners = sim_contest(1000, st.session_state.working_seed, maps_dict, Contest_Size)
505
- Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners))
506
-
507
- #st.table(Sim_Winner_Frame)
508
-
509
- # Initial setup
510
- Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners), columns=column_names + ['Fantasy'])
511
- Sim_Winner_Frame['GPP_Proj'] = (Sim_Winner_Frame['proj'] + Sim_Winner_Frame['Fantasy']) / 2
512
- 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)
513
- Sim_Winner_Frame = Sim_Winner_Frame.assign(win_count=Sim_Winner_Frame['unique_id'].map(Sim_Winner_Frame['unique_id'].value_counts()))
514
-
515
- # Type Casting
516
- type_cast_dict = {'salary': int, 'proj': np.float16, 'Fantasy': np.float16, 'GPP_Proj': np.float32, 'Own': np.float32}
517
- Sim_Winner_Frame = Sim_Winner_Frame.astype(type_cast_dict)
518
-
519
- # Sorting
520
- 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)
521
- st.session_state.Sim_Winner_Frame.drop(columns='unique_id', inplace=True)
522
-
523
- # Data Copying
524
- st.session_state.Sim_Winner_Export = Sim_Winner_Frame.copy()
525
-
526
- # Data Copying
527
- st.session_state.Sim_Winner_Display = Sim_Winner_Frame.copy()
528
-
529
- else:
530
- if sim_site_var1 == 'Draftkings':
531
- if sim_slate_var1 == 'Showdown':
532
- st.session_state.working_seed = init_DK_seed_frames(sim_sport_var1, sharp_split_var)
533
- if sport_var1 == 'NFL':
534
- export_id_dict = dict(zip(dk_raw['Player'], dk_raw['player_id']))
535
- elif sport_var1 == 'NBA':
536
- export_id_dict = dict(zip(dk_raw['Player'], dk_raw['player_id']))
537
- elif sim_slate_var1 == 'Secondary Showdown':
538
- st.session_state.working_seed = init_DK_secondary_seed_frames(sim_sport_var1, sharp_split_var)
539
- if sport_var1 == 'NFL':
540
- export_id_dict = dict(zip(dk_raw['Player'], dk_raw['player_id']))
541
- elif sport_var1 == 'NBA':
542
- export_id_dict = dict(zip(dk_raw['Player'], dk_raw['player_id']))
543
- elif sim_slate_var1 == 'Auxiliary Showdown':
544
- st.session_state.working_seed = init_DK_auxiliary_seed_frames(sim_sport_var1, sharp_split_var)
545
- if sport_var1 == 'NFL':
546
- export_id_dict = dict(zip(dk_raw['Player'], dk_raw['player_id']))
547
- elif sport_var1 == 'NBA':
548
- export_id_dict = dict(zip(dk_raw['Player'], dk_raw['player_id']))
549
- raw_baselines = dk_raw
550
- column_names = dk_columns
551
- elif sim_site_var1 == 'Fanduel':
552
- if sim_slate_var1 == 'Showdown':
553
- st.session_state.working_seed = init_FD_seed_frames(sim_sport_var1, sharp_split_var)
554
- if sport_var1 == 'NFL':
555
- export_id_dict = dict(zip(fd_raw['Player'], fd_raw['player_id']))
556
- elif sport_var1 == 'NBA':
557
- export_id_dict = dict(zip(fd_raw['Player'], fd_raw['player_id']))
558
- elif sim_slate_var1 == 'Secondary Showdown':
559
- st.session_state.working_seed = init_FD_secondary_seed_frames(sim_sport_var1, sharp_split_var)
560
- if sport_var1 == 'NFL':
561
- export_id_dict = dict(zip(fd_raw['Player'], fd_raw['player_id']))
562
- elif sport_var1 == 'NBA':
563
- export_id_dict = dict(zip(fd_raw['Player'], fd_raw['player_id']))
564
- elif sim_slate_var1 == 'Auxiliary Showdown':
565
- st.session_state.working_seed = init_FD_auxiliary_seed_frames(sim_sport_var1, sharp_split_var)
566
- if sport_var1 == 'NFL':
567
- export_id_dict = dict(zip(fd_raw['Player'], fd_raw['player_id']))
568
- elif sport_var1 == 'NBA':
569
- export_id_dict = dict(zip(fd_raw['Player'], fd_raw['player_id']))
570
- raw_baselines = fd_raw
571
- column_names = fd_columns
572
- maps_dict = {
573
- 'Projection_map':dict(zip(raw_baselines.Player,raw_baselines.Median)),
574
- 'cpt_projection_map':dict(zip(raw_baselines.Player,raw_baselines.cpt_Median)),
575
- 'Salary_map':dict(zip(raw_baselines.Player,raw_baselines.Salary)),
576
- 'Pos_map':dict(zip(raw_baselines.Player,raw_baselines.Position)),
577
- 'Own_map':dict(zip(raw_baselines.Player,raw_baselines['Own'])),
578
- 'cpt_Own_map':dict(zip(raw_baselines.Player,raw_baselines['CPT_Own'])),
579
- 'Team_map':dict(zip(raw_baselines.Player,raw_baselines.Team)),
580
- 'STDev_map':dict(zip(raw_baselines.Player,raw_baselines.STDev)),
581
- 'cpt_STDev_map':dict(zip(raw_baselines.Player,raw_baselines['CPT_STDev']))
582
- }
583
- Sim_Winners = sim_contest(1000, st.session_state.working_seed, maps_dict, Contest_Size)
584
- Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners))
585
-
586
- #st.table(Sim_Winner_Frame)
587
-
588
- # Initial setup
589
- Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners), columns=column_names + ['Fantasy'])
590
- Sim_Winner_Frame['GPP_Proj'] = (Sim_Winner_Frame['proj'] + Sim_Winner_Frame['Fantasy']) / 2
591
- 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)
592
- # Add percent rank columns for ownership at each roster position
593
- # Calculate Dupes column for Fanduel
594
- if sim_site_var1 == 'Fanduel':
595
- dup_count_columns = ['CPT_Own_percent_rank', 'FLEX1_Own_percent_rank', 'FLEX2_Own_percent_rank', 'FLEX3_Own_percent_rank', 'FLEX4_Own_percent_rank']
596
- own_columns = ['CPT_Own', 'FLEX1_Own', 'FLEX2_Own', 'FLEX3_Own', 'FLEX4_Own']
597
- calc_columns = ['own_product', 'avg_own_rank', 'dupes_calc']
598
- Sim_Winner_Frame['CPT_Own_percent_rank'] = Sim_Winner_Frame.iloc[:,0].map(maps_dict['cpt_Own_map']).rank(pct=True)
599
- Sim_Winner_Frame['FLEX1_Own_percent_rank'] = Sim_Winner_Frame.iloc[:,1].map(maps_dict['Own_map']).rank(pct=True)
600
- Sim_Winner_Frame['FLEX2_Own_percent_rank'] = Sim_Winner_Frame.iloc[:,2].map(maps_dict['Own_map']).rank(pct=True)
601
- Sim_Winner_Frame['FLEX3_Own_percent_rank'] = Sim_Winner_Frame.iloc[:,3].map(maps_dict['Own_map']).rank(pct=True)
602
- Sim_Winner_Frame['FLEX4_Own_percent_rank'] = Sim_Winner_Frame.iloc[:,4].map(maps_dict['Own_map']).rank(pct=True)
603
- Sim_Winner_Frame['CPT_Own'] = Sim_Winner_Frame.iloc[:,0].map(maps_dict['cpt_Own_map']) / 100
604
- Sim_Winner_Frame['FLEX1_Own'] = Sim_Winner_Frame.iloc[:,1].map(maps_dict['Own_map']) / 100
605
- Sim_Winner_Frame['FLEX2_Own'] = Sim_Winner_Frame.iloc[:,2].map(maps_dict['Own_map']) / 100
606
- Sim_Winner_Frame['FLEX3_Own'] = Sim_Winner_Frame.iloc[:,3].map(maps_dict['Own_map']) / 100
607
- Sim_Winner_Frame['FLEX4_Own'] = Sim_Winner_Frame.iloc[:,4].map(maps_dict['Own_map']) / 100
608
-
609
- # Calculate ownership product and convert to probability
610
- Sim_Winner_Frame['own_product'] = (Sim_Winner_Frame[own_columns].product(axis=1)) + 0.0001
611
-
612
- # Calculate average of ownership percent rank columns
613
- Sim_Winner_Frame['avg_own_rank'] = Sim_Winner_Frame[dup_count_columns].mean(axis=1)
614
-
615
- # Calculate dupes formula
616
- Sim_Winner_Frame['dupes_calc'] = ((Sim_Winner_Frame['own_product'] * Sim_Winner_Frame['avg_own_rank']) * (Contest_Size * 1.5)) + ((Sim_Winner_Frame['salary'] - 59800) / 100)
617
-
618
- # Round and handle negative values
619
- Sim_Winner_Frame['Dupes'] = np.where(
620
- np.round(Sim_Winner_Frame['dupes_calc'], 0) <= 0,
621
- 0,
622
- np.round(Sim_Winner_Frame['dupes_calc'], 0) - 1
623
- )
624
- Sim_Winner_Frame['Dupes'] = (Sim_Winner_Frame['Dupes'] * (500000 / sharp_split)) / 2
625
- elif sim_site_var1 == 'Draftkings':
626
- dup_count_columns = ['CPT_Own_percent_rank', 'FLEX1_Own_percent_rank', 'FLEX2_Own_percent_rank', 'FLEX3_Own_percent_rank', 'FLEX4_Own_percent_rank', 'FLEX5_Own_percent_rank']
627
- own_columns = ['CPT_Own', 'FLEX1_Own', 'FLEX2_Own', 'FLEX3_Own', 'FLEX4_Own', 'FLEX5_Own']
628
- calc_columns = ['own_product', 'avg_own_rank', 'dupes_calc']
629
- Sim_Winner_Frame['CPT_Own_percent_rank'] = Sim_Winner_Frame.iloc[:,0].map(maps_dict['cpt_Own_map']).rank(pct=True)
630
- Sim_Winner_Frame['FLEX1_Own_percent_rank'] = Sim_Winner_Frame.iloc[:,1].map(maps_dict['Own_map']).rank(pct=True)
631
- Sim_Winner_Frame['FLEX2_Own_percent_rank'] = Sim_Winner_Frame.iloc[:,2].map(maps_dict['Own_map']).rank(pct=True)
632
- Sim_Winner_Frame['FLEX3_Own_percent_rank'] = Sim_Winner_Frame.iloc[:,3].map(maps_dict['Own_map']).rank(pct=True)
633
- Sim_Winner_Frame['FLEX4_Own_percent_rank'] = Sim_Winner_Frame.iloc[:,4].map(maps_dict['Own_map']).rank(pct=True)
634
- Sim_Winner_Frame['FLEX5_Own_percent_rank'] = Sim_Winner_Frame.iloc[:,5].map(maps_dict['Own_map']).rank(pct=True)
635
- Sim_Winner_Frame['CPT_Own'] = Sim_Winner_Frame.iloc[:,0].map(maps_dict['cpt_Own_map']) / 100
636
- Sim_Winner_Frame['FLEX1_Own'] = Sim_Winner_Frame.iloc[:,1].map(maps_dict['Own_map']) / 100
637
- Sim_Winner_Frame['FLEX2_Own'] = Sim_Winner_Frame.iloc[:,2].map(maps_dict['Own_map']) / 100
638
- Sim_Winner_Frame['FLEX3_Own'] = Sim_Winner_Frame.iloc[:,3].map(maps_dict['Own_map']) / 100
639
- Sim_Winner_Frame['FLEX4_Own'] = Sim_Winner_Frame.iloc[:,4].map(maps_dict['Own_map']) / 100
640
- Sim_Winner_Frame['FLEX5_Own'] = Sim_Winner_Frame.iloc[:,5].map(maps_dict['Own_map']) / 100
641
-
642
- # Calculate ownership product and convert to probability
643
- Sim_Winner_Frame['own_product'] = (Sim_Winner_Frame[own_columns].product(axis=1))
644
-
645
- # Calculate average of ownership percent rank columns
646
- Sim_Winner_Frame['avg_own_rank'] = Sim_Winner_Frame[dup_count_columns].mean(axis=1)
647
-
648
- # Calculate dupes formula
649
- Sim_Winner_Frame['dupes_calc'] = ((Sim_Winner_Frame['own_product'] * Sim_Winner_Frame['avg_own_rank']) * (Contest_Size * 1.5)) + ((Sim_Winner_Frame['salary'] - 49800) / 100)
650
-
651
- # Round and handle negative values
652
- Sim_Winner_Frame['Dupes'] = np.where(
653
- np.round(Sim_Winner_Frame['dupes_calc'], 0) <= 0,
654
- 0,
655
- np.round(Sim_Winner_Frame['dupes_calc'], 0) - 1
656
- )
657
- Sim_Winner_Frame['Dupes'] = (Sim_Winner_Frame['Dupes'] * (500000 / sharp_split)) / 2
658
- Sim_Winner_Frame['Dupes'] = np.round(Sim_Winner_Frame['Dupes'], 0)
659
- Sim_Winner_Frame['Dupes'] = np.where(
660
- np.round(Sim_Winner_Frame['dupes_calc'], 0) <= 0,
661
- 0,
662
- np.round(Sim_Winner_Frame['dupes_calc'], 0)
663
- )
664
- Sim_Winner_Frame = Sim_Winner_Frame.drop(columns=dup_count_columns)
665
- Sim_Winner_Frame = Sim_Winner_Frame.drop(columns=own_columns)
666
- Sim_Winner_Frame = Sim_Winner_Frame.drop(columns=calc_columns)
667
-
668
- Sim_Winner_Frame = Sim_Winner_Frame.assign(win_count=Sim_Winner_Frame['unique_id'].map(Sim_Winner_Frame['unique_id'].value_counts()))
669
-
670
- # Type Casting
671
- type_cast_dict = {'salary': int, 'proj': np.float16, 'Fantasy': np.float16, 'GPP_Proj': np.float32, 'Own': np.float32, 'Dupes': int}
672
- Sim_Winner_Frame = Sim_Winner_Frame.astype(type_cast_dict)
673
-
674
- # Sorting
675
- 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)
676
- st.session_state.Sim_Winner_Frame.drop(columns='unique_id', inplace=True)
677
-
678
- # Data Copying
679
- st.session_state.Sim_Winner_Export = Sim_Winner_Frame.copy()
680
- 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))
681
-
682
- # Data Copying
683
- st.session_state.Sim_Winner_Display = Sim_Winner_Frame.copy()
684
- freq_copy = st.session_state.Sim_Winner_Display
685
-
686
- if sim_site_var1 == 'Draftkings':
687
- freq_working = pd.DataFrame(np.column_stack(np.unique(freq_copy.iloc[:,0:6].values, return_counts=True)),
688
- columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
689
- elif sim_site_var1 == 'Fanduel':
690
- freq_working = pd.DataFrame(np.column_stack(np.unique(freq_copy.iloc[:,0:5].values, return_counts=True)),
691
- columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
692
- freq_working['Freq'] = freq_working['Freq'].astype(int)
693
- freq_working['Position'] = freq_working['Player'].map(maps_dict['Pos_map'])
694
- if sim_site_var1 == 'Draftkings':
695
- if sim_sport_var1 == 'NFL':
696
- freq_working['Salary'] = freq_working['Player'].map(maps_dict['Salary_map']) / 1.5
697
- elif sim_sport_var1 == 'NBA':
698
- freq_working['Salary'] = freq_working['Player'].map(maps_dict['Salary_map'])
699
- elif sim_site_var1 == 'Fanduel':
700
- freq_working['Salary'] = freq_working['Player'].map(maps_dict['Salary_map'])
701
- freq_working['Proj Own'] = freq_working['Player'].map(maps_dict['Own_map']) / 100
702
- freq_working['Exposure'] = freq_working['Freq']/(1000)
703
- freq_working['Edge'] = freq_working['Exposure'] - freq_working['Proj Own']
704
- freq_working['Team'] = freq_working['Player'].map(maps_dict['Team_map'])
705
- st.session_state.player_freq = freq_working.copy()
706
-
707
- if sim_site_var1 == 'Draftkings':
708
- cpt_working = pd.DataFrame(np.column_stack(np.unique(freq_copy.iloc[:,0:1].values, return_counts=True)),
709
- columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
710
- elif sim_site_var1 == 'Fanduel':
711
- cpt_working = pd.DataFrame(np.column_stack(np.unique(freq_copy.iloc[:,0:1].values, return_counts=True)),
712
- columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
713
- cpt_working['Freq'] = cpt_working['Freq'].astype(int)
714
- cpt_working['Position'] = cpt_working['Player'].map(maps_dict['Pos_map'])
715
- if sim_sport_var1 == 'NFL':
716
- cpt_working['Salary'] = cpt_working['Player'].map(maps_dict['Salary_map'])
717
- elif sim_sport_var1 == 'NBA':
718
- cpt_working['Salary'] = cpt_working['Player'].map(maps_dict['Salary_map']) * 1.5
719
- cpt_working['Proj Own'] = cpt_working['Player'].map(maps_dict['cpt_Own_map']) / 100
720
- cpt_working['Exposure'] = cpt_working['Freq']/(1000)
721
- cpt_working['Edge'] = cpt_working['Exposure'] - cpt_working['Proj Own']
722
- cpt_working['Team'] = cpt_working['Player'].map(maps_dict['Team_map'])
723
- st.session_state.sp_freq = cpt_working.copy()
724
-
725
- if sim_site_var1 == 'Draftkings':
726
- flex_working = pd.DataFrame(np.column_stack(np.unique(freq_copy.iloc[:,1:6].values, return_counts=True)),
727
- columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
728
- cpt_own_div = 600
729
- elif sim_site_var1 == 'Fanduel':
730
- flex_working = pd.DataFrame(np.column_stack(np.unique(freq_copy.iloc[:,1:5].values, return_counts=True)),
731
- columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
732
- cpt_own_div = 500
733
- flex_working['Freq'] = flex_working['Freq'].astype(int)
734
- flex_working['Position'] = flex_working['Player'].map(maps_dict['Pos_map'])
735
- if sim_site_var1 == 'Draftkings':
736
- if sim_sport_var1 == 'NFL':
737
- flex_working['Salary'] = flex_working['Player'].map(maps_dict['Salary_map']) / 1.5
738
- elif sim_sport_var1 == 'NBA':
739
- flex_working['Salary'] = flex_working['Player'].map(maps_dict['Salary_map'])
740
- elif sim_site_var1 == 'Fanduel':
741
- flex_working['Salary'] = flex_working['Player'].map(maps_dict['Salary_map'])
742
- flex_working['Proj Own'] = (flex_working['Player'].map(maps_dict['Own_map']) / 100) - (flex_working['Player'].map(maps_dict['cpt_Own_map']) / 100)
743
- flex_working['Exposure'] = flex_working['Freq']/(1000)
744
- flex_working['Edge'] = flex_working['Exposure'] - flex_working['Proj Own']
745
- flex_working['Team'] = flex_working['Player'].map(maps_dict['Team_map'])
746
- st.session_state.flex_freq = flex_working.copy()
747
-
748
- if sim_site_var1 == 'Draftkings':
749
- team_working = pd.DataFrame(np.column_stack(np.unique(freq_copy.iloc[:,8:9].values, return_counts=True)),
750
- columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
751
- elif sim_site_var1 == 'Fanduel':
752
- team_working = pd.DataFrame(np.column_stack(np.unique(freq_copy.iloc[:,7:8].values, return_counts=True)),
753
- columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
754
- team_working['Freq'] = team_working['Freq'].astype(int)
755
- team_working['Exposure'] = team_working['Freq']/(1000)
756
- st.session_state.team_freq = team_working.copy()
757
-
758
- with st.container():
759
- if st.button("Reset Sim", key='reset_sim'):
760
- for key in st.session_state.keys():
761
- del st.session_state[key]
762
- if 'player_freq' in st.session_state:
763
- player_split_var2 = st.radio("Are you wanting to isolate any lineups with specific players?", ('Full Players', 'Specific Players'), key='player_split_var2')
764
- if player_split_var2 == 'Specific Players':
765
- find_var2 = st.multiselect('Which players must be included in the lineups?', options = st.session_state.player_freq['Player'].unique())
766
- elif player_split_var2 == 'Full Players':
767
- find_var2 = st.session_state.player_freq.Player.values.tolist()
768
-
769
- if player_split_var2 == 'Specific Players':
770
- 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)]
771
- if player_split_var2 == 'Full Players':
772
- st.session_state.Sim_Winner_Display = st.session_state.Sim_Winner_Frame
773
- if 'Sim_Winner_Display' in st.session_state:
774
- st.dataframe(st.session_state.Sim_Winner_Display.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(precision=2), use_container_width = True)
775
- if 'Sim_Winner_Export' in st.session_state:
776
- st.download_button(
777
- label="Export Full Frame",
778
- data=st.session_state.Sim_Winner_Export.to_csv().encode('utf-8'),
779
- file_name='NFL_SD_consim_export.csv',
780
- mime='text/csv',
781
- )
782
-
783
- with st.container():
784
- tab1, tab2, tab3, tab4 = st.tabs(['Overall Exposures', 'CPT Exposures', 'FLEX Exposures', 'Team Exposures'])
785
- with tab1:
786
- if 'player_freq' in st.session_state:
787
-
788
- 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)
789
- st.download_button(
790
- label="Export Exposures",
791
- data=st.session_state.player_freq.to_csv().encode('utf-8'),
792
- file_name='player_freq_export.csv',
793
- mime='text/csv',
794
- key='overall'
795
- )
796
- with tab2:
797
- if 'sp_freq' in st.session_state:
798
-
799
- 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)
800
- st.download_button(
801
- label="Export Exposures",
802
- data=st.session_state.sp_freq.to_csv().encode('utf-8'),
803
- file_name='cpt_freq.csv',
804
- mime='text/csv',
805
- key='sp'
806
- )
807
- with tab3:
808
- if 'flex_freq' in st.session_state:
809
-
810
- 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)
811
- st.download_button(
812
- label="Export Exposures",
813
- data=st.session_state.flex_freq.to_csv().encode('utf-8'),
814
- file_name='flex_freq.csv',
815
- mime='text/csv',
816
- key='flex'
817
- )
818
- with tab4:
819
- if 'team_freq' in st.session_state:
820
-
821
- 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)
822
- st.download_button(
823
- label="Export Exposures",
824
- data=st.session_state.team_freq.to_csv().encode('utf-8'),
825
- file_name='team_freq.csv',
826
- mime='text/csv',
827
- key='team'
828
- )
 
281
  dk_raw, fd_raw = init_baselines('NBA')
282
 
283
  tab1, tab2 = st.tabs(['Contest Sims', 'Data Export'])
284
+
285
+ with tab1:
286
+ with st.expander("Info and Filters"):
287
+ if st.button("Load/Reset Data", key='reset2'):
288
+ st.cache_data.clear()
289
+ for key in st.session_state.keys():
290
+ del st.session_state[key]
291
+ dk_raw, fd_raw = init_baselines('NFL')
292
+ sim_sport_var1 = st.radio("What sport are you working with?", ('NBA', 'NFL'), key='sim_sport_var1')
293
+ dk_raw, fd_raw = init_baselines(sim_sport_var1)
294
+ sim_slate_var1 = st.radio("Which data are you loading?", ('Showdown', 'Secondary Showdown', 'Auxiliary Showdown'), key='sim_slate_var1')
295
+ sim_site_var1 = st.radio("What site are you working with?", ('Draftkings', 'Fanduel'), key='sim_site_var1')
296
+ if sim_site_var1 == 'Draftkings':
297
+ raw_baselines = dk_raw
298
+ column_names = dk_columns
299
+ elif sim_site_var1 == 'Fanduel':
300
+ raw_baselines = fd_raw
301
+ column_names = fd_columns
302
+ contest_var1 = st.selectbox("What contest size are you simulating?", ('Small', 'Medium', 'Large', 'Custom'))
303
+ if contest_var1 == 'Small':
304
+ Contest_Size = 1000
305
+ st.write("Small field size is 1,000 entrants.")
306
+ raw_baselines['Own'] = raw_baselines['Small_Field_Own']
307
+ raw_baselines['CPT_Own'] = raw_baselines['small_CPT_Own']
308
+ elif contest_var1 == 'Medium':
309
+ Contest_Size = 5000
310
+ st.write("Medium field size is 5,000 entrants.")
311
+ elif contest_var1 == 'Large':
312
+ Contest_Size = 10000
313
+ st.write("Large field size is 10,000 entrants.")
314
+ elif contest_var1 == 'Custom':
315
+ Contest_Size = st.number_input("Insert contest size", value=100, min_value=1, max_value=100000)
316
+ strength_var1 = st.selectbox("How sharp is the field in the contest?", ('Very', 'Above Average', 'Average', 'Below Average', 'Not Very'))
317
+ if strength_var1 == 'Not Very':
318
+ sharp_split = 500000
319
+ elif strength_var1 == 'Below Average':
320
+ sharp_split = 400000
321
+ elif strength_var1 == 'Average':
322
+ sharp_split = 300000
323
+ elif strength_var1 == 'Above Average':
324
+ sharp_split = 200000
325
+ elif strength_var1 == 'Very':
326
+ sharp_split = 100000
327
+
328
+ if st.button("Run Contest Sim"):
329
+ if 'working_seed' in st.session_state:
330
+ maps_dict = {
331
+ 'Projection_map':dict(zip(raw_baselines.Player,raw_baselines.Median)),
332
+ 'cpt_projection_map':dict(zip(raw_baselines.Player,raw_baselines.cpt_Median)),
333
+ 'Salary_map':dict(zip(raw_baselines.Player,raw_baselines.Salary)),
334
+ 'Pos_map':dict(zip(raw_baselines.Player,raw_baselines.Position)),
335
+ 'Own_map':dict(zip(raw_baselines.Player,raw_baselines['Own'])),
336
+ 'cpt_Own_map':dict(zip(raw_baselines.Player,raw_baselines['CPT_Own'])),
337
+ 'Team_map':dict(zip(raw_baselines.Player,raw_baselines.Team)),
338
+ 'STDev_map':dict(zip(raw_baselines.Player,raw_baselines.STDev)),
339
+ 'cpt_STDev_map':dict(zip(raw_baselines.Player,raw_baselines['CPT_STDev']))
340
+ }
341
+ Sim_Winners = sim_contest(1000, st.session_state.working_seed, maps_dict, Contest_Size)
342
+ Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners))
343
+
344
+ #st.table(Sim_Winner_Frame)
345
+
346
+ # Initial setup
347
+ Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners), columns=column_names + ['Fantasy'])
348
+ Sim_Winner_Frame['GPP_Proj'] = (Sim_Winner_Frame['proj'] + Sim_Winner_Frame['Fantasy']) / 2
349
+ 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)
350
+ Sim_Winner_Frame = Sim_Winner_Frame.assign(win_count=Sim_Winner_Frame['unique_id'].map(Sim_Winner_Frame['unique_id'].value_counts()))
351
+
352
+ # Type Casting
353
+ type_cast_dict = {'salary': int, 'proj': np.float16, 'Fantasy': np.float16, 'GPP_Proj': np.float32, 'Own': np.float32}
354
+ Sim_Winner_Frame = Sim_Winner_Frame.astype(type_cast_dict)
355
+
356
+ # Sorting
357
+ 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)
358
+ st.session_state.Sim_Winner_Frame.drop(columns='unique_id', inplace=True)
359
+
360
+ # Data Copying
361
+ st.session_state.Sim_Winner_Export = Sim_Winner_Frame.copy()
362
+
363
+ # Data Copying
364
+ st.session_state.Sim_Winner_Display = Sim_Winner_Frame.copy()
365
+
366
+ else:
367
+ if sim_site_var1 == 'Draftkings':
368
+ if sim_slate_var1 == 'Showdown':
369
+ st.session_state.working_seed = init_DK_seed_frames(sim_sport_var1, sharp_split_var)
370
+ if sport_var1 == 'NFL':
371
+ export_id_dict = dict(zip(dk_raw['Player'], dk_raw['player_id']))
372
+ elif sport_var1 == 'NBA':
373
+ export_id_dict = dict(zip(dk_raw['Player'], dk_raw['player_id']))
374
+ elif sim_slate_var1 == 'Secondary Showdown':
375
+ st.session_state.working_seed = init_DK_secondary_seed_frames(sim_sport_var1, sharp_split_var)
376
+ if sport_var1 == 'NFL':
377
+ export_id_dict = dict(zip(dk_raw['Player'], dk_raw['player_id']))
378
+ elif sport_var1 == 'NBA':
379
+ export_id_dict = dict(zip(dk_raw['Player'], dk_raw['player_id']))
380
+ elif sim_slate_var1 == 'Auxiliary Showdown':
381
+ st.session_state.working_seed = init_DK_auxiliary_seed_frames(sim_sport_var1, sharp_split_var)
382
+ if sport_var1 == 'NFL':
383
+ export_id_dict = dict(zip(dk_raw['Player'], dk_raw['player_id']))
384
+ elif sport_var1 == 'NBA':
385
+ export_id_dict = dict(zip(dk_raw['Player'], dk_raw['player_id']))
386
+ raw_baselines = dk_raw
387
+ column_names = dk_columns
388
+ elif sim_site_var1 == 'Fanduel':
389
+ if sim_slate_var1 == 'Showdown':
390
+ st.session_state.working_seed = init_FD_seed_frames(sim_sport_var1, sharp_split_var)
391
+ if sport_var1 == 'NFL':
392
+ export_id_dict = dict(zip(fd_raw['Player'], fd_raw['player_id']))
393
+ elif sport_var1 == 'NBA':
394
+ export_id_dict = dict(zip(fd_raw['Player'], fd_raw['player_id']))
395
+ elif sim_slate_var1 == 'Secondary Showdown':
396
+ st.session_state.working_seed = init_FD_secondary_seed_frames(sim_sport_var1, sharp_split_var)
397
+ if sport_var1 == 'NFL':
398
+ export_id_dict = dict(zip(fd_raw['Player'], fd_raw['player_id']))
399
+ elif sport_var1 == 'NBA':
400
+ export_id_dict = dict(zip(fd_raw['Player'], fd_raw['player_id']))
401
+ elif sim_slate_var1 == 'Auxiliary Showdown':
402
+ st.session_state.working_seed = init_FD_auxiliary_seed_frames(sim_sport_var1, sharp_split_var)
403
+ if sport_var1 == 'NFL':
404
+ export_id_dict = dict(zip(fd_raw['Player'], fd_raw['player_id']))
405
+ elif sport_var1 == 'NBA':
406
+ export_id_dict = dict(zip(fd_raw['Player'], fd_raw['player_id']))
407
+ raw_baselines = fd_raw
408
+ column_names = fd_columns
409
+ maps_dict = {
410
+ 'Projection_map':dict(zip(raw_baselines.Player,raw_baselines.Median)),
411
+ 'cpt_projection_map':dict(zip(raw_baselines.Player,raw_baselines.cpt_Median)),
412
+ 'Salary_map':dict(zip(raw_baselines.Player,raw_baselines.Salary)),
413
+ 'Pos_map':dict(zip(raw_baselines.Player,raw_baselines.Position)),
414
+ 'Own_map':dict(zip(raw_baselines.Player,raw_baselines['Own'])),
415
+ 'cpt_Own_map':dict(zip(raw_baselines.Player,raw_baselines['CPT_Own'])),
416
+ 'Team_map':dict(zip(raw_baselines.Player,raw_baselines.Team)),
417
+ 'STDev_map':dict(zip(raw_baselines.Player,raw_baselines.STDev)),
418
+ 'cpt_STDev_map':dict(zip(raw_baselines.Player,raw_baselines['CPT_STDev']))
419
+ }
420
+ Sim_Winners = sim_contest(1000, st.session_state.working_seed, maps_dict, Contest_Size)
421
+ Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners))
422
+
423
+ #st.table(Sim_Winner_Frame)
424
+
425
+ # Initial setup
426
+ Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners), columns=column_names + ['Fantasy'])
427
+ Sim_Winner_Frame['GPP_Proj'] = (Sim_Winner_Frame['proj'] + Sim_Winner_Frame['Fantasy']) / 2
428
+ 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)
429
+ # Add percent rank columns for ownership at each roster position
430
+ # Calculate Dupes column for Fanduel
431
+ if sim_site_var1 == 'Fanduel':
432
+ dup_count_columns = ['CPT_Own_percent_rank', 'FLEX1_Own_percent_rank', 'FLEX2_Own_percent_rank', 'FLEX3_Own_percent_rank', 'FLEX4_Own_percent_rank']
433
+ own_columns = ['CPT_Own', 'FLEX1_Own', 'FLEX2_Own', 'FLEX3_Own', 'FLEX4_Own']
434
+ calc_columns = ['own_product', 'avg_own_rank', 'dupes_calc']
435
+ Sim_Winner_Frame['CPT_Own_percent_rank'] = Sim_Winner_Frame.iloc[:,0].map(maps_dict['cpt_Own_map']).rank(pct=True)
436
+ Sim_Winner_Frame['FLEX1_Own_percent_rank'] = Sim_Winner_Frame.iloc[:,1].map(maps_dict['Own_map']).rank(pct=True)
437
+ Sim_Winner_Frame['FLEX2_Own_percent_rank'] = Sim_Winner_Frame.iloc[:,2].map(maps_dict['Own_map']).rank(pct=True)
438
+ Sim_Winner_Frame['FLEX3_Own_percent_rank'] = Sim_Winner_Frame.iloc[:,3].map(maps_dict['Own_map']).rank(pct=True)
439
+ Sim_Winner_Frame['FLEX4_Own_percent_rank'] = Sim_Winner_Frame.iloc[:,4].map(maps_dict['Own_map']).rank(pct=True)
440
+ Sim_Winner_Frame['CPT_Own'] = Sim_Winner_Frame.iloc[:,0].map(maps_dict['cpt_Own_map']) / 100
441
+ Sim_Winner_Frame['FLEX1_Own'] = Sim_Winner_Frame.iloc[:,1].map(maps_dict['Own_map']) / 100
442
+ Sim_Winner_Frame['FLEX2_Own'] = Sim_Winner_Frame.iloc[:,2].map(maps_dict['Own_map']) / 100
443
+ Sim_Winner_Frame['FLEX3_Own'] = Sim_Winner_Frame.iloc[:,3].map(maps_dict['Own_map']) / 100
444
+ Sim_Winner_Frame['FLEX4_Own'] = Sim_Winner_Frame.iloc[:,4].map(maps_dict['Own_map']) / 100
445
+
446
+ # Calculate ownership product and convert to probability
447
+ Sim_Winner_Frame['own_product'] = (Sim_Winner_Frame[own_columns].product(axis=1)) + 0.0001
448
+
449
+ # Calculate average of ownership percent rank columns
450
+ Sim_Winner_Frame['avg_own_rank'] = Sim_Winner_Frame[dup_count_columns].mean(axis=1)
451
+
452
+ # Calculate dupes formula
453
+ Sim_Winner_Frame['dupes_calc'] = ((Sim_Winner_Frame['own_product'] * Sim_Winner_Frame['avg_own_rank']) * (Contest_Size * 1.5)) + ((Sim_Winner_Frame['salary'] - 59800) / 100)
454
+
455
+ # Round and handle negative values
456
+ Sim_Winner_Frame['Dupes'] = np.where(
457
+ np.round(Sim_Winner_Frame['dupes_calc'], 0) <= 0,
458
+ 0,
459
+ np.round(Sim_Winner_Frame['dupes_calc'], 0) - 1
460
+ )
461
+ Sim_Winner_Frame['Dupes'] = (Sim_Winner_Frame['Dupes'] * (500000 / sharp_split)) / 2
462
+ elif sim_site_var1 == 'Draftkings':
463
+ dup_count_columns = ['CPT_Own_percent_rank', 'FLEX1_Own_percent_rank', 'FLEX2_Own_percent_rank', 'FLEX3_Own_percent_rank', 'FLEX4_Own_percent_rank', 'FLEX5_Own_percent_rank']
464
+ own_columns = ['CPT_Own', 'FLEX1_Own', 'FLEX2_Own', 'FLEX3_Own', 'FLEX4_Own', 'FLEX5_Own']
465
+ calc_columns = ['own_product', 'avg_own_rank', 'dupes_calc']
466
+ Sim_Winner_Frame['CPT_Own_percent_rank'] = Sim_Winner_Frame.iloc[:,0].map(maps_dict['cpt_Own_map']).rank(pct=True)
467
+ Sim_Winner_Frame['FLEX1_Own_percent_rank'] = Sim_Winner_Frame.iloc[:,1].map(maps_dict['Own_map']).rank(pct=True)
468
+ Sim_Winner_Frame['FLEX2_Own_percent_rank'] = Sim_Winner_Frame.iloc[:,2].map(maps_dict['Own_map']).rank(pct=True)
469
+ Sim_Winner_Frame['FLEX3_Own_percent_rank'] = Sim_Winner_Frame.iloc[:,3].map(maps_dict['Own_map']).rank(pct=True)
470
+ Sim_Winner_Frame['FLEX4_Own_percent_rank'] = Sim_Winner_Frame.iloc[:,4].map(maps_dict['Own_map']).rank(pct=True)
471
+ Sim_Winner_Frame['FLEX5_Own_percent_rank'] = Sim_Winner_Frame.iloc[:,5].map(maps_dict['Own_map']).rank(pct=True)
472
+ Sim_Winner_Frame['CPT_Own'] = Sim_Winner_Frame.iloc[:,0].map(maps_dict['cpt_Own_map']) / 100
473
+ Sim_Winner_Frame['FLEX1_Own'] = Sim_Winner_Frame.iloc[:,1].map(maps_dict['Own_map']) / 100
474
+ Sim_Winner_Frame['FLEX2_Own'] = Sim_Winner_Frame.iloc[:,2].map(maps_dict['Own_map']) / 100
475
+ Sim_Winner_Frame['FLEX3_Own'] = Sim_Winner_Frame.iloc[:,3].map(maps_dict['Own_map']) / 100
476
+ Sim_Winner_Frame['FLEX4_Own'] = Sim_Winner_Frame.iloc[:,4].map(maps_dict['Own_map']) / 100
477
+ Sim_Winner_Frame['FLEX5_Own'] = Sim_Winner_Frame.iloc[:,5].map(maps_dict['Own_map']) / 100
478
+
479
+ # Calculate ownership product and convert to probability
480
+ Sim_Winner_Frame['own_product'] = (Sim_Winner_Frame[own_columns].product(axis=1))
481
+
482
+ # Calculate average of ownership percent rank columns
483
+ Sim_Winner_Frame['avg_own_rank'] = Sim_Winner_Frame[dup_count_columns].mean(axis=1)
484
+
485
+ # Calculate dupes formula
486
+ Sim_Winner_Frame['dupes_calc'] = ((Sim_Winner_Frame['own_product'] * Sim_Winner_Frame['avg_own_rank']) * (Contest_Size * 1.5)) + ((Sim_Winner_Frame['salary'] - 49800) / 100)
487
+
488
+ # Round and handle negative values
489
+ Sim_Winner_Frame['Dupes'] = np.where(
490
+ np.round(Sim_Winner_Frame['dupes_calc'], 0) <= 0,
491
+ 0,
492
+ np.round(Sim_Winner_Frame['dupes_calc'], 0) - 1
493
+ )
494
+ Sim_Winner_Frame['Dupes'] = (Sim_Winner_Frame['Dupes'] * (500000 / sharp_split)) / 2
495
+ Sim_Winner_Frame['Dupes'] = np.round(Sim_Winner_Frame['Dupes'], 0)
496
+ Sim_Winner_Frame['Dupes'] = np.where(
497
+ np.round(Sim_Winner_Frame['dupes_calc'], 0) <= 0,
498
+ 0,
499
+ np.round(Sim_Winner_Frame['dupes_calc'], 0)
500
+ )
501
+ Sim_Winner_Frame = Sim_Winner_Frame.drop(columns=dup_count_columns)
502
+ Sim_Winner_Frame = Sim_Winner_Frame.drop(columns=own_columns)
503
+ Sim_Winner_Frame = Sim_Winner_Frame.drop(columns=calc_columns)
504
+
505
+ Sim_Winner_Frame = Sim_Winner_Frame.assign(win_count=Sim_Winner_Frame['unique_id'].map(Sim_Winner_Frame['unique_id'].value_counts()))
506
+
507
+ # Type Casting
508
+ type_cast_dict = {'salary': int, 'proj': np.float16, 'Fantasy': np.float16, 'GPP_Proj': np.float32, 'Own': np.float32, 'Dupes': int}
509
+ Sim_Winner_Frame = Sim_Winner_Frame.astype(type_cast_dict)
510
+
511
+ # Sorting
512
+ 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)
513
+ st.session_state.Sim_Winner_Frame.drop(columns='unique_id', inplace=True)
514
+
515
+ # Data Copying
516
+ st.session_state.Sim_Winner_Export = Sim_Winner_Frame.copy()
517
+ 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))
518
+
519
+ # Data Copying
520
+ st.session_state.Sim_Winner_Display = Sim_Winner_Frame.copy()
521
+ freq_copy = st.session_state.Sim_Winner_Display
522
+
523
+ if sim_site_var1 == 'Draftkings':
524
+ freq_working = pd.DataFrame(np.column_stack(np.unique(freq_copy.iloc[:,0:6].values, return_counts=True)),
525
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
526
+ elif sim_site_var1 == 'Fanduel':
527
+ freq_working = pd.DataFrame(np.column_stack(np.unique(freq_copy.iloc[:,0:5].values, return_counts=True)),
528
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
529
+ freq_working['Freq'] = freq_working['Freq'].astype(int)
530
+ freq_working['Position'] = freq_working['Player'].map(maps_dict['Pos_map'])
531
+ if sim_site_var1 == 'Draftkings':
532
+ if sim_sport_var1 == 'NFL':
533
+ freq_working['Salary'] = freq_working['Player'].map(maps_dict['Salary_map']) / 1.5
534
+ elif sim_sport_var1 == 'NBA':
535
+ freq_working['Salary'] = freq_working['Player'].map(maps_dict['Salary_map'])
536
+ elif sim_site_var1 == 'Fanduel':
537
+ freq_working['Salary'] = freq_working['Player'].map(maps_dict['Salary_map'])
538
+ freq_working['Proj Own'] = freq_working['Player'].map(maps_dict['Own_map']) / 100
539
+ freq_working['Exposure'] = freq_working['Freq']/(1000)
540
+ freq_working['Edge'] = freq_working['Exposure'] - freq_working['Proj Own']
541
+ freq_working['Team'] = freq_working['Player'].map(maps_dict['Team_map'])
542
+ st.session_state.player_freq = freq_working.copy()
543
+
544
+ if sim_site_var1 == 'Draftkings':
545
+ cpt_working = pd.DataFrame(np.column_stack(np.unique(freq_copy.iloc[:,0:1].values, return_counts=True)),
546
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
547
+ elif sim_site_var1 == 'Fanduel':
548
+ cpt_working = pd.DataFrame(np.column_stack(np.unique(freq_copy.iloc[:,0:1].values, return_counts=True)),
549
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
550
+ cpt_working['Freq'] = cpt_working['Freq'].astype(int)
551
+ cpt_working['Position'] = cpt_working['Player'].map(maps_dict['Pos_map'])
552
+ if sim_sport_var1 == 'NFL':
553
+ cpt_working['Salary'] = cpt_working['Player'].map(maps_dict['Salary_map'])
554
+ elif sim_sport_var1 == 'NBA':
555
+ cpt_working['Salary'] = cpt_working['Player'].map(maps_dict['Salary_map']) * 1.5
556
+ cpt_working['Proj Own'] = cpt_working['Player'].map(maps_dict['cpt_Own_map']) / 100
557
+ cpt_working['Exposure'] = cpt_working['Freq']/(1000)
558
+ cpt_working['Edge'] = cpt_working['Exposure'] - cpt_working['Proj Own']
559
+ cpt_working['Team'] = cpt_working['Player'].map(maps_dict['Team_map'])
560
+ st.session_state.sp_freq = cpt_working.copy()
561
+
562
+ if sim_site_var1 == 'Draftkings':
563
+ flex_working = pd.DataFrame(np.column_stack(np.unique(freq_copy.iloc[:,1:6].values, return_counts=True)),
564
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
565
+ cpt_own_div = 600
566
+ elif sim_site_var1 == 'Fanduel':
567
+ flex_working = pd.DataFrame(np.column_stack(np.unique(freq_copy.iloc[:,1:5].values, return_counts=True)),
568
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
569
+ cpt_own_div = 500
570
+ flex_working['Freq'] = flex_working['Freq'].astype(int)
571
+ flex_working['Position'] = flex_working['Player'].map(maps_dict['Pos_map'])
572
+ if sim_site_var1 == 'Draftkings':
573
+ if sim_sport_var1 == 'NFL':
574
+ flex_working['Salary'] = flex_working['Player'].map(maps_dict['Salary_map']) / 1.5
575
+ elif sim_sport_var1 == 'NBA':
576
+ flex_working['Salary'] = flex_working['Player'].map(maps_dict['Salary_map'])
577
+ elif sim_site_var1 == 'Fanduel':
578
+ flex_working['Salary'] = flex_working['Player'].map(maps_dict['Salary_map'])
579
+ flex_working['Proj Own'] = (flex_working['Player'].map(maps_dict['Own_map']) / 100) - (flex_working['Player'].map(maps_dict['cpt_Own_map']) / 100)
580
+ flex_working['Exposure'] = flex_working['Freq']/(1000)
581
+ flex_working['Edge'] = flex_working['Exposure'] - flex_working['Proj Own']
582
+ flex_working['Team'] = flex_working['Player'].map(maps_dict['Team_map'])
583
+ st.session_state.flex_freq = flex_working.copy()
584
+
585
+ if sim_site_var1 == 'Draftkings':
586
+ team_working = pd.DataFrame(np.column_stack(np.unique(freq_copy.iloc[:,8:9].values, return_counts=True)),
587
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
588
+ elif sim_site_var1 == 'Fanduel':
589
+ team_working = pd.DataFrame(np.column_stack(np.unique(freq_copy.iloc[:,7:8].values, return_counts=True)),
590
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
591
+ team_working['Freq'] = team_working['Freq'].astype(int)
592
+ team_working['Exposure'] = team_working['Freq']/(1000)
593
+ st.session_state.team_freq = team_working.copy()
594
+
595
+ with st.container():
596
+ if st.button("Reset Sim", key='reset_sim'):
597
+ for key in st.session_state.keys():
598
+ del st.session_state[key]
599
+ if 'player_freq' in st.session_state:
600
+ player_split_var2 = st.radio("Are you wanting to isolate any lineups with specific players?", ('Full Players', 'Specific Players'), key='player_split_var2')
601
+ if player_split_var2 == 'Specific Players':
602
+ find_var2 = st.multiselect('Which players must be included in the lineups?', options = st.session_state.player_freq['Player'].unique())
603
+ elif player_split_var2 == 'Full Players':
604
+ find_var2 = st.session_state.player_freq.Player.values.tolist()
605
+
606
+ if player_split_var2 == 'Specific Players':
607
+ 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)]
608
+ if player_split_var2 == 'Full Players':
609
+ st.session_state.Sim_Winner_Display = st.session_state.Sim_Winner_Frame
610
+ if 'Sim_Winner_Display' in st.session_state:
611
+ st.dataframe(st.session_state.Sim_Winner_Display.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(precision=2), use_container_width = True)
612
+ if 'Sim_Winner_Export' in st.session_state:
613
+ st.download_button(
614
+ label="Export Full Frame",
615
+ data=st.session_state.Sim_Winner_Export.to_csv().encode('utf-8'),
616
+ file_name='NFL_SD_consim_export.csv',
617
+ mime='text/csv',
618
+ )
619
+
620
+ with st.container():
621
+ tab1, tab2, tab3, tab4 = st.tabs(['Overall Exposures', 'CPT Exposures', 'FLEX Exposures', 'Team Exposures'])
622
+ with tab1:
623
+ if 'player_freq' in st.session_state:
624
+
625
+ 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)
626
+ st.download_button(
627
+ label="Export Exposures",
628
+ data=st.session_state.player_freq.to_csv().encode('utf-8'),
629
+ file_name='player_freq_export.csv',
630
+ mime='text/csv',
631
+ key='overall'
632
+ )
633
+ with tab2:
634
+ if 'sp_freq' in st.session_state:
635
+
636
+ 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)
637
+ st.download_button(
638
+ label="Export Exposures",
639
+ data=st.session_state.sp_freq.to_csv().encode('utf-8'),
640
+ file_name='cpt_freq.csv',
641
+ mime='text/csv',
642
+ key='sp'
643
+ )
644
+ with tab3:
645
+ if 'flex_freq' in st.session_state:
646
+
647
+ 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)
648
+ st.download_button(
649
+ label="Export Exposures",
650
+ data=st.session_state.flex_freq.to_csv().encode('utf-8'),
651
+ file_name='flex_freq.csv',
652
+ mime='text/csv',
653
+ key='flex'
654
+ )
655
+ with tab4:
656
+ if 'team_freq' in st.session_state:
657
+
658
+ 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)
659
+ st.download_button(
660
+ label="Export Exposures",
661
+ data=st.session_state.team_freq.to_csv().encode('utf-8'),
662
+ file_name='team_freq.csv',
663
+ mime='text/csv',
664
+ key='team'
665
+ )
666
+
667
  with tab2:
668
  with st.expander("Info and Filters"):
669
  if st.button("Load/Reset Data", key='reset1'):
 
823
 
824
  with st.container():
825
  if 'data_export_display' in st.session_state:
826
+ st.dataframe(st.session_state.data_export_display.style.format(freq_format, precision=2), use_container_width = True)