vibhorag101 commited on
Commit
fe61012
1 Parent(s): c9b69d1

Added SIP step-up

Browse files
Files changed (1) hide show
  1. app.py +54 -31
app.py CHANGED
@@ -3,6 +3,7 @@ import pandas as pd
3
  import plotly.graph_objects as go
4
  from datetime import datetime, timedelta
5
  import requests
 
6
 
7
  js_func = """
8
  function refresh() {
@@ -15,6 +16,17 @@ function refresh() {
15
  }
16
  """
17
 
 
 
 
 
 
 
 
 
 
 
 
18
  def get_nav_data(scheme_code):
19
  url = f"https://api.mfapi.in/mf/{scheme_code}"
20
  response = requests.get(url)
@@ -26,7 +38,7 @@ def get_nav_data(scheme_code):
26
  inception_date = df['date'].min()
27
  return df, inception_date
28
 
29
- def calculate_sip_returns(nav_data, sip_amount, start_date, end_date, SIP_Date):
30
  start_date = pd.Timestamp(start_date)
31
  end_date = pd.Timestamp(end_date)
32
 
@@ -39,28 +51,31 @@ def calculate_sip_returns(nav_data, sip_amount, start_date, end_date, SIP_Date):
39
  else:
40
  last_dates = nav_data_filtered.groupby([nav_data_filtered['date'].dt.year, nav_data_filtered['date'].dt.month]).apply(lambda x: x.iloc[len(x)//2])
41
 
42
- units_accumulated = 0
43
- total_investment = 0
44
-
 
 
 
 
 
45
  for _, row in last_dates.iloc[:-1].iterrows():
46
- units_bought = sip_amount / row['nav']
 
 
 
 
 
47
  units_accumulated += units_bought
48
- total_investment += sip_amount
49
-
50
  final_value = units_accumulated * last_dates.iloc[-1]['nav']
51
  total_return = (final_value - total_investment) / total_investment * 100
52
-
53
  return total_return, final_value, total_investment
54
 
55
- def create_pie_chart(schemes):
56
- labels = list(schemes.keys())
57
- values = list(schemes.values())
58
-
59
- fig = go.Figure(data=[go.Pie(labels=labels, values=values)])
60
- fig.update_layout(title_text="Scheme Weightages")
61
- return fig
62
 
63
- def calculate_portfolio_returns(schemes, sip_amount, start_date, end_date, SIP_date, schemes_df):
64
  scheme_returns = []
65
  total_investment = 0
66
  final_value = 0
@@ -70,8 +85,8 @@ def calculate_portfolio_returns(schemes, sip_amount, start_date, end_date, SIP_d
70
  scheme_code = schemes_df[schemes_df['schemeName'] == scheme_name]['schemeCode'].values[0]
71
  nav_data, inception_date = get_nav_data(scheme_code)
72
  inception_dates.append((scheme_name, inception_date))
73
- scheme_return, scheme_final_value, scheme_total_investment = calculate_sip_returns(nav_data, sip_amount * scheme_weight / 100, start_date, end_date, SIP_date)
74
- scheme_returns.append((scheme_name, scheme_return))
75
  final_value += scheme_final_value
76
  total_investment += scheme_total_investment
77
 
@@ -84,10 +99,12 @@ def update_sip_calculator(*args):
84
  custom_end_date = args[2]
85
  SIP_Date = args[3]
86
  sip_amount = args[4]
87
- schemes_df = args[5]
 
 
88
  schemes = {}
89
 
90
- for i in range(6, len(args) - 1, 2): # Adjust range to account for use_inception_date
91
  if args[i] and args[i+1]:
92
  schemes[args[i]] = float(args[i+1])
93
 
@@ -124,7 +141,7 @@ def update_sip_calculator(*args):
124
  start_date = end_date - timedelta(days=months*30)
125
 
126
  try:
127
- portfolio_return, final_value, total_investment, scheme_returns, inception_dates = calculate_portfolio_returns(schemes, sip_amount, start_date, end_date, SIP_Date, schemes_df)
128
  except Exception as e:
129
  return f"Error: {str(e)}", None, None, None
130
 
@@ -141,12 +158,15 @@ def update_sip_calculator(*args):
141
  result += "\n".join(inception_warnings) + "\n\n"
142
  result += f"Possible start date for all chosen schemes is: {earliest_inception_date.date()}\n\n"
143
 
144
- result += f"Total portfolio SIP return: {portfolio_return:.2f}%\n"
145
- result += f"Total investment: {total_investment:.2f}\n"
146
- result += f"Final value: {final_value:.2f}\n\n"
147
  result += "Individual scheme returns:\n"
148
- for scheme_name, scheme_return in scheme_returns:
149
- result += f"{scheme_name}: {scheme_return:.2f}%\n"
 
 
 
150
  # pie_chart = create_pie_chart(schemes)
151
  # return result, pie_chart, final_value, total_investment
152
  return result
@@ -265,7 +285,10 @@ def create_ui():
265
  use_inception_date = gr.Checkbox(label="Use Earliest Inception Date", value=False)
266
  inception_date_display = gr.Textbox(label="Earliest Inception Date", interactive=False)
267
 
268
- sip_amount = gr.Number(label="SIP Amount (₹)")
 
 
 
269
 
270
  schemes_list = gr.State([])
271
 
@@ -288,7 +311,7 @@ def create_ui():
288
 
289
  calculate_button = gr.Button("Calculate Returns")
290
 
291
- result = gr.Textbox(label="Results")
292
  # pie_chart = gr.Plot(label="Scheme Weightages")
293
  # final_value = gr.Number(label="Final Value (₹)", interactive=False)
294
  # total_investment = gr.Number(label="Total Investment (₹)", interactive=False)
@@ -352,8 +375,8 @@ def create_ui():
352
  outputs=inception_date_display
353
  )
354
 
355
- def prepare_inputs_with_inception(period, custom_start, custom_end, SIP_Date, sip_amount, schemes_list, schemes_df, use_inception_date, inception_date_display):
356
- inputs = [period, custom_start, custom_end, SIP_Date, sip_amount, schemes_df]
357
  for name, weight in schemes_list:
358
  inputs.extend([name, weight])
359
 
@@ -365,7 +388,7 @@ def create_ui():
365
 
366
  calculate_button.click(
367
  lambda *args: update_sip_calculator(*prepare_inputs_with_inception(*args)),
368
- inputs=[period, custom_start_date, custom_end_date, SIP_Date, sip_amount, schemes_list, gr.State(schemes_df), use_inception_date, inception_date_display],
369
  outputs=[result]
370
  # outputs=[result, final_value, total_investment]
371
  # outputs=[result, pie_chart, final_value, total_investment]
 
3
  import plotly.graph_objects as go
4
  from datetime import datetime, timedelta
5
  import requests
6
+ import locale
7
 
8
  js_func = """
9
  function refresh() {
 
16
  }
17
  """
18
 
19
+ locale.setlocale(locale.LC_MONETARY, 'en_IN')
20
+
21
+ # def create_pie_chart(schemes):
22
+ # labels = list(schemes.keys())
23
+ # values = list(schemes.values())
24
+
25
+ # fig = go.Figure(data=[go.Pie(labels=labels, values=values)])
26
+ # fig.update_layout(title_text="Scheme Weightages")
27
+ # return fig
28
+
29
+
30
  def get_nav_data(scheme_code):
31
  url = f"https://api.mfapi.in/mf/{scheme_code}"
32
  response = requests.get(url)
 
38
  inception_date = df['date'].min()
39
  return df, inception_date
40
 
41
+ def calculate_sip_returns(nav_data, sip_amount, upfront_amount, stepup, start_date, end_date, SIP_Date):
42
  start_date = pd.Timestamp(start_date)
43
  end_date = pd.Timestamp(end_date)
44
 
 
51
  else:
52
  last_dates = nav_data_filtered.groupby([nav_data_filtered['date'].dt.year, nav_data_filtered['date'].dt.month]).apply(lambda x: x.iloc[len(x)//2])
53
 
54
+ total_investment = upfront_amount
55
+ current_sip_amount = sip_amount
56
+
57
+ # do calculation for upfront investment
58
+ units_bought = upfront_amount / nav_data_filtered.iloc[0]['nav']
59
+ units_accumulated = units_bought
60
+ previous_year = start_date.year
61
+
62
  for _, row in last_dates.iloc[:-1].iterrows():
63
+ # Check if a year has passed and increase SIP amount accordingly
64
+ if row['date'].year > previous_year:
65
+ current_sip_amount += current_sip_amount * (stepup / 100)
66
+ previous_year = row['date'].year
67
+
68
+ units_bought = current_sip_amount / row['nav']
69
  units_accumulated += units_bought
70
+ total_investment += current_sip_amount
71
+
72
  final_value = units_accumulated * last_dates.iloc[-1]['nav']
73
  total_return = (final_value - total_investment) / total_investment * 100
74
+
75
  return total_return, final_value, total_investment
76
 
 
 
 
 
 
 
 
77
 
78
+ def calculate_portfolio_returns(schemes, sip_amount, upfront_amount, stepup, start_date, end_date, SIP_date, schemes_df):
79
  scheme_returns = []
80
  total_investment = 0
81
  final_value = 0
 
85
  scheme_code = schemes_df[schemes_df['schemeName'] == scheme_name]['schemeCode'].values[0]
86
  nav_data, inception_date = get_nav_data(scheme_code)
87
  inception_dates.append((scheme_name, inception_date))
88
+ scheme_return, scheme_final_value, scheme_total_investment = calculate_sip_returns(nav_data, sip_amount * scheme_weight / 100, upfront_amount * scheme_weight / 100, stepup, start_date, end_date, SIP_date)
89
+ scheme_returns.append((scheme_name, scheme_return,scheme_final_value,scheme_total_investment))
90
  final_value += scheme_final_value
91
  total_investment += scheme_total_investment
92
 
 
99
  custom_end_date = args[2]
100
  SIP_Date = args[3]
101
  sip_amount = args[4]
102
+ upfront_amount = args[5]
103
+ stepup = args[6]
104
+ schemes_df = args[7]
105
  schemes = {}
106
 
107
+ for i in range(8, len(args) - 1, 2): # Adjust range to account for use_inception_date
108
  if args[i] and args[i+1]:
109
  schemes[args[i]] = float(args[i+1])
110
 
 
141
  start_date = end_date - timedelta(days=months*30)
142
 
143
  try:
144
+ portfolio_return, final_value, total_investment, scheme_returns, inception_dates = calculate_portfolio_returns(schemes, sip_amount, upfront_amount,stepup, start_date, end_date, SIP_Date, schemes_df)
145
  except Exception as e:
146
  return f"Error: {str(e)}", None, None, None
147
 
 
158
  result += "\n".join(inception_warnings) + "\n\n"
159
  result += f"Possible start date for all chosen schemes is: {earliest_inception_date.date()}\n\n"
160
 
161
+ result += f"Portfolio Absolute return: {portfolio_return:.2f}%\n"
162
+ result += f"Total investment: {locale.currency(total_investment,grouping=True)}\n"
163
+ result += f"Final value: {locale.currency(final_value,grouping=True)}\n\n"
164
  result += "Individual scheme returns:\n"
165
+ for scheme_name, scheme_return, scheme_final_value, scheme_total_investment in scheme_returns:
166
+ result += f"---- {scheme_name} ----:\n"
167
+ result += f"Return: {scheme_return:.2f}%\n"
168
+ result += f"Total investment: {locale.currency(scheme_total_investment,grouping=True)}\n"
169
+ result += f"Final value: {locale.currency(scheme_final_value,grouping=True)}\n\n"
170
  # pie_chart = create_pie_chart(schemes)
171
  # return result, pie_chart, final_value, total_investment
172
  return result
 
285
  use_inception_date = gr.Checkbox(label="Use Earliest Inception Date", value=False)
286
  inception_date_display = gr.Textbox(label="Earliest Inception Date", interactive=False)
287
 
288
+ with gr.Row():
289
+ sip_amount = gr.Number(label="SIP Amount (₹)")
290
+ upfront_amount = gr.Number(label="Upfront Investment (₹)",value=0)
291
+ stepup = gr.Number(label="Stepup %",value=0)
292
 
293
  schemes_list = gr.State([])
294
 
 
311
 
312
  calculate_button = gr.Button("Calculate Returns")
313
 
314
+ result = gr.Textbox(label="Results",)
315
  # pie_chart = gr.Plot(label="Scheme Weightages")
316
  # final_value = gr.Number(label="Final Value (₹)", interactive=False)
317
  # total_investment = gr.Number(label="Total Investment (₹)", interactive=False)
 
375
  outputs=inception_date_display
376
  )
377
 
378
+ def prepare_inputs_with_inception(period, custom_start, custom_end, SIP_Date, sip_amount, upfront_amount,stepup, schemes_list, schemes_df, use_inception_date, inception_date_display):
379
+ inputs = [period, custom_start, custom_end, SIP_Date, sip_amount, upfront_amount, stepup, schemes_df]
380
  for name, weight in schemes_list:
381
  inputs.extend([name, weight])
382
 
 
388
 
389
  calculate_button.click(
390
  lambda *args: update_sip_calculator(*prepare_inputs_with_inception(*args)),
391
+ inputs=[period, custom_start_date, custom_end_date, SIP_Date, sip_amount,upfront_amount,stepup,schemes_list, gr.State(schemes_df), use_inception_date, inception_date_display],
392
  outputs=[result]
393
  # outputs=[result, final_value, total_investment]
394
  # outputs=[result, pie_chart, final_value, total_investment]