## 数据描述 沪深北A股日频公司资料:三套行业分类归属、所属申万一级行业指数行情、可转债发行标记。 ## 数据简介 公司资料表 `cn_stock_factors_company_profile` 以「交易日期 + 证券代码」为主键,把一只股票在某个交易日的**行业归属**和**公司层面属性**汇总到一行,共 30 个字段。 这张表回答的是「这只股票当天属于哪个行业、行业当天表现如何」这类问题: - **它属于哪个行业**:申万(2021)、申万(2014)、中信三套分类体系下的一/二/三级行业代码与名称; - **它所属行业当天涨了还是跌了**:所属申万一级行业(2021)对应的行业指数代码、名称,以及该指数当日的开高低收、成交量额、换手率; - **它有没有在交易中的可转债**:当日是否存在成交量大于 0 的存续可转债。 行业字段是**状态量**,主要用于行业中性化、分组统计和行业轮动;行业指数行情是**价格量**,可直接用于计算行业动量、个股相对行业的超额收益;可转债标记是 0/1 **事件量**。 ## 数据表基本信息 | 项目 | 说明 | |---|---| | 数据表名称 | `cn_stock_factors_company_profile` | | 数据粒度 | 日频,股票维度 | | 主键字段 | `date`、`instrument` | | 标的范围 | 沪深北全部 A 股,与 `cn_stock_instruments` 严格对齐(**包含北交所**) | | 数据开始日期 | **2010-01-01**(部分字段的有效起点更晚,见「数据开始日期」一节) | | 数据结束日期 | 最新交易日,每日增量更新 | | 字段数量 | 30 个(2 个主键 + 18 个行业成分 + 9 个行业指数 + 1 个可转债标记) | ## 数据开始日期 本表历史数据从 **2010-01-01** 开始,之前的日期查不到任何数据。 这个起点由上游决定:`cn_stock_instruments` 和 `cn_stock_industry_component` 的最早可用年份都是 2010 年,本表以前者为骨架逐日 `LEFT JOIN` 加工,因此起点与之保持一致。 需要注意的是,表内有数据不等于每个字段都有意义。下面这几组字段的**有效起点晚于 2010-01-01**: | 字段 | 有效起点 | 说明 | |---|---|---| | `sw2021_level1` 等申万(2021)字段 | 2010-01(全历史回溯) | 申万 2021 版分类对历史区间做了回溯划分,覆盖度较高 | | `sw_level1_open` 等行业指数字段 | 约 2014 年 | 2014 年之前存在旧版申万代码无法映射到现行行业指数的情况,覆盖度门槛因此放宽到 90% | | `cbond_issue_factor` | 可转债市场活跃之后 | 早期存续可转债极少,该字段大面积为 0,不代表数据缺失 | 因此取数时的一般建议是:整体区间不早于 2010-01-01;若用到行业指数行情,起点放到 2014 年之后更稳妥;若研究可转债相关逻辑,起点放到 2017 年之后。 ## 字段说明 ### 基础字段 | 字段名 | 类型 | 含义 | 取值说明 | |---|---|---|---| | `date` | TIMESTAMP_NS | 日期 | 主键 | | `instrument` | VARCHAR | 证券代码 | 主键,形如 `000001.SZ` | ### 行业成分:行业代码 | 字段名 | 类型 | 含义 | 取值说明 | |---|---|---|---| | `sw2021_level1` | VARCHAR | 申万一级行业代码(2021) | 共 31 个,形如 `801010` | | `sw2021_level2` | VARCHAR | 申万二级行业代码(2021) | — | | `sw2021_level3` | VARCHAR | 申万三级行业代码(2021) | — | | `sw2014_level1` | VARCHAR | 申万一级行业代码(2014) | 2023 年起不再为新上市股票分配 | | `sw2014_level2` | VARCHAR | 申万二级行业代码(2014) | 同上 | | `sw2014_level3` | VARCHAR | 申万三级行业代码(2014) | 同上 | | `cs_level1` | VARCHAR | 中信一级行业代码 | 不覆盖全部 A 股 | | `cs_level2` | VARCHAR | 中信二级行业代码 | 同上 | | `cs_level3` | VARCHAR | 中信三级行业代码 | 同上 | ### 行业成分:行业名称 | 字段名 | 类型 | 含义 | 取值说明 | |---|---|---|---| | `sw2021_level1_name` | VARCHAR | 申万一级行业名称(2021) | 形如 `农林牧渔` | | `sw2021_level2_name` | VARCHAR | 申万二级行业名称(2021) | — | | `sw2021_level3_name` | VARCHAR | 申万三级行业名称(2021) | — | | `sw2014_level1_name` | VARCHAR | 申万一级行业名称(2014) | — | | `sw2014_level2_name` | VARCHAR | 申万二级行业名称(2014) | — | | `sw2014_level3_name` | VARCHAR | 申万三级行业名称(2014) | — | | `cs_level1_name` | VARCHAR | 中信一级行业名称 | — | | `cs_level2_name` | VARCHAR | 中信二级行业名称 | — | | `cs_level3_name` | VARCHAR | 中信三级行业名称 | — | ### 行业指数(所属申万一级行业 2021) | 字段名 | 类型 | 含义 | 取值说明 | |---|---|---|---| | `sw_level1_name` | VARCHAR | 申万一级行业指数名称 | 由 `sw2021_level1` 映射得到 | | `sw_level_index_code` | VARCHAR | 申万一级行业指数代码 | 与 `sw2021_level1` 一一映射,形如 `801010.SWI` | | `sw_level1_open` | DOUBLE | 行业指数开盘价 | — | | `sw_level1_high` | DOUBLE | 行业指数最高价 | — | | `sw_level1_low` | DOUBLE | 行业指数最低价 | — | | `sw_level1_close` | DOUBLE | 行业指数收盘价 | — | | `sw_level1_volume` | BIGINT | 行业指数成交量 | — | | `sw_level1_amount` | DOUBLE | 行业指数成交额 | — | | `sw_level1_turn` | DOUBLE | 行业指数换手率 | — | 同一天同一行业的所有成分股,这 9 个字段的取值完全相同,它们描述的是行业而不是个股。 ### 可转债 | 字段名 | 类型 | 含义 | 取值说明 | |---|---|---|---| | `cbond_issue_factor` | INTEGER | 可转债发行标记 | 0-当日无成交的存续可转债;1-当日存在成交量大于 0 的存续可转债 | 该字段无缺失值,未命中一律补 0。 ## 依赖的原始数据表 本表不含任何自有原始数据,30 个字段全部由下面 **6 张上游表**加工而来。任一张表停更或回补,本表对应字段都会跟着变化。 | 原始数据表 | 读取的源字段 | 产出的本表字段 | 角色 | |---|---|---|---| | `cn_stock_instruments` | `date`、`instrument` | `date`、`instrument` | **基准表**,决定输出的股票池与行数 | | `cn_stock_industry_component` | `date`、`instrument`、`industry`、`industry_level1/2/3_code`、`industry_level1/2/3_name` | 18 个行业成分字段 | 行业成分明细,同一股票在三套体系下各占一行 | | `cn_stock_industry_index_mapper` | `kind`、`industry_level1_code`、`industry_level1_name`、`index_level1_code` | `sw_level1_name`、`sw_level_index_code` | 行业代码到行业指数的静态映射,无 `date` 字段,当前 31 行 | | `cn_stock_industry_sw_bar1d` | `date`、`instrument`、`open`、`high`、`low`、`close`、`volume`、`amount`、`turn` | 7 个行业指数行情字段 | 申万行业指数日线行情 | | `cn_cbond_bar1d` | `date`、`instrument`、`volume` | `cbond_issue_factor` | 可转债日线行情,用 `volume > 0` 判断当日是否活跃 | | `cn_cbond_basic_info` | `instrument`、`stock_code` | `cbond_issue_factor` | 可转债到正股的对应关系 | ### 依赖关系图 ``` cn_stock_instruments ──────────────── 基准骨架 (date, instrument) │ ├── cn_stock_industry_component ──── 18 个行业成分字段 │ │ │ └── (全历史聚合) ─────── 行业名称字典, 补齐「有代码无名称」 │ ├── cn_stock_industry_index_mapper ── sw2021_level1 → 指数代码/名称 │ │ │ └── cn_stock_industry_sw_bar1d ── 7 个行业指数行情字段 │ └── cn_cbond_bar1d + cn_cbond_basic_info ───── cbond_issue_factor ``` 几点补充说明: - `cn_stock_industry_component` 被读取**两次**:一次按当前取数窗口取行业成分明细,一次按全历史聚合出「体系 + 层级 + 代码 → 名称」字典用于补名。后者结果只有一千行左右,成本可以忽略。 - `cn_stock_industry_sw_bar1d` 的关联路径是间接的:先由 `cn_stock_industry_index_mapper` 把 `sw2021_level1` 换算成指数代码,再用「日期 + 指数代码」关联行情,所以行业指数字段的可用性同时受这两张表制约。 - `cn_cbond_basic_info` 提供 `stock_code`,比 `cn_cbond_bar1d` 自带的正股字段更完整(后者近年有少量缺失),因此正股代码一律取自前者。 - 数据检查脚本额外查询 `cn_stock_instruments`(行数与主键一致性)和 `cn_stock_industry_index_mapper`(行业代码基数上限),不产出字段。 ## 加工逻辑说明 以 `cn_stock_instruments` 作为基准股票池,确定输出的 `(date, instrument)` 粒度,其余数据表一律 `LEFT JOIN`,因此本表的行数与 `cn_stock_instruments` 严格一致,不会多出已退市标的。 三个子表都不能用 `PRUNE JOIN`:它带分区裁剪优化,语义上接近 INNER JOIN,右表未匹配的行会被直接过滤掉,变成行缺失而不是字段补 NULL。 | 字段 | 来源表 | 加工方式 | |---|---|---| | 18 个行业成分字段 | `cn_stock_industry_component` | 按 `date, instrument` 分组,`max(if(industry = '体系', 字段, null))` 把三套体系打平成一行 | | `sw_level1_name`、`sw_level_index_code` | `cn_stock_industry_index_mapper` | 按 `sw2021_level1` 关联,`kind = 'sw'`,1:1 映射不会膨胀 | | 7 个行业指数行情字段 | `cn_stock_industry_sw_bar1d` | 按 `date, sw_level_index_code` 关联 | | `cbond_issue_factor` | `cn_cbond_bar1d`、`cn_cbond_basic_info` | 可转债行情按 `stock_code` 映射到正股,要求 `volume > 0`,同一天多只转债聚合去重,未命中 `coalesce` 补 0 | ### 前值填充 行业分类是**状态量**,上游 `cn_stock_industry_component` 并非每个交易日都有记录,直接用会出现大量假缺失。加工时做两层填充: 1. **行业成分按证券 ffill**:某一天查不到记录(或该体系下代码为空)时,沿用该股票最近一次已知的分类。只做 `ffill` 不做 `bfill`,保证不引入未来信息。 2. **行业指数行情按指数序列 ffill**:把行情透视成 `(交易日 × 指数)` 网格后按列填充,再还原成长表。按指数自身而不是按股票填充,避免个别指数某日缺行情时,该行业全部成分股的行业指数字段一起变成缺失值。 为了让区间头部也能填充到位,加工时统一往前多取 `lookback_days = 400` 个自然日的数据,填充完成后再裁剪回目标区间。400 天足以覆盖一年以上的行业分类空档。 前值填充放在 pandas 侧而不是 SQL 的窗口函数里:DAI 的 `date` 过滤会下推到分区裁剪,与窗口函数叠加时窗口范围会被静默改写,结果不可控。 ### 行业名称字典填充 上游存在少量「有代码、无名称」的记录(申万 2014 体系约 1%)。行业名称是行业代码的静态属性,加工时用全历史聚合出的「体系 + 层级 + 代码 → 名称」字典补齐,不涉及未来信息。字典按全历史聚合而不是只看当前取数窗口,保证窗口再短也能补全。 ## 缺失值来源 即便做了前值填充和字典补名,本表仍有一部分字段无法做到 100% 覆盖,原因都在上游,不是加工遗漏。数据检查脚本 `tester.py` 因此对不同字段设置了不同的覆盖度门槛: | 字段组 | 覆盖度门槛 | 缺失原因 | |---|---|---| | 申万(2021) 各级代码与名称 | 95% | 新上市股票在首次分类披露前无归属 | | 申万(2014) 各级代码与名称 | 70% | 该体系 2023 年起不再为新上市股票分配代码,越往后缺失越多 | | 中信各级代码与名称 | 80% | 中信体系本身不覆盖全部 A 股 | | 9 个行业指数字段 | 90% | 2014 年之前存在旧版申万代码无法映射到现行行业指数 | | `cbond_issue_factor` | 100% | 该字段不允许缺失,未命中补 0 | 低于门槛会触发关键测试失败,增量任务会直接报错而不是把脏数据写进表里。 ## 使用注意事项 ### 行业分类用哪一套 申万(2021) 覆盖度最高且仍在维护,做行业中性化时建议默认用 `sw2021_level1`。申万(2014) 只在需要与旧研究口径对齐时使用,注意它 2023 年之后对新股缺失严重。中信体系覆盖面窄,适合做交叉验证而不是主口径。 ### 行业分类是填充后的状态量 行业字段经过按证券的前值填充,某一天的取值可能来自更早的一次分类披露,而不是当天上游真的有记录。这对回测是安全的(只用了过去信息),但如果你要统计「行业分类调整发生在哪一天」,本表看到的调整日期会晚于实际生效日,应回原始表 `cn_stock_industry_component` 确认。 ### 行业指数字段是行业级别的 `sw_level1_open` 等 9 个字段描述的是行业指数而不是个股,同一天同一行业的成分股取值完全相同。做截面回归时直接把它们当个股因子会引入强共线性,通常的用法是先算行业收益,再取个股相对行业的超额。 行业指数行情也经过按指数序列的前值填充,指数停更日会沿用上一交易日的价格,此时 `sw_level1_volume` 同样是沿用值而不是 0。 ### 可转债标记的口径 `cbond_issue_factor = 1` 表示「当日有成交量大于 0 的存续可转债」,不是「当日发行可转债」。它反映的是转债处于活跃交易状态,成交量为 0 的停牌类快照被剔除。若要研究发行事件本身,应回 `cn_cbond_basic_info` 取发行日。 ### 历史数据的构建方式 历史数据按 2 年一批(builder 的 `history_step = 2`)从 2010 年逐批加工写入,批次之间按右开区间切分,不会在边界日重复。每批约 260 万行,步长调大会显著吃内存,因为前值填充在 pandas 侧完成。 ## 数据访问示例 ### Python:取某段区间的全部字段 ```python import dai df = dai.query( "SELECT * FROM cn_stock_factors_company_profile", filters={"date": ["2025-01-01", "2025-06-30"]}, ).df() ``` ### Python:取申万一级行业(2021)分类,用于行业中性化 ```python import dai sql = """ SELECT date, instrument, sw2021_level1, sw2021_level1_name FROM cn_stock_factors_company_profile WHERE sw2021_level1 IS NOT NULL ORDER BY date, instrument """ df = dai.query(sql, filters={"date": ["2025-01-01", "2025-06-30"]}).df() ``` ### SQL:计算个股相对所属行业的超额收益 ```sql SELECT p.date, p.instrument, p.sw2021_level1_name, b.close / lag(b.close) OVER (PARTITION BY p.instrument ORDER BY p.date) - 1 AS stock_ret, p.sw_level1_close / lag(p.sw_level1_close) OVER (PARTITION BY p.sw_level_index_code ORDER BY p.date) - 1 AS industry_ret FROM cn_stock_factors_company_profile AS p LEFT JOIN cn_stock_bar1d AS b ON p.date = b.date AND p.instrument = b.instrument WHERE p.sw_level_index_code IS NOT NULL ``` ### SQL:统计每日各申万一级行业的股票数量 ```sql SELECT date, sw2021_level1_name, count(DISTINCT instrument) AS stock_num FROM cn_stock_factors_company_profile WHERE sw2021_level1_name IS NOT NULL GROUP BY date, sw2021_level1_name ORDER BY date, stock_num DESC ``` ### SQL:筛选当日有活跃可转债的标的 ```sql SELECT date, instrument, sw2021_level1_name FROM cn_stock_factors_company_profile WHERE cbond_issue_factor = 1 ORDER BY date, instrument ``` ## 示例数据 展示最新一日数据的前 5 行和后 5 行 {{sample_data}}
公司资料 (cn_stock_factors_company_profile)
数据描述: 沪深北A股日频公司资料:三套行业分类归属、所属申万一级行业指数行情、可转债发行标记。
文档
用例
表结构
| 字段 | 字段类型 | 字段描述 |
| date | timestamp[ns] | 日期 |
| cs_level1 | string | 中信一级行业代码 |
| cs_level2 | string | 中信二级行业代码 |
| cs_level3 | string | 中信三级行业代码 |
| sw2014_level1 | string | 申万一级行业代码(2014) |
| sw2014_level2 | string | 申万二级行业代码(2014) |
| sw2014_level3 | string | 申万三级行业代码(2014) |
| sw2021_level1 | string | 申万一级行业代码(2021) |
| sw2021_level2 | string | 申万二级行业代码(2021) |
| sw2021_level3 | string | 申万三级行业代码(2021) |
| sw_level1_low | double | 申万一级行业指数最低价 |
| cs_level1_name | string | 中信一级行业名称 |
| cs_level2_name | string | 中信二级行业名称 |
| cs_level3_name | string | 中信三级行业名称 |
| sw_level1_high | double | 申万一级行业指数最高价 |
| sw_level1_name | string | 申万一级行业指数名称. 由 sw2021_level1 映射得到 |
| sw_level1_open | double | 申万一级行业指数开盘价 |
| sw_level1_turn | double | 申万一级行业指数换手率 |
| __PARTITION__ | int64 | - |
| sw_level1_amount | double | 申万一级行业指数成交额 |
| sw_level1_volume | int64 | 申万一级行业指数成交量 |
| cbond_issue_factor | int32 | 可转债发行标记. 0: 当日无成交的存续可转债; 1: 当日存在成交量大于0的存续可转债 |
| sw2014_level1_name | string | 申万一级行业名称(2014) |
| sw2014_level2_name | string | 申万二级行业名称(2014) |
| sw2014_level3_name | string | 申万三级行业名称(2014) |
| sw2021_level1_name | string | 申万一级行业名称(2021) |
| sw2021_level2_name | string | 申万二级行业名称(2021) |
| sw2021_level3_name | string | 申万三级行业名称(2021) |
| sw_level_index_code | string | 申万一级行业指数代码. 与 sw2021_level1 一一映射, 形如 801010.SWI |
| sw_level1_close | double | 申万一级行业指数收盘价 |
| instrument | string | 证券代码 |
表名:cn_stock_factors_company_profile
起始时间:
最近更新时间: