使用 Python 进行多种策略的投资组合管理

松鼠Quant
2024-06-04
A. 两种资产的投资组合

其中采用的策略是:

  • 等权重投资组合

  • 市值加权投资组合

  • 最小方差投资组合

B. 三种资产的投资组合

其中采用的策略是:

  • 最大夏普比率投资组合

  • 风险平价投资组合

  • 逆波动率加权投资组合

A. 两种资产的投资组合

每日收益和累计收益的可视化

首先,让我们看一下包含 2 只股票的投资组合的可视化,即 APPLE(股票代码 = AAPL)和可口可乐(股票代码 = KO)。我们将看到投资组合的每日回报以及累计回报。






































































import pandas as pdimport numpy as npimport yfinance as yfimport matplotlib.pyplot as plt

# Downloading AAPL and MSFT data from Yahoo Financeassets = ['AAPL', 'KO']start_date = '2014-01-01'end_date = '2024-04-07'portfolio_data = yf.download(assets, start=start_date, end=end_date)['Adj Close']

# Calculate daily returns for each assetdaily_returns = portfolio_data.pct_change()

# Define portfolio weights (e.g., 50% AAPL and 50% MSFT)weights = np.array([0.5, 0.5])

# Calculate portfolio returnsportfolio_returns = daily_returns.dot(weights)

# Calculate cumulative returns for each assetcumulative_returns = (1 + daily_returns).cumprod() - 1

# Calculate Sharpe ratio (assuming risk-free rate of 0%)sharpe_ratio = (portfolio_returns.mean() / portfolio_returns.std()) * np.sqrt(252)

# Visualise both daily returns and cumulative returnsplt.figure(figsize=(12, 12))

# Plot daily returnsplt.subplot(2, 1, 1)daily_returns.plot(ax=plt.gca())plt.title('Daily Portfolio Returns')plt.xlabel('Date')plt.ylabel('Daily Return')plt.grid(True)

# Plot cumulative returns for each asset with different coloursplt.subplot(2, 1, 2)for asset in cumulative_returns.columns:   cumulative_returns[asset].plot(label=asset)plt.title('Cumulative Portfolio Returns')plt.xlabel('Date')plt.ylabel('Cumulative Return')plt.legend()plt.grid(True)

plt.tight_layout()plt.show()

# Print portfolio performance metricsprint('Portfolio Performance Metrics:')print(f'Sharpe Ratio: {sharpe_ratio:.2f}')print(f'Average Daily Return: {portfolio_returns.mean():.4f}')print(f'Average Annualised Return: {portfolio_returns.mean() * 252:.2f}')print(f'Volatility (Standard Deviation of Daily Returns): {portfolio_returns.std():.4f}')







# Print portfolio performance metricsprint('Portfolio Performance Metrics:')print(f'Sharpe Ratio: {sharpe_ratio:.2f}')print(f'Average Daily Return: {portfolio_returns.mean():.4f}')print(f'Average Annualised Return: {portfolio_returns.mean() * 252:.2f}')print(f'Volatility (Standard Deviation of Daily Returns): {portfolio_returns.std():.4f}')

输出:

图片

图片






投资组合绩效指标:夏普比率:0.90平均每日回报率:0.0007平均年化回报率:0.17波动率(每日收益的标准差):0.0121

在上面的输出中,观察结果如下:

  • 夏普比率为 0.90 意味着,平均而言,投资组合每单位风险产生 0.90 个单位的超额回报。夏普比率越高,风险调整后的表现越好。

  • 平均每日回报率表示给定时间段内投资组合的每日平均回报率。平均每日回报率为 0.0007 意味着投资组合的价值平均增长了 0.07%。

  • 投资组合的年化平均回报率是通过将日均回报率乘以一年的交易日数(本例中为 252 天)计算得出的。年化平均回报率为 0.17 意味着投资组合的平均回报率为 17%。

  • 波动率(每日收益的标准差)衡量收益在平均收益附近的分散程度。它表示投资组合收益的变化程度。每日收益的标准差为 0.0121 意味着,平均而言,投资组合的每日收益与平均收益的偏差为 1.2%。

使用两种资产组合的投资策略

现在让我们使用不同的策略来形象化两种资产的投资组合,即“AAPL 和 KO”:

  1. 等权重投资组合

  2. 市值加权投资组合

  3. 最小方差投资组合



























































































import pandas as pdimport numpy as npimport yfinance as yfimport matplotlib.pyplot as plt

# Downloading stock data from Yahoo Financedef download_stock_data(tickers, start_date, end_date):   data = yf.download(tickers, start=start_date, end=end_date)['Adj Close']   return data

# Equal Weighted Portfoliodef equal_weighted_portfolio(data):   num_assets = len(data.columns)   weights = np.ones(num_assets) / num_assets   equal_weighted_returns = data.pct_change().dot(weights)   return equal_weighted_returns

# Market Cap Weighted Portfoliodef market_cap_weighted_portfolio(data):   market_caps = data.iloc[-1]   # Using latest market capitalisation   weights = market_caps / market_caps.sum()   market_cap_returns = data.pct_change().dot(weights)   return market_cap_returns

# Minimum Variance Portfoliodef minimum_variance_portfolio(data):   cov_matrix = data.pct_change().cov()   inv_cov_matrix = np.linalg.inv(cov_matrix)   ones_vector = np.ones(len(data.columns))   weights = inv_cov_matrix.dot(ones_vector) / ones_vector.dot(inv_cov_matrix).dot(ones_vector)   minimum_var_returns = data.pct_change().dot(weights)   return minimum_var_returns

# Define parametersassets = ['AAPL', 'KO']start_date = '2014-01-01'end_date = '2024-04-07'

# Download stock datadata = download_stock_data(tickers, start_date, end_date)

# Calculate portfolio returns using different strategiesequal_weighted_returns = equal_weighted_portfolio(data)market_cap_returns = market_cap_weighted_portfolio(data)minimum_var_returns = minimum_variance_portfolio(data)

# Visualise portfolio returns on separate graphsplt.figure(figsize=(12, 12))

# Equal Weighted Portfolioplt.subplot(3, 1, 1)equal_weighted_returns.plot(label='Equal Weighted Portfolio')plt.title('Equal Weighted Portfolio Returns')plt.xlabel('Date')plt.ylabel('Portfolio Return')plt.legend()plt.grid(True)

# Market Cap Weighted Portfolioplt.subplot(3, 1, 2)market_cap_returns.plot(label='Market Cap Weighted Portfolio')plt.title('Market Cap Weighted Portfolio Returns')plt.xlabel('Date')plt.ylabel('Portfolio Return')plt.legend()plt.grid(True)

# Minimum Variance Portfolioplt.subplot(3, 1, 3)minimum_var_returns.plot(label='Minimum Variance Portfolio')plt.title('Minimum Variance Portfolio Returns')plt.xlabel('Date')plt.ylabel('Portfolio Return')plt.legend()plt.grid(True)

plt.tight_layout()plt.show()

输出:

图片

上面每个图表的含义如下:

  • 等权重投资组合:此图表显示投资组合的表现,其中每项资产被赋予相同的权重,即分配给每项资产的投资金额相同。绘制的线表示投资组合在指定时间段内的累计回报。它有助于直观地展示由等权重资产组成的投资组合与其他策略相比的表现。

  • 市值加权投资组合:此图表显示投资组合的表现,其中资产的权重根据其市值确定。与市值较低的资产相比,市值较高的资产在投资组合中的权重较大。绘制的线表示投资组合随时间的累计回报,反映了此市值加权策略的表现。

  • 最小方差投资组合:此图显示了为最小化投资组合方差或波动性而构建的投资组合的表现。此投资组合中资产的权重被确定为最小化投资组合的整体风险,同时实现所需的回报水平。绘制的线表示投资组合随时间的累积回报,说明了这种风险优化策略的表现。

每个绘制的图表都提供了不同投资组合构建策略随时间表现的洞察,让投资者能够评估其在实现投资目标和管理风险方面的有效性。如果策略未达到预期结果,则可以相应地设置投资组合中的参数,例如分配的权重、数量等。

使用相同的策略,您可以纳入一个包含您通常交易的尽可能多的资产的投资组合,这些资产彼此之间具有较低或负相关性。

纳入相关性较低的资产有助于降低投资组合风险,同时可能提高回报。有效投资组合中包含的具体资产取决于各种因素,例如投资目标、风险承受能力、投资期限和市场条件。

B. 三种资产的投资组合

这次,我们将考虑一个包含 3 只股票的投资组合,即 APPLE(股票代码 = AAPL)、可口可乐(股票代码 = KO)和 Old National Corp(股票代码 = ONB)。我们将看到该投资组合的每日回报以及累计回报。

之后,我们将使用三种策略分别查看投资组合的表现,即

  1. 最大夏普比率投资组合

  2. 风险平价投资组合

  3. 逆波动率加权投资组合

在下面的代码中,我们编译了必要的所有步骤。


































































































































import pandas as pdimport numpy as npimport yfinance as yfimport matplotlib.pyplot as plt

# Downloading stock data from Yahoo Financedefdownload_stock_data(tickers, start_date, end_date):   data = yf.download(tickers, start=start_date, end=end_date)['Adj Close']return data

# Calculate daily returnsdefcalculate_daily_returns(data):return data.pct_change()

# Calculate cumulative returnsdefcalculate_cumulative_returns(data):return (1 + data.pct_change()).cumprod() - 1

# Maximum Sharpe Ratio Portfoliodefmaximum_sharpe_ratio_portfolio(returns):   cov_matrix = returns.cov()   inv_cov_matrix = np.linalg.inv(cov_matrix)   ones_vector = np.ones(len(returns.columns))   weights = inv_cov_matrix.dot(ones_vector) / ones_vector.dot(inv_cov_matrix).dot(ones_vector)return returns.dot(weights)

# Risk Parity Portfoliodefrisk_parity_portfolio(returns):   inv_cov_matrix = np.linalg.inv(returns.cov())   weights = inv_cov_matrix.dot(np.ones(len(returns.columns))) / len(returns.columns)return returns.dot(weights)

# Inverse Volatility Weighted Portfoliodefinverse_volatility_weighted_portfolio(returns):   weights = 1 / returns.std()   weights /= weights.sum()return returns.dot(weights)

# Define parameterstickers = ['AAPL', 'KO', 'ONB']start_date = '2010-01-01'end_date = '2024-04-07'

# Download stock datadata = download_stock_data(tickers, start_date, end_date)

# Calculate daily returns for each assetdaily_returns = calculate_daily_returns(data)

# Calculate cumulative returns for each assetcumulative_returns = calculate_cumulative_returns(data)

# Visualise daily returns for each assetplt.figure(figsize=(12, 6))for asset in daily_returns.columns:   daily_returns[asset].plot(label=asset)plt.title('Daily Returns')plt.xlabel('Date')plt.ylabel('Daily Return')plt.legend()plt.grid(True)plt.show()

# Visualise cumulative returns for each assetplt.figure(figsize=(12, 6))for asset in cumulative_returns.columns:    cumulative_returns[asset].plot(label=asset)plt.title('Cumulative Returns')plt.xlabel('Date')plt.ylabel('Cumulative Return')plt.legend()plt.grid(True)plt.show()

# Calculate portfolio returns using different strategiesmax_sharpe_ratio_portfolio_returns = maximum_sharpe_ratio_portfolio(daily_returns)risk_parity_portfolio_returns = risk_parity_portfolio(daily_returns)inverse_volatility_weighted_portfolio_returns = inverse_volatility_weighted_portfolio(daily_returns)

# Visualise portfolio returnsplt.figure(figsize=(12, 6))

# Maximum Sharpe Ratio Portfoliomax_sharpe_ratio_portfolio_returns.plot(label='Max Sharpe Ratio Portfolio', linestyle='--')plt.title('Maximum Sharpe Ratio Portfolio Returns')plt.xlabel('Date')plt.ylabel('Portfolio Return')plt.legend()plt.grid(True)plt.show()

# Risk Parity Portfolioplt.figure(figsize=(12, 6))risk_parity_portfolio_returns.plot(label='Risk Parity Portfolio', linestyle='-.')plt.title('Risk Parity Portfolio Returns')plt.xlabel('Date')plt.ylabel('Portfolio Return')plt.legend()plt.grid(True)plt.show()

# Inverse Volatility Weighted Portfolioplt.figure(figsize=(12, 6))inverse_volatility_weighted_portfolio_returns.plot(label='Inverse Volatility Weighted Portfolio', linestyle=':')plt.title('Inverse Volatility Weighted Portfolio Returns')plt.xlabel('Date')plt.ylabel('Portfolio Return')plt.legend()plt.grid(True)plt.show()

输出:

图片

图片

图片

上面输出中的每个图表代表一个不同的投资组合策略及其表现:

  • 最大夏普比率投资组合:输出中的图表显示使用最大夏普比率 (MSR) 方法构建的投资组合产生的回报。它显示了回报如何随时间波动,反映了该策略旨在通过实现尽可能高的夏普比率来最大化风险调整后的回报。

  • 风险平价投资组合:此图显示了使用风险平价方法构建的投资组合产生的回报。它强调了回报随时间的变化,表明该策略专注于平衡各个资产类别的风险贡献,以获得更稳定的回报。

  • 逆波动率加权投资组合:该图描绘了使用逆波动率加权方法构建的投资组合的收益。它展示了收益如何随时间变化,展示了该策略强调为波动性较小的资产分配更高的权重以降低投资组合的波动性。

值得注意的是,回测结果并不能保证未来的表现。所呈现的策略结果仅用于教育目的,不应被解释为投资建议。需要对策略的多个参数进行全面评估,以评估其有效性。


分享