第1章:绿色资产数据获取与清洗

做绿色金融量化模型,最头疼的是什么?

不是策略设计,不是回测框架。是数据。

我做了这么多年,见过太多人模型写得漂亮,结果数据一塌糊涂,最后全白干。绿色金融的数据尤其麻烦——绿色债券的发行标准不统一,ESG评分各家机构各玩各的,数据缺失更是家常便饭。

这一章,咱们就把这些坑一个一个填上。

1.1 绿色债券数据源介绍

绿色债券的数据源,我把它分成三类:官方认证渠道、第三方数据商、交易所公开信息。

数据源类型 代表机构 特点 我个人的使用建议
官方认证 气候债券倡议组织(CBI) 标准严格,覆盖面广 做基准分析时首选
第三方数据商 Wind、Bloomberg 数据齐全,但收费高 机构用户必备
交易所公开信息 上交所、深交所 免费,但格式不统一 适合小团队起步

我在项目中遇到过最尴尬的事——用了某家数据商的绿色债券标签,结果发现里面混了不少"漂绿"债券。后来我学乖了,一定要交叉验证。比如CBI认证的债券,再去交易所核对一下资金用途说明。

小技巧: 如果你刚开始做绿色债券研究,建议先从CBI的绿色债券数据库入手。他们每年发布报告,数据质量相对可靠。我一般会同时拉取Wind的数据做对照。

1.2 ESG评分数据获取

ESG评分这东西,说白了就是各家评级机构对公司的"主观打分"。MSCI、Sustainalytics、商道融绿……每家都有自己的方法论。

为什么会这样?因为ESG本身就没有统一的定义。你觉得碳排放重要,我觉得劳工权益重要,评分自然不一样。

获取ESG数据,我常用的方式:

  • MSCI ESG Ratings:覆盖面最广,但需要订阅
  • Sustainalytics:风险导向型评分,适合做风控
  • 商道融绿:国内A股覆盖好,性价比高
  • Refinitiv:数据维度细,适合做因子拆解

嗯,这里要注意——不同机构的ESG评分相关性其实不高。我做过一次统计,MSCI和Sustainalytics对同一家公司的评分,相关系数只有0.6左右。所以做模型时,千万别只依赖一家数据源

避坑指南: 我曾经因为只用了一家ESG数据,导致模型在回测时表现很好,实盘却一塌糊涂。后来发现是那家数据商对某些行业的评分有系统性偏差。建议至少用两家数据源做交叉验证。

1.3 数据缺失值处理

绿色金融数据缺失是常态。尤其是早期的绿色债券,很多发行信息都不完整。ESG评分更是如此——小公司可能根本没有评级。

处理缺失值,我一般按这个优先级来:

  1. 删除法:缺失比例超过50%的字段,直接删掉
  2. 均值/中位数填充:适用于数值型数据,比如债券收益率
  3. 前向/后向填充:适用于时间序列数据,比如ESG评分的变化
  4. 模型预测填充:用KNN或随机森林预测缺失值

你想想看,如果一只绿色债券的发行规模缺失了,用均值填充问题不大。但如果它的ESG评分缺失了,用均值填充就可能出大问题——因为ESG评分和行业高度相关。

# 我常用的缺失值处理代码
import pandas as pd
import numpy as np

def handle_missing_values(df, method='median'):
    """
    处理绿色金融数据的缺失值
    method: 'median', 'forward_fill', 'knn'
    """
    if method == 'median':
        # 按行业分组填充中位数
        for col in df.columns:
            if df[col].isnull().sum() > 0:
                df[col] = df.groupby('industry')[col].transform(
                    lambda x: x.fillna(x.median())
                )
    elif method == 'forward_fill':
        # 时间序列前向填充
        df = df.fillna(method='ffill')
    
    return df
核心原则: 缺失值处理没有银弹。我的经验是——先理解数据为什么缺失,再决定怎么处理。如果是系统性缺失(比如小公司没有ESG评分),那就要考虑是否要调整样本范围。

1.4 异常值检测与修正

异常值在绿色金融数据里很常见。比如某只绿色债券的收益率突然飙升到20%,或者某公司的ESG评分一夜之间从60跳到95。

为什么会这样?可能是数据录入错误,也可能是公司发生了重大事件。但不管怎样,异常值会严重扭曲模型结果。

我常用的异常值检测方法:

  • Z-score方法:适用于正态分布的数据,比如债券收益率
  • IQR方法:适用于偏态分布的数据,比如ESG评分
  • 孤立森林:适用于高维数据,比如多因子模型

记得有一次,我在做绿色债券的波动率模型时,发现某只债券的日收益率出现了-15%的异常值。查了半天,原来是数据商把债券除息日的数据搞错了。这种错误,用Z-score一抓一个准。

# 异常值检测示例
def detect_outliers_iqr(df, column):
    Q1 = df[column].quantile(0.25)
    Q3 = df[column].quantile(0.75)
    IQR = Q3 - Q1
    
    lower_bound = Q1 - 1.5 * IQR
    upper_bound = Q3 + 1.5 * IQR
    
    outliers = df[(df[column] < lower_bound) | 
                  (df[column] > upper_bound)]
    return outliers
注意: 异常值不一定要删除。如果异常值反映了真实的市场事件(比如某公司爆出环境丑闻导致ESG评分暴跌),那反而应该保留。我一般会先标记异常值,再根据业务逻辑判断是否修正。

1.5 数据标准化方法

绿色金融数据里,各种指标的量纲差异巨大。债券收益率是百分之几,ESG评分是0-100,发行规模是亿元。如果不做标准化,模型就会"偏爱"数值大的特征。

我常用的标准化方法:

方法 公式 适用场景
Z-score标准化 (x - μ) / σ 数据近似正态分布
Min-Max标准化 (x - min) / (max - min) 数据有明确边界
Robust标准化 (x - median) / IQR 数据有异常值

我个人习惯用Robust标准化处理绿色金融数据。为什么?因为ESG评分经常有异常值,用Z-score会被极端值拉偏。Robust标准化用中位数和四分位距,抗干扰能力强。

# 标准化代码示例
from sklearn.preprocessing import RobustScaler

def standardize_green_finance_data(df, columns):
    scaler = RobustScaler()
    df[columns] = scaler.fit_transform(df[columns])
    return df, scaler
实战建议: 标准化后记得保存scaler对象。这样在实盘时,可以用同样的参数对新数据进行标准化,保证一致性。

本章知识体系

下面这张图,是我梳理的绿色资产数据获取与清洗的完整流程。你可以把它当作操作手册来用。

绿色资产数据获取与清洗流程 数据获取 ESG评分获取 交叉验证 缺失值处理 异常值检测与修正 数据标准化 清洗后的高质量数据集 风险平价模型构建 数据质量决定了模型的上限,花80%的时间在数据上,一点都不为过

数据清洗这件事,说白了就是"垃圾进,垃圾出"。你模型再厉害,数据不行全白搭。我见过太多人花一周写模型,却只花一天处理数据——结果模型跑出来全是噪音。

这一章的内容,是我这些年踩坑踩出来的经验。绿色金融的数据处理没有捷径,但有了这套流程,至少能帮你少走弯路。


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