在投资的世界中,稳健收益一直是投资者追求的目标。而低相关资产配置则是实现这一目标的关键法则之一。
今天,我们将探讨如何利用 Python 计算资产相关性,并利用这些知识来优化投资组合,从而实现稳健收益。
什么是资产相关性?
资产相关性是指不同资产之间的价格变动关系。相关性系数的取值范围是 -1 到 1,具体含义如下:
-
1 :完全正相关,两个资产价格总是同涨同跌。
-
-1 :完全负相关,两个资产价格总是一个涨一个跌。
-
0 :无相关性,两个资产的价格变动没有固定的关系。
在投资组合管理中,资产之间的相关性是一个关键因素。
相关性越低,意味着资产之间的价格波动规律越不一致,这有利于降低投资组合的整体风险。
相反,如果投资组合中的资产高度相关,当某一资产发生下跌时,其他资产也很可能会随之下跌,从而导致整体投资组合的大幅亏损。
因此,合理配置低相关资产,是实现稳健收益的关键法则之一。
通过选择低相关性甚至负相关的资产,可以有效分散投资风险,实现更稳健的收益。
数据获取与处理
这里我们可以利用上一篇文章中的AKShare库,获取数据:
## 从上到下依次获取:沪深300、中证500、创业板、美股纳斯达克、美股标普500、标普油气指数、豆粕(商品)、香港恒生指数
import akshare as ak
import datetime
import pandas as pd
hs300_df = ak.stock_zh_index_daily(symbol="sh000300")
zz500_df = ak.stock_zh_index_daily(symbol="sh000905")
cyb_df = ak.stock_zh_index_daily(symbol="sz399006")
nasdaq_df = ak.index_us_stock_sina(symbol=".IXIC")
bp500_df = ak.index_us_stock_sina(symbol=".INX")
oil_df = ak.index_us_stock_sina(symbol="XOP")
doupo_df = ak.futures_main_sina(symbol="M0")
hsi_df = ak.stock_hk_index_daily_em(symbol="HSI")
其中,以沪深300 为例,得到的数据格式如下图所示:
记录了日期、开盘价、收盘价、最高价、最低价和成交量,计算相关性需要用到日期和收盘价
这里没有选择使用国内相关的ETF作为代替,是因为国内ETF的跟踪性不够精准。
处理不同品种的开盘日期问题
由于需要处理不同商品,不同国家的股票,因此需要设计一个dataframe 去存储数据 ,实际上使用了一个字典列表
dataframe_list = [
{'df': hs300_df, 'name': 'hs300'},
{'df': zz500_df, 'name': 'zz500'},
{'df': cyb_df, 'name': 'cyb'},
{'df': nasdaq_df, 'name': 'nasdaq'},
{'df': bp500_df, 'name': 'bp500'},
{'df': oil_df, 'name': 'oil'},
{'df': doupo_df, 'name': 'doupo'},
{'df': hsi_df, 'name': 'hsi'},
]
这个字典列表中记录了每个股票、商品的数据和名称
市场开盘的时间也略微有所差距(各个国家的节假日不同),因此需要获取不同品种的相同日期:
这里定义一个get_same_date函数
## 定义起始日期和节数日期
begin_date = datetime.date(2000, 11, 30)
end_date = datetime.date.today()
def get_same_date(dataframe_list):
delta = datetime.timedelta(days=1)
date = begin_date
total_date = []
while date <= end_date:
times = 0
for dataframe in dataframe_list:
if date in dataframe['df']['date'].values:
times += 1
if times == len(dataframe_list):
total_date.append(date)
date += delta
return pd.DataFrame(total_date, columns=["date"])
这里使用一个比较浅显易懂的方案:
通过对不同品种的时间进行对比,对于某一个日期而言,如果这些品种都在该日期有交易的话,就保存这个日期,反之就不保存了。
获取日收益率
根据刚才得到的日期,获取每个股票的收盘价:
def get_daily_close_price(dataframe_list):
same_date = get_same_date(dataframe_list)
daily_close_price = same_date.copy(deep=True)
# init
for dataframe in dataframe_list:
daily_close_price[dataframe['name']] = 0
tmp_df = dataframe['df']
row = 0
for date in same_date['date'].values:
tmp = tmp_df[tmp_df['date'] == date]
close_price = tmp['close'].values[0]
daily_close_price.loc[row, dataframe['name']] = close_price
row += 1
return daily_close_price
通过收盘价计算日收益率:
def get_daily_changes(df):
daily_changes = df.copy(deep=True)
daily_changes.iloc[1:, 1:] = daily_changes.iloc[1:, 1:].div(daily_changes.iloc[:-1, 1:].values, axis=0) - 1
daily_changes.iloc[0, 1:] = 0
return daily_changes
计算相关性矩阵
调用上述函数实现相关性矩阵,这里直接使用dataframe自带的**corr()**函数计算相关性系数矩阵
daily_close_price = get_daily_close_price(dataframe_list)
daily_changes = get_daily_changes(daily_close_price)
stock_name = [item['name'] for item in dataframe_list]
corr = daily_changes[stock_name].corr()
print(corr)
通过上述代码,我们可以得到上述股票或商品的相关性系数
根据上文定义:相关性系数越接近于0的,两个品种的相关性越小
从中可以看出,沪深300、中证500、创业板 之间的相关性较大,标普500、纳斯达克 相关性较大,石油、豆粕、恒生指数与其他资产的相关性较小
构建自己的投资组合的时候,可以选择相关性较小的几个,比方说选择创业板、标普500、石油、豆粕、恒生指数作为投资组合标的,可以提高组合的抗风险能力。
可以增加更多的品种,计算他们之间的相关性,作为自己资产配置的参考
低相关资产配置的优势
低相关资产配置的核心在于分散风险。
正如**现代投资组合理论(Modern Portfolio Theory, MPT)**所提到的,通过持有多种低相关资产,可以在保持预期收益不变的情况下,有效降低组合的整体风险。
这样,即使某些资产在某段时间表现不佳,其他资产的良好表现可以抵消其影响,从而使整个投资组合更加稳健。
沃伦·巴菲特曾说过:鸡蛋不能放到同一个篮子里。
这句经典名言形象地表达了分散投资的概念,通过投资于不同的资产,特别是低相关的资产,可以有效降低整体风险。