anaucoin commited on
Commit
769eef4
·
1 Parent(s): 7a98ad5

theme updates and chart constant

Browse files
Files changed (1) hide show
  1. app.py +117 -120
app.py CHANGED
@@ -435,73 +435,70 @@ def runapp() -> None:
435
  c = st.columns(9)
436
  with c[4]:
437
  submitted = st.form_submit_button("Get Cookin'!")
438
-
439
  if submitted and principal_balance * lev > dollar_cap:
440
  lev = np.floor(dollar_cap/principal_balance)
441
  st.error(f"WARNING: (Starting Balance)*(Leverage) exceeds the ${dollar_cap} limit. Using maximum available leverage of {lev}")
442
 
443
- if submitted and no_errors:
444
- df = df[(df[dateheader] >= startdate) & (df[dateheader] <= enddate)]
445
- signal_map = {'Long': 1, 'Short':-1}
446
-
447
-
448
- if len(df) == 0:
449
- st.error("There are no available trades matching your selections. Please try again!")
450
- no_errors = False
451
-
452
- if no_errors:
453
- if bot_selections == "Cinnamon Toast":
454
- dca_map = {1: dca1/100, 2: dca2/100, 3: dca3/100, 4: dca4/100, 1.1: dca5/100, 2.1: dca6/100}
455
- df['DCA %'] = df['DCA'].map(dca_map)
456
- df['Calculated Return %'] = df['Signal'].map(signal_map)*(df['DCA %'])*(1-fees)*((df['Sell Price']-df['Buy Price'])/df['Buy Price'] - fees) #accounts for fees on open and close of trade
457
- df['DCA'] = np.floor(df['DCA'].values)
458
-
459
- df['Return Per Trade'] = np.nan
460
- df['Balance used in Trade'] = np.nan
461
- df['New Balance'] = np.nan
462
-
463
- g = df.groupby('Exit Date').sum(numeric_only=True)['Calculated Return %'].reset_index(name='Return Per Trade')
464
- df.loc[df['DCA']==1.0,'Return Per Trade'] = 1+lev*g['Return Per Trade'].values
465
-
466
- df['Compounded Return'] = df['Return Per Trade'].cumprod()
467
- df.loc[df['DCA']==1.0,'New Balance'] = [min(dollar_cap/lev, bal*principal_balance) for bal in df.loc[df['DCA']==1.0,'Compounded Return']]
468
- df.loc[df['DCA']==1.0,'Balance used in Trade'] = np.concatenate([[principal_balance], df.loc[df['DCA']==1.0,'New Balance'].values[:-1]])
469
- else:
470
- df['Calculated Return %'] = df['Signal'].map(signal_map)*(1-fees)*((df['Sell Price']-df['Buy Price'])/df['Buy Price'] - fees) #accounts for fees on open and close of trade
471
- df['Return Per Trade'] = np.nan
472
- g = df.groupby('Exit Date').sum(numeric_only=True)['Calculated Return %'].reset_index(name='Return Per Trade')
473
- df['Return Per Trade'] = 1+lev*g['Return Per Trade'].values
474
-
475
- df['Compounded Return'] = df['Return Per Trade'].cumprod()
476
- df['New Balance'] = [min(dollar_cap/lev, bal*principal_balance) for bal in df['Compounded Return']]
477
- df['Balance used in Trade'] = np.concatenate([[principal_balance], df['New Balance'].values[:-1]])
478
- df['Net P/L Per Trade'] = (df['Return Per Trade']-1)*df['Balance used in Trade']
479
- df['Cumulative P/L'] = df['Net P/L Per Trade'].cumsum()
480
-
481
- if bot_selections == "Cinnamon Toast" or bot_selections == "Cosmic Cupcake":
482
- cum_pl = df.loc[df.drop('Drawdown %', axis=1).dropna().index[-1],'Cumulative P/L'] + principal_balance
483
- #cum_sdp = sd_df.loc[sd_df.drop('Drawdown %', axis=1).dropna().index[-1],'Cumulative P/L (+)'] + principal_balance
484
- #cum_sdm = sd_df.loc[sd_df.drop('Drawdown %', axis=1).dropna().index[-1],'Cumulative P/L (-)'] + principal_balance
485
- else:
486
- cum_pl = df.loc[df.dropna().index[-1],'Cumulative P/L'] + principal_balance
487
- #cum_sdp = sd_df.loc[sd_df.dropna().index[-1],'Cumulative P/L (+)'] + principal_balance
488
- #cum_sdm = sd_df.loc[sd_df.dropna().index[-1],'Cumulative P/L (-)'] + principal_balance
489
- #sd = 2*.00026
490
- #sd_df = get_sd_df(get_sd_df(df.copy(), sd, bot_selections, dca1, dca2, dca3, dca4, dca5, dca6, fees, lev, dollar_cap, principal_balance)
491
-
492
- effective_return = 100*((cum_pl - principal_balance)/principal_balance)
493
 
494
- st.header(f"{bot_selections} Results")
495
- with st.container():
496
-
497
- if len(bot_selections) > 1:
498
- col1, col2 = st.columns(2)
499
- with col1:
500
- st.metric(
501
- "Total Account Balance",
502
- f"${cum_pl:.2f}",
503
- f"{100*(cum_pl-principal_balance)/(principal_balance):.2f} %",
504
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
505
 
506
  # with col2:
507
  # st.write("95% of trades should fall within this 2 std. dev. range.")
@@ -515,67 +512,70 @@ def runapp() -> None:
515
  # f"" ,#${cum_sdm:.2f}"
516
  # f"{100*(cum_sdm-principal_balance)/(principal_balance):.2f} %",
517
  # )
518
- if bot_selections == "Cinnamon Toast" or bot_selections == "Cosmic Cupcake":
519
- #st.line_chart(data=df.drop('Drawdown %', axis=1).dropna(), x='Exit Date', y='Cumulative P/L', use_container_width=True)
520
- dfdata = df.drop('Drawdown %', axis=1).dropna()
521
- #sd_df = sd_df.drop('Drawdown %', axis=1).dropna()
522
- else:
523
- #st.line_chart(data=df.dropna(), x='Exit Date', y='Cumulative P/L', use_container_width=True)
524
- dfdata = df.dropna()
525
- #sd_df = sd_df.dropna()
526
-
527
- # Create figure
528
- fig = go.Figure()
529
-
530
- pyLogo = Image.open("logo.png")
531
-
532
  # fig.add_traces(go.Scatter(x=sd_df['Exit Date'], y = sd_df['Cumulative P/L (+)'],line_shape='spline',
533
  # line = dict(smoothing = 1.3, color='rgba(31, 119, 200,0)'), showlegend = False)
534
  # )
535
-
536
  # fig.add_traces(go.Scatter(x=sd_df['Exit Date'], y = sd_df['Cumulative P/L (-)'],
537
  # line = dict(smoothing = 1.3, color='rgba(31, 119, 200,0)'), line_shape='spline',
538
  # fill='tonexty',
539
  # fillcolor = 'rgba(31, 119, 200,.2)', name = '+/- Standard Deviation')
540
  # )
541
 
542
- # Add trace
543
- fig.add_trace(
544
- go.Scatter(x=dfdata['Exit Date'], y=np.round(dfdata['Cumulative P/L'].values,2), line_shape='spline',
545
- line = {'smoothing': 1.0, 'color' : 'rgba(31, 119, 200,.8)'},
546
- name='Cumulative P/L')
547
- )
548
- buyhold = (principal_balance/dfdata['Buy Price'][dfdata.index[0]])*(dfdata['Buy Price']-dfdata['Buy Price'][dfdata.index[0]])
549
- fig.add_trace(go.Scatter(x=dfdata['Exit Date'], y=np.round(buyhold.values,2), line_shape='spline',
550
- line = {'smoothing': 1.0, 'color' :'red'}, name = 'Buy & Hold Return')
551
- )
552
-
553
- fig.add_layout_image(
554
- dict(
555
- source=pyLogo,
556
- xref="paper",
557
- yref="paper",
558
- x = 0.05, #dfdata['Exit Date'].astype('int64').min() // 10**9,
559
- y = .85, #dfdata['Cumulative P/L'].max(),
560
- sizex= .9, #(dfdata['Exit Date'].astype('int64').max() - dfdata['Exit Date'].astype('int64').min()) // 10**9,
561
- sizey= .9, #(dfdata['Cumulative P/L'].max() - dfdata['Cumulative P/L'].min()),
562
- sizing="contain",
563
- opacity=0.2,
564
- layer = "below")
565
- )
566
-
567
- #style layout
568
- fig.update_layout(
569
- height = 600,
570
- xaxis=dict(
571
- title="Exit Date",
572
- tickmode='array',
573
- ),
574
- yaxis=dict(
575
- title="Cumulative P/L"
576
- ) )
577
-
578
- st.plotly_chart(fig, theme=None, use_container_width=True,height=600)
 
 
 
579
  st.write()
580
  df['Per Trade Return Rate'] = df['Return Per Trade']-1
581
 
@@ -588,7 +588,7 @@ def runapp() -> None:
588
 
589
  totals['Cum. P/L'] = cum_pl-principal_balance
590
  totals['Cum. P/L (%)'] = 100*(cum_pl-principal_balance)/principal_balance
591
-
592
  if df.empty:
593
  st.error("Oops! None of the data provided matches your selection(s). Please try again.")
594
  else:
@@ -650,7 +650,7 @@ def runapp() -> None:
650
  "",#f"{(1+get_rolling_stats(df,otimeheader, 30))*principal_balance:.2f}",
651
  f"{get_rolling_stats(df,lev, otimeheader, 180):.2f}%",
652
  )
653
-
654
  if bot_selections == "Cinnamon Toast":
655
  if submitted:
656
  grouped_df = df.groupby('Exit Date').agg({'Signal':'min','Entry Date': 'min','Exit Date': 'max','Buy Price': 'mean',
@@ -663,10 +663,7 @@ def runapp() -> None:
663
  'Net P/L Per Trade':'Net P/L',
664
  'Calculated Return %':'P/L %'}, inplace=True)
665
  else:
666
- dca_map = {1: 25/100, 2: 25/100, 3: 25/100, 4: 25/100, 1.1: 50/100, 2.1: 50/100}
667
- df['DCA %'] = df['DCA'].map(dca_map)
668
- df['Calculated Return %'] = (df['DCA %'])*(1-fees)*((df['Sell Price']-df['Buy Price'])/df['Buy Price'] - fees) #accounts for fees on open and close of trade
669
-
670
  grouped_df = df.groupby('Exit Date').agg({'Signal':'min','Entry Date': 'min','Exit Date': 'max','Buy Price': 'mean',
671
  'Sell Price' : 'max',
672
  'P/L per token': 'mean',
 
435
  c = st.columns(9)
436
  with c[4]:
437
  submitted = st.form_submit_button("Get Cookin'!")
438
+ signal_map = {'Long': 1, 'Short':-1}
439
  if submitted and principal_balance * lev > dollar_cap:
440
  lev = np.floor(dollar_cap/principal_balance)
441
  st.error(f"WARNING: (Starting Balance)*(Leverage) exceeds the ${dollar_cap} limit. Using maximum available leverage of {lev}")
442
 
443
+ df = df[(df[dateheader] >= startdate) & (df[dateheader] <= enddate)]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
444
 
445
+ if submitted and len(df) == 0:
446
+ st.error("There are no available trades matching your selections. Please try again!")
447
+ no_errors = False
448
+
449
+ if no_errors:
450
+ if bot_selections == "Cinnamon Toast":
451
+ dca_map = {1: dca1/100, 2: dca2/100, 3: dca3/100, 4: dca4/100, 1.1: dca5/100, 2.1: dca6/100}
452
+ df['DCA %'] = df['DCA'].map(dca_map)
453
+ df['Calculated Return %'] = df['Signal'].map(signal_map)*(df['DCA %'])*(1-fees)*((df['Sell Price']-df['Buy Price'])/df['Buy Price'] - fees) #accounts for fees on open and close of trade
454
+ df['DCA'] = np.floor(df['DCA'].values)
455
+
456
+ df['Return Per Trade'] = np.nan
457
+ df['Balance used in Trade'] = np.nan
458
+ df['New Balance'] = np.nan
459
+
460
+ g = df.groupby('Exit Date').sum(numeric_only=True)['Calculated Return %'].reset_index(name='Return Per Trade')
461
+ df.loc[df['DCA']==1.0,'Return Per Trade'] = 1+lev*g['Return Per Trade'].values
462
+
463
+ df['Compounded Return'] = df['Return Per Trade'].cumprod()
464
+ df.loc[df['DCA']==1.0,'New Balance'] = [min(dollar_cap/lev, bal*principal_balance) for bal in df.loc[df['DCA']==1.0,'Compounded Return']]
465
+ df.loc[df['DCA']==1.0,'Balance used in Trade'] = np.concatenate([[principal_balance], df.loc[df['DCA']==1.0,'New Balance'].values[:-1]])
466
+ else:
467
+ df['Calculated Return %'] = df['Signal'].map(signal_map)*(1-fees)*((df['Sell Price']-df['Buy Price'])/df['Buy Price'] - fees) #accounts for fees on open and close of trade
468
+ df['Return Per Trade'] = np.nan
469
+ g = df.groupby('Exit Date').sum(numeric_only=True)['Calculated Return %'].reset_index(name='Return Per Trade')
470
+ df['Return Per Trade'] = 1+lev*g['Return Per Trade'].values
471
+
472
+ df['Compounded Return'] = df['Return Per Trade'].cumprod()
473
+ df['New Balance'] = [min(dollar_cap/lev, bal*principal_balance) for bal in df['Compounded Return']]
474
+ df['Balance used in Trade'] = np.concatenate([[principal_balance], df['New Balance'].values[:-1]])
475
+ df['Net P/L Per Trade'] = (df['Return Per Trade']-1)*df['Balance used in Trade']
476
+ df['Cumulative P/L'] = df['Net P/L Per Trade'].cumsum()
477
+
478
+ if bot_selections == "Cinnamon Toast" or bot_selections == "Cosmic Cupcake":
479
+ cum_pl = df.loc[df.drop('Drawdown %', axis=1).dropna().index[-1],'Cumulative P/L'] + principal_balance
480
+ #cum_sdp = sd_df.loc[sd_df.drop('Drawdown %', axis=1).dropna().index[-1],'Cumulative P/L (+)'] + principal_balance
481
+ #cum_sdm = sd_df.loc[sd_df.drop('Drawdown %', axis=1).dropna().index[-1],'Cumulative P/L (-)'] + principal_balance
482
+ else:
483
+ cum_pl = df.loc[df.dropna().index[-1],'Cumulative P/L'] + principal_balance
484
+ #cum_sdp = sd_df.loc[sd_df.dropna().index[-1],'Cumulative P/L (+)'] + principal_balance
485
+ #cum_sdm = sd_df.loc[sd_df.dropna().index[-1],'Cumulative P/L (-)'] + principal_balance
486
+ #sd = 2*.00026
487
+ #sd_df = get_sd_df(get_sd_df(df.copy(), sd, bot_selections, dca1, dca2, dca3, dca4, dca5, dca6, fees, lev, dollar_cap, principal_balance)
488
+
489
+ effective_return = 100*((cum_pl - principal_balance)/principal_balance)
490
+
491
+ st.header(f"{bot_selections} Results")
492
+ with st.container():
493
+
494
+ if len(bot_selections) > 1:
495
+ col1, col2 = st.columns(2)
496
+ with col1:
497
+ st.metric(
498
+ "Total Account Balance",
499
+ f"${cum_pl:.2f}",
500
+ f"{100*(cum_pl-principal_balance)/(principal_balance):.2f} %",
501
+ )
502
 
503
  # with col2:
504
  # st.write("95% of trades should fall within this 2 std. dev. range.")
 
512
  # f"" ,#${cum_sdm:.2f}"
513
  # f"{100*(cum_sdm-principal_balance)/(principal_balance):.2f} %",
514
  # )
515
+ if bot_selections == "Cinnamon Toast" or bot_selections == "Cosmic Cupcake":
516
+ #st.line_chart(data=df.drop('Drawdown %', axis=1).dropna(), x='Exit Date', y='Cumulative P/L', use_container_width=True)
517
+ dfdata = df.drop('Drawdown %', axis=1).dropna()
518
+ #sd_df = sd_df.drop('Drawdown %', axis=1).dropna()
519
+ else:
520
+ #st.line_chart(data=df.dropna(), x='Exit Date', y='Cumulative P/L', use_container_width=True)
521
+ dfdata = df.dropna()
522
+ #sd_df = sd_df.dropna()
523
+
524
+ # Create figure
525
+ fig = go.Figure()
526
+
527
+ pyLogo = Image.open("logo.png")
528
+
529
  # fig.add_traces(go.Scatter(x=sd_df['Exit Date'], y = sd_df['Cumulative P/L (+)'],line_shape='spline',
530
  # line = dict(smoothing = 1.3, color='rgba(31, 119, 200,0)'), showlegend = False)
531
  # )
532
+
533
  # fig.add_traces(go.Scatter(x=sd_df['Exit Date'], y = sd_df['Cumulative P/L (-)'],
534
  # line = dict(smoothing = 1.3, color='rgba(31, 119, 200,0)'), line_shape='spline',
535
  # fill='tonexty',
536
  # fillcolor = 'rgba(31, 119, 200,.2)', name = '+/- Standard Deviation')
537
  # )
538
 
539
+ # Add trace
540
+ fig.add_trace(
541
+ go.Scatter(x=dfdata['Exit Date'], y=np.round(dfdata['Cumulative P/L'].values,2), line_shape='spline',
542
+ line = {'smoothing': 1.0, 'color' : 'rgba(90, 223, 137, 1)'},
543
+ name='Cumulative P/L')
544
+ )
545
+ buyhold = (principal_balance/dfdata['Buy Price'][dfdata.index[0]])*(dfdata['Buy Price']-dfdata['Buy Price'][dfdata.index[0]])
546
+ fig.add_trace(go.Scatter(x=dfdata['Exit Date'], y=np.round(buyhold.values,2), line_shape='spline',
547
+ line = {'smoothing': 1.0, 'color' :'rgba(33, 212, 225, 1)'}, name = 'Buy & Hold Return')
548
+ )
549
+
550
+ fig.add_layout_image(
551
+ dict(
552
+ source=pyLogo,
553
+ xref="paper",
554
+ yref="paper",
555
+ x = 0.05, #dfdata['Exit Date'].astype('int64').min() // 10**9,
556
+ y = .85, #dfdata['Cumulative P/L'].max(),
557
+ sizex= .9, #(dfdata['Exit Date'].astype('int64').max() - dfdata['Exit Date'].astype('int64').min()) // 10**9,
558
+ sizey= .9, #(dfdata['Cumulative P/L'].max() - dfdata['Cumulative P/L'].min()),
559
+ sizing="contain",
560
+ opacity=0.2,
561
+ layer = "below")
562
+ )
563
+
564
+ #style layout
565
+ fig.update_layout(
566
+ height = 600,
567
+ xaxis=dict(
568
+ title="Exit Date",
569
+ tickmode='array',
570
+ ),
571
+ yaxis=dict(
572
+ title="Cumulative P/L"
573
+ ),
574
+ plot_bgcolor = 'rgba(10, 10, 10, 1)'
575
+ )
576
+
577
+ st.plotly_chart(fig, theme=None, use_container_width=True,height=600)
578
+ if submitted:
579
  st.write()
580
  df['Per Trade Return Rate'] = df['Return Per Trade']-1
581
 
 
588
 
589
  totals['Cum. P/L'] = cum_pl-principal_balance
590
  totals['Cum. P/L (%)'] = 100*(cum_pl-principal_balance)/principal_balance
591
+
592
  if df.empty:
593
  st.error("Oops! None of the data provided matches your selection(s). Please try again.")
594
  else:
 
650
  "",#f"{(1+get_rolling_stats(df,otimeheader, 30))*principal_balance:.2f}",
651
  f"{get_rolling_stats(df,lev, otimeheader, 180):.2f}%",
652
  )
653
+
654
  if bot_selections == "Cinnamon Toast":
655
  if submitted:
656
  grouped_df = df.groupby('Exit Date').agg({'Signal':'min','Entry Date': 'min','Exit Date': 'max','Buy Price': 'mean',
 
663
  'Net P/L Per Trade':'Net P/L',
664
  'Calculated Return %':'P/L %'}, inplace=True)
665
  else:
666
+
 
 
 
667
  grouped_df = df.groupby('Exit Date').agg({'Signal':'min','Entry Date': 'min','Exit Date': 'max','Buy Price': 'mean',
668
  'Sell Price' : 'max',
669
  'P/L per token': 'mean',