数据基础设施:主流ESG评级机构对比与数据清洗实战

做量化投资的朋友都知道一句话:垃圾进,垃圾出。ESG整合策略更是如此——评级数据本身就不干净,你指望它能跑出什么好结果?

今天咱们就聊聊ESG数据基础设施怎么搭。我踩过的坑不少,希望能帮你省点时间。

一、三大评级机构:谁的数据更靠谱?

目前市场上主流的ESG评级机构有三家:MSCI、Sustainalytics、Refinitiv。每家都有自己的脾气。

维度 MSCI Sustainalytics Refinitiv
覆盖范围 约8500家公司 约12000家公司 约7000家公司
评级体系 AAA-CCC七档 0-100分+风险等级 0-100分+四档
数据更新频率 季度/事件驱动 月度/事件驱动 年度为主
争议事件处理 有专门模块 强项,实时监控 较弱
API成熟度 中等 较好 优秀

我个人习惯:做多因子模型时用MSCI,做风险控制时用Sustainalytics。为什么?MSCI的评级更偏向「好公司」的筛选,而Sustainalytics对争议事件的敏感度更高——你想想看,一个突然爆出环境污染的公司,Sustainalytics的反应速度比MSCI快至少两周。

核心观点:不要迷信任何一家评级机构。我建议至少融合两家数据源,取交集或加权平均。单一数据源的偏差可能让你的策略在回测中看起来很美,实盘却一塌糊涂。

二、数据获取渠道与API实战

数据怎么拿?三种方式:

  1. 直接购买:MSCI、Sustainalytics都有官方数据订阅,价格不菲。小团队慎入。
  2. 第三方聚合平台:比如Bloomberg Terminal、FactSet,但API调用有次数限制。
  3. 开源/免费渠道:World Bank、CDP、SASB有部分免费数据,但覆盖不全。

这里我重点说说API调用。以Refinitiv为例,它的API设计得比较友好:

# Refinitiv ESG API 调用示例
import requests
import json

# 配置你的API密钥
api_key = "your_refinitiv_api_key"
base_url = "https://api.refinitiv.com/esg/v1"

# 获取某公司的ESG综合评分
def get_esg_score(ric_code):
    endpoint = f"{base_url}/scores/{ric_code}"
    headers = {
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json"
    }
    params = {
        "fields": "esgScore,environmentalScore,socialScore,governanceScore",
        "date": "2024-12-31"
    }
    
    response = requests.get(endpoint, headers=headers, params=params)
    if response.status_code == 200:
        return response.json()
    else:
        print(f"请求失败: {response.status_code}")
        return None

# 调用示例
result = get_esg_score("AAPL.O")
print(json.dumps(result, indent=2))

避坑指南:我曾经在调用MSCI的API时,发现返回的数据里有些字段是空的。后来排查发现,MSCI对某些小市值公司只披露了部分指标。所以,一定要做缺失值检查,别直接拿过来就用。

三、数据清洗与标准化——这才是重头戏

数据拿到手了,但不同来源的格式、单位、评分标准都不一样。怎么办?

第一步:统一评分尺度

MSCI是AAA-CCC,Sustainalytics是0-100,Refinitiv也是0-100但分档不同。我一般会做百分制映射:

# MSCI评级转百分制
def msci_to_percent(msci_rating):
    mapping = {
        "AAA": 95, "AA": 85, "A": 75,
        "BBB": 65, "BB": 55, "B": 45,
        "CCC": 30
    }
    return mapping.get(msci_rating.upper(), None)

# Sustainalytics风险评分转正向评分(越低越好转越高越好)
def sustainalytics_to_percent(risk_score):
    # 假设风险评分范围0-100,越低越好
    return 100 - risk_score

# Refinitiv直接是0-100,但需要检查是否标准化
def refinitiv_to_percent(raw_score):
    # 有些版本返回的是0-1的小数
    if raw_score <= 1:
        return raw_score * 100
    return raw_score

第二步:处理时间对齐

不同机构的更新频率不同。MSCI可能3月更新,Sustainalytics可能4月才更新。你建模型时,时间戳必须对齐。

我的做法:取每个季度末的最新评级。如果某家机构在该季度没有更新,就用上一季度的数据填充。

注意:千万别用「前向填充」!我曾经犯过这个错——用未来的数据填充过去,回测结果漂亮得离谱,实盘直接打脸。一定要用「后向填充」或「最近可用值」。

第三步:异常值处理

ESG数据里经常出现极端值。比如某公司突然从AA跌到CCC,可能是数据错误,也可能是重大事件。怎么区分?

  • 3σ原则:超过均值±3个标准差的值,标记为可疑
  • IQR方法:四分位距法,更稳健
  • 业务规则:比如评级不可能在一天内从AAA跌到CCC,除非有确凿证据
# 异常值检测示例
import numpy as np

def detect_outliers_iqr(data):
    Q1 = np.percentile(data, 25)
    Q3 = np.percentile(data, 75)
    IQR = Q3 - Q1
    lower_bound = Q1 - 1.5 * IQR
    upper_bound = Q3 + 1.5 * IQR
    return (data < lower_bound) | (data > upper_bound)

# 应用
esg_scores = np.array([85, 90, 88, 92, 30, 87, 91])  # 30是异常值
outliers = detect_outliers_iqr(esg_scores)
print(f"异常值位置: {np.where(outliers)[0]}")

四、知识体系框架

下面这张图概括了ESG数据基础设施的核心流程:

ESG数据基础设施核心流程 数据源层 MSCI Sustainalytics Refinitiv 其他来源 数据获取层 官方API 第三方平台 爬虫/文件导入 数据清洗与标准化层 评分映射 时间对齐 异常值处理 缺失值填充 输出层 标准化ESG评分矩阵 量化模型输入

说白了,数据基础设施就是四个字:干净、对齐、可用。你花80%的时间在数据清洗上,剩下20%的时间建模,这才是正常的比例。如果反过来,你的模型大概率会出问题。

最后说一句:ESG数据不像股价数据那样标准化。每家机构都有自己的方法论,甚至同一家机构不同年份的方法论都可能变。所以,版本控制很重要——我每次更新数据都会记录评级机构的方法论版本号,方便回溯。


蓝海数据掘金营,专注资料整理