Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -6,7 +6,6 @@ import pytz
|
|
6 |
import matplotlib.pyplot as plt
|
7 |
from PIL import Image
|
8 |
import numpy as np
|
9 |
-
import functions.py
|
10 |
|
11 |
nifty_list = ["ADANIENT","ADANIPORTS","APOLLOHOSP","ASIANPAINT","AXISBANK","BAJAJ-AUTO","BAJFINANCE","BAJAJFINSV","BPCL","BHARTIARTL","BRITANNIA","CIPLA","COALINDIA","DIVISLAB","DRREDDY","EICHERMOT","GRASIM","HCLTECH","HDFCBANK","HDFCLIFE","HEROMOTOCO","HINDALCO","HINDUNILVR","ICICIBANK","ITC","INDUSINDBK","INFY","JSWSTEEL","KOTAKBANK","LTIM","LT","M&M","MARUTI","NTPC","NESTLEIND","ONGC","POWERGRID","RELIANCE","SBILIFE","SBIN","SUNPHARMA","TCS","TATACONSUM","TATAMOTORS","TATASTEEL","TECHM","TITAN","UPL","ULTRACEMCO","WIPRO","%5ENSEI"]
|
12 |
|
@@ -90,10 +89,178 @@ stocks_dict = {symbol: Stocks(symbol) for symbol in nifty_list}
|
|
90 |
nifty_stocks = {symbol: stocks_dict[symbol] for symbol in nifty_list[:-1]}
|
91 |
|
92 |
nifty50 = {"nifty50": stocks_dict[nifty_list[-1]]}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
93 |
|
|
|
94 |
title = "Portfolio tracking Nifty50 Stocks"
|
95 |
description = """
|
96 |
-
This App Demo is made for an Assignment. This Demo takes Initial Equity, Start Date, End Date, Time Window as inputs
|
97 |
"""
|
98 |
|
99 |
|
|
|
6 |
import matplotlib.pyplot as plt
|
7 |
from PIL import Image
|
8 |
import numpy as np
|
|
|
9 |
|
10 |
nifty_list = ["ADANIENT","ADANIPORTS","APOLLOHOSP","ASIANPAINT","AXISBANK","BAJAJ-AUTO","BAJFINANCE","BAJAJFINSV","BPCL","BHARTIARTL","BRITANNIA","CIPLA","COALINDIA","DIVISLAB","DRREDDY","EICHERMOT","GRASIM","HCLTECH","HDFCBANK","HDFCLIFE","HEROMOTOCO","HINDALCO","HINDUNILVR","ICICIBANK","ITC","INDUSINDBK","INFY","JSWSTEEL","KOTAKBANK","LTIM","LT","M&M","MARUTI","NTPC","NESTLEIND","ONGC","POWERGRID","RELIANCE","SBILIFE","SBIN","SUNPHARMA","TCS","TATACONSUM","TATAMOTORS","TATASTEEL","TECHM","TITAN","UPL","ULTRACEMCO","WIPRO","%5ENSEI"]
|
11 |
|
|
|
89 |
nifty_stocks = {symbol: stocks_dict[symbol] for symbol in nifty_list[:-1]}
|
90 |
|
91 |
nifty50 = {"nifty50": stocks_dict[nifty_list[-1]]}
|
92 |
+
def dateoffset(input_date_str):
|
93 |
+
|
94 |
+
input_date_dt = datetime.strptime(input_date_str, "%Y-%m-%d")
|
95 |
+
|
96 |
+
|
97 |
+
new_date_dt = input_date_dt - timedelta(days=1)
|
98 |
+
|
99 |
+
|
100 |
+
new_date_str = new_date_dt.strftime("%Y-%m-%d")
|
101 |
+
|
102 |
+
return new_date_str
|
103 |
+
|
104 |
+
|
105 |
+
def setdates(startdate, enddate):
|
106 |
+
while startdate not in nifty50["nifty50"].data.index:
|
107 |
+
startdate = dateoffset(startdate)
|
108 |
+
|
109 |
+
while enddate not in nifty50["nifty50"].data.index:
|
110 |
+
enddate = dateoffset(enddate)
|
111 |
+
|
112 |
+
return startdate, enddate
|
113 |
+
|
114 |
+
|
115 |
+
def organisedata(startdate, enddate):
|
116 |
+
|
117 |
+
startdate, enddate = setdates(startdate, enddate)
|
118 |
+
|
119 |
+
|
120 |
+
symbols = list(nifty_stocks.keys())
|
121 |
+
|
122 |
+
|
123 |
+
common_index = nifty50["nifty50"].data.loc[startdate:enddate].index
|
124 |
+
|
125 |
+
|
126 |
+
data_frame = pd.DataFrame(index=symbols, columns=common_index)
|
127 |
+
|
128 |
+
|
129 |
+
for symbol, stock_object in nifty_stocks.items():
|
130 |
+
stock_data = stock_object.data.loc[startdate:enddate, 'Close']
|
131 |
+
data_frame.loc[symbol] = stock_data.reindex(common_index).values
|
132 |
+
|
133 |
+
return data_frame
|
134 |
+
|
135 |
+
def previoustimeframedata(n, startdate):
|
136 |
+
|
137 |
+
startdate_dt = pd.to_datetime(startdate)
|
138 |
+
|
139 |
+
|
140 |
+
ndaysagodate = startdate_dt - timedelta(days=int(n))
|
141 |
+
|
142 |
+
|
143 |
+
ndaysagodate_str = ndaysagodate.strftime("%Y-%m-%d")
|
144 |
+
startdate_str = startdate_dt.strftime("%Y-%m-%d")
|
145 |
+
|
146 |
+
|
147 |
+
return organisedata(ndaysagodate_str, startdate_str)
|
148 |
+
|
149 |
+
def portfoliooperations(equity,startdate,ndaywindow,portfolio):
|
150 |
+
|
151 |
+
startdate_dt = pd.to_datetime(startdate)
|
152 |
+
windowenddate = startdate_dt + timedelta(days=int(ndaywindow))
|
153 |
+
windowenddate_str = windowenddate.strftime("%Y-%m-%d")
|
154 |
+
|
155 |
+
startdate,windowenddate = setdates(startdate,windowenddate_str)
|
156 |
+
|
157 |
+
window_data = organisedata(startdate,windowenddate)
|
158 |
+
|
159 |
+
differences = window_data.iloc[:, -1] - window_data.iloc[:, 0]
|
160 |
+
|
161 |
+
next_portfolio = differences[differences > 0].index.tolist()
|
162 |
+
|
163 |
+
|
164 |
+
portfolio_sum = window_data.loc[portfolio, window_data.columns[0]].sum()
|
165 |
+
|
166 |
+
|
167 |
+
multiplier = equity / portfolio_sum if portfolio_sum != 0 else 0
|
168 |
+
|
169 |
+
|
170 |
+
portfolio_value = pd.DataFrame(index=window_data.columns, columns=['value'])
|
171 |
+
|
172 |
+
for date in window_data.columns:
|
173 |
+
|
174 |
+
portfolio_sum = window_data.loc[portfolio, date].sum()
|
175 |
+
|
176 |
+
portfolio_value.loc[date, 'value'] = portfolio_sum * multiplier
|
177 |
+
|
178 |
+
|
179 |
+
return next_portfolio,portfolio_value
|
180 |
+
|
181 |
+
def mainfunction (equity,startdate,enddate,ndaywindow):
|
182 |
+
|
183 |
+
pastwindow = previoustimeframedata(n=ndaywindow,startdate=startdate) # No Errors untill here
|
184 |
+
|
185 |
+
differences = pastwindow.iloc[:, -1] - pastwindow.iloc[:, 0]
|
186 |
+
|
187 |
+
portfolio = differences[differences > 0].index.tolist() # No Errors untill here
|
188 |
+
|
189 |
+
portfolio,portfolio_value = portfoliooperations(equity=equity,startdate=startdate,ndaywindow=ndaywindow,portfolio=portfolio)
|
190 |
+
|
191 |
+
|
192 |
+
|
193 |
+
enddate_tz = datetime.strptime(enddate,"%Y-%m-%d").replace(tzinfo=pytz.timezone('Asia/Kolkata'))
|
194 |
+
|
195 |
+
while portfolio_value.index[-1] < pd.to_datetime(enddate_tz) - timedelta(days=int(ndaywindow)):
|
196 |
+
|
197 |
+
portfolio,new_portfolio_value = portfoliooperations(equity=equity,startdate=startdate,ndaywindow=ndaywindow,portfolio=portfolio)
|
198 |
+
|
199 |
+
portfolio_value = pd.concat([portfolio_value, new_portfolio_value])
|
200 |
+
|
201 |
+
startdate = (pd.to_datetime(startdate)+ timedelta(days=int(ndaywindow))).strftime("%Y-%m-%d")
|
202 |
+
|
203 |
+
equity = portfolio_value.iloc[-1, 0]
|
204 |
+
|
205 |
+
return portfolio_value
|
206 |
+
|
207 |
+
def calculate_cagr(series):
|
208 |
+
total_return = (series.iloc[-1] / series.iloc[0]) - 1
|
209 |
+
num_years = len(series) / 252
|
210 |
+
cagr = (1 + total_return) ** (1 / num_years) - 1
|
211 |
+
return cagr * 100
|
212 |
+
|
213 |
+
|
214 |
+
def calculate_volatility(series):
|
215 |
+
return series.pct_change().std() * np.sqrt(252) * 100
|
216 |
+
|
217 |
+
|
218 |
+
def calculate_sharpe_ratio(series, risk_free_rate=0):
|
219 |
+
cagr = calculate_cagr(series)
|
220 |
+
volatility = calculate_volatility(series)
|
221 |
+
sharpe_ratio = (cagr - risk_free_rate) / volatility
|
222 |
+
return sharpe_ratio
|
223 |
+
|
224 |
+
|
225 |
+
def final_function(equity,startdate,enddate,ndaywindow):
|
226 |
+
|
227 |
+
equity = int(equity)
|
228 |
+
ndaywindow = int(ndaywindow)
|
229 |
+
|
230 |
+
portfolio_value = mainfunction(equity=equity,startdate=startdate,enddate=enddate,ndaywindow=ndaywindow)
|
231 |
+
nifty_data = nifty50["nifty50"].data
|
232 |
+
subset_data = nifty_data[startdate:enddate]
|
233 |
+
initial_nifty = subset_data['Close'][0]
|
234 |
+
nifty_dataseries = (equity/initial_nifty)*subset_data['Close']
|
235 |
+
plt.figure(figsize=(10, 6))
|
236 |
+
plt.plot(portfolio_value['value'], label='Strategy')
|
237 |
+
plt.plot(nifty_dataseries, label='Nifty50 as Benchmark')
|
238 |
+
plt.title('Benchmark vs Strategy')
|
239 |
+
plt.xlabel('Date')
|
240 |
+
plt.ylabel('Close Price')
|
241 |
+
plt.legend()
|
242 |
+
|
243 |
+
|
244 |
+
image_path = "output_plot.png"
|
245 |
+
plt.savefig(image_path)
|
246 |
+
plt.close()
|
247 |
+
|
248 |
+
|
249 |
+
image = Image.open(image_path)
|
250 |
+
|
251 |
+
strategy_cagr = calculate_cagr(portfolio_value['value'])
|
252 |
+
strategy_volatility = calculate_volatility(portfolio_value['value'])
|
253 |
+
strategy_sharpe_ratio = calculate_sharpe_ratio(portfolio_value['value'])
|
254 |
+
|
255 |
+
benchmark_cagr = calculate_cagr(nifty_dataseries)
|
256 |
+
benchmark_volatility = calculate_volatility(nifty_dataseries)
|
257 |
+
benchmark_sharpe_ratio = calculate_sharpe_ratio(nifty_dataseries)
|
258 |
+
|
259 |
|
260 |
+
return image, strategy_cagr, strategy_volatility, strategy_sharpe_ratio, benchmark_cagr, benchmark_volatility, benchmark_sharpe_ratio
|
261 |
title = "Portfolio tracking Nifty50 Stocks"
|
262 |
description = """
|
263 |
+
This App Demo is made for an Assignment. This Demo takes Initial Equity, Start Date, End Date, Time Window as inputs. Due to COVID 19 causing the fall of almost all Stock Prices, some Dates might result in strategy falling to zero at March 2020. Hence please try other dates
|
264 |
"""
|
265 |
|
266 |
|