Harshithtd commited on
Commit
20ac3c9
·
verified ·
1 Parent(s): dee429f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +41 -34
app.py CHANGED
@@ -19,9 +19,28 @@ def plot_cum_returns(data, title):
19
  fig = px.line(daily_cum_returns, title=title)
20
  return fig
21
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
 
23
-
24
- def output_results(start_date, end_date, tickers_string, investment_amount):
25
  tickers = tickers_string.split(',')
26
 
27
  # Get Stock Prices
@@ -34,15 +53,15 @@ def output_results(start_date, end_date, tickers_string, investment_amount):
34
  fig_cum_returns = plot_cum_returns(stocks_df, 'Cumulative Returns of Individual Stocks Starting with ₹100')
35
 
36
  # Calculate and Plot Correlation Matrix between Stocks
37
- # corr_df = stocks_df.corr().round(2)
38
- # fig_corr = px.imshow(corr_df, text_auto=True, title = 'Correlation between Stocks')
39
 
40
  # Calculate expected returns and sample covariance matrix for portfolio optimization later
41
  mu = expected_returns.mean_historical_return(stocks_df)
42
  S = risk_models.sample_cov(stocks_df)
43
 
44
  # Plot efficient frontier curve
45
- #fig_efficient_frontier = plot_efficient_frontier_and_max_sharpe(mu, S)
46
 
47
  # Get optimized weights
48
  ef = EfficientFrontier(mu, S)
@@ -51,21 +70,13 @@ def output_results(start_date, end_date, tickers_string, investment_amount):
51
  expected_annual_return, annual_volatility, sharpe_ratio = ef.portfolio_performance()
52
 
53
  expected_annual_return, annual_volatility, sharpe_ratio = '{}%'.format((expected_annual_return*100).round(2)), \
54
- '{}%'.format((annual_volatility*100).round(2)), \
55
- '{}%'.format((sharpe_ratio*100).round(2))
56
 
57
- weights_df = pd.DataFrame.from_dict(weights, orient='index').reset_index()
 
58
  weights_df.columns = ['Tickers', 'Weights']
59
 
60
- # Get the latest prices
61
- latest_prices = get_latest_prices(stocks_df)
62
-
63
- # Allocate the stocks based on the given budget
64
- da = DiscreteAllocation(weights, latest_prices, total_portfolio_value=investment_amount)
65
- allocation, leftover = da.lp_portfolio()
66
-
67
- allocation_df = pd.DataFrame(list(allocation.items()), columns=['Ticker', 'Shares'])
68
-
69
  # Calculate returns of portfolio with optimized weights
70
  stocks_df['Optimized Portfolio'] = 0
71
  for ticker, weight in weights.items():
@@ -74,8 +85,8 @@ def output_results(start_date, end_date, tickers_string, investment_amount):
74
  # Plot Cumulative Returns of Optimized Portfolio
75
  fig_cum_returns_optimized = plot_cum_returns(stocks_df['Optimized Portfolio'], 'Cumulative Returns of Optimized Portfolio Starting with ₹100')
76
 
77
- return fig_cum_returns_optimized, allocation_df, \
78
- expected_annual_return, leftover.round(), fig_indiv_prices, fig_cum_returns
79
 
80
 
81
  with gr.Blocks() as app:
@@ -90,34 +101,30 @@ with gr.Blocks() as app:
90
  tickers_string = gr.Textbox("TCS.NS,INFY.NS,RELIANCE.NS,HDFCBANK.NS,ICICIBANK.NS,SBIN.NS",
91
  label='Enter all stock tickers to be included in portfolio separated \
92
  by commas WITHOUT spaces, e.g. "TCS.NS,INFY.NS,RELIANCE.NS,HDFCBANK.NS,ICICIBANK.NS,SBIN.NS"')
93
- investment_amount = gr.Number(label="Investment Amount (in ₹)")
94
  btn = gr.Button("Get Optimized Portfolio")
95
 
96
- # with gr.Row():
97
- # gr.HTML("<h3>Optimized Portfolio Metrics</h3>")
98
 
99
  with gr.Row():
100
  expected_annual_return = gr.Text(label="Expected Annual Return")
101
- leftover = gr.Number(label="Leftover Amount (in ₹)")
 
102
 
103
  with gr.Row():
104
  fig_cum_returns_optimized = gr.Plot(label="Cumulative Returns of Optimized Portfolio (Starting Price of ₹100)")
105
- allocation_df = gr.DataFrame(label="Stock Allocation")
106
 
107
- # with gr.Row():
108
- # fig_efficient_frontier = gr.Plot(label="Efficient Frontier")
109
- # fig_corr = gr.Plot(label="Correlation between Stocks")
110
 
111
  with gr.Row():
112
  fig_indiv_prices = gr.Plot(label="Price of Individual Stocks")
113
  fig_cum_returns = gr.Plot(label="Cumulative Returns of Individual Stocks Starting with ₹100")
114
-
115
- # with gr.Row():
116
- # allocation_df = gr.DataFrame(label="Stock Allocation")
117
- #leftover = gr.Number(label="Leftover Amount (in ₹)")
118
 
119
- btn.click(fn=output_results, inputs=[start_date, end_date, tickers_string, investment_amount],
120
- outputs=[fig_cum_returns_optimized, allocation_df, \
121
- expected_annual_return,leftover, fig_indiv_prices, fig_cum_returns])
122
 
123
  app.launch()
 
19
  fig = px.line(daily_cum_returns, title=title)
20
  return fig
21
 
22
+ def plot_efficient_frontier_and_max_sharpe(mu, S):
23
+ # Optimize portfolio for max Sharpe ratio and plot it out with efficient frontier curve
24
+ ef = EfficientFrontier(mu, S)
25
+ fig, ax = plt.subplots(figsize=(6,4))
26
+ ef_max_sharpe = copy.deepcopy(ef)
27
+ plotting.plot_efficient_frontier(ef, ax=ax, show_assets=False)
28
+ # Find the max sharpe portfolio
29
+ ef_max_sharpe.max_sharpe(risk_free_rate=0.02)
30
+ ret_tangent, std_tangent, _ = ef_max_sharpe.portfolio_performance()
31
+ ax.scatter(std_tangent, ret_tangent, marker="*", s=100, c="r", label="Max Sharpe")
32
+ # Generate random portfolios with random weights
33
+ n_samples = 1000
34
+ w = np.random.dirichlet(np.ones(ef.n_assets), n_samples)
35
+ rets = w.dot(ef.expected_returns)
36
+ stds = np.sqrt(np.diag(w @ ef.cov_matrix @ w.T))
37
+ sharpes = rets / stds
38
+ ax.scatter(stds, rets, marker=".", c=sharpes, cmap="viridis_r")
39
+ # Output
40
+ ax.legend()
41
+ return fig
42
 
43
+ def output_results(start_date, end_date, tickers_string):
 
44
  tickers = tickers_string.split(',')
45
 
46
  # Get Stock Prices
 
53
  fig_cum_returns = plot_cum_returns(stocks_df, 'Cumulative Returns of Individual Stocks Starting with ₹100')
54
 
55
  # Calculate and Plot Correlation Matrix between Stocks
56
+ corr_df = stocks_df.corr().round(2)
57
+ fig_corr = px.imshow(corr_df, text_auto=True, title = 'Correlation between Stocks')
58
 
59
  # Calculate expected returns and sample covariance matrix for portfolio optimization later
60
  mu = expected_returns.mean_historical_return(stocks_df)
61
  S = risk_models.sample_cov(stocks_df)
62
 
63
  # Plot efficient frontier curve
64
+ fig_efficient_frontier = plot_efficient_frontier_and_max_sharpe(mu, S)
65
 
66
  # Get optimized weights
67
  ef = EfficientFrontier(mu, S)
 
70
  expected_annual_return, annual_volatility, sharpe_ratio = ef.portfolio_performance()
71
 
72
  expected_annual_return, annual_volatility, sharpe_ratio = '{}%'.format((expected_annual_return*100).round(2)), \
73
+ '{}%'.format((annual_volatility*100).round(2)), \
74
+ '{}%'.format((sharpe_ratio*100).round(2))
75
 
76
+ weights_df = pd.DataFrame.from_dict(weights, orient = 'index')
77
+ weights_df = weights_df.reset_index()
78
  weights_df.columns = ['Tickers', 'Weights']
79
 
 
 
 
 
 
 
 
 
 
80
  # Calculate returns of portfolio with optimized weights
81
  stocks_df['Optimized Portfolio'] = 0
82
  for ticker, weight in weights.items():
 
85
  # Plot Cumulative Returns of Optimized Portfolio
86
  fig_cum_returns_optimized = plot_cum_returns(stocks_df['Optimized Portfolio'], 'Cumulative Returns of Optimized Portfolio Starting with ₹100')
87
 
88
+ return fig_cum_returns_optimized, weights_df, fig_efficient_frontier, fig_corr, \
89
+ expected_annual_return, annual_volatility, sharpe_ratio, fig_indiv_prices, fig_cum_returns
90
 
91
 
92
  with gr.Blocks() as app:
 
101
  tickers_string = gr.Textbox("TCS.NS,INFY.NS,RELIANCE.NS,HDFCBANK.NS,ICICIBANK.NS,SBIN.NS",
102
  label='Enter all stock tickers to be included in portfolio separated \
103
  by commas WITHOUT spaces, e.g. "TCS.NS,INFY.NS,RELIANCE.NS,HDFCBANK.NS,ICICIBANK.NS,SBIN.NS"')
 
104
  btn = gr.Button("Get Optimized Portfolio")
105
 
106
+ with gr.Row():
107
+ gr.HTML("<h3>Optimized Portfolio Metrics</h3>")
108
 
109
  with gr.Row():
110
  expected_annual_return = gr.Text(label="Expected Annual Return")
111
+ annual_volatility = gr.Text(label="Annual Volatility")
112
+ sharpe_ratio = gr.Text(label="Sharpe Ratio")
113
 
114
  with gr.Row():
115
  fig_cum_returns_optimized = gr.Plot(label="Cumulative Returns of Optimized Portfolio (Starting Price of ₹100)")
116
+ weights_df = gr.DataFrame(label="Optimized Weights of Each Ticker")
117
 
118
+ with gr.Row():
119
+ fig_efficient_frontier = gr.Plot(label="Efficient Frontier")
120
+ fig_corr = gr.Plot(label="Correlation between Stocks")
121
 
122
  with gr.Row():
123
  fig_indiv_prices = gr.Plot(label="Price of Individual Stocks")
124
  fig_cum_returns = gr.Plot(label="Cumulative Returns of Individual Stocks Starting with ₹100")
 
 
 
 
125
 
126
+ btn.click(fn=output_results, inputs=[start_date, end_date, tickers_string],
127
+ outputs=[fig_cum_returns_optimized, weights_df, fig_efficient_frontier, fig_corr, \
128
+ expected_annual_return, annual_volatility, sharpe_ratio, fig_indiv_prices, fig_cum_returns])
129
 
130
  app.launch()