做债券数据的人大概都有过这种体验:一份看着很简单的数据需求——“把近三年绿色债券的发行明细给我,按债券分类拆一下”,真正落到终端里,变成几百上千行、几十个字段、多套口径的原始表格之后,麻烦才刚开始。同样是“绿色债券”,在不同的分类栏里能给出不同的答案;同样一只债,按品种是一类,按募集资金用途又是一类,按市场归属再变一次。标题里的“绿色债券基本资料-债券分类”,说的其实就是这件看起来很枯燥、实际非常吃功力的事:把一只绿色债券的静态基础档案,和它所处的分类体系对应起来,形成一张能被人信任、能拿去跑统计、能做后续分析的底表。这篇内容我会把自己在数据整理、口径对齐、字段映射上踩过的坑摊开来说,重点讲清楚三件事:绿色债券的基本资料到底包含哪些维度、债券分类为什么必须做成“一棵树”而不是一堆标签、以及从数据终端里把这个样本拉出来并洗干净的全过程。适合两类人看:一类是刚开始接手债券数据需求、需要一个能照抄的操作路径;另一类是做投研、做统计、做数据治理,被“同一个数不同人算出不同结果”折磨过的同行。
1. 先把标题拆开看:绿色债券基本资料和债券分类到底卡在哪
1.1 从“基本资料”这个词读懂数据需求的真实颗粒度
“基本资料”这四个字在债券语境里,指的是一整套静态描述字段,跟行情、估值这种动态序列完全是两回事。静态意味着它在一只债券的生命周期内基本不变,或者变化频率极低:债券代码、债券简称、发行主体、发行日期、起息日、到期日、发行规模、票面利率、付息频率、计息方式、担保方式、债项评级、主体评级、上市流通场所、含权条款、是否跨市场等等。这套东西拼起来,构成了债券的“身份证”。
问题在于,身份证上的信息不是一个部门、一个时点录进去的,而是分散在发行文件、上市公告、评级报告、募集说明书多个来源里。我见过最常见的情况是:同一个字段,通用债券库里有值,绿色专项库里也有值,但两者不一致。比如发行规模,一处填的是计划发行规模,一处填的是实际发行规模;再比如到期日,含权债里填的是行权日还是法定到期日,不同表口径不同。
所以第一件事不是急着筛“绿色”,而是先想清楚这张底表最终要回答什么问题。如果只是统计绿色债券的发行只数和规模,那字段只要十来个就够;如果要做期限结构、利率分布、主体集中度分析,就得把评级、期限、票面、含权这些字段一并拉全。颗粒度定错了,后面筛得再准也是白干。我的建议是:宁可第一版多拉十个字段,也不要为了“表好看”把可能用到的维度砍掉,因为补数据的成本远高于删列。
1.2 为什么不能用“名字里带绿色”来做筛选
新手最容易犯的错,是在债券简称里做关键词匹配,把带“绿色”“碳中和”“低碳”“可持续”字样的全捞出来,当成绿色债券样本。这个做法在早期样本量小的时候能凑合,规模一大就彻底失效,原因至少有三个。
第一,命名不规范。债券简称有长度限制,很多发行人在起名时为了塞进主体名和期数,会主动省略“绿色”二字,导致一只正儿八经的绿色债,简称里根本找不到关键词。反过来,一些名字带“绿色”的其实是发行人名号里带了相关字样,跟募集资金用途毫无关系。
第二,子集关系被压平。贴标绿色债券内部还分层:普通绿色债、绿色资产支持证券、碳减排相关主题债、可持续挂钩类产品。这些在名称上未必能区分,但在分类字段里是明确的。用关键词匹配会把它们揉成一团,后续做细分统计时又得手工拆。
第三,跨市场重复。同一期债券在银行间和交易所两个场所流通时,可能对应不同的代码或不同的登记托管记录,简称也可能有细微差异。纯靠名称匹配再去重,非常容易漏掉或者重复计算。
注意:关键词匹配只能当“校验手段”,不能当“筛选主逻辑”。真正的筛选入口应该是终端里那套结构化的分类字段和专项标识字段。
1.3 分类字段的本质:给一只债打上多个正交的属性
债券分类在数据终端里从来不是单一字段,而是多组互相独立的维度。理解这一点,后面所有操作都会顺。我一般把分类维度分成四组:
- 品种维度:这只债在发行审批和流通环节属于哪一类产品,决定了它的信息披露要求、投资者适当性、交易规则。
- 信用维度:利率债还是信用债,有没有增信,评级落在哪个区间。
- 结构维度:固定利率还是浮动利率,是否含权,是否永续,期限落在哪个区间。
- 主题维度:绿色、社会责任、乡村振兴、科技创新等专项标签。
主题维度跟前面三组是正交的,一只绿色债同时也可以是含权的中期品种、可以是高等级信用债。这就是为什么不能把“绿色”塞进品种分类的某一级里,否则整棵树就乱了。标题里“债券分类”这四个字的分量,就在这里。
2. 绿色债券基本资料该包含哪些维度
2.1 债项层与主体层的信息必须分开存放
做底表最容易混的一件事,是把发行主体的信息和债项的信息塞在同一行里不分彼此。主体信息是“谁借的钱”:主体名称、所属行业、企业性质、注册地、主体评级、主体评级展望。债项信息是“这一笔借款的条款”:债券代码、发行规模、票面利率、期限、担保、债项评级、募集资金用途。
分开的意义在于,一只主体可以发很多只债,主体评级下调会同时影响它名下所有债,但债项评级因为有担保可能只影响其中几只。如果底表里主体和债项混着存,做主体集中度统计时就会把同一主体不同期的规模重复计入主体个数,做债项统计时又会因为主体字段冗余而难以更新。
我在建表时会强制拆成两张:一张主体维表,一张债项明细表,用主体唯一标识关联。哪怕只是临时分析,也建议在表格里用列名前缀区分,比如issuer_和bond_,后期透视的时候一目了然。这个习惯看起来啰嗦,但当你需要把绿色债券样本和全市场债券样本做对比时,主体维表可以直接复用,省掉大量重复劳动。
2.2 募集资金用途字段是绿色属性的根,但往往最不结构化
绿色债券之所以是绿色债券,核心在于募集资金投向。国内主流标准对绿色项目的界定,一般围绕节能环保、清洁能源、清洁交通、生态保护与修复、资源循环利用、绿色建筑、水资源节约等大类展开。数据终端里对这一块的记录方式差异很大:有的给一个粗颗粒的主题标签,有的给一段自由文本描述,有的干脆只标记“是否绿色”布尔值。
自由文本最要命。我整理过一批样本,描述字段里出现过的写法有十几种:“用于某风电项目”“补充绿色项目流动资金”“偿还绿色项目前期借款”“投向清洁能源领域”……你没法用一两条规则全覆盖。我的处理方式是分两步:先按结构化标签做主筛选,再把自由文本导出来,用关键词规则粗分类,最后人工抽查一批确认规则是否合理。
这里还有个隐蔽的坑:募集资金用途里可能同时包含绿色项目和非绿色项目,也就是“部分绿色”。这类债在有些口径下算绿色,在另一些口径下不算。做统计时必须明确写清楚你的处理原则,是全额计入还是按比例折算,否则不同人算出来的规模差异会非常大。
2.3 第三方评估认证信息是判断贴标质量的关键字段
贴标绿色债券通常会有一份独立的评估认证意见,说明募集资金投向是否符合某一套绿色标准,以及管理机制是否健全。这份信息在数据终端里往往以“是否经第三方认证”“认证机构”“认证结论”这类字段体现。
为什么这个字段重要?因为同是贴标绿债,认证质量差别不小。有的只做了发行前认证,没有存续期跟踪;有的做了存续期年度评估;有的只是在募集说明书里做了自我声明。做深度分析时,把“有第三方认证”和“无第三方认证”分开看,得到的结论会很不一样。
提示:如果终端里这个字段缺失率高,不要急着用 0 填充。缺失和“明确未认证”是两回事,混在一起会系统性低估认证比例。建议单独做一个“未知”类别,在最终报告里披露缺失占比。
2.4 分类标签与基本资料要建立稳定的映射关系
基本资料是“事实”,分类标签是“判断”。事实可以直接从终端字段取,判断则依赖口径和规则。比如一只债是否属于“碳减排相关主题”,取决于它有没有明确披露碳减排量测算、募集资金是否全部投向符合条件领域,这个判断过程需要一套规则。
我的做法是单独维护一张映射表,把终端字段、规则、结果三者对应起来。表里至少包含:字段来源、原始取值、判定规则、判定结果、置信度、备注。这张表看着土,但它是整个数据资产里最值钱的部分——口径变了,改映射表就行,不用推翻重做;换一个人接手,看表就能明白每个数字怎么来的。
3. 债券分类体系的设计思路:做成树,而不是贴一墙标签
3.1 一级到四级分类的拆法与实践经验
一套能长期用的债券分类,层级不宜太深也不宜太浅。太浅,颗粒度不够,做细分分析时无路可走;太深,维护成本陡增,且大量节点是空的。我的经验是四级封顶,且每一级的划分依据必须单一。
| 层级 | 划分依据 | 典型节点示例 | 使用场景 |
|---|---|---|---|
| 一级 | 信用属性 | 利率债类、信用债类 | 大类资产配置、风险敞口统计 |
| 二级 | 审批与流通品种 | 债务融资工具类、公司债类、资产支持证券类等 | 监管报送、发行统计 |
| 三级 | 计息与结构特征 | 固定利率、浮动利率、含权、永续 | 久期测算、条款分析 |
| 四级 | 专项主题标签 | 绿色、社会责任、科技创新等 | 主题投资、专项统计 |
关键点在第四级:主题标签挂在这一层,意味着它是“附加属性”,不破坏前三级的结构。这样一只含权的固定利率绿色债,路径是清晰的:信用债类 → 某品种 → 含权固定利率 → 绿色。任何一个维度单独抽出来做透视,都不会矛盾。
我见过反面案例:有人把“绿色债券”直接做成了二级分类的一个节点,结果所有绿色债都被强制归到这一类,品种信息丢失,做发行审批口径统计时数据对不上,只能返工。
3.2 绿色属性的子标签怎么切
绿色债券本身也需要再分层,否则几百只样本堆在一起,分析价值很低。我通常按三个角度切子标签。
按产品形态切:普通贴标绿色债、绿色资产支持证券、可持续挂钩类产品。这三类的偿付逻辑完全不同,资产支持证券看底层资产现金流,挂钩类看关键绩效指标触发,普通债看主体信用。
按资金投向切:清洁能源、节能环保、清洁交通、生态保护、资源循环利用、绿色建筑、水资源等。这套分类和国内主流绿色项目目录的大类基本对齐,便于和公开统计口径对照。
按主题强度切:有的债明确披露了碳减排量,有的只是资金投向绿色领域但没做量化,有的还带转型属性。这三类在投资叙事上差别很大,混在一起统计会失真。
3.3 分类字段与筛选字段要分清用途
分类字段是给人看的,筛选字段是给机器跑的。这两者不分开,后面写查询会非常痛苦。
我的做法是:分类字段允许是中文长文本,方便阅读和报表展示;同时为每个分类节点配一个编码字段,纯数字或短字符串,规则固定、不带空格、不带中文标点。所有查询、汇总、程序处理都走编码字段,中文只用于最终输出。
这个习惯的来源很实际:中文分类名里经常有多余空格、全角半角混用、括号中英文不一致,做匹配时动不动就出现“绿色债券”和“绿色债券 ”被当成两类。编码字段一步到位解决这个问题,而且换终端、换数据源时,只要重新映射编码,业务逻辑一行都不用改。
4. 实操过程:从数据终端把绿色债券样本拉干净
4.1 字段清单准备与导出设置
动手之前先列字段清单,别打开终端就开始勾。我一般分三组列:
第一组是主键与识别字段:债券代码、债券简称、发行主体标识、主体名称、上市日期。
第二组是分类与标签字段:品种分类各级、信用属性、计息方式、含权标识、期限区间、绿色标识、绿色子类、第三方认证标识。这一组是本次任务的核心,务必确认终端里这些字段的覆盖率和口径说明。
第三组是计量与分析字段:发行规模、债券余额、票面利率、发行期限、剩余期限、债项评级、主体评级、担保方式。
导出时有几个细节值得注意。一是字符编码,尽量统一成一种,避免中文简称出现乱码;二是日期格式,导出时确认是标准日期还是文本,文本格式的日期在后续处理里会带来大量额外解析工作;三是空值表示方式,有的终端用空字符串,有的用特殊符号,导出后先看一眼原始表。
提示:导出前先在终端里做一次小样本预览,随便挑十只债看字段值是否符合预期。这个动作花不了一分钟,但能避免导出几千行之后才发现某个关键字段整列空白。
4.2 筛选条件的组合方式与去重逻辑
筛选条件我一般用三层组合,而不是单一条件。
第一层是结构化标签:绿色标识字段等于“是”。这一层保证召回的是贴标样本,准确率高。
第二层是品种限定:排除掉一些明显不属于统计范围的记录,比如已经到期摘牌的、发行失败的、重复登记托管的。这一步很关键,很多统计差异就是把这部分算进去了。
第三层是时间窗口:按发行日还是起息日切,务必和你的统计口径一致。我在项目里通常用起息日,因为它更接近资金实际到账时间,但如果是做发行审批统计,发行日更合适。
去重是另一个重灾区。同一次发行可能在终端里出现多行,原因是跨市场登记、分期发行、数据源合并。我的去重规则是:以债券代码为主键,代码相同则保留信息最完整的一行;代码不同但主体、起息日、发行规模、票面利率四项完全相同的,标记为疑似重复,人工确认后再处理。
不能简单按“主体+日期”去重,因为同一主体完全可能在同一天发两期不同的债,规模利率都不一样。也不能只看代码,因为同一期债在两个市场可能有两个代码。这个判断必须回到业务逻辑上:一次发行行为对应一份募集说明书,那就以募集说明书为唯一性的锚点。
4.3 数据清洗的具体代码实现
导出后的原始表通常不能直接用,下面这段是我常用的清洗骨架,逻辑清晰,改动成本低。
import pandas as pd import numpy as np # 1. 读取原始导出表,统一编码 raw = pd.read_excel("green_bond_raw.xlsx", dtype=str) raw.columns = [c.strip().replace(" ", "") for c in raw.columns] # 2. 日期字段标准化 date_cols = ["起息日", "到期日", "发行日"] for col in date_cols: if col in raw.columns: raw[col] = pd.to_datetime(raw[col], errors="coerce", format="mixed") # 3. 规模字段转数值,注意单位统一(假设原始为亿元) raw["发行规模"] = pd.to_numeric(raw["发行规模"], errors="coerce") # 4. 剔除无效记录:无代码、无起息日、规模为空或为0 mask_valid = ( raw["债券代码"].notna() & raw["起息日"].notna() & raw["发行规模"].fillna(0).gt(0) ) df = raw[mask_valid].copy() # 5. 去重:同代码保留信息完整度最高的一行 df["_nonnull"] = df.notna().sum(axis=1) df = df.sort_values("_nonnull", ascending=False).drop_duplicates( subset=["债券代码"], keep="first" ).drop(columns=["_nonnull"]) # 6. 疑似重复标记:不同代码但核心条款完全一致 key_cols = ["主体名称", "起息日", "发行规模", "票面利率"] dup_flag = df.duplicated(subset=key_cols, keep=False) df["疑似重复"] = np.where(dup_flag, "是", "否") # 7. 期限派生:按年计算,保留两位小数 df["发行期限_年"] = ( (df["到期日"] - df["起息日"]).dt.days / 365 ).round(2) # 8. 期限分档,用于后续结构分析 bins = [0, 1, 3, 5, 10, 100] labels = ["1年以内", "1-3年", "3-5年", "5-10年", "10年以上"] df["期限档位"] = pd.cut(df["发行期限_年"], bins=bins, labels=labels) df.to_excel("green_bond_clean.xlsx", index=False)这段代码里最值得说的是第 5 步和第 6 步。第 5 步用非空计数排序,是因为同一个代码的多行记录往往一行字段全、一行字段缺,保留全的那行比随便取第一行靠谱得多。第 6 步不直接删疑似重复,而是打标记,因为跨市场双代码的情况确实存在,直接删会丢样本,标记出来让人工判断更稳妥。
清洗完成后一定要做一次规模合计核对。把清洗后的发行规模加总,跟你在终端里按同样条件做的汇总数对一下,差异在千分之几以内算正常,差得多就说明筛选或去重出了问题。
4.4 分类映射表的建立与参数校验
清洗完的宽表还不能直接出报告,得把分类映射挂上去。具体做法是准备一张两列映射表:一列是终端的原始分类取值,一列是统一后的分类编码。用左连接挂上去,匹配不上的记录单独拎出来看。
这一步常见的匹配失败原因是原始取值带了层级前缀或多余描述,比如“信用债-中期票据”和“中期票据”被当成两个值。处理办法是先把原始取值做一次规范化:去空格、去前缀、统一标点。规范化的规则要写进文档,因为下次换数据源还得重来一遍。
参数校验我一般看四个指标:
- 规模校验:清洗后样本规模合计与终端汇总数偏差。
- 期限合理性:发行期限是否出现负数或超过五十年这类异常值。
- 利率合理性:票面利率是否落在合理区间,零利率或超过百分之十五的要逐条看。
- 缺失率:评级、认证标识、募集资金用途描述这三个字段的缺失比例,超过两成就得回头找数据源。
5. 常见问题与排查技巧实录
5.1 样本对不上的六种典型原因
同样一个“近三年绿色债券发行规模”,两个人算出差异,九成是下面几种情况之一。
| 问题现象 | 高概率原因 | 排查方法 |
|---|---|---|
| 样本只数明显偏少 | 只用了关键词匹配,漏掉简称不含“绿色”的债 | 改用结构化绿色标识字段重新召回 |
| 样本只数偏多 | 把发行主体的绿色属性误当成债项属性 | 检查标签字段是主体级还是债项级 |
| 规模偏高 | 跨市场重复代码未去重 | 按主体、起息日、规模、利率四项查重 |
| 规模偏高 | 用债券余额代替发行规模 | 确认字段是发行规模还是当前余额 |
| 规模偏低 | 剔除了无评级或认证信息缺失的样本 | 缺失不等于不符合,单独设未知类 |
| 期限结构异常 | 含权债用了行权日而非到期日 | 核对到期日字段定义 |
这张表我基本每次做新项目都会拿出来过一遍,能省掉大量来回沟通。
5.2 三层校验清单,建议直接抄
第一层是内部一致性校验:同一张表里,到期日必须晚于起息日;发行规模不能为负;票面利率与计息方式要匹配,浮动利率债的票面通常是一个基准加点的形式,如果只有一个孤零零的数字,就要怀疑取错了字段。
第二层是外部对标校验:把你的统计结果与公开披露的年度或半年度汇总数据做对比。差异存在是正常的,因为口径、时间窗口、样本范围都可能不同,但差异率要能解释。解释不了,就是有问题。
第三层是分布合理性校验:把样本按发行规模、期限、评级做分布,看有没有异常尖峰。比如某一年份的绿色债规模突然全部集中在一个区间,很可能是把某一类特殊品种混进来了,或者单位换算错了——亿元和万元搞混,这种低级错误在真实项目里出现频率远比想象中高。
注意:单位换算是数据事故的头号来源。终端里不同模块的单位可能不一样,债券模块用亿元、资金模块用万元的情况都见过。每次导数据第一件事就是确认单位,并在表头写明。
5.3 几个只有实操才会知道的小技巧
第一个技巧:先在终端里做一次“反向筛选”。不是筛绿色,而是筛“非绿色但名称含绿色”,看有多少只。这个数字能帮你判断关键词匹配的污染程度,也能在报告里作为方法说明的一个支撑点。
第二个技巧:把认证标识和募集资金用途描述做交叉表。如果某一年份认证标识大面积为空但用途描述很完整,说明那一年的数据源换了,需要单独处理。
第三个技巧:留一份原始导出文件的快照。数据终端的数据会回溯修订,今天导出的表和三个月后导出的表可能不一致。做分析时把原始文件按日期命名存档,出了问题能追溯。这个习惯帮我定位过好几次“数据自己变了”的诡异情况。
第四个技巧:分类编码尽量用有意义的短码而不是纯序号。比如绿色子类用GR-ENE表示清洁能源,比用01好得多,因为纯序号一旦中间插入新类别,全部要重编。
5.4 存续期信息的更新策略
基本资料不是一次拉完就完事。绿色债券在存续期内会新增信息:年度评估报告、募集资金使用情况说明、绿色项目进展披露。这些信息在终端里可能以新增字段的形式出现,也可能只记录在公告里。
我的做法是建立一个轻量的更新机制:每月拉一次全量基本资料做增量比对,用债券代码做键,比对字段值有没有变化;同时单独留一张存续期信息表,按债券代码和披露日期记录,允许一只债对应多行。这两张表分开的原因很简单:基本资料是一只债一行,存续期信息是一只债多行,混在一张表里会导致主键重复,后续所有关联都出错。
6. 这套分类底表的延展用法与影响范围
6.1 投研场景:从样本筛选到主题指数构建
分类底表做好之后,最直接的用法是主题筛选。有了绿色标识加子类标签加期限档位,可以很轻松地切出“三年期以内、清洁能源方向、有第三方认证”这样一个组合,直接用于组合构建的初筛池。
再往前走一步是指数化。做主题指数需要三个前提:成分可稳定识别、权重可计算、调整规则可复现。分类底表刚好解决第一个问题,权重用发行规模或余额都能算,调整规则挂在映射表上。这套东西搭一次,后面每季度换数据只要重跑流程,不用重新定义样本。
需要提醒的是,主题指数的样本口径一定要写进方法说明,尤其是“部分绿色”债券的处理方式。这个细节不写清楚,不同机构算出来的指数表现会有差异,容易被质疑。
6.2 统计与披露场景:口径文档比数据本身更值钱
做统计分析时,我越来越觉得,交付物里最核心的不是那张表,而是口径文档。文档里要写清楚:数据来源与导出日期、样本范围与筛选条件、去重规则、单位、缺失值处理方式、分类映射规则版本。
这份文档的价值在于可复现。半年后有人问“这个数怎么来的”,翻文档就能回答,不用重新推一遍。而且口径一旦变化,改文档比改代码容易得多,改完再同步更新代码,逻辑清晰。
我通常把口径文档和数据文件放在同一个目录,命名带版本号。版本号不是形式主义,它解决的是“到底哪一版是最终版”这个永恒的问题。
6.3 数据建模场景:把一次性的活变成可复用的资产
如果这套东西要长期用,建议按星型模型来组织:一张债项事实表,若干张维表(主体维、分类维、时间维、主题维)。分类维表就是前面说的映射表,主题维表里放绿色子类、认证类型这些。
这样组织的好处是扩展成本低。以后要加社会责任主题、科技创新主题,只需要往主题维表里加行,事实表结构不变。要加新的分析维度,比如按省份看绿色债分布,只需要在主体维表里补一个地区字段。
我实际做过对比:同样一份季度统计,用宽表每次要重新清洗半小时,用星型模型加脚本,跑一遍三分钟。更重要的是,宽表模式下每个人清洗的方式都不一样,数据没法横向比较;模型化之后,大家用的是同一套定义,讨论才有意义。
6.4 一个容易被忽略的影响:跨口径沟通成本
最后说个软性的点。这类数据工作真正花时间的往往不是技术,而是沟通。业务方要一个数,你给了,他问为什么和他的不一样;你解释口径,他说这些细节不重要;等他拿去汇报被追问细节,又回来找你要说明。
我的应对方式是把口径做成一张随时能发出去的单页说明:一页纸,写清楚样本怎么来的、单位是什么、有哪些已知差异。这张纸在项目初期就写好,随数据一起交付。实测下来,这张纸能消掉八成的返工沟通,因为它把“为什么不一样”这个问题提前回答了。
绿色债券基本资料和债券分类这两件事,表面上看是把终端里的字段勾一勾、导出来、拼一起,实际做下来,真正决定成败的是三件事:颗粒度定得对不对、分类树搭得稳不稳、口径文档写得清不清。字段缺失可以补,样本错了可以重跑,唯独口径混乱会一直往后传染,越到后面修正成本越高。我个人的经验是,宁可前期多花两天把映射表和口径说明做扎实,也不要在交付后被反复追问里耗掉两周。