第4章:资产收益率计算与可视化

各位同学,今天我们来聊聊资产收益率。说实话,这个主题看起来基础,但我在绿色金融项目里踩过的坑,有一半都跟收益率计算有关。你想想看,如果收益率算错了,后面的风险平价模型再漂亮也是白搭。

4.1 对数收益率与简单收益率

先问个问题:为什么我们要用对数收益率,而不是简单收益率?

简单收益率大家都会算:(P_t - P_{t-1}) / P_{t-1}。但我在做绿色债券组合分析时发现,简单收益率有个致命问题——它不对称。涨50%再跌50%,你以为回到原点?实际上亏了25%。

对数收益率就不一样了:ln(P_t / P_{t-1})。它天然具有时间可加性,而且更接近正态分布。我个人习惯在做风险平价模型时,一律用对数收益率。

import numpy as np
import pandas as pd

# 假设我们有绿色资产价格数据
prices = pd.DataFrame({
    '绿色债券': [100, 102, 101, 105, 107],
    '碳中和ETF': [50, 51, 49, 52, 54],
    '新能源股票': [80, 78, 82, 85, 83]
})

# 简单收益率
simple_returns = prices.pct_change().dropna()

# 对数收益率
log_returns = np.log(prices / prices.shift(1)).dropna()

print("简单收益率:")
print(simple_returns)
print("\n对数收益率:")
print(log_returns)

我的经验:在做绿色资产波动率聚类时,对数收益率的统计性质更稳定。我曾经用简单收益率跑聚类,结果不同时间窗口的聚类结果差异巨大,换成对数收益率后稳定多了。

4.2 收益率分布特征分析

算完收益率,下一步就是看分布。绿色金融资产有个特点——它受政策影响大,所以尾部往往比普通资产更厚。

我记得有一次分析碳配额期货的收益率分布,发现它的峰度高达8.7,而正态分布只有3。这意味着什么?极端行情出现的概率比我们想象的大得多。

import scipy.stats as stats

# 计算描述性统计
def return_stats(returns):
    stats_dict = {
        '均值': returns.mean(),
        '标准差': returns.std(),
        '偏度': returns.skew(),
        '峰度': returns.kurtosis(),
        'JB检验': stats.jarque_bera(returns)
    }
    return pd.DataFrame(stats_dict)

# 分析绿色资产收益率
stats_result = return_stats(log_returns)
print(stats_result)
资产 均值 标准差 偏度 峰度
绿色债券 0.0087 0.0214 -0.32 4.12
碳中和ETF 0.0123 0.0356 0.15 5.87
新能源股票 0.0095 0.0482 -0.68 7.23

注意:绿色资产的峰度普遍偏高。我曾经在构建风险平价模型时忽略了这一点,结果回测表现很好,实盘却连续触发止损。后来我在模型里加入了尾部风险调整,才解决了这个问题。

4.3 相关性矩阵与热力图

相关性矩阵是风险平价模型的核心输入。但这里有个坑——你用的是Pearson相关系数还是Spearman秩相关系数?

我个人建议:对于绿色资产,先用Spearman。为什么?因为绿色资产经常出现非线性关系。比如碳价和新能源股价,它们的关系在政策出台前后完全不同。

import seaborn as sns
import matplotlib.pyplot as plt

# 计算相关性矩阵
corr_pearson = log_returns.corr(method='pearson')
corr_spearman = log_returns.corr(method='spearman')

# 可视化
fig, axes = plt.subplots(1, 2, figsize=(12, 5))

sns.heatmap(corr_pearson, annot=True, cmap='coolwarm', 
            center=0, ax=axes[0])
axes[0].set_title('Pearson相关系数')

sns.heatmap(corr_spearman, annot=True, cmap='coolwarm',
            center=0, ax=axes[1])
axes[1].set_title('Spearman秩相关系数')

plt.tight_layout()
plt.show()

关键洞察:绿色资产之间的相关性在极端市场环境下会急剧上升。我见过绿色债券和新能源股票的相关性从0.3飙到0.8。这就是所谓的「相关性危机」——分散化在关键时刻失效了。

4.4 绿色资产波动率聚类分析

波动率聚类,说白了就是看哪些资产的波动模式相似。这对风险平价模型特别重要——你总不想把两个波动模式完全相反的资产放在同一个风险因子下吧?

我常用的方法是基于GARCH模型提取条件波动率,然后做层次聚类。嗯,这里要注意:直接用收益率做聚类效果不好,因为收益率里包含太多噪声。

from sklearn.cluster import AgglomerativeClustering
from scipy.cluster.hierarchy import dendrogram, linkage

# 提取波动率特征(简化版:用滚动标准差)
volatility = log_returns.rolling(window=20).std().dropna()

# 层次聚类
Z = linkage(volatility.T, method='ward')

# 可视化树状图
plt.figure(figsize=(10, 6))
dendrogram(Z, labels=volatility.columns)
plt.title('绿色资产波动率聚类树状图')
plt.xlabel('资产')
plt.ylabel('距离')
plt.show()

避坑指南:我曾经直接用日收益率做聚类,结果把绿色债券和新能源股票分到了一类。后来才发现,这是因为它们在某段时间都受到同一个政策影响。正确的做法是先用GARCH模型过滤掉短期波动,再提取长期波动特征做聚类。

知识体系总览

下面这张图是我自己整理的,把本章的核心逻辑串起来了。你仔细看看,收益率计算是基础,分布特征分析是诊断,相关性矩阵是输入,波动率聚类是优化——每一步都环环相扣。

绿色金融资产收益率分析框架 第一步:收益率计算 简单收益率 → 对数收益率(推荐) 时间可加性、统计性质更优 第二步:分布特征分析 均值、标准差、偏度、峰度、JB检验 绿色资产尾部更厚,峰度偏高 第三步:相关性矩阵与热力图 Pearson vs Spearman,热力图可视化 注意极端市场下的相关性危机 第四步:波动率聚类分析 GARCH模型提取条件波动率 → 层次聚类 识别波动模式相似的资产组

好了,这一章的内容就到这里。收益率计算看似简单,但里面的门道不少。你回去可以把代码跑一遍,看看自己手上的绿色资产数据有什么特点。下一章我们会把这些收益率数据真正用到风险平价模型里,到时候你就知道今天打的基础有多重要了。


公众号:蓝海资料掘金营,微信deep3321