金融科技研究:如何定义公司公告中的事件

张高歌(喵喵学长)的头像
张高歌(喵喵学长)

从国际金融数据平台的公开分类与 API 出发,讨论如何把公司公告转化为可检索、可关联、可解释、可追溯的事件数据。

夕阳暖色光影中的长曝光模糊人物剪影
图片: Milo Weiler · 原图 · Unsplash License

一名投资者问:“今天有哪些公司发生了重大的股东卖出事件?”

这个问题听起来并不复杂。可是,如果信息系统只有公告标题、正文和下载接口,它就很难直接回答。系统不仅要找到当天发布的所有公告,还要识别“股东卖出”对应的规范概念,判断哪些事件足够重大,把同一减持计划的多次披露关联起来,并为每个结论提供可以核验的原文证据。

传统公告检索解决的是“哪些文档包含这些词”。事件搜索需要回答的则是“现实世界里发生了什么”。两者之间隔着一层并不显眼、却非常关键的基础设施:公司事件层

本文从金融数据平台公开的分类、Schema 和 API 出发,讨论公司公告事件应该如何定义,以及一个面向中文公告的智能搜索引擎应当采用怎样的颗粒度。

公告不是事件

公告是一份文档,事件是对现实变化的结构化描述。二者并非一一对应。

一份《关于控股股东减持股份计划的公告》可能同时包含以下事实:

  • 控股股东准备减持;
  • 拟采用集中竞价和大宗交易两种方式;
  • 减持期间尚未开始;
  • 最大减持比例为公司总股本的 2%;
  • 减持不会导致控制权变化。

半年之后,公司可能继续发布进展公告、数量过半公告、实施完毕公告或者提前终止公告。这些文档描述的不是多项互不相关的事件,而是同一项减持计划的不同生命周期节点。

反过来,一份年度报告也可能产生多项事件:业绩变化、分红方案、会计差错更正、管理层变动和重大诉讼进展等。因此,系统至少需要区分三种对象:

flowchart LR
  D[公告文档] --> X[事实抽取]
  X --> E1[事件记录一]
  X --> E2[事件记录二]
  D2[后续公告] --> X2[事实抽取]
  X2 --> E3[事件进展]
  E1 --> P[同一事件计划]
  E3 --> P
  • 文档 Document:公告原文及其版本、来源和发布时间;
  • 事件 Event:一次披露所表达的结构化事实;
  • 事件计划 Event Program:跨越多份公告的持续事项,例如一项减持计划或一笔并购交易。

如果不建立这三个层次,搜索结果很容易重复计数,也无法回答“这件事后来怎么样了”。

各个平台到底定义了多少类事件

公开资料里的数字差异很大:有的平台只有 4 类,有的平台有 60 多类,还有的平台声称能识别 7,400 多类。原因不是谁做得更认真,而是它们统计的层级不同。

平台或产品 公开数量 分类范围 Schema 公开程度
FactSet Event Calendar 12 种事件类型 业绩会、股东大会、分红、拆股等日历事件 API 公开完整枚举和字段
Alpaca Corporate Actions 4 个一级类型、9 个子类型 分红、合并、分拆、拆股 SDK 公开完整枚举和对象模型
LSEG Corporate Actions 8 个请求筛选开关、50 多种 ISO 15022 事件类型、80 多种通知类型 标准化公司行动 公开 API 请求结构与产品覆盖数量
Intrinio Corporate Actions 45 多类 国际公司行动 提供 API,完整枚举未完全公开
Bloomberg Corporate Actions 50 种 全球公司行动 公司行动日历公开数量,详细字典面向客户
S&P Global Managed Corporate Actions 60 多类 全球公司行动 公开数量和交付方式,详细字典面向客户
FactSet Alexandria 31 类 新闻中的公司语义事件 公开数量和代表性类型
RavenPack 7,400 多类 新闻语义、主体角色和行业事件模板 公开总体数量,分类体系为专有资产

这些数字不能横向直接排序。

日历事件通常只有十余类

FactSet 的公开 Event Calendar SDK 定义了 12 个枚举,包括 Earnings、Guidance Call、Shareholders Meeting、Conference、Dividend 和 Split 等。这一层解决的是“公司什么时候开会、披露业绩或进行标准公司行动”,并不覆盖股东减持、诉讼、监管处罚和重大合同。

所以,“12 种”并不代表 FactSet 只能识别 12 种公司变化,而只反映了这一项 API 的覆盖范围。

公司行动产品通常覆盖数十种类型

LSEG 的 DataScope Select API 标准提取请求公开了 8 个事件筛选开关:资本变化、分红、业绩、并购、面值变化、公开股权发行、流通股本变化和投票权变化。其产品资料同时表示,系统覆盖 50 多种 ISO 15022 标准事件类型,以及 80 多种通知类型。

Bloomberg 的公司行动日历公开覆盖 50 种公司行动类型;S&P Global 的 Managed Corporate Actions 数据集覆盖 60 多种事件类型;Intrinio 的 Corporate Actions API 则覆盖 45 多种。虽然统计口径并不完全相同,但这些产品都采用数十种稳定业务类型来组织标准公司行动。

但公司行动仍然只是公司事件的一部分。重大合同、管理层离任、安全事故、产品召回和监管调查,通常不会被完整地归入 Corporate Actions。

新闻语义事件可以扩张到数千类

FactSet Alexandria 采用相对克制的体系,将新闻归入 31 类事件,例如业绩、并购、业绩指引、经营变化、管理层变化、临床试验和政府互动。

RavenPack 则公开表示能够识别 7,400 多种事件类型。这里的“类型”已经深入到语义层:谁起诉了谁、谁在交易中扮演收购方、盈利数字是多少、评级机构做了什么,以及不同行业中的专有动作。它更接近大量结构化语义模板,而不是产品导航中向用户展示的 7,400 个筛选项。

因此,事件数量至少要区分以下层级:

层级 常见数量 用途
事件大类 8—20 产品导航、订阅和粗粒度过滤
标准事件类型 30—200 用户查询和 API 中稳定的业务概念
子类型与属性维度 100—500 描述方式、主体角色、状态和影响
内部抽取模板 数百至数千 识别不同文风、句式和行业表达

国内平台提供了什么

国内平台的公开 Schema 明显少于国际数据服务商。

东方财富 Choice 的官方用户指南展示了行动事件库。股票目录下可见基本资料、交易、股本股东、业绩披露、IPO、增发、配股、分红、重大事项、股权激励、经营事件、并购重组、退市和三板转市等 14 个一级目录。这里既包含事件,也包含“基本资料”和“交易”这样的数据领域,因此不能把 14 直接理解为事件类型数量。

Wind 和 iFinD 的公开网页没有提供完整的事件枚举。能够确认的是,它们拥有股东增减持、并购重组、定向增发、股权质押、股东大会、解禁和重大事项等专题数据;具体字段和数据字典通常属于终端或数据接口权限的一部分。

Tushare 的优势是把许多常用数据做成可调用的专题接口,例如分红、回购、股东增减持、质押、大宗交易、解禁、停复牌、业绩预告和业绩快报。它更像一组结构化数据接口,而非一套统一的公司事件模型。使用者仍然需要知道应该调用哪个接口,并自行完成事件关联、重大性判断和自然语言映射。

这也说明,新的公告搜索产品不必复制所有历史数据表。更有价值的方向,是在不同专题之上建立一个稳定、统一、可解释的事件查询层。

事件分类不应是一张无限增长的枚举表

假设系统要表示“控股股东通过集中竞价减持,计划已经实施完毕”。最直接但也最危险的做法,是把整句话定义成一个叶子类型:

controlling-shareholder-auction-reduction-completed

继续扩展后,很快还会出现:

actual-controller-block-trade-reduction-planned
executive-auction-reduction-in-progress
major-shareholder-agreement-transfer-completed
shareholder-judicial-passive-reduction-completed

主体角色、交易方式、主动或被动、生命周期阶段相互组合,类型数量会指数式膨胀。更合理的模型,是把稳定的业务概念与可组合维度分开:

{
  "event_family": "ownership_change",
  "event_type": "shareholder_reduction",
  "stage": "completed",
  "holder_role": "controlling_shareholder",
  "method": "auction",
  "is_passive": false
}

其中:

  • event_family 表示大类;
  • event_type 表示稳定、可查询的标准事件;
  • event_subtype 在需要时进一步细分子类型;
  • stage 表示生命周期;
  • holder_rolemethod 等字段表示事件维度。

这样,用户既可以搜索所有股东减持,也可以进一步筛选“控股股东”“集中竞价”或者“已经完成”,而系统不需要为每种组合维护一个独立类型。

建议采用四层事件体系

一个面向中国公司公告的第一版系统,可以采用以下颗粒度。

第一层:12 至 16 个事件大类

建议的大类包括:

  1. 股东与持股变动;
  2. 控制权变更;
  3. 质押、冻结与司法处置;
  4. 回购与注销;
  5. 分红送转;
  6. 业绩与财务披露;
  7. 股权及债务融资;
  8. 并购重组与资产交易;
  9. 重大合同与经营项目;
  10. 诉讼仲裁;
  11. 监管调查与处罚;
  12. 债务、违约与信用评级;
  13. 董监高与公司治理;
  14. 股权激励与员工持股;
  15. 停复牌、风险警示与退市;
  16. 经营异常、安全事故与产品事件。

大类主要用于产品导航、订阅和权限管理,不必承担全部业务表达。

第二层:40 至 60 个标准事件类型

这一层应当稳定地出现在搜索接口中,例如:

shareholder_reduction       股东减持
shareholder_increase        股东增持
control_change              控制权变更
equity_transfer             股权转让
share_pledge                股权质押
share_freeze                股份冻结
judicial_disposal           司法处置
share_repurchase            股份回购
earnings_forecast           业绩预告
earnings_revision           业绩预告修正
private_placement           定向增发
merger                      合并
major_asset_restructuring   重大资产重组
major_contract              重大合同
litigation                  诉讼仲裁
regulatory_investigation    监管调查
regulatory_penalty          监管处罚
debt_default                债务违约
executive_change            董监高变动
risk_warning                风险警示
delisting                   退市

第一期不必对所有类型平均用力。股东变化、业绩、并购、诉讼、监管、债务和退市等高价值领域,应优先做到字段完整和关系准确。

第三层:100 至 150 个子类型与属性维度

这一层描述:

  • 计划、进行中、完成、终止和修订;
  • 集中竞价、大宗交易、协议转让和司法处置;
  • 实际控制人、控股股东、持股 5% 以上股东和董监高;
  • 主动或被动;
  • 境内或境外;
  • 是否跨越法定持股阈值;
  • 是否可能引起控制权变化。

这些维度决定了事件能否支持真正有用的组合查询。

第四层:数百个内部抽取模板

用户只需要理解“股东减持”,但抽取系统必须理解:

  • “拟减持不超过公司总股本的……”;
  • “通过集中竞价累计减持……”;
  • “持股比例由 5.23% 降至 4.98%”;
  • “因司法强制执行导致被动减持”;
  • “减持数量已过半”;
  • “减持期限届满”;
  • “决定提前终止本次减持计划”。

这些句式应当映射到同一个标准事件,再通过阶段和属性表达差异。内部模板可以不断增长,而公开 API 的核心类型必须保持稳定。

生命周期是事件系统的核心

Alpaca 的 Corporate Actions 模型提供了一个值得参考的设计:多次公告可以通过稳定的 corporate_action_id 归属于同一项公司行动。

中文公告系统同样需要一个 event_program_id。以减持为例,它可能经历:

stateDiagram-v2
  [*] --> 计划披露
  计划披露 --> 实施中
  实施中 --> 数量过半
  实施中 --> 时间过半
  数量过半 --> 实施完成
  时间过半 --> 实施完成
  计划披露 --> 提前终止
  实施中 --> 提前终止
  实施完成 --> [*]
  提前终止 --> [*]

系统要同时保留两种事实:

  1. 每一次公告当时表达了什么;
  2. 截至某个时间点,这项计划的最新状态是什么。

这要求数据具备版本和时点属性。后续公告不能简单覆盖旧记录,否则用户无法回测“当时市场已经知道什么”。

“重大”是一种判断,不是一种事件

用户会问“重大减持”“重大诉讼”或“重大合同”,但“重大”不应该成为新的事件类型。它应当由一组可解释规则和模型结果共同表达:

{
  "materiality": {
    "level": "high",
    "score": 91,
    "reasons": [
      "controlling_shareholder",
      "planned_ratio_above_1_percent",
      "possible_threshold_crossing"
    ]
  }
}

股东减持的重大性可以考虑:

  • 减持主体是否为实际控制人或控股股东;
  • 计划和实际减持比例;
  • 是否跨越 5% 等法定持股阈值;
  • 是否可能改变第一大股东或控制权;
  • 涉及金额和相对市值;
  • 多名一致行动人是否同时减持;
  • 是否属于司法处置或被动减持;
  • 是否在敏感窗口集中发生。

结果页面不能只显示一个来源不明的分数,还应解释:“减持主体为控股股东,最大比例为 2.5%,减持后可能接近关键持股阈值。”可解释性本身就是金融数据产品的一部分。

一个可用的统一 Schema

事件对象应采用“通用核心字段 + 事件专属载荷”的结构。下面以股东减持为例:

{
  "event_id": "evt_01...",
  "event_program_id": "program_01...",
  "parent_event_id": null,

  "event_family": "ownership_change",
  "event_type": "shareholder_reduction",
  "event_subtype": "market_sale",
  "stage": "plan",
  "status": "active",

  "issuer_id": "issuer_cn_...",
  "security_ids": ["600000.SH"],

  "disclosed_at": "2026-08-05T19:32:00+08:00",
  "occurred_at": null,
  "effective_at": null,
  "start_at": "2026-08-20",
  "end_at": "2026-11-19",

  "subjects": [
    {
      "entity_id": "entity_...",
      "name": "某某集团",
      "role": "controlling_shareholder"
    }
  ],

  "materiality": {
    "level": "high",
    "score": 86,
    "reasons": [
      "controlling_shareholder",
      "planned_ratio_above_1_percent"
    ]
  },

  "payload": {
    "method": ["auction", "block_trade"],
    "planned_shares": 30000000,
    "planned_ratio": 0.025,
    "holding_before_ratio": 0.126,
    "holding_after_min_ratio": 0.101,
    "is_passive": false,
    "may_change_control": false
  },

  "source": {
    "document_id": "doc_01...",
    "source_url": "https://...",
    "page": 2,
    "evidence_spans": [
      {
        "text": "拟通过集中竞价及大宗交易方式减持不超过三千万股",
        "start": 812,
        "end": 840
      }
    ]
  },

  "confidence": 0.97,
  "schema_version": "1.0",
  "ingested_at": "2026-08-05T19:33:08+08:00"
}

其中有几项不能省略:

  • event_program_id:关联计划、进展、完成和终止;
  • 多种时间字段:区分披露时间、发生时间和生效时间;
  • subjects 和角色:不能只保存一段主体名称文本;
  • materiality.reasons:解释为什么被判断为重大;
  • evidence_spans:把结构化事实定位回原文;
  • schema_versioningested_at:支持修订、回测和可追溯性。

从自然语言到事件查询

用户的问题:

今天有哪些公司发生了重大的股东卖出事件?

可以被转换为:

{
  "time_field": "disclosed_at",
  "date": "today",
  "event_type": ["shareholder_reduction"],
  "materiality_level": ["high", "critical"],
  "group_by": "issuer_id",
  "deduplicate_by": "event_program_id",
  "sort": [
    "materiality_score desc",
    "disclosed_at desc"
  ]
}

这一步看似只是自然语言解析,实际依赖前面所有基础工作:

  1. “今天”默认映射到公告披露时间;
  2. “股东卖出”归一到 shareholder_reduction
  3. “重大”映射到重大性等级和规则;
  4. 同一减持计划的多份公告按 event_program_id 去重;
  5. 公司、股东和证券完成实体消歧;
  6. 每项结论附带公告原文证据。

如果底层只有向量搜索,系统可能找到语义相似的段落,却难以保证结果完备,也难以证明“今天所有符合条件的公司都已经被找出”。面向监测和筛选的金融搜索需要结构化索引保障召回,语言模型更适合承担查询理解、结果解释和疑难文本抽取。

第一阶段应该做到多大

一个务实的第一版目标是:

  • 12 个左右的事件大类;
  • 40 至 60 个标准事件类型;
  • 100 至 150 个子类型与属性维度;
  • 300 至 800 个内部抽取模板;
  • 15 至 20 个跨事件通用字段;
  • 每个事件大类增加 10 至 30 个专属字段。

但建设顺序比总数量更重要。第一阶段可以优先做深以下事件:

  1. 股东减持与增持;
  2. 控制权变更;
  3. 股权质押、冻结和司法处置;
  4. 股份回购;
  5. 业绩预告及修正;
  6. 并购重组;
  7. 重大合同和中标;
  8. 诉讼仲裁;
  9. 监管调查和处罚;
  10. 债务违约;
  11. 董监高变动;
  12. 风险警示和退市。

每一种事件都应完整解决主体、数值、阶段、关联、重大性和证据,而不是先铺开几百个只有标题标签的类别。

结语

公司公告智能搜索的难点不在于让大模型读懂某一份 PDF,而在于持续处理全市场公告,把同一现实事项在不同时间、不同文档、不同措辞下的披露统一到一个稳定的事件体系中。

成熟平台给出的共同启示是:

  • 用户可见的类型应当少而稳定;
  • 复杂性应进入属性维度和内部抽取模板;
  • 事件必须具有生命周期和稳定标识;
  • “重大”必须可解释;
  • 结构化结论必须能够回到公告原文;
  • 公告时间、事件时间和系统知道该事实的时间必须分开。

类型数量可以逐步扩张,但时间、身份、关系和证据这些底层模型一旦设计错误,后续很难补救。

参考资料

知经 KNOWECON

卓越的北大清华人大经济金融统计管理考研辅导

过去5年,知经已帮助超过300名同学顺利考上北京大学经济学和金融学硕士项目,战绩昭昭。我们也为清华大学、中国人民大学等顶尖院校提供同等质量的考研专业课辅导服务。