Spaces:
Runtime error
Runtime error
Commit
•
e664a97
1
Parent(s):
7940af2
Upload 8 files
Browse files- app.py +117 -0
- json_loader.py +11 -0
- lambda_strategy_statistics.py +141 -0
- performance_old.py +213 -0
- requirements.txt +47 -0
- requirements2.txt +0 -0
- requirements_heroku.txt +96 -0
- returnsDf.py +38 -0
app.py
ADDED
@@ -0,0 +1,117 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import pandas as pd
|
2 |
+
from pandas import Timestamp
|
3 |
+
import numpy as np
|
4 |
+
import streamlit as st
|
5 |
+
import plotly.graph_objects as go
|
6 |
+
from plotly import tools
|
7 |
+
import plotly.offline as py
|
8 |
+
import plotly.express as px
|
9 |
+
import requests,json
|
10 |
+
from datetime import datetime, time,timedelta
|
11 |
+
import plotly.express as px
|
12 |
+
import warnings
|
13 |
+
import io
|
14 |
+
warnings.filterwarnings('ignore')
|
15 |
+
pd.options.display.float_format = '${:,.2f}'.format
|
16 |
+
one_day=timedelta(days=1)
|
17 |
+
st.set_page_config(page_title="SquareoffbotsPerformance",layout='wide')
|
18 |
+
st.markdown("""<style> div[role="listbox"] ul {
|
19 |
+
background-color: rgb(229, 236, 122);
|
20 |
+
}
|
21 |
+
div[role="listbox"],option{
|
22 |
+
float:right;
|
23 |
+
}
|
24 |
+
#MainMenu {display:none;}
|
25 |
+
footer {display:none !important}
|
26 |
+
|
27 |
+
|
28 |
+
</style>
|
29 |
+
|
30 |
+
"""
|
31 |
+
|
32 |
+
,unsafe_allow_html=True)
|
33 |
+
|
34 |
+
|
35 |
+
query_params = st.experimental_get_query_params()
|
36 |
+
#st.runtime.legacy_caching.clear_cache()
|
37 |
+
@st.cache(ttl=23*60*60)
|
38 |
+
def get_ret_dic():
|
39 |
+
streamlit_data_url=r'https://dailysymbols.s3.ap-south-1.amazonaws.com/streamlit_data_ppl.json'
|
40 |
+
ret_dic=requests.get(streamlit_data_url).json()
|
41 |
+
return ret_dic
|
42 |
+
# def get_ret_dic():
|
43 |
+
# from json_loader import json_load
|
44 |
+
# return json_load('streamlit_data_ppl.json')
|
45 |
+
# with open('streamlit_data_ppl.json','r') as fr:
|
46 |
+
# data=eval(fr.read().replace("'",'"')) comment
|
47 |
+
# return data
|
48 |
+
ret_dic=get_ret_dic()
|
49 |
+
|
50 |
+
# charges_dic=requests.get(charges_url).json()
|
51 |
+
botNameDic={"orb":"ORB","rsi":"RSI","it":"Intraday Trend","sh":"StopHunt","grb":"GRB","orb2pm":"ORB2pm","pcr":"NiftyOptionSelling","lapp":"Learnapp","bss":"BNF Straddle","nss":"Nifty Straddle","bos":"BNFOptionSelling","grbo":"GRB Options","bssr":"BNF Strangle","mlb":"ML Bot","bnfmon":"BNF ORB","mss":"1% Short Straddle (BNF)","mssn":"1% Short Straddle(NF)","dts":"Double Top","ats":"Auto Strangle","dbss":"BNF Straddle(Directional)"}
|
52 |
+
botCapitalDic={"orb":50000,"rsi":50000,"it":50000,"sh":50000,"grb":300000,"orb2pm":300000,"pcr":300000,"lapp":300000,"bss":300000,"nss":300000,"bos":300000,"grbo":150000,"bssr":300000,"bnfmon":150000,"mlb":400000,"mss":300000,"mssn":300000,"dts":150000,"ats":300000,"dbss":150000}
|
53 |
+
curBots=['orb','rsi','it','grb','bss','grbo','bssr','bnfmon','mlb','mss','mssn','ats','dbss']
|
54 |
+
botName = query_params["bot"][0] if "bot" in query_params else None
|
55 |
+
|
56 |
+
botsList=list(botNameDic.keys())
|
57 |
+
if botName not in botsList:
|
58 |
+
botName='bss'
|
59 |
+
botsList.remove('bss')
|
60 |
+
botsList=['bss']+botsList
|
61 |
+
if not botName:
|
62 |
+
botName = st.selectbox('Select a Strategy',tuple(botsList))
|
63 |
+
|
64 |
+
|
65 |
+
botCapital,capital_used_appendum,results_row,t_stats_Df,month_groups,strat_df,drawdown_df,i_fields,botFullName=ret_dic[botName]
|
66 |
+
# with open('strat_df.txt','w') as fw:
|
67 |
+
# fw.write(strat_df)
|
68 |
+
def df_from_string(str):
|
69 |
+
jstr=eval(str.replace('nan','0'))
|
70 |
+
df=pd.DataFrame.from_dict(jstr)
|
71 |
+
|
72 |
+
return df
|
73 |
+
|
74 |
+
t_stats_Df=df_from_string(t_stats_Df)
|
75 |
+
|
76 |
+
|
77 |
+
month_groups=df_from_string(month_groups)
|
78 |
+
strat_df=df_from_string(strat_df)
|
79 |
+
drawdown_df=df_from_string(drawdown_df)
|
80 |
+
results_row=results_row.replace('nan','0')
|
81 |
+
results_row=eval(results_row)
|
82 |
+
|
83 |
+
title_text="<h1 style='text-align: center; color: rgb(21, 86, 112);'>**♟**SQUAREOFF BOTS PERFORMANCE**♟**</h1><br><div style='text-align: center; color: rgb(21, 86, 112);'>**LIVE PERFORMANCE OF "+botFullName+"****[Capital used is "+str(botCapital)+capital_used_appendum+"]** </div>"
|
84 |
+
st.markdown(title_text, unsafe_allow_html=True)
|
85 |
+
|
86 |
+
fig=px.line(strat_df, x="Time", y='cum_pnl', title=botFullName+' PNL',width=800, height=400)
|
87 |
+
dd_fig=px.line(drawdown_df,x="Time",y="drawdown", title=botFullName+' PNL',width=800, height=400)
|
88 |
+
|
89 |
+
if botCapital>50000 and botName!='mlb':
|
90 |
+
# col1.write("**(Capital used before July 2021 is "+str(int(botCapital/1.5))+capital_used_appendum+")**")
|
91 |
+
st.markdown("<div style='text-align: center; color: rgb(21, 86, 112);'>**(Capital used before July 2021 is "+str(int(botCapital/1.5))+capital_used_appendum+")** </div>", unsafe_allow_html=True)
|
92 |
+
col1, col2 = st.columns(2)
|
93 |
+
col2.markdown('##')
|
94 |
+
|
95 |
+
col1.write("Net ROI : "+str(results_row[-1])+"%")
|
96 |
+
col1.write("**Statistics**")
|
97 |
+
col1.table(t_stats_Df)
|
98 |
+
|
99 |
+
|
100 |
+
|
101 |
+
col2.write("**PNL Curve**")
|
102 |
+
col2.plotly_chart(fig)
|
103 |
+
col2.write("**Drawdown Curve**")
|
104 |
+
col2.plotly_chart(dd_fig)
|
105 |
+
st.write("**Month-wise PNL**")
|
106 |
+
st.table(month_groups)
|
107 |
+
st.write("**Date-wise PNL (Last 30 Days)**")
|
108 |
+
st.table(strat_df[i_fields][:30])
|
109 |
+
|
110 |
+
# strat_df['Date']=strat_df.index
|
111 |
+
# strat_df['pd_date']=pd.to_datetime(strat_df['Date'],format='%Y-%m-%d')
|
112 |
+
# strat_df.sort_values('pd_date',inplace=True)
|
113 |
+
# strat_df.sort_index(key=lambda x:datetime.strptime(x,'%Y-%m-%d'),inplace=True)
|
114 |
+
# strat_df.drop('pd_date',axis=1,inplace=True)
|
115 |
+
# strat_df.to_csv(f"{botName}.csv")
|
116 |
+
|
117 |
+
|
json_loader.py
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import json
|
2 |
+
|
3 |
+
def json_dump(file_name,data):
|
4 |
+
with open(file_name,'w') as fw:
|
5 |
+
json.dump(data,fw)
|
6 |
+
fw.close()
|
7 |
+
def json_load(file_name):
|
8 |
+
with open(file_name,'r') as fr:
|
9 |
+
data=json.load(fr)
|
10 |
+
fr.close()
|
11 |
+
return data
|
lambda_strategy_statistics.py
ADDED
@@ -0,0 +1,141 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import pandas as pd
|
2 |
+
import requests,json
|
3 |
+
from datetime import datetime, time,timedelta
|
4 |
+
from json_loader import json_load
|
5 |
+
from returnsDf import agg_df
|
6 |
+
import warnings
|
7 |
+
warnings.filterwarnings('ignore')
|
8 |
+
pd.options.display.float_format = '${:,.2f}'.format
|
9 |
+
one_day=timedelta(days=1)
|
10 |
+
|
11 |
+
pnl_url=r'http://performance.squareoffbots.com/assets/json/sqbots_allData_21052021.json'
|
12 |
+
cap_url=r'http://performance.squareoffbots.com/assets/json/newCAp21052021.json'
|
13 |
+
charges_url=r'http://performance.squareoffbots.com/assets/json/charges.json'
|
14 |
+
|
15 |
+
def getResources1():
|
16 |
+
charges_dic=requests.get(charges_url).json()
|
17 |
+
pnl_data=requests.get(pnl_url).json()
|
18 |
+
cap_data=requests.get(cap_url).json()
|
19 |
+
pnl_df_t=pd.DataFrame.from_dict(pnl_data)
|
20 |
+
cap_df_t=pd.DataFrame.from_dict(cap_data)
|
21 |
+
pnl_df=pnl_df_t.T
|
22 |
+
cap_df=cap_df_t.T
|
23 |
+
return charges_dic,pnl_data,cap_data,pnl_df,cap_df,query_params
|
24 |
+
|
25 |
+
|
26 |
+
botNameDic={"orb":"ORB","rsi":"RSI","it":"Intraday Trend","sh":"StopHunt","grb":"GRB","orb2pm":"ORB2pm","pcr":"NiftyOptionSelling","lapp":"Learnapp","bss":"BNF Straddle","nss":"Nifty Straddle","bos":"BNFOptionSelling","grbo":"GRB Options","bssr":"BNF Strangle","mlb":"ML Bot","bnfmon":"BNF ORB","mss":"1% Short Straddle (BNF)","mssn":"1% Short Straddle(NF)","dts":"Double Top"}
|
27 |
+
botCapitalDic={"orb":50000,"rsi":50000,"it":50000,"sh":50000,"grb":300000,"orb2pm":300000,"pcr":300000,"lapp":300000,"bss":300000,"nss":300000,"bos":300000,"grbo":150000,"bssr":300000,"bnfmon":150000,"mlb":400000,"mss":300000,"mssn":300000,"dts":150000}
|
28 |
+
curBots=['orb','rsi','it','grb','bss','grbo','bssr','bnfmon','mlb','mss','mssn','dts']
|
29 |
+
|
30 |
+
|
31 |
+
|
32 |
+
def strategy_statistics():
|
33 |
+
charges_dic,pnl_data,cap_data,pnl_df,cap_df,query_params=getResources1()
|
34 |
+
ret_dic={}
|
35 |
+
for botName in curBots:
|
36 |
+
eq_bots=["orb","rsi","sh","it"]
|
37 |
+
botFullName=botNameDic[botName]
|
38 |
+
botCapital=botCapitalDic[botName]
|
39 |
+
|
40 |
+
|
41 |
+
|
42 |
+
strat_pnl_Df=pnl_df[[botFullName]]
|
43 |
+
strat_pnl_Df.dropna(inplace=True)
|
44 |
+
strat_cap_df=cap_df[[botFullName]]
|
45 |
+
#returns calculation
|
46 |
+
strat_df=agg_df(strat_pnl_Df,strat_cap_df)
|
47 |
+
##PNL plot
|
48 |
+
strat_df['pdTime']=pd.to_datetime(strat_df.index,format="%Y-%m-%d")
|
49 |
+
strat_df.sort_values('pdTime',inplace=True)
|
50 |
+
strat_df[botFullName+'_adj_PnL']=(botCapital/100)*strat_df[botFullName+' Returns'].astype(float)
|
51 |
+
strat_df[botFullName+'_gross_PnL']=strat_df[botFullName+'_adj_PnL']
|
52 |
+
charges_types=['Brokerage','TransactionCharges','ClearingCharges','STT','GST','SEBI','StampDuty','TotalCharges']
|
53 |
+
def getCharges(x):
|
54 |
+
notGotCharges=True
|
55 |
+
original_date=x
|
56 |
+
cDayObj=datetime.strptime(x,'%Y-%m-%d')
|
57 |
+
direction=-1
|
58 |
+
direction_counter=0
|
59 |
+
|
60 |
+
while notGotCharges:
|
61 |
+
try:
|
62 |
+
return charges_dic[cDayObj.strftime('%Y%m%d')][botName.upper()+'_'+ct]
|
63 |
+
|
64 |
+
except Exception as e:
|
65 |
+
direction_counter+=1
|
66 |
+
if direction_counter==10:
|
67 |
+
direction*=-1
|
68 |
+
|
69 |
+
|
70 |
+
cDayObj+=direction*one_day
|
71 |
+
continue
|
72 |
+
for ct in charges_types:
|
73 |
+
strat_df[ct]=strat_df.index.to_series().apply(lambda x:getCharges(x))
|
74 |
+
i_fields=['PNL','Brokerage','TransactionCharges','ClearingCharges','STT','GST','SEBI','StampDuty','TotalCharges','net_PNL']
|
75 |
+
|
76 |
+
|
77 |
+
|
78 |
+
##xxx
|
79 |
+
if botName in eq_bots:
|
80 |
+
i_fields=["PNL"]
|
81 |
+
strat_df['net_PNL']=strat_df[botFullName+'_gross_PnL']
|
82 |
+
else:
|
83 |
+
strat_df['net_PNL']=strat_df[botFullName+'_gross_PnL']-strat_df['TotalCharges']
|
84 |
+
|
85 |
+
strat_df['net_rets']=100*strat_df['net_PNL']/botCapital
|
86 |
+
strat_df["Time"]=strat_df.index
|
87 |
+
strat_df['PNL']=strat_df[botFullName+'_adj_PnL']
|
88 |
+
strat_df['cum_pnl']=strat_df[botFullName+'_adj_PnL'].cumsum()
|
89 |
+
##DRAWDOWN
|
90 |
+
drawdown_df=strat_df.copy()
|
91 |
+
drawdown_df.reset_index(drop=True,inplace=True)
|
92 |
+
drawdown_df['max_value_so_far']=drawdown_df['cum_pnl'].cummax()
|
93 |
+
drawdown_df['drawdown']=drawdown_df['cum_pnl']-drawdown_df['max_value_so_far']
|
94 |
+
max_drawdown=drawdown_df['drawdown'].min()
|
95 |
+
##Strategy statistics .
|
96 |
+
stats_Df=pd.DataFrame(columns=["Total Days","Winning Days","Losing Days","Winning Accuracy(%)","Max Profit","Max Loss","Max Drawdown","Average Profit on Win Days","Average Profit on loss days","Average Profit Per day","Gross Profit","Charges","Net profit","Returns (%)","net Returns (%)"])
|
97 |
+
total_days=len(strat_df)
|
98 |
+
win_df=strat_df[strat_df[botFullName+'_adj_PnL'].astype('float')>0]
|
99 |
+
lose_df=strat_df[strat_df[botFullName+'_adj_PnL'].astype('float')<0]
|
100 |
+
noTrade_df=strat_df[strat_df[botFullName+'_adj_PnL'].astype('float')==0]
|
101 |
+
win_days=len(win_df)
|
102 |
+
lose_days=len(lose_df)
|
103 |
+
win_ratio=win_days*100.0/(lose_days+win_days)
|
104 |
+
max_profit=strat_df[botFullName+'_adj_PnL'].max()
|
105 |
+
max_loss=strat_df[botFullName+'_adj_PnL'].min()
|
106 |
+
# max_drawdown=0
|
107 |
+
win_average_profit=win_df[botFullName+'_adj_PnL'].sum()/win_days
|
108 |
+
loss_average_profit=lose_df[botFullName+'_adj_PnL'].sum()/lose_days
|
109 |
+
total_profit=strat_df[botFullName+'_adj_PnL'].sum()
|
110 |
+
|
111 |
+
if botName not in eq_bots:
|
112 |
+
total_charges=strat_df['TotalCharges'].sum()
|
113 |
+
else:
|
114 |
+
total_charges=0
|
115 |
+
net_profit=total_profit-total_charges
|
116 |
+
average_profit=total_profit/total_days
|
117 |
+
gross_returns=strat_df[botFullName+' Returns'].sum()
|
118 |
+
net_returns=strat_df['net_rets'].sum()
|
119 |
+
results_row=[total_days,win_days,lose_days,win_ratio,max_profit,max_loss,max_drawdown,win_average_profit,loss_average_profit,average_profit,total_profit,total_charges,net_profit,gross_returns,net_returns]
|
120 |
+
results_row=[results_row[i] if i<3 else round(results_row[i],2) for i in range(len(results_row)) ]
|
121 |
+
stats_Df.loc[0,:]=results_row
|
122 |
+
t_stats_Df=stats_Df.T
|
123 |
+
t_stats_Df.rename(columns={0:''},inplace=True)
|
124 |
+
|
125 |
+
strat_df['month']=strat_df['pdTime'].apply(lambda x:x.strftime('%b,%Y'))
|
126 |
+
month_groups=strat_df.groupby('month',sort=False)[i_fields].sum()
|
127 |
+
##last 30 days pnl
|
128 |
+
strat_df=strat_df.reindex(strat_df.index[::-1])
|
129 |
+
if botName in eq_bots:
|
130 |
+
capital_used_appendum=''
|
131 |
+
else:
|
132 |
+
capital_used_appendum=' per Lot'
|
133 |
+
|
134 |
+
ret_dic[botName]=[botCapital,capital_used_appendum,results_row,t_stats_Df,month_groups,strat_df,i_fields,botFullName]
|
135 |
+
return ret_dic
|
136 |
+
|
137 |
+
def lambda_handler(event,context):
|
138 |
+
|
139 |
+
ret_dic=strategy_statistics()
|
140 |
+
ret_dic_js=json.dumps(ret_dic)
|
141 |
+
print(ret_dic_js)
|
performance_old.py
ADDED
@@ -0,0 +1,213 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import pandas as pd
|
2 |
+
import numpy as np
|
3 |
+
import streamlit as st
|
4 |
+
import plotly.graph_objects as go
|
5 |
+
from plotly import tools
|
6 |
+
import plotly.offline as py
|
7 |
+
import plotly.express as px
|
8 |
+
import requests,json
|
9 |
+
from datetime import datetime, time,timedelta
|
10 |
+
import plotly.express as px
|
11 |
+
from json_loader import json_load
|
12 |
+
from returnsDf import agg_df
|
13 |
+
import warnings
|
14 |
+
warnings.filterwarnings('ignore')
|
15 |
+
pd.options.display.float_format = '${:,.2f}'.format
|
16 |
+
one_day=timedelta(days=1)
|
17 |
+
st.set_page_config(page_title="SquareoffbotsPerformance",layout='wide')
|
18 |
+
st.markdown("""<style> div[role="listbox"] ul {
|
19 |
+
background-color: rgb(229, 236, 122);
|
20 |
+
}
|
21 |
+
div[role="listbox"],option{
|
22 |
+
float:right;
|
23 |
+
}
|
24 |
+
#MainMenu {display:none;}
|
25 |
+
footer {display:none !important}
|
26 |
+
|
27 |
+
|
28 |
+
</style>
|
29 |
+
|
30 |
+
"""
|
31 |
+
|
32 |
+
,unsafe_allow_html=True)
|
33 |
+
|
34 |
+
pnl_url=r'http://performance.squareoffbots.com/assets/json/sqbots_allData_21052021.json'
|
35 |
+
cap_url=r'http://performance.squareoffbots.com/assets/json/newCAp21052021.json'
|
36 |
+
charges_url=r'http://performance.squareoffbots.com/assets/json/charges.json'
|
37 |
+
|
38 |
+
query_params = st.experimental_get_query_params()
|
39 |
+
@st.cache(ttl=20*60*60)
|
40 |
+
def getResources1():
|
41 |
+
charges_dic=requests.get(charges_url).json()
|
42 |
+
# charges_dic=json_load('charges.json')
|
43 |
+
pnl_data=requests.get(pnl_url).json()
|
44 |
+
cap_data=requests.get(cap_url).json()
|
45 |
+
pnl_df_t=pd.DataFrame.from_dict(pnl_data)
|
46 |
+
cap_df_t=pd.DataFrame.from_dict(cap_data)
|
47 |
+
pnl_df=pnl_df_t.T
|
48 |
+
cap_df=cap_df_t.T
|
49 |
+
return charges_dic,pnl_data,cap_data,pnl_df,cap_df,query_params
|
50 |
+
charges_dic,pnl_data,cap_data,pnl_df,cap_df,query_params=getResources1()
|
51 |
+
# charges_dic=requests.get(charges_url).json()
|
52 |
+
botNameDic={"orb":"ORB","rsi":"RSI","it":"Intraday Trend","sh":"StopHunt","grb":"GRB","orb2pm":"ORB2pm","pcr":"NiftyOptionSelling","lapp":"Learnapp","bss":"BNF Straddle","nss":"Nifty Straddle","bos":"BNFOptionSelling","grbo":"GRB Options","bssr":"BNF Strangle","mlb":"ML Bot","bnfmon":"BNF ORB","mss":"1% Short Straddle (BNF)","mssn":"1% Short Straddle(NF)","dts":"Double Top"}
|
53 |
+
botCapitalDic={"orb":50000,"rsi":50000,"it":50000,"sh":50000,"grb":300000,"orb2pm":300000,"pcr":300000,"lapp":300000,"bss":300000,"nss":300000,"bos":300000,"grbo":150000,"bssr":300000,"bnfmon":150000,"mlb":400000,"mss":300000,"mssn":300000,"dts":150000}
|
54 |
+
curBots=['orb','rsi','it','grb','bss','grbo','bssr','bnfmon','mlb','mss','mssn','dts']
|
55 |
+
botName = query_params["bot"][0] if "bot" in query_params else None
|
56 |
+
|
57 |
+
botsList=list(botNameDic.keys())
|
58 |
+
if botName not in botsList:
|
59 |
+
botName='bss'
|
60 |
+
botsList.remove('bss')
|
61 |
+
botsList=['bss']+botsList
|
62 |
+
if not botName:
|
63 |
+
botName = st.selectbox('Select a Strategy',tuple(botsList))
|
64 |
+
|
65 |
+
@st.cache(ttl=20*60*60,suppress_st_warning=True,allow_output_mutation=True)
|
66 |
+
def strategy_statistics():
|
67 |
+
ret_dic={}
|
68 |
+
for botName in curBots:
|
69 |
+
eq_bots=["orb","rsi","sh","it"]
|
70 |
+
botFullName=botNameDic[botName]
|
71 |
+
botCapital=botCapitalDic[botName]
|
72 |
+
|
73 |
+
|
74 |
+
|
75 |
+
strat_pnl_Df=pnl_df[[botFullName]]
|
76 |
+
strat_pnl_Df.dropna(inplace=True)
|
77 |
+
strat_cap_df=cap_df[[botFullName]]
|
78 |
+
#returns calculation
|
79 |
+
strat_df=agg_df(strat_pnl_Df,strat_cap_df)
|
80 |
+
##PNL plot
|
81 |
+
strat_df['pdTime']=pd.to_datetime(strat_df.index,format="%Y-%m-%d")
|
82 |
+
strat_df.sort_values('pdTime',inplace=True)
|
83 |
+
strat_df[botFullName+'_adj_PnL']=(botCapital/100)*strat_df[botFullName+' Returns'].astype(float)
|
84 |
+
strat_df[botFullName+'_gross_PnL']=strat_df[botFullName+'_adj_PnL']
|
85 |
+
charges_types=['Brokerage','TransactionCharges','ClearingCharges','STT','GST','SEBI','StampDuty','TotalCharges']
|
86 |
+
def getCharges(x):
|
87 |
+
notGotCharges=True
|
88 |
+
original_date=x
|
89 |
+
cDayObj=datetime.strptime(x,'%Y-%m-%d')
|
90 |
+
direction=-1
|
91 |
+
direction_counter=0
|
92 |
+
|
93 |
+
while notGotCharges:
|
94 |
+
try:
|
95 |
+
return charges_dic[cDayObj.strftime('%Y%m%d')][botName.upper()+'_'+ct]
|
96 |
+
|
97 |
+
except Exception as e:
|
98 |
+
direction_counter+=1
|
99 |
+
if direction_counter==10:
|
100 |
+
direction*=-1
|
101 |
+
|
102 |
+
|
103 |
+
cDayObj+=direction*one_day
|
104 |
+
continue
|
105 |
+
for ct in charges_types:
|
106 |
+
strat_df[ct]=strat_df.index.to_series().apply(lambda x:getCharges(x))
|
107 |
+
i_fields=['PNL','Brokerage','TransactionCharges','ClearingCharges','STT','GST','SEBI','StampDuty','TotalCharges','net_PNL']
|
108 |
+
|
109 |
+
|
110 |
+
|
111 |
+
##xxx
|
112 |
+
if botName in eq_bots:
|
113 |
+
i_fields=["PNL"]
|
114 |
+
strat_df['net_PNL']=strat_df[botFullName+'_gross_PnL']
|
115 |
+
else:
|
116 |
+
strat_df['net_PNL']=strat_df[botFullName+'_gross_PnL']-strat_df['TotalCharges']
|
117 |
+
|
118 |
+
strat_df['net_rets']=100*strat_df['net_PNL']/botCapital
|
119 |
+
strat_df["Time"]=strat_df.index
|
120 |
+
strat_df['PNL']=strat_df[botFullName+'_adj_PnL']
|
121 |
+
strat_df['cum_pnl']=strat_df[botFullName+'_adj_PnL'].cumsum()
|
122 |
+
##DRAWDOWN
|
123 |
+
drawdown_df=strat_df.copy()
|
124 |
+
drawdown_df.reset_index(drop=True,inplace=True)
|
125 |
+
drawdown_df['max_value_so_far']=drawdown_df['cum_pnl'].cummax()
|
126 |
+
drawdown_df['drawdown']=drawdown_df['cum_pnl']-drawdown_df['max_value_so_far']
|
127 |
+
max_drawdown=drawdown_df['drawdown'].min()
|
128 |
+
##Strategy statistics .
|
129 |
+
stats_Df=pd.DataFrame(columns=["Total Days","Winning Days","Losing Days","Winning Accuracy(%)","Max Profit","Max Loss","Max Drawdown","Average Profit on Win Days","Average Profit on loss days","Average Profit Per day","Gross Profit","Charges","Net profit","Returns (%)","net Returns (%)"])
|
130 |
+
total_days=len(strat_df)
|
131 |
+
win_df=strat_df[strat_df[botFullName+'_adj_PnL'].astype('float')>0]
|
132 |
+
lose_df=strat_df[strat_df[botFullName+'_adj_PnL'].astype('float')<0]
|
133 |
+
noTrade_df=strat_df[strat_df[botFullName+'_adj_PnL'].astype('float')==0]
|
134 |
+
win_days=len(win_df)
|
135 |
+
lose_days=len(lose_df)
|
136 |
+
win_ratio=win_days*100.0/(lose_days+win_days)
|
137 |
+
max_profit=strat_df[botFullName+'_adj_PnL'].max()
|
138 |
+
max_loss=strat_df[botFullName+'_adj_PnL'].min()
|
139 |
+
# max_drawdown=0
|
140 |
+
win_average_profit=win_df[botFullName+'_adj_PnL'].sum()/win_days
|
141 |
+
loss_average_profit=lose_df[botFullName+'_adj_PnL'].sum()/lose_days
|
142 |
+
total_profit=strat_df[botFullName+'_adj_PnL'].sum()
|
143 |
+
|
144 |
+
if botName not in eq_bots:
|
145 |
+
total_charges=strat_df['TotalCharges'].sum()
|
146 |
+
else:
|
147 |
+
total_charges=0
|
148 |
+
net_profit=total_profit-total_charges
|
149 |
+
average_profit=total_profit/total_days
|
150 |
+
gross_returns=strat_df[botFullName+' Returns'].sum()
|
151 |
+
net_returns=strat_df['net_rets'].sum()
|
152 |
+
results_row=[total_days,win_days,lose_days,win_ratio,max_profit,max_loss,max_drawdown,win_average_profit,loss_average_profit,average_profit,total_profit,total_charges,net_profit,gross_returns,net_returns]
|
153 |
+
results_row=[results_row[i] if i<3 else round(results_row[i],2) for i in range(len(results_row)) ]
|
154 |
+
stats_Df.loc[0,:]=results_row
|
155 |
+
t_stats_Df=stats_Df.T
|
156 |
+
t_stats_Df.rename(columns={0:''},inplace=True)
|
157 |
+
fig=px.line(strat_df, x="Time", y='cum_pnl', title=botFullName+' PNL',width=800, height=400)
|
158 |
+
dd_fig=px.line(drawdown_df,x="Time",y="drawdown", title=botFullName+' PNL',width=800, height=400)
|
159 |
+
strat_df['month']=strat_df['pdTime'].apply(lambda x:x.strftime('%b,%Y'))
|
160 |
+
month_groups=strat_df.groupby('month',sort=False)[i_fields].sum()
|
161 |
+
##last 30 days pnl
|
162 |
+
strat_df=strat_df.reindex(strat_df.index[::-1])
|
163 |
+
if botName in eq_bots:
|
164 |
+
capital_used_appendum=''
|
165 |
+
else:
|
166 |
+
capital_used_appendum=' per Lot'
|
167 |
+
|
168 |
+
ret_dic[botName]=[botCapital,capital_used_appendum,results_row,t_stats_Df,fig,dd_fig,month_groups,strat_df,i_fields,botFullName]
|
169 |
+
return ret_dic
|
170 |
+
ret_dic=strategy_statistics()
|
171 |
+
botCapital,capital_used_appendum,results_row,t_stats_Df,fig,dd_fig,month_groups,strat_df,i_fields,botFullName=ret_dic[botName]
|
172 |
+
title_text="<h1 style='text-align: center; color: rgb(21, 86, 112);'>**♟**SQUAREOFF BOTS PERFORMANCE**♟**</h1><br><div style='text-align: center; color: rgb(21, 86, 112);'>**LIVE PERFORMANCE OF "+botFullName+"****[Capital used is "+str(botCapital)+capital_used_appendum+"]** </div>"
|
173 |
+
st.markdown(title_text, unsafe_allow_html=True)
|
174 |
+
|
175 |
+
|
176 |
+
|
177 |
+
if botCapital>50000 and botName!='mlb':
|
178 |
+
# col1.write("**(Capital used before July 2021 is "+str(int(botCapital/1.5))+capital_used_appendum+")**")
|
179 |
+
st.markdown("<div style='text-align: center; color: rgb(21, 86, 112);'>**(Capital used before July 2021 is "+str(int(botCapital/1.5))+capital_used_appendum+")** </div>", unsafe_allow_html=True)
|
180 |
+
col1, col2 = st.columns(2)
|
181 |
+
col2.markdown('##')
|
182 |
+
|
183 |
+
col1.write("Net ROI : "+str(results_row[-1])+"%")
|
184 |
+
col1.write("**Statistics**")
|
185 |
+
col1.table(t_stats_Df)
|
186 |
+
|
187 |
+
|
188 |
+
|
189 |
+
col2.write("**PNL Curve**")
|
190 |
+
col2.plotly_chart(fig)
|
191 |
+
col2.write("**Drawdown Curve**")
|
192 |
+
col2.plotly_chart(dd_fig)
|
193 |
+
st.write("**Month-wise PNL**")
|
194 |
+
st.table(month_groups)
|
195 |
+
st.write("**Date-wise PNL (Last 30 Days)**")
|
196 |
+
st.table(strat_df[i_fields][:30])
|
197 |
+
|
198 |
+
|
199 |
+
|
200 |
+
|
201 |
+
##TABLE
|
202 |
+
# fig2=go.Figure(data=[go.Table(
|
203 |
+
# header=dict(values=['Date','BSS'],
|
204 |
+
# fill_color='white',
|
205 |
+
# line_color='black',
|
206 |
+
|
207 |
+
# align='left'),
|
208 |
+
# cells=dict(values=[strat_df.index,strat_df[botFullName+'_adj_PnL']],
|
209 |
+
# fill_color='white',
|
210 |
+
|
211 |
+
|
212 |
+
# align='left'))])
|
213 |
+
# st.plotly_chart(fig2)
|
requirements.txt
ADDED
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
altair==4.2.0
|
2 |
+
attrs==22.1.0
|
3 |
+
blinker==1.5
|
4 |
+
cachetools==5.2.0
|
5 |
+
certifi==2022.12.7
|
6 |
+
charset-normalizer==2.1.1
|
7 |
+
click==8.1.3
|
8 |
+
commonmark==0.9.1
|
9 |
+
decorator==5.1.1
|
10 |
+
entrypoints==0.4
|
11 |
+
gitdb==4.0.10
|
12 |
+
GitPython==3.1.29
|
13 |
+
idna==3.4
|
14 |
+
importlib-metadata==5.1.0
|
15 |
+
Jinja2==3.1.2
|
16 |
+
jsonschema==4.17.3
|
17 |
+
MarkupSafe==2.1.1
|
18 |
+
numpy==1.23.5
|
19 |
+
packaging==22.0
|
20 |
+
pandas==1.5.2
|
21 |
+
Pillow==9.3.0
|
22 |
+
plotly==5.11.0
|
23 |
+
protobuf==3.20.3
|
24 |
+
pyarrow==10.0.1
|
25 |
+
pydeck==0.8.0
|
26 |
+
Pygments==2.13.0
|
27 |
+
Pympler==1.0.1
|
28 |
+
pyrsistent==0.19.2
|
29 |
+
python-dateutil==2.8.2
|
30 |
+
pytz==2022.7
|
31 |
+
pytz-deprecation-shim==0.1.0.post0
|
32 |
+
requests==2.28.1
|
33 |
+
rich==12.6.0
|
34 |
+
semver==2.13.0
|
35 |
+
six==1.16.0
|
36 |
+
smmap==5.0.0
|
37 |
+
streamlit==1.16.0
|
38 |
+
tenacity==8.1.0
|
39 |
+
toml==0.10.2
|
40 |
+
toolz==0.12.0
|
41 |
+
tornado==6.2
|
42 |
+
typing_extensions==4.4.0
|
43 |
+
tzdata==2022.7
|
44 |
+
tzlocal==4.2
|
45 |
+
urllib3==1.26.13
|
46 |
+
validators==0.20.0
|
47 |
+
zipp==3.11.0
|
requirements2.txt
ADDED
File without changes
|
requirements_heroku.txt
ADDED
@@ -0,0 +1,96 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
altair==4.2.0
|
2 |
+
appnope==0.1.3
|
3 |
+
argon2-cffi==21.3.0
|
4 |
+
argon2-cffi-bindings==21.2.0
|
5 |
+
asttokens==2.0.5
|
6 |
+
attrs==21.4.0
|
7 |
+
backcall==0.2.0
|
8 |
+
beautifulsoup4==4.11.1
|
9 |
+
bleach==5.0.1
|
10 |
+
blinker==1.5
|
11 |
+
cachetools==5.2.0
|
12 |
+
certifi==2022.6.15
|
13 |
+
cffi==1.15.1
|
14 |
+
charset-normalizer==2.1.0
|
15 |
+
click==8.1.3
|
16 |
+
commonmark==0.9.1
|
17 |
+
debugpy==1.6.2
|
18 |
+
decorator==5.1.1
|
19 |
+
defusedxml==0.7.1
|
20 |
+
entrypoints==0.4
|
21 |
+
executing==0.9.0
|
22 |
+
fastjsonschema==2.16.1
|
23 |
+
gitdb==4.0.9
|
24 |
+
GitPython==3.1.27
|
25 |
+
idna==3.3
|
26 |
+
importlib-metadata==4.12.0
|
27 |
+
ipykernel==6.15.1
|
28 |
+
ipython==8.4.0
|
29 |
+
ipython-genutils==0.2.0
|
30 |
+
ipywidgets==7.7.1
|
31 |
+
jedi==0.18.1
|
32 |
+
Jinja2==3.1.2
|
33 |
+
jsonschema==4.7.2
|
34 |
+
jupyter-client==7.3.4
|
35 |
+
jupyter-core==4.11.1
|
36 |
+
jupyterlab-pygments==0.2.2
|
37 |
+
jupyterlab-widgets==1.1.1
|
38 |
+
MarkupSafe==2.1.1
|
39 |
+
matplotlib-inline==0.1.3
|
40 |
+
mistune==0.8.4
|
41 |
+
nbclient==0.6.6
|
42 |
+
nbconvert==6.5.0
|
43 |
+
nbformat==5.4.0
|
44 |
+
nest-asyncio==1.5.5
|
45 |
+
notebook==6.4.12
|
46 |
+
numpy==1.22.3
|
47 |
+
packaging==21.3
|
48 |
+
pandas==1.4.3
|
49 |
+
pandocfilters==1.5.0
|
50 |
+
parso==0.8.3
|
51 |
+
pexpect==4.8.0
|
52 |
+
pickleshare==0.7.5
|
53 |
+
Pillow==9.2.0
|
54 |
+
plotly==5.9.0
|
55 |
+
prometheus-client==0.14.1
|
56 |
+
prompt-toolkit==3.0.30
|
57 |
+
protobuf==3.20.1
|
58 |
+
psutil==5.9.1
|
59 |
+
ptyprocess==0.7.0
|
60 |
+
pure-eval==0.2.2
|
61 |
+
pyarrow==8.0.0
|
62 |
+
pycparser==2.21
|
63 |
+
pydeck==0.7.1
|
64 |
+
Pygments==2.12.0
|
65 |
+
Pympler==1.0.1
|
66 |
+
pyparsing==3.0.9
|
67 |
+
pyrsistent==0.18.1
|
68 |
+
python-dateutil==2.8.2
|
69 |
+
pytz==2022.1
|
70 |
+
pytz-deprecation-shim==0.1.0.post0
|
71 |
+
pyzmq==23.2.0
|
72 |
+
requests==2.28.1
|
73 |
+
rich==12.5.1
|
74 |
+
semver==2.13.0
|
75 |
+
Send2Trash==1.8.0
|
76 |
+
six==1.16.0
|
77 |
+
smmap==5.0.0
|
78 |
+
soupsieve==2.3.2.post1
|
79 |
+
stack-data==0.3.0
|
80 |
+
streamlit==1.11.0
|
81 |
+
tenacity==8.0.1
|
82 |
+
terminado==0.15.0
|
83 |
+
tinycss2==1.1.1
|
84 |
+
toml==0.10.2
|
85 |
+
toolz==0.12.0
|
86 |
+
tornado==6.2
|
87 |
+
traitlets==5.3.0
|
88 |
+
typing_extensions==4.3.0
|
89 |
+
tzdata==2022.1
|
90 |
+
tzlocal==4.2
|
91 |
+
urllib3==1.26.10
|
92 |
+
validators==0.20.0
|
93 |
+
wcwidth==0.2.5
|
94 |
+
webencodings==0.5.1
|
95 |
+
widgetsnbextension==3.6.1
|
96 |
+
zipp==3.8.1
|
returnsDf.py
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import pandas as pd
|
2 |
+
from json_loader import *
|
3 |
+
import re
|
4 |
+
|
5 |
+
|
6 |
+
|
7 |
+
def calCulateReturn(pnl,cap):
|
8 |
+
|
9 |
+
try:
|
10 |
+
fc=float(cap)
|
11 |
+
fp=float(pnl)
|
12 |
+
except ValueError:
|
13 |
+
return 0
|
14 |
+
if(not re.search('\d',str(pnl)) or not re.search('\d',str(cap))):
|
15 |
+
return 0
|
16 |
+
|
17 |
+
|
18 |
+
elif (fc==0 or fp==0):
|
19 |
+
return 0
|
20 |
+
else:
|
21 |
+
return 100*float(pnl)/float(cap)
|
22 |
+
|
23 |
+
def agg_df(pnlDf,capDf):
|
24 |
+
returnsColumns=[c+' Returns' for c in capDf.columns]
|
25 |
+
capDf.columns=[c+' Capital' for c in capDf.columns]
|
26 |
+
pnlDf.columns=[c+' PnL' for c in pnlDf.columns]
|
27 |
+
|
28 |
+
result = pd.concat([capDf, pnlDf], axis=1, join="inner")
|
29 |
+
|
30 |
+
|
31 |
+
|
32 |
+
for r in returnsColumns:
|
33 |
+
stratName=r.split(' Returns')[0];
|
34 |
+
capColumnName=stratName+' Capital'
|
35 |
+
pnlColumnName=stratName+' PnL'
|
36 |
+
result[r]=result.apply(lambda x:calCulateReturn(x[pnlColumnName],x[capColumnName]),axis=1)
|
37 |
+
return result
|
38 |
+
|