結論、コピペしたまえ!w
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import yfinance as yf
def plot_risk_and_returns(annual_returns, annual_risk):
# Summarize the results
summary = pd.DataFrame({
'Annual Return (%)': annual_returns,
'Annual Risk (%)': annual_risk
})
# Plotting the results
plt.figure(figsize=(10, 6))
plt.scatter(summary['Annual Risk (%)'], summary['Annual Return (%)'], color='blue')
for i, txt in enumerate(summary.index):
plt.annotate(txt, (summary['Annual Risk (%)'][i], summary['Annual Return (%)'][i]), fontsize=12)
plt.title('Annual Return vs. Annual Risk')
plt.xlabel('Annual Risk (%)')
plt.ylabel('Annual Return (%)')
plt.grid(True)
plt.xlim(0, summary['Annual Risk (%)'].max() * 1.1) # Extend x-axis slightly
plt.ylim(0, summary['Annual Return (%)'].max() * 1.1) # Extend y-axis slightly
plt.savefig("risk_and_returns.png")
def plot_cov_matrix(cov_matrix):
# Display the covariance matrix as a heatmap
plt.figure(figsize=(10, 8))
sns.heatmap(cov_matrix, annot=True, fmt=".6f", cmap='coolwarm', linewidths=.5)
plt.title('Covariance Matrix Heatmap')
plt.savefig("cov_matrix.png")
# Define the tickers
tickers = ['VTI', 'BND','GLDM']
# Fetch historical data for the past 10 years
data = yf.download(tickers, start='2014-05-31', end='2024-05-31')['Adj Close']
returns = data.pct_change().dropna()
# Calculate annual returns and risk
annual_returns = returns.mean() * 252
annual_risk = returns.std() * np.sqrt(252)
plot_risk_and_returns(annual_returns, annual_risk)
# Calculate covariance matrix
cov_matrix = returns.cov() * 252
plot_cov_matrix(cov_matrix)
# Monte Carlo simulation
num_portfolios = 100000
results = np.zeros((3 + len(tickers), num_portfolios))
for i in range(num_portfolios):
weights = np.random.random(len(tickers))
weights /= np.sum(weights)
portfolio_return = np.dot(weights, annual_returns)
portfolio_risk = np.sqrt(np.dot(weights.T, np.dot(cov_matrix, weights)))
results[0, i] = portfolio_return
results[1, i] = portfolio_risk
results[2, i] = portfolio_return / portfolio_risk
for j in range(len(tickers)):
results[3 + j, i] = weights[j]
# Create DataFrame
columns = ['Return', 'Risk', 'Sharpe Ratio'] + tickers
results_frame = pd.DataFrame(results.T, columns=columns)
# Find the portfolio with the maximum Sharpe Ratio
max_sharpe_idx = results_frame['Sharpe Ratio'].idxmax()
max_sharpe_portfolio = results_frame.loc[max_sharpe_idx]
# Plot efficient frontier
plt.figure(figsize=(10, 6))
plt.scatter(results_frame['Risk'], results_frame['Return'], c=results_frame['Sharpe Ratio'], cmap='viridis')
plt.colorbar(label='Sharpe Ratio')
plt.xlabel('Risk')
plt.ylabel('Return')
plt.title('Efficient Frontier')
plt.scatter(max_sharpe_portfolio['Risk'], max_sharpe_portfolio['Return'], color='red', marker='*', s=100) # Max Sharpe Ratio point
plt.xlim(0, results_frame['Risk'].max() * 1.1) # Extend x-axis slightly
plt.ylim(0, results_frame['Return'].max() * 1.1) # Extend y-axis slightly
plt.savefig("mvo.png")
# Output the portfolio with the maximum Sharpe Ratio
max_sharpe_weights = max_sharpe_portfolio[tickers]
print(f"Max Sharpe Ratio Portfolio Weights:\n{max_sharpe_weights}")
日本語に訳すと効果的な最適化
ref