3、ESG数据全景:主流评级机构、数据获取与清洗对齐
做ESG动量因子,第一步不是写代码,而是搞清楚数据从哪来、怎么来、来了之后长什么样。
我刚开始接触ESG量化时,踩过一个坑——从不同平台拉回来的数据,公司名字对不上,评级标准也不一样。折腾了两周,最后发现是数据对齐出了问题。嗯,这节课我们就来系统梳理一下ESG数据的全貌。
3.1 主流ESG评级机构
目前全球公认的三大ESG数据提供商是:MSCI、Sustainalytics、Refinitiv。它们各有各的打分逻辑,我一个个说。
3.1.1 MSCI ESG评级
MSCI的评级体系,说白了就是「行业相对法」。它把每个公司放在同行业里比,评出AAA到CCC七个等级。
- 覆盖范围:全球约8500家公司
- 核心指标:环境、社会、治理三大支柱下共37个关键议题
- 权重逻辑:行业不同,权重不同。比如石油公司环境权重高,科技公司社会权重高
我个人习惯用MSCI做基准对比。因为它的评级更新频率是季度,比较稳定。
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披露信息
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数据缺失率很高。小公司、非发达市场的公司经常没有评级。
我一般用三种策略:
- 前向填充:用上一期评级填充本期缺失
- 行业均值:用同行业公司的平均评级填充
- 直接剔除:如果连续三期缺失,就剔除该股票
3.4 知识体系总览
下面这张图,是我自己梳理的ESG数据全流程框架。你照着这个思路走,基本不会乱。
这张图把ESG数据从源头到最终输出的路径画清楚了。你每次做数据清洗时,都可以对照着检查自己卡在哪一层。
好了,ESG数据全景就讲到这里。下一节我们会深入MSCI的评级方法论,看看它的37个关键议题到底怎么打分。
公众号:蓝海资料掘金营,微信deep3321