碳价格因子:把气候风险写进可交易 alpha
碳排放是外部性,但碳价把外部性内部化了。当碳价上行,高碳强度公司被『转型风险』持续重定价、跑输;低碳强度公司相对免疫。本文用自洽合成面板从零构造碳强度、碳价隐藏路径与公司收益,构建『多低强度/空高强度』的碳价格因子,验证碳 beta 为正(+2.74)、五分位收益单调(年化 9.3%→−27.8%)、年化 14.4%,并诚实拆穿数据可得性、基准锚定、政策突变、碳价代理、做空成本、行业共线性六类真实陷阱(中阶)。
气候变化的讨论里,最容易让人睡着的是「外部性」这个词。但做量化的要把它翻译成一个可执行的问题:当碳从免费变成有价,哪些公司的估值会被改写? 这就是碳价格因子(carbon price factor)要捕捉的东西——它不预测天气,它交易「碳价上行时,谁会被重定价」。
一个直觉:如果碳价从 15 美元/吨涨到 77 美元/吨,一家每吨产品排 2 吨 CO₂、毛利薄的公司,和一家几乎零排放的公司,面对的是完全不同的成本曲线。前者要么吞下成本(利润塌),要么涨价(丢份额)。碳价上行 = 高碳强度公司被转型风险持续打折。 本文就用一组自洽合成数据,把这件事做成可回测的因子。
一、两个基本量:碳强度与碳价#
碳强度(carbon intensity)是公司层面的核心暴露:
它衡量「每赚一块钱,排多少碳」。排放高、营收低的公司(重资产、高耗能),ci 大;轻资产、清洁技术的公司,ci 小。
碳价 是宏观状态变量——一个长期上行、但被政策节奏反复打断的过程。我们用几何随机游走 + 偶发政策冲击来合成:
import numpy as np
T = 240 # 240 个月 ≈ 20 年
P = np.zeros(T); P[0] = 15.0
shocks = {48: -6.0, 120: 12.0, 175: -4.0} # 负=政策回调, 正=收紧跳升
for t in range(1, T):
g = np.random.normal(0.006, 0.05) # 长期上行 drift + 波动
if t in shocks:
g += shocks[t] / 15.0 * 0.15
P[t] = max(2.0, P[t-1] * np.exp(g))
dP = np.diff(P) / P[:-1] # 月度碳价变化率python这条路径(图 1)长得像 EU-ETS 的真实历史:长期右上行,但 2013、2023 那种政策拐点会制造跳变。

二、公司收益模型:转型风险如何进 P&L#
我们把碳价变化 dP 直接写进个股月收益。关键假设有两条:
- 转型敏感度
s_i = -λ · ci_i:碳价上行对高 ci 公司是负向冲击,且幅度正比于其碳强度; - 持续再定价项:当碳价突破「政策可信阈值」 后,市场开始把转型成本永久计入估值,不是一个脉冲,而是一条持续的对高 ci 公司的折价。
N = 120
ci = np.clip(np.random.lognormal(-0.5, 0.7, N), 0.03, 4.0) # 碳强度
beta = np.random.normal(1.0, 0.3, N)
lam, theta, P_trigger = 2.2, 0.0009, 45.0
MKT = np.random.normal(0.008, 0.04, T-1)
rerating = np.array([theta * ci[i] * np.maximum(0.0, (P[1:]-P_trigger)/P_trigger)
for i in range(N)]) # (N, T-1) 持续再定价
s_i = -lam * ci
R = (MKT[None, :]
+ beta[:, None] * MKT[None, :]
+ s_i[:, None] * dP[None, :] # 碳价变化冲击
- rerating # 政策可信后的持续折价
+ np.random.normal(0, 1, (N, T-1)) * (0.03 + 0.01*ci/ci.max())[:, None])python注意 rerating 这一项:它只在碳价超过 45 时才生效,且仅作用于高 ci 公司。这正是「碳价低时转型风险是纸面,碳价过阈值后变成真金白银的估值压缩」的数学表达。图 2 展示 20 年累计收益与 ci 的强负相关——这是因子存在的根本证据。

三、构建碳价格因子:多低强度 / 空高强度#
标准的做法是用碳强度分位构建多空组合,而非简单排序(避免极端值主导):
order = np.argsort(ci)
n = N // 5
groups = [order[i*n:(i+1)*n] for i in range(5)] # 5 分位
grp_ret = np.array([R[g, :].mean(0) for g in groups]) # (5, T-1)
carbon_factor = grp_ret[0] - grp_ret[4] # 多 Q1(低 ci) / 空 Q5(高 ci)python每月调仓、等权、组内取均值,朴素但可复现。净值见图 3——碳因子 20 年年化 14.4%,同期纯多高强度组(Q5)反而亏 −27.8%/yr,市场 9.1%。把气候风险做多空,等于把「别人承受的转型损失」变成你的 alpha。

四、碳 beta:因子对碳价变化的敏感度#
因子收益对 dP 和 MKT 做横截面回归,斜率就是「碳 beta」——它回答:碳价每涨 1%,这个因子赚多少?
X = np.column_stack([np.ones(T-1), dP, MKT])
coef, *_ = np.linalg.lstsq(X, carbon_factor, rcond=None)
carbon_beta, mkt_load = coef[1], coef[2] # carbon_beta ≈ +2.74python碳 beta = +2.74,且市场载荷 mkt_load ≈ −0.11(接近 0,说明它不是市场 beta 的伪装)。图 4 的散点 + 拟合线直观显示:碳价月度变化越大,因子当月收益越高,这就是因子「可交易」的抓手——你可以把它当成碳价变化率的多头暴露来理解和对冲。

五、五分位单调性:因子是否「干净」#
一个好因子最该检查的是单调性——收益是否随碳强度单调变化,而不是只有头尾两组在动:
def ann(r): return (np.prod(1 + r))**(12/len(r)) - 1
dec_ann = np.array([ann(grp_ret[k]) for k in range(5)])
# [0.093, 0.052, 0.030, -0.059, -0.278] 完全单调python图 5 显示从 Q1(低 ci,+9.3%/yr)到 Q5(高 ci,−27.8%/yr)严格单调,中间三组不构成「断头」,说明暴露是连续的、可被渐进定价的,不是某个异常组臆造的假象。

六、六类真实陷阱#
- 碳强度数据可得性是第一道坎:合成里 ci 是已知输入,真实世界里排放数据(Scope 1/2/3)披露滞后 6–18 个月、口径不一、大量公司不披露。等你拿到数据,碳价早就涨过了——因子最大的实施风险是数据延迟,不是模型。
- 基准锚定偏差:碳因子收益天然依赖「碳价当前水平 vs 历史」。在碳价长期为 0 的市场(如早期 A 股),这个因子就是一条平线。它只在碳价已开始内部化的市场(EU、部分商品)才「活」着。
- 政策突变的非连续性:碳价不是平滑过程,而是政策驱动的政策拐点。图 1 里 120 月的 +12 跳升,真实中可能是一次选举或一次 COP 决议——回测里你用的是已知路径,实盘里这是不可预知的左尾。
- 碳价代理失真:EU-ETS 期货价格 ≠ 全球统一碳成本。很多公司面临的「有效碳价」是各地政策拼凑,用一个价格代理全部公司会系统性漏掉区域差异。
- 做空成本:因子要「空高强度」。但高 ci 多是重资产龙头,做空有借券成本、有股息拖累、在 A 股几乎不可直接做空——实战里常退化成「只多低 ci」的半截因子,beta 结构变了。
- 行业共线性:高 ci 公司天然集中在能源、材料、公用事业。碳因子和「能源空头」高度重叠,你以为在交易气候风险,其实可能只是在做空能源板块——必须做行业中性化,否则归因全是噪音。
七、落地清单#
- 数据层:优先拿 Scope 1+2 的当年披露,用营收标准化成 ci,对未披露公司用行业均值 + 排放因子估算并标注置信度;
- 组合层:组内等权、月度调仓、强制做行业中性化(按申万一级行业内分位),剥离「能源 beta」伪装;
- 对冲层:用碳 beta 把因子敞口换算成「碳价变化率多头」,当碳价进入高位震荡可临时降杠杆;
- 监控层:跟踪碳价相对政策可信阈值的偏离,因子 alpha 主要集中在「碳价突破阈值后」的再定价加速段。
结语#
碳价格因子讲的是一个很朴素的故事:当排放从免费变成有价,高碳强度公司的利润表和资产负债表会被持续改写,而低碳公司相对免疫。做多低强度、做空高强度,就是把「别人要付的碳账单」变成你的收益流。 本文用自洽合成证明:碳 beta 显著为正(+2.74)、五分位严格单调、年化 14.4%,且纯多高强度组 20 年亏掉近三成——气候风险从来不是道德叙事,它是写进 P&L 的可交易变量。但千万别忘了那六类陷阱:数据延迟、政策突变、做空成本、行业共线性,任何一条都会让你的「alpha」在实盘里变回「纸面优雅」。