# Question1
!pip install pandas_datareader
!pip install yfinance
!pip install numpy
!pip install matplotlib
import pandas_datareader as pdr
import yfinance as yf
import matplotlib.pyplot as plt
import numpy as np
import datetime
yf.pdr_override()
end_date = datetime.datetime.now()
start_date = end_date - datetime.timedelta(days=5*365)
stocks = ['AMZN', 'TSLA', 'NVDA', 'COST', 'NFLX']
data = pdr.data.get_data_yahoo(stocks, start=start_date, end=end_date)['Adj Close']
daily_returns = data.pct_change().dropna()
print("Mean Returns:")
print(daily_returns.mean())
print("\nStandard Deviation:")
print(daily_returns.std())
# Visualization
colors = ['blue', 'orange', 'red', 'purple', 'pink']
for i, stock in enumerate(stocks):
plt.hist(daily_returns[stock], bins=50, alpha=0.3, label=f'{stock}', color=colors[i])
plt.xlabel('Daily Return')
plt.ylabel('Frequency')
plt.title('Distribution of Daily Returns in the Past 5 Years')
plt.legend()
plt.show()
Run to view results
#Question2
!pip install PyPortfolioOpt
from pypfopt.efficient_frontier import EfficientFrontier
from pypfopt import risk_models
from pypfopt import expected_returns
import pandas_datareader as pdr
import yfinance as yf
import matplotlib.pyplot as plt
import numpy as np
import datetime
yf.pdr_override()
end_date = datetime.datetime.now()
start_date = end_date - datetime.timedelta(days=5*365)
stocks = ['AMZN', 'TSLA', 'NVDA', 'COST', 'NFLX']
data = pdr.data.get_data_yahoo(stocks, start=start_date, end=end_date)['Adj Close']
daily_returns = data.pct_change().dropna()
mu = expected_returns.mean_historical_return(data)
S = risk_models.sample_cov(data)
# Maximize the Sharpe ratio
ef = EfficientFrontier(mu, S)
weights = ef.max_sharpe()
ef.portfolio_performance(verbose=True)
optimized_weights = np.array(list(weights.values()))
daily_portfolio_returns = daily_returns.dot(optimized_weights)
annualized_return = ((1 + daily_portfolio_returns.mean()) ** 252) - 1
annualized_volatility = daily_portfolio_returns.std() * np.sqrt(252)
# Assuming a risk-free rate of 1% for the Sharpe ratio
risk_free_rate = 0.01
sharpe_ratio = (annualized_return - risk_free_rate) / annualized_volatility
print(f"\nAdditional Portfolio Statistics:")
print(f"Annualized Portfolio Return: {annualized_return}")
print(f"Annualized Portfolio Volatility: {annualized_volatility}")
print(f"Portfolio Sharpe Ratio: {sharpe_ratio}")
# Cumulative Returns Plot
cumulative_returns = (1 + daily_portfolio_returns).cumprod()
plt.plot(cumulative_returns.index, cumulative_returns)
plt.xlabel('Date')
plt.ylabel('Cumulative Returns')
plt.title('5-Year Cumulative Returns of the Portfolio')
plt.show()
print(weights)
Run to view results
#Question3
from pypfopt.efficient_frontier import EfficientFrontier
from pypfopt import risk_models
from pypfopt import expected_returns
import pandas_datareader as pdr
import yfinance as yf
import matplotlib.pyplot as plt
import numpy as np
import datetime
yf.pdr_override()
end_date = datetime.datetime.now()
start_date = end_date - datetime.timedelta(days=5*365)
stocks = ['AMZN', 'TSLA', 'NVDA', 'COST', 'NFLX']
data = pdr.data.get_data_yahoo(stocks, start=start_date, end=end_date)['Adj Close']
daily_returns = data.pct_change().dropna()
# Calculate expected returns and sample covariance
mu = expected_returns.mean_historical_return(data)
S = risk_models.sample_cov(data)
# Portfolio with Maximum Sharpe Ratio
ef = EfficientFrontier(mu, S)
max_sharpe_weights = ef.max_sharpe() # Maximize the Sharpe ratio
ef.portfolio_performance(verbose=True)
daily_max_sharpe_returns = daily_returns.dot(np.array(list(max_sharpe_weights.values())))
# Portfolio with Minimum Volatility
ef = EfficientFrontier(mu, S)
min_volatility_weights = ef.min_volatility()
ef.portfolio_performance(verbose=True)
daily_min_volatility_returns = daily_returns.dot(np.array(list(min_volatility_weights.values())))
# Function to calculate statistics
def calculate_statistics(daily_portfolio_returns):
annualized_return = ((1 + daily_portfolio_returns.mean()) ** 252) - 1
annualized_volatility = daily_portfolio_returns.std() * np.sqrt(252)
risk_free_rate = 0.01
sharpe_ratio = (annualized_return - risk_free_rate) / annualized_volatility
print(f"Annualized Portfolio Return: {annualized_return}")
print(f"Annualized Portfolio Volatility: {annualized_volatility}")
print(f"Portfolio Sharpe Ratio: {sharpe_ratio}")
print("\nMaximum Sharpe Portfolio Statistics:")
calculate_statistics(daily_max_sharpe_returns)
print("\nMinimum Volatility Portfolio Statistics:")
calculate_statistics(daily_min_volatility_returns)
# Cumulative Returns Plot
cumulative_max_sharpe_returns = (1 + daily_max_sharpe_returns).cumprod()
cumulative_min_volatility_returns = (1 + daily_min_volatility_returns).cumprod()
plt.figure(figsize=(14, 7))
plt.plot(cumulative_max_sharpe_returns.index, cumulative_max_sharpe_returns, label="Max Sharpe Portfolio")
plt.plot(cumulative_min_volatility_returns.index, cumulative_min_volatility_returns, label="Min Volatility Portfolio")
plt.xlabel('Date')
plt.ylabel('Cumulative Returns')
plt.title('5-Year Cumulative Returns')
plt.legend()
plt.show()
print(max_sharpe_weights)
print(min_volatility_weights)
Run to view results
#Question4
import yfinance as yf
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from pypfopt import EfficientFrontier, risk_models, expected_returns, black_litterman, BlackLittermanModel, objective_functions
# Download stock data
tickers = ['AMZN', 'TSLA', 'NVDA', 'COST', 'NFLX']
prices = yf.download(tickers, start="2018-01-01", end="2023-01-01")['Adj Close']
# Calculate expected returns and sample covariance
mu = expected_returns.mean_historical_return(prices)
S = risk_models.sample_cov(prices)
# Black-Litterman model
market_caps = {"AMZN": 1.426, "TSLA": 0.788, "NVDA": 1.126, "COST": 0.244, "NFLX": 0.196}
viewdict = {"AMZN": 0.10, "TSLA": 0.05}
market_prior = black_litterman.market_implied_prior_returns(market_caps, risk_aversion=1.0, risk_free_rate=0.01, cov_matrix=S)
bl = BlackLittermanModel(S, pi=market_prior, absolute_views=viewdict)
ret_bl, S_bl = bl.bl_returns(), bl.bl_cov()
# Efficient Frontier with L2 Regularization
ef = EfficientFrontier(ret_bl, S_bl, weight_bounds=(0, 1))
ef.add_objective(objective_functions.L2_reg, gamma=0.1)
ef.max_sharpe()
weights = ef.clean_weights()
print(weights)
# Calculate and show the portfolio performance
ef.portfolio_performance(verbose=True)
# Plotting the portfolio
pd.Series(weights).plot.pie(autopct="%.2f%%")
plt.show()
print(bl)
Run to view results