1. 绿色金融数据概览:什么是绿色金融数据?
说实话,我刚入行那会儿,对「绿色金融数据」这个概念也挺模糊的。大家一上来就聊ESG、碳排放、绿色债券,听着挺唬人。但说白了,绿色金融数据就是——用来衡量一家企业、一个项目或者一项资产,到底有多「绿」的数据。
我个人习惯把这类数据分成两大类:一类是定性数据,比如ESG评级里的治理结构描述;另一类是定量数据,比如碳排放量、绿色信贷余额。嗯,这里要注意,定量数据才是我们做因子挖掘的主力军。
1.1 数据来源:你从哪里搞到这些数据?
我遇到过不少刚入行的朋友,一上来就问:「老师,绿色金融数据去哪儿找?」其实渠道挺多的,但质量参差不齐。我列几个主要的:
- ESG评级数据:MSCI、Sustainalytics、商道融绿、华证指数等。这些评级机构会给出综合评分,但各家标准不一样,你想想看,同一家公司,MSCI给A,商道融绿可能给B+,这就是典型的「评级分歧」问题。
- 碳排放数据:CDP(碳披露项目)、各交易所强制披露的碳排放报告、还有第三方核查数据。我个人经验是,碳排放数据缺失率极高,尤其是Scope 3(供应链排放),很多公司根本不报。
- 绿色债券数据:气候债券倡议组织(CBI)、中央结算公司、Wind等。绿色债券的关键字段包括:募集资金用途、第三方认证、存续期信息披露。
- 绿色信贷数据:央行、银保监会、各银行年报。这块数据比较「重」,通常以季度或年度频率更新。
- 环境处罚数据:各级环保部门官网、蔚蓝地图等。这类数据时效性很强,适合做事件驱动因子。
核心观点:绿色金融数据不是「一个数据源」能搞定的。我建议你至少整合3个以上来源,做交叉验证。否则,单源数据里的坑,能让你哭都哭不出来。
1.2 数据特征:这些数据到底长什么样?
搞量化的人,最怕的就是数据不干净。绿色金融数据在这方面,简直是「重灾区」。我总结了几大特征,你感受一下:
| 特征 | 说明 | 我的踩坑经历 |
|---|---|---|
| 高缺失率 | 很多公司不披露碳排放数据,尤其是中小盘股。ESG评级也经常出现「无评级」的情况。 | 我曾经做过一个A股全样本的碳排放因子,结果发现超过60%的公司没有数据。最后只能用行业均值填充,效果嘛……嗯,你懂的。 |
| 频率不统一 | ESG评级通常是季度或年度更新,碳排放数据一年一次,而股价是日频。怎么对齐?这是个头疼的问题。 | 我建议的做法是:低频数据向前填充,但要注意避免「未来信息」泄露。 |
| 标准不一致 | 不同评级机构对同一家公司的评分可能天差地别。比如,特斯拉在MSCI里是AAA,但在某些机构眼里可能只是B。 | 这其实是个「因子噪音」问题。我一般会取多家评级的排名百分位均值,而不是直接用原始分数。 |
| 数据漂移 | 评级机构会回溯调整历史评级。你今天下载的数据,和三个月前下载的同一时间点的数据,可能不一样。 | 这很坑!我建议你每次下载数据都打上时间戳,并且保留原始版本,别覆盖。 |
| 非线性关系 | 碳排放量和股价之间,往往不是简单的线性关系。比如,碳排放突然大幅增加,可能是企业扩张导致的,也可能是环保事故导致的。 | 所以做因子时,我习惯先做分位数变换,或者用排名代替原始值。 |
1.3 知识体系:一张图看懂绿色金融数据
下面这张图,是我自己梳理的绿色金融数据知识体系。你把它存下来,以后做数据清洗和因子构造时,随时回来对照。
1.4 避坑指南:我踩过的那些坑
坑1:盲目相信单一评级
我曾经用某家机构的ESG评级直接做因子,回测效果特别好。结果一上实盘,完全失效。后来才发现,那家机构在回测期内修改了评级方法论,导致历史数据被「优化」了。所以我现在做任何因子,至少用3家机构的评级做等权合成。
小技巧:如何处理碳排放数据的缺失值?
我个人的做法是:如果某公司连续3年都没有碳排放数据,直接剔除。如果只是偶尔缺失,用行业-规模分组的均值来填充。注意,千万别用全样本均值,那会抹平行业差异。
坑2:忽略数据的时间戳
绿色金融数据经常被回溯修正。比如,你今天下载的2023年碳排放数据,和明年下载的2023年数据,可能不一样。我建议你每次下载都记录下载日期,并且保留原始文件。别问我为什么知道——我曾经因为覆盖了原始数据,导致整个因子库重建,那叫一个酸爽。
1.5 代码示例:快速检查数据质量
下面这段代码,是我每次拿到新数据后必跑的「体检」脚本。你直接拿去用:
import pandas as pd
import numpy as np
def green_data_quality_check(df, date_col='date', id_col='stock_code'):
"""
绿色金融数据质量快速检查
"""
print("="*50)
print("数据质量报告")
print("="*50)
# 1. 缺失率统计
missing_rate = df.isnull().mean().sort_values(ascending=False)
print("\n>>> 缺失率最高的5个字段:")
print(missing_rate.head())
# 2. 时间跨度
print(f"\n>>> 时间跨度:{df[date_col].min()} 至 {df[date_col].max()}")
# 3. 样本数量
print(f">>> 总记录数:{len(df):,}")
print(f">>> 唯一股票数:{df[id_col].nunique()}")
# 4. 检查是否有未来数据(常见坑!)
latest_date = df[date_col].max()
print(f">>> 最新数据日期:{latest_date}")
# 5. 检查是否有重复记录
dup_count = df.duplicated(subset=[date_col, id_col]).sum()
if dup_count > 0:
print(f"\n⚠️ 发现 {dup_count} 条重复记录,建议去重!")
else:
print("\n✅ 无重复记录")
return missing_rate
# 使用示例
# df = pd.read_csv('esg_data.csv')
# green_data_quality_check(df)
我的习惯:每次跑完这个检查,我都会把结果截图保存。这样万一以后因子出问题,可以快速定位是数据本身的问题,还是模型的问题。