bohmian commited on
Commit
6b66c0a
1 Parent(s): 89453c8

corrected spelling

Browse files
Files changed (2) hide show
  1. app.py +0 -2
  2. app.py.bak +132 -0
app.py CHANGED
@@ -10,9 +10,7 @@ import numpy as np
10
  import pandas as pd
11
  import plotly.express as px
12
  import matplotlib.pyplot as plt
13
- import seaborn as sns
14
  from datetime import datetime
15
- from io import BytesIO
16
  import datetime
17
 
18
  def plot_cum_returns(data, title):
 
10
  import pandas as pd
11
  import plotly.express as px
12
  import matplotlib.pyplot as plt
 
13
  from datetime import datetime
 
14
  import datetime
15
 
16
  def plot_cum_returns(data, title):
app.py.bak ADDED
@@ -0,0 +1,132 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import yfinance as yf
3
+ from pypfopt.discrete_allocation import DiscreteAllocation, get_latest_prices
4
+ from pypfopt import EfficientFrontier
5
+ from pypfopt import risk_models
6
+ from pypfopt import expected_returns
7
+ from pypfopt import plotting
8
+ import copy
9
+ import numpy as np
10
+ import pandas as pd
11
+ import plotly.express as px
12
+ import matplotlib.pyplot as plt
13
+ import seaborn as sns
14
+ from datetime import datetime
15
+ from io import BytesIO
16
+ import datetime
17
+
18
+ def plot_cum_returns(data, title):
19
+ daily_cum_returns = 1 + data.dropna().pct_change()
20
+ daily_cum_returns = daily_cum_returns.cumprod()*100
21
+ fig = px.line(daily_cum_returns, title=title)
22
+ return fig
23
+
24
+ def plot_efficient_frontier_and_max_sharpe(mu, S):
25
+ # Optimize portfolio for max Sharpe ratio and plot it out with efficient frontier curve
26
+ ef = EfficientFrontier(mu, S)
27
+ fig, ax = plt.subplots(figsize=(6,4))
28
+ ef_max_sharpe = copy.deepcopy(ef)
29
+ plotting.plot_efficient_frontier(ef, ax=ax, show_assets=False)
30
+ # Find the max sharpe portfolio
31
+ ef_max_sharpe.max_sharpe(risk_free_rate=0.02)
32
+ ret_tangent, std_tangent, _ = ef_max_sharpe.portfolio_performance()
33
+ ax.scatter(std_tangent, ret_tangent, marker="*", s=100, c="r", label="Max Sharpe")
34
+ # Generate random portfolios
35
+ n_samples = 1000
36
+ w = np.random.dirichlet(np.ones(ef.n_assets), n_samples)
37
+ rets = w.dot(ef.expected_returns)
38
+ stds = np.sqrt(np.diag(w @ ef.cov_matrix @ w.T))
39
+ sharpes = rets / stds
40
+ ax.scatter(stds, rets, marker=".", c=sharpes, cmap="viridis_r")
41
+ # Output
42
+ ax.legend()
43
+ return fig
44
+
45
+ def output_results(start_date, end_date, tickers_string):
46
+ tickers = tickers_string.split(',')
47
+
48
+ # Get Stock Prices
49
+ stocks_df = yf.download(tickers, start=start_date, end=end_date)['Adj Close']
50
+
51
+ # Plot Individual Stock Prices
52
+ fig_indiv_prices = px.line(stocks_df, title='Price of Individual Stocks')
53
+
54
+ # Plot Individual Cumulative Returns
55
+ fig_cum_returns = plot_cum_returns(stocks_df, 'Cumulative Returns of Individual Stocks Starting with $100')
56
+
57
+ # Calculatge and Plot Correlation Matrix between Stocks
58
+ corr_df = stocks_df.corr().round(2)
59
+ fig_corr = px.imshow(corr_df, text_auto=True, title = 'Correlation between Stocks')
60
+
61
+ # Calculate expected returns and sample covariance matrix for portfolio optimization later
62
+ mu = expected_returns.mean_historical_return(stocks_df)
63
+ S = risk_models.sample_cov(stocks_df)
64
+
65
+ # Plot efficient frontier curve
66
+ fig_efficient_frontier = plot_efficient_frontier_and_max_sharpe(mu, S)
67
+
68
+ # Get optimized weights
69
+ ef = EfficientFrontier(mu, S)
70
+ ef.max_sharpe(risk_free_rate=0.02)
71
+ weights = ef.clean_weights()
72
+ expected_annual_return, annual_volatility, sharpe_ratio = ef.portfolio_performance()
73
+
74
+ expected_annual_return, annual_volatility, sharpe_ratio = '{}%'.format((expected_annual_return*100).round(2)), \
75
+ '{}%'.format((annual_volatility*100).round(2)), \
76
+ '{}%'.format((sharpe_ratio*100).round(2))
77
+
78
+ weights_df = pd.DataFrame.from_dict(weights, orient = 'index')
79
+ weights_df = weights_df.reset_index()
80
+ weights_df.columns = ['Tickers', 'Weights']
81
+
82
+ # Calculate returns of portfolio with optimized weights
83
+ stocks_df['Optimized Portfolio'] = 0
84
+ for ticker, weight in weights.items():
85
+ stocks_df['Optimized Portfolio'] += stocks_df[ticker]*weight
86
+
87
+ # Plot Cumulative Returns of Optimized Portfolio
88
+ fig_cum_returns_optimized = plot_cum_returns(stocks_df['Optimized Portfolio'], 'Cumulative Returns of Optimized Portfolio Starting with $100')
89
+
90
+ return fig_cum_returns_optimized, weights_df, fig_efficient_frontier, fig_corr, \
91
+ expected_annual_return, annual_volatility, sharpe_ratio, fig_indiv_prices, fig_cum_returns
92
+
93
+
94
+ with gr.Blocks() as app:
95
+ with gr.Row():
96
+ gr.HTML("<h1>Bohmian's Stock Portfolio Optimizer</h1>")
97
+
98
+ with gr.Row():
99
+ start_date = gr.Textbox("2013-01-01", label="Start Date")
100
+ end_date = gr.Textbox(datetime.datetime.now().date(), label="End Date")
101
+
102
+ with gr.Row():
103
+ tickers_string = gr.Textbox("MA,META,V,AMZN,JPM,BA",
104
+ label='Enter all stock tickers to be included in portfolio separated \
105
+ by commas WITHOUT spaces, e.g. "MA,META,V,AMZN,JPM,BA"')
106
+ btn = gr.Button("Get Optimized Portfolio")
107
+
108
+ with gr.Row():
109
+ gr.Markdown("Optimizied Portfolio Metrics")
110
+
111
+ with gr.Row():
112
+ expected_annual_return = gr.Text(label="Expected Annual Return")
113
+ annual_volatility = gr.Text(label="Annual Volatility")
114
+ sharpe_ratio = gr.Text(label="Sharpe Ratio")
115
+
116
+ with gr.Row():
117
+ fig_cum_returns_optimized = gr.Plot(label="Cumulative Returns of Optimized Portfolio (Starting Price of $100)")
118
+ weights_df = gr.DataFrame(label="Optimized Weights of Each Ticker")
119
+
120
+ with gr.Row():
121
+ fig_efficient_frontier = gr.Plot(label="Efficient Frontier")
122
+ fig_corr = gr.Plot(label="Correlation between Stocks")
123
+
124
+ with gr.Row():
125
+ fig_indiv_prices = gr.Plot(label="Price of Individual Stocks")
126
+ fig_cum_returns = gr.Plot(label="Cumulative Returns of Individual Stocks Starting with $100")
127
+
128
+ btn.click(fn=output_results, inputs=[start_date, end_date, tickers_string],
129
+ outputs=[fig_cum_returns_optimized, weights_df, fig_efficient_frontier, fig_corr, \
130
+ expected_annual_return, annual_volatility, sharpe_ratio, fig_indiv_prices, fig_cum_returns])
131
+
132
+ app.launch()