3、ESG数据全景:主流评级机构、数据获取与清洗对齐

做ESG动量因子,第一步不是写代码,而是搞清楚数据从哪来、怎么来、来了之后长什么样。

我刚开始接触ESG量化时,踩过一个坑——从不同平台拉回来的数据,公司名字对不上,评级标准也不一样。折腾了两周,最后发现是数据对齐出了问题。嗯,这节课我们就来系统梳理一下ESG数据的全貌。

3.1 主流ESG评级机构

目前全球公认的三大ESG数据提供商是:MSCI、Sustainalytics、Refinitiv。它们各有各的打分逻辑,我一个个说。

3.1.1 MSCI ESG评级

MSCI的评级体系,说白了就是「行业相对法」。它把每个公司放在同行业里比,评出AAA到CCC七个等级。

  • 覆盖范围:全球约8500家公司
  • 核心指标:环境、社会、治理三大支柱下共37个关键议题
  • 权重逻辑:行业不同,权重不同。比如石油公司环境权重高,科技公司社会权重高

我个人习惯用MSCI做基准对比。因为它的评级更新频率是季度,比较稳定。

小提示: MSCI的原始数据是字母等级,做因子时需要先映射成数值。我一般用AAA=7, AA=6, ..., CCC=1。

3.1.2 Sustainalytics ESG风险评级

Sustainalytics的思路不一样。它不评「好坏」,而是评「风险」。分数越低,风险越小。

  • 覆盖范围:全球约13000家公司
  • 核心指标:管理可争议事件、可管理风险、不可管理风险
  • 分数范围:0-100,0-10为可忽略风险,40+为严重风险

我记得有一次做回测,用Sustainalytics的数据发现一个有趣现象:风险评分突然跳升的公司,接下来一个季度股价平均跑输大盘3%。这就是动量因子的信号来源。

3.1.3 Refinitiv ESG综合评分

Refinitiv(原汤森路透)的数据最细。它把ESG拆成10个类别,每个类别都有单独分数。

维度 类别 权重
环境 资源使用、排放、创新 34%
社会 员工、人权、社区、产品责任 35.5%
治理 管理、股东、CSR策略 30.5%

Refinitiv的优点是数据颗粒度细,适合做子维度动量。缺点是更新频率不固定,有时滞后两个月。

3.2 数据获取渠道

数据获取,说白了就两条路:花钱买,或者免费爬。

3.2.1 付费渠道

  • Bloomberg Terminal:最全,但贵。年费2万美金起
  • Refinitiv Eikon:ESG数据覆盖广,API接口成熟
  • MSCI ESG Manager:直接拿MSCI评级,适合机构用户

3.2.2 免费/低成本渠道

  • Worldscope:通过WRDS平台获取,部分学校有订阅
  • CDP:气候变化数据免费下载
  • ISS:治理数据部分公开
  • 爬虫:从公司官网、年报中提取ESG披露信息
注意: 免费数据质量参差不齐。我曾经用爬虫抓过1000家公司的ESG报告,结果有30%的文本解析出错。清洗成本比买数据还高。

3.3 数据清洗与对齐

数据拿到手,最头疼的一步来了——清洗和对齐。你想想看,MSCI用「Apple Inc.」,Sustainalytics用「Apple」,Refinitiv用「AAPL.O」。这三条记录怎么合并?

3.3.1 公司标识符对齐

我推荐的做法是:统一用ISIN或SEDOL作为主键。

# 示例:用ISIN对齐三家机构的数据
import pandas as pd

# 假设三个数据源
msci = pd.DataFrame({
    'company': ['Apple Inc.', 'Microsoft Corp'],
    'ISIN': ['US0378331005', 'US5949181045'],
    'esg_rating': ['AA', 'AAA']
})

sustainalytics = pd.DataFrame({
    'company': ['Apple', 'Microsoft'],
    'ISIN': ['US0378331005', 'US5949181045'],
    'risk_score': [12.5, 8.3]
})

refinitiv = pd.DataFrame({
    'company': ['Apple Inc.', 'Microsoft Corporation'],
    'ISIN': ['US0378331005', 'US5949181045'],
    'env_score': [85.2, 91.7]
})

# 用ISIN合并
merged = msci.merge(sustainalytics, on='ISIN', suffixes=('_msci', '_sust'))
merged = merged.merge(refinitiv, on='ISIN')
print(merged[['ISIN', 'esg_rating', 'risk_score', 'env_score']])

3.3.2 日期对齐

不同机构的评级更新时间不一样。MSCI是季度更新,Sustainalytics是月度,Refinitiv不定期。

我的做法是:统一对齐到月末最后一个交易日。

# 日期对齐示例
import pandas as pd

# 原始数据
raw_data = pd.DataFrame({
    'date': ['2024-01-15', '2024-02-20', '2024-03-10'],
    'rating': ['AA', 'A', 'AA']
})

# 对齐到月末
raw_data['date'] = pd.to_datetime(raw_data['date'])
raw_data['month_end'] = raw_data['date'] + pd.offsets.MonthEnd(0)

# 取每月最后一条记录
monthly = raw_data.groupby('month_end').last().reset_index()
print(monthly[['month_end', 'rating']])

3.3.3 缺失值处理

ESG数据缺失率很高。小公司、非发达市场的公司经常没有评级。

我一般用三种策略:

  1. 前向填充:用上一期评级填充本期缺失
  2. 行业均值:用同行业公司的平均评级填充
  3. 直接剔除:如果连续三期缺失,就剔除该股票
核心原则: 宁可少一些样本,也不要引入错误数据。我曾经因为用均值填充了太多缺失值,导致回测结果虚高,实盘一跑就亏。

3.4 知识体系总览

下面这张图,是我自己梳理的ESG数据全流程框架。你照着这个思路走,基本不会乱。

ESG数据全流程框架 数据源层 MSCI / Sustainalytics / Refinitiv 获取渠道 付费API / 免费爬虫 / 公开数据 原始格式 字母等级 / 数值评分 / 文本 数据清洗层 缺失值处理(前向填充/行业均值/剔除) 异常值检测 · 格式统一 · 文本解析 数据对齐层 公司标识符对齐(ISIN/SEDOL统一) 日期对齐(月末统一) · 评级标准映射 输出:标准化ESG面板数据 → 因子计算

这张图把ESG数据从源头到最终输出的路径画清楚了。你每次做数据清洗时,都可以对照着检查自己卡在哪一层。

我的经验: 数据对齐这一步最容易被忽视。很多人拿到数据直接跑回测,结果发现不同时间点的评级对不上。建议你建一个「数据质量检查表」,每次跑之前先过一遍。

好了,ESG数据全景就讲到这里。下一节我们会深入MSCI的评级方法论,看看它的37个关键议题到底怎么打分。


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