rohanphadke commited on
Commit
295d75e
·
verified ·
1 Parent(s): 4ac25d0

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +105 -0
app.py ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ import numpy as np
4
+ import matplotlib.pyplot as plt
5
+ import yfinance as yf
6
+
7
+ # The efficient frontier function modified for use in Streamlit
8
+ def plot_efficient_frontier(dataframes, names):
9
+ # Your efficient frontier function with slight modifications for Streamlit
10
+ # This is the same function you've been working with, so ensure it's correctly adjusted for Streamlit output
11
+
12
+ # Ensure you include the code for the function here
13
+ # Calculate daily returns for each asset
14
+ returns = pd.concat([df['Close'].pct_change().dropna() for df in dataframes], axis=1)
15
+ returns.columns = names
16
+
17
+ # Calculate mean and standard deviation of daily returns for each asset
18
+ mean_returns = returns.mean() * 252 # Annualize the mean returns
19
+ cov_matrix = returns.cov() * 252 # Annualize the covariance matrix
20
+
21
+ num_portfolios = 10000
22
+ all_weights = np.zeros((num_portfolios, len(dataframes)))
23
+ ret_arr = np.zeros(num_portfolios)
24
+ vol_arr = np.zeros(num_portfolios)
25
+ sharpe_arr = np.zeros(num_portfolios)
26
+
27
+ for i in range(num_portfolios):
28
+ weights = np.random.random(len(dataframes))
29
+ weights /= np.sum(weights) # Normalize weights
30
+ all_weights[i, :] = weights
31
+
32
+ # Expected portfolio return
33
+ ret_arr[i] = np.dot(weights, mean_returns)
34
+
35
+ # Expected portfolio volatility
36
+ vol_arr[i] = np.sqrt(np.dot(weights.T, np.dot(cov_matrix, weights)))
37
+
38
+ # Sharpe Ratio, assuming risk-free rate is 0
39
+ sharpe_arr[i] = ret_arr[i] / vol_arr[i]
40
+
41
+ # Find the portfolio with the highest Sharpe ratio
42
+ max_sharpe_idx = np.argmax(sharpe_arr)
43
+ max_sharpe_return = ret_arr[max_sharpe_idx]
44
+ max_sharpe_volatility = vol_arr[max_sharpe_idx]
45
+ optimal_weights = all_weights[max_sharpe_idx]
46
+
47
+ # Find the portfolio with the minimum volatility
48
+ min_vol_idx = np.argmin(vol_arr)
49
+ min_vol_return = ret_arr[min_vol_idx]
50
+ min_vol_volatility = vol_arr[min_vol_idx]
51
+
52
+ # Print the portfolio weights for the optimal portfolio
53
+ print("Optimal Portfolio Weights:")
54
+ for i, name in enumerate(names):
55
+ print(f"{name}: {optimal_weights[i]:.4f}")
56
+
57
+ # Plotting the efficient frontier
58
+ plt.figure(figsize=(10,6))
59
+ scatter = plt.scatter(vol_arr, ret_arr, c=sharpe_arr, cmap='Blues')
60
+ plt.colorbar(scatter, label='Sharpe Ratio')
61
+ plt.xlabel('Volatility')
62
+ plt.ylabel('Return')
63
+ plt.title('Efficient Frontier for a Portfolio of ' + str(len(names)) + ' Assets')
64
+
65
+ # Highlight the optimal portfolio
66
+ plt.scatter(max_sharpe_volatility, max_sharpe_return, c='red', s=200, edgecolors='black', marker='*', label='Optimal Portfolio (Max Sharpe Ratio)')
67
+
68
+ # Highlight the minimum volatility portfolio
69
+ plt.scatter(min_vol_volatility, min_vol_return, c='purple', s=150, edgecolors='black', marker='o', label='Minimum Volatility Portfolio')
70
+
71
+ # Set axes starting points
72
+ plt.xlim(0, plt.xlim()[1])
73
+ plt.ylim(0, plt.ylim()[1])
74
+
75
+ plt.legend()
76
+
77
+ plt.show()
78
+
79
+ # Streamlit application layout
80
+ st.title("Portfolio Optimization with Efficient Frontier")
81
+
82
+ # User input for tickers
83
+ user_input = st.text_input("Enter tickers separated by commas (e.g., AAPL,MSFT,GOOGL)", "NVDA,AMD,AAPL,MSFT,GOOGL")
84
+
85
+ # Process input tickers
86
+ tickers = [ticker.strip().upper() for ticker in user_input.split(',')]
87
+
88
+ # Fetch data and calculate efficient frontier upon button click
89
+ if st.button("Optimize Portfolio"):
90
+ # Fetch stock data
91
+ timeframe = '1y' # Define the timeframe for data fetching
92
+ dataframes = []
93
+ for ticker in tickers:
94
+ tick = yf.Ticker(ticker)
95
+ stock_data = tick.history(period=timeframe)
96
+ dataframes.append(stock_data)
97
+
98
+ # Ensure we have the data before proceeding
99
+ if len(dataframes) > 0:
100
+ # Plot efficient frontier and display optimal weights
101
+ plot_efficient_frontier(dataframes, tickers)
102
+ else:
103
+ st.write("Please enter valid tickers.")
104
+
105
+ # Instructions to run the app