数据采集与清洗:上市公司股东数据、供应链数据、关联交易数据的获取与预处理

各位同学,咱们今天聊点实在的。做量化投资,数据就是你的弹药。没有干净、可靠的数据,再牛的模型也是空中楼阁。我个人习惯,花在数据清洗上的时间,至少占整个项目周期的60%。别嫌多,这钱花得值。

今天这一章,咱们就聚焦三类核心数据:股东数据供应链数据关联交易数据。这三者构成了投资关联网络的骨架。你想想看,一家公司背后站着谁,它跟谁做生意,它跟谁有利益输送——这些信息挖透了,股价的异动往往就有迹可循。

核心观点:数据采集不是简单的“爬虫+存库”。你需要理解数据背后的业务逻辑,否则你清洗出来的数据,可能只是“干净的垃圾”。

2.1 上市公司股东数据:从“十大”到“全量”

股东数据,说白了就是看谁在持有这家公司的股票。但这里有个坑:很多人只盯着季报里的“前十大股东”。嗯,这远远不够。

数据来源:

  • 定期报告(季报、年报): 这是最权威的来源。但注意,它只披露前十大股东,而且有滞后性(季报截止日后一个月才出)。
  • 交易所披露(大宗交易、增减持公告): 这里能抓到“大资金”的实时动向。我在项目中遇到过,某只股票突然放量下跌,结果一查,是某家机构通过大宗交易折价减持。这种信息,季报里根本看不到。
  • 中登公司数据(付费): 这是最全的,能看到所有股东账户的持仓明细。但价格不菲,一般机构才用。

清洗要点:

  1. 股东名称归一化: 同一个机构,在不同报告期可能写法不一样。比如“香港中央结算有限公司”和“香港中央结算(代理人)有限公司”,其实是同一个东西。我建议你建一个映射表,手动做一次匹配。
  2. 持股比例计算: 注意区分“占总股本比例”和“占流通股本比例”。有些股票有大量限售股,流通盘很小,前十大股东可能就占了80%以上。这时候,你看到的“集中度”其实是虚的。
  3. 时间对齐: 不同报告期的数据,截止日期不同。做时间序列分析时,一定要把数据对齐到同一个时间轴上。我习惯用“报告期截止日”作为时间戳,而不是“披露日”。

小技巧: 对于“国家队”(证金、汇金、社保基金)的持股,我建议单独建一个标签。这些资金的动向,往往有政策风向标的意义。

2.2 供应链数据:上下游的“隐形关联”

供应链数据,是挖掘关联网络的重头戏。一家公司的客户是谁、供应商是谁,直接决定了它的议价能力和经营风险。

数据来源:

  • 年报“前五大客户/供应商”: 这是最直接的来源。但很多公司只披露“客户一、客户二”,不写具体名称。这时候,你需要结合招股说明书、公司公告去“猜”。
  • 招股说明书(IPO): 这是信息最全的文档。公司上市前,必须详细披露前十大客户和供应商,甚至包括合作历史、合同金额。我建议你把所有IPO公司的供应链数据都扒下来,建一个历史库。
  • 行业报告、新闻、公司官网: 这些是补充来源。比如,某家汽车零部件公司宣布成为特斯拉的供应商,这条信息会立刻反映在股价上。你需要用NLP技术从新闻里提取这种“供应链关系”。

清洗要点:

  1. 公司名称匹配: 这是最头疼的问题。同一家公司,在A公司的年报里叫“华为技术有限公司”,在B公司的年报里可能叫“华为”。我建议你用“统一社会信用代码”作为唯一标识,如果没有,就用“公司全称+注册地”做模糊匹配。
  2. 关系方向: 一定要区分“客户”和“供应商”。这是有向边。我见过有人把这两个搞反了,结果整个网络分析都错了。
  3. 金额归一化: 有些公司披露的是“销售额”,有些是“采购额”,还有些是“占营收比例”。你需要统一换算成“金额(元)”,才能做横向对比。

避坑指南: 我曾经在做一个汽车行业的项目时,发现某家公司的前五大客户里,有一家是“关联方”。但年报里没有明确说。后来我查了工商信息,发现这两家公司的法人代表是同一人。这种“隐性关联”,如果不做交叉验证,很容易漏掉。

2.3 关联交易数据:利益输送的“蛛丝马迹”

关联交易,说白了就是上市公司跟“自己人”做的生意。正常的关联交易没问题,但如果是“利益输送”,那就危险了。

数据来源:

  • 年报“关联交易”章节: 这是最详细的披露。包括关联方名称、交易类型(采购、销售、租赁、担保等)、交易金额、定价原则。
  • 临时公告: 日常关联交易预计、关联交易补充确认等。这些公告往往能提前透露一些信息。
  • 工商信息(企查查、天眼查): 用来验证关联方关系。比如,某家公司的董事,同时是另一家公司的股东。这种“人员关联”,也是关联交易的一种。

清洗要点:

  1. 关联方识别: 关联方不一定是公司,也可能是个人(董事、高管、他们的亲属)。你需要建立一个“关联方图谱”,把所有人都放进去。
  2. 交易类型分类: 我建议你把关联交易分成三类:经营性(采购、销售)、非经营性(资金拆借、担保)、资产性(收购、出售)。不同类型的交易,对股价的影响完全不同。
  3. 金额异常检测: 如果某笔关联交易的金额,远高于市场公允价,或者交易频率异常,那就要警惕了。我习惯用“Z-score”来做异常检测,超过3个标准差的,标记为“可疑”。

实战经验: 我做过一个回测,把“关联交易金额/营收”这个指标加入因子库。结果发现,这个比值超过20%的公司,未来一年的超额收益显著为负。说白了,关联交易太多的公司,大概率有问题。

2.4 数据清洗的通用流程

不管是什么数据,清洗流程都差不多。我总结了一个“五步法”:

  1. 去重: 同一个数据,可能从多个来源获取。比如,股东数据既可以从Wind拿,也可以从Choice拿。你需要根据“时间戳+公司代码+股东代码”做去重。
  2. 缺失值处理: 对于缺失的字段,我建议分情况处理。如果是“金额”字段缺失,可以用行业平均值填充;如果是“股东名称”缺失,直接删除这条记录。
  3. 异常值处理: 比如,某家公司的“前五大客户销售额”突然增长了1000%,这明显是数据错误。我习惯用“移动平均法”来修正。
  4. 格式统一: 日期格式统一为“YYYY-MM-DD”,金额统一为“元”,百分比统一为“小数”。
  5. 交叉验证: 用不同来源的数据互相验证。比如,年报里的“前十大股东”数据,跟中登公司的数据做对比。如果差异超过5%,就要去查原因。

效率提升: 我建议你把这些清洗逻辑写成Python函数,然后用Pandas的apply方法批量处理。别手动一条条改,那是新手干的事。

2.5 知识体系框架图

下面这张图,是我自己画的。它把本章的知识点串起来了。你仔细看看,能帮你理清思路。

数据采集与清洗:知识体系框架 股东数据 供应链数据 关联交易数据 来源: 定期报告、交易所披露 中登公司数据 来源: 年报、招股说明书 行业报告、新闻 来源: 年报、临时公告 工商信息 数据清洗五步法:去重 → 缺失值处理 → 异常值处理 → 格式统一 → 交叉验证 输出:干净、对齐、可分析的关联网络数据

2.6 代码示例:股东数据清洗

光说不练假把式。我给你看一段我实际用过的代码。这段代码用来清洗股东数据,处理股东名称归一化和持股比例计算。

import pandas as pd
import numpy as np

# 加载原始数据
df = pd.read_csv('shareholder_raw.csv')

# 股东名称归一化映射表
name_mapping = {
    '香港中央结算有限公司': '香港中央结算(代理人)有限公司',
    '中国证券金融股份有限公司': '证金公司',
    '中央汇金资产管理有限责任公司': '汇金公司'
}

df['shareholder_name'] = df['shareholder_name'].replace(name_mapping)

# 计算持股比例(占总股本)
df['holding_ratio'] = df['shares_held'] / df['total_shares']

# 标记“国家队”
national_team = ['证金公司', '汇金公司', '全国社会保障基金理事会']
df['is_national_team'] = df['shareholder_name'].isin(national_team).astype(int)

# 去重:按报告期+公司代码+股东代码
df = df.drop_duplicates(subset=['report_date', 'stock_code', 'shareholder_code'])

# 输出清洗后的数据
df.to_csv('shareholder_clean.csv', index=False)
print('清洗完成,共保留 {} 条记录'.format(len(df)))

提示: 这段代码里,我用了replace方法做名称映射。如果你的数据量大,建议用map方法,速度更快。

好了,这一章的内容就到这里。数据采集和清洗,听起来枯燥,但它是整个量化投资体系的基石。你想想看,如果数据不准,你后面做的所有分析、所有模型,都是错的。所以,别怕麻烦,把这一步做扎实了。

记住:干净的数据,是策略盈利的第一步。

专注资料整理