AI 原生量化投研平台AI-native quantitative research platform
正在加载…Loading…
页面仍在加载,可以继续等待,或重新加载。The page is still loading. You can keep waiting or reload.
部分页面资源未能加载,请重新加载。Some page resources could not load. Please reload.
设备当前处于离线状态,恢复连接后可以继续等待或重新加载。Your device is offline. Once connected, you can keep waiting or reload.
该数据表综合收录了公司资产负债表、现金流量表、利润表的相关字段和内容,并通过“shift”字段(以季为单位)来表示与当前最新一期报告期的偏移量。这些数据从公司财报首次披露开始,按报告期记录,直至最新一期。LF指 last file,即取对应报告期的财务数据
313 个字段
请注意:该表不是日频数据,不能直接作为因子使用。该表适合对财务数据有深入研究的用户,日频财务数据的加工方法见文末“通用文档”。
LF(last file)指最新一期的财务数据。
| 关键字 | 释意 |
|---|---|
| date | 公告日,表示站在这一天能看到的财务数据(shift = 0 为当时最新一期),不是报告期(报告期见 report_date),可能不是交易日;与 cn_stock_financial_changedate 中的 changedate 对应,详见文末“通用文档” |
| instrument | 股票代码 |
| report_date | 财务报告期,规则见文末“通用文档” |
| shift | 偏移期,站在 date 这一天,向前偏移 n 期的财务数据,0 为当时最新一期,单位为季度 |
字段名由原始财务科目加后缀 _lf 组成,比如利润表的 net_profit 对应 net_profit_lf。
以华润微(688396.SH)为例,该股票于 2020 年 2 月 27 日在科创板上市,2020 年 4 月 23 日首次披露财报。
import dai
changedate_data = dai.query("""SELECT *FROM cn_stock_financial_changedateWHERE instrument = '688396.SH'AND report_date = '2020-03-31'""").pl().sort(["changedate", "report_date"])
raw_data = dai.query("""运行上述代码,得到以下数据:
| instrument | report_date | changedate | statement_type |
|---|---|---|---|
| 688396.SH | 2020-03-31 | 2020-04-23,2020-04-24 | balance_sheet |
| 688396.SH | 2020-03-31 | 2020-04-23,2020-04-24,2021-04-30 | income |
| 688396.SH | 2020-03-31 | 2020-04-23,2020-04-24,2021-04-30 | cash_flow |
| date | instrument | report_date | change_type | fs_quarter_index | net_profit |
|---|---|---|---|---|---|
| 2020-04-23 | 688396.SH | 2020-03-31 | 0 | 1 | 125609986.33 |
| 2020-04-24 | 688396.SH | 2020-03-31 | 1 | 1 | 125609986.33 |
| 2020-07-29 | 688396.SH | 2020-06-30 | 0 | 2 | 446735348.17 |
| 2020-10-20 | 688396.SH | 2020-09-30 | 0 | 3 | 757549644.05 |
| 2021-04-30 | 688396.SH | 2020-03-31 | 1 | 1 | |
| 2021-04-30 | 688396.SH | 2020-12-31 | 0 | 4 | 1059708487.82 |
| 2021-04-30 | 688396.SH | 2021-03-31 | 0 | 1 | 407247392.27 |
| date | instrument | report_date | shift | net_profit_lf |
|---|---|---|---|---|
| 2020-04-23 | 688396.SH | 2020-03-31 | 0 | 125609986.33 |
| 2020-04-23 | 688396.SH | 2019-12-31 | 1 | 512426548.38 |
| 2020-04-23 | 688396.SH | 2019-09-30 | 2 | 354609489.45 |
| 2020-04-23 | 688396.SH | 2019-06-30 | 3 | 212885369.68 |
| 2020-04-23 | 688396.SH | 2019-03-31 | 4 | 36184852.26 |
| 2020-04-23 | 688396.SH | 2018-12-31 | 5 | 537562074.28 |
| 2020-04-23 | 688396.SH | 2018-09-30 | 6 | 541831000 |
| 2020-04-23 | 688396.SH | 2017-12-31 | 9 | -102688060 |
| 2020-04-23 | 688396.SH | 2016-12-31 | 13 | -302249732.88 |
| date | instrument | report_date | shift | net_profit_lf |
|---|---|---|---|---|
| 2021-04-30 | 688396.SH | 2021-03-31 | 0 | 407247392.27 |
| 2021-04-30 | 688396.SH | 2020-12-31 | 1 | 1059708487.82 |
| 2021-04-30 | 688396.SH | 2020-09-30 | 2 | 757549644.05 |
| 2021-04-30 | 688396.SH | 2020-06-30 | 3 | 446735348.17 |
| 2021-04-30 | 688396.SH | 2020-03-31 | 4 | |
| 2021-04-30 | 688396.SH | 2019-12-31 | 5 | 512426548.38 |
| 2021-04-30 | 688396.SH | 2019-09-30 | 6 | 354609489.45 |
| 2021-04-30 | 688396.SH | 2019-06-30 | 7 | 212885369.68 |
| 2021-04-30 | 688396.SH | 2019-03-31 | 8 | 36184852.26 |
| 2021-04-30 | 688396.SH | 2018-12-31 | 9 | 537562074.28 |
| 2021-04-30 | 688396.SH | 2018-09-30 | 10 | 541831000 |
| 2021-04-30 | 688396.SH | 2017-12-31 | 13 | -102688060 |
| 2021-04-30 | 688396.SH | 2016-12-31 | 17 | -302249732.88 |
有了 shift 数据,就可以在历史时间点 T 往前拿到所有报告期的财务数据,因此能计算很多财务指标,比如 N 年复合增长率,代码实现可参考:https://bigquant.com/wiki/doc/n-KfcuAUffwy
2026-10-26 至 2026-11-02 的数据,字段较多,只展示 6 个字段,按日期、股票代码、报告期排序,展示前 5 行和后 5 行。
| date | instrument | report_date | shift | net_profit_lf | total_current_assets_lf |
|---|---|---|---|---|---|
| 2026-10-26 | 000020.SZ | 2008-12-31 | 71 | 7567912.54 | 197562537.78 |
| 2026-10-26 | 000020.SZ | 2009-03-31 | 70 | 2102778.89 | |
| 2026-10-26 | 000020.SZ | 2009-06-30 | 69 | 4359222.8 | |
| 2026-10-26 | 000020.SZ | 2009-09-30 | 68 | 10105170.71 | |
| 2026-10-26 | 000020.SZ | 2009-12-31 | 67 | 4154592.65 | 443806974.87 |
| 2026-11-02 | 001381.SZ | 2025-09-30 | 4 | 244299228.79 | |
| 2026-11-02 | 001381.SZ | 2025-12-31 | 3 | 309178977.17 | 1805097189.48 |
| 2026-11-02 | 001381.SZ | 2026-03-31 | 2 | 84891600 | |
| 2026-11-02 | 001381.SZ | 2026-06-30 | 1 | 158654530.74 | 2130558660.23 |
| 2026-11-02 | 001381.SZ | 2026-09-30 | 0 | 225035402.5 | 2224924619 |
平台的财务数据分四类,从原始披露到加工指标逐层派生:
| 类别 | 数据表 | 说明 |
|---|---|---|
| 原始数据 | 资产负债表、利润表、现金流量表 PIT(cn_stock_financial_*_pit),财报变更日期(cn_stock_financial_changedate),财务附注(cn_stock_financial_note_*) | 公司披露什么就记录什么,只在披露财报时有记录,不是日频 |
| 衍生数据 | cn_stock_financial_lf_shift、ly_shift、mrq_shift、ttm_shift、notes_shift | 把原始数据加工成最新一期(LF)、最新年报(LY)、单季度(MRQ)、滚动十二期(TTM),并用 shift 带出历史各期 |
| 财务分析 | cn_stock_financial_profitability、growth、operating、debt_repay、capital、cash_flow、earning_quality、xps、derivative | 在衍生数据的基础上做加减乘除得到的财务指标 |
| 盈利预期 | cn_stock_financial_earnings_preview、cn_stock_financial_forecast_consensus_rolling | 业绩快报和机构一致预期,口径独立,见各表文档 |
以上财务表都不是日频数据,不能直接当作每日因子使用,需要先按公告日对齐到交易日,做法见本文五。衍生数据和财务分析适合对财务数据有较深了解、希望构建复杂财务因子的用户。
财务表里有两个时间概念,含义不同,使用时不要混淆:
date:公告日,即这条财务数据对外公布(首次披露或更正)的日期,也是这条数据可以被使用的最早日期。date 不是报告期。report_date:报告期,即这条数据属于哪一期财报。关于 date 的几点说明:
date 就是公告日,原样记录,公告日不是交易日(周末、节假日)时也不会顺延,所以 date 可能不是交易日。按交易日使用时,用 date <= 交易日 取最新的记录即可(见本文五的 ASOF JOIN)。date 来自 cn_stock_financial_changedate 的 changedate,二者约等于同一个日期。数据入库时会去重,所有字段的取值完全相同的记录只保留一条。report_date 首次披露和后来更正,会有不同的 date。date 同样是公告日,表里只有公司有公告的日期。站在这一天,shift = 0 是当时能看到的最新一期,shift = 1, 2… 是更早的各期,数值是当时能看到的版本,示例见本文四。报告期的取值:
上市公司一年内披露四次财务报告,披露时限如下:
判断某一天能看到哪些数据要用 date,不能用 report_date,否则会用到当时还没有公布的数据。
上市公司除了正常披露财务报表外,后续会时常对历史财务数据进行修正。因此在量化投资领域,加工财务数据时不能只用最新修正后的数据,而要基于历史时间节点获取当时能获取的最新数据。PIT(Point In Time)数据指的是在某个时间点上,基于已公布的财务报表获取的某个财务指标的取值。
以 002473.SZ 的财务数据为例,在平台上调用以下代码:
import daiimport pandas as pdpd.set_option('display.float_format', '{:.2f}'.format)
dai.query("""SELECT date, instrument, report_date, change_type, total_current_assetsFROM cn_stock_financial_balance_general_pitWHERE instrument='002473.SZ'AND report_date='2019-12-31'AND date>'2020-01-01'""").df()运行上述代码,能得到以下数据:
| date | instrument | report_date | change_type | total_current_assets |
|---|---|---|---|---|
| 2020-04-30 | 002473.SZ | 2019-12-31 | 0 | 223449880.95 |
| 2020-08-27 | 002473.SZ | 2019-12-31 | 1 | 228470428.90 |
| 2020-10-26 | 002473.SZ | 2019-12-31 | 1 | 228470428.90 |
| 2021-04-29 | 002473.SZ | 2019-12-31 | 1 | 228470428.90 |
该公司于 2020 年 4 月 30 日首次公布 2019 年年报,披露的流动资产(total_current_assets)为 223449880.95,又于 2020 年 8 月 27 日对 2019 年年报的流动资产进行修正,修正为 228470428.90,因此 2019 年年报在表中有多条记录。
date 为 2020-08-27、2020-10-26、2021-04-29 的 total_current_assets 取值相同,这些重复记录是必要的:公司每披露某一期财报,都会附带上年同期或上年年末的数据作对比,极少部分公司即使不发布修正公告,也会通过这种方式修改历史财务数据,所以每次披露都保留一条记录。
原始数据表里与此相关的字段:
| 字段 | 释意 |
|---|---|
| change_type | 0 表示首次披露的财务数据,1 表示非首次披露或有更改的财务数据 |
| fs_quarter_index | 对应季度,1 指一季报,2 指半年报,3 指三季报,4 指年报,仅报表 PIT 表有 |
原始财务数据只在公司披露财报时才有记录,这类非规整的数据很难直接用于量化投资。衍生数据把原始数据加工成四类,字段名就是原始财务字段加上对应的后缀。要查具体字段,先在原始财报的文档里找到财务字段,再加上后缀,比如利润表的 net_profit 对应 net_profit_lf、net_profit_ttm。
cn_stock_financial_lf_shiftcn_stock_financial_ly_shiftcn_stock_financial_mrq_shiftcn_stock_financial_ttm_shift在平台加工的“衍生数据”和“财务分析”两大类财务数据中,我们同样进行 PIT 处理,以 002473.SZ 这只股票的流动资产(total_current_assets)数据举例:
import daiimport pandas as pdpd.set_option('display.float_format', '{:.2f}'.format)
dai.query("""SELECT date, instrument, report_date, shift, total_current_assets_lfFROM cn_stock_financial_lf_shiftWHERE instrument='002473.SZ'AND shift < 3AND ((date='2020-04-30')OR (date='2020-08-27'))""").df().sort_values("date")通过上述代码,我们得到以下数据,可以看出,站在 2020 年 4 月 30 日这一天,我们能获取到的 2019 年年报的流动资产为 223449880.95,但站在 2020-08-27 这一天时,我们能获取到的 2019 年年报的流动资产为 228470428.90。
| date | instrument | report_date | shift | total_current_assets_lf |
|---|---|---|---|---|
| 2020-04-30 | 002473.SZ | 2019-09-30 | 2 | 268546184.69 |
| 2020-04-30 | 002473.SZ | 2019-12-31 | 1 | 223449880.95 |
| 2020-04-30 | 002473.SZ | 2020-03-31 | 0 | 213964081.16 |
| 2020-08-27 | 002473.SZ | 2019-12-31 | 2 | 228470428.90 |
| 2020-08-27 | 002473.SZ | 2020-03-31 | 1 | 233220236.75 |
| 2020-08-27 | 002473.SZ | 2020-06-30 | 0 | 222315509.19 |
衍生数据按公告日存储,不是日频。要得到日频数据,把财务表按公告日对齐到交易日:某一天只使用当天及之前已经公告的最新一期(shift = 0),在下一次公告之前沿用上一期的值。DAI SQL 用 ASOF JOIN 完成。
下面以日频 ROE 为例,ROE = 滚动十二期归属母公司股东的净利润 / 最新一期归属母公司股东的所有者权益:
import dai
df = dai.query("""SELECT b.date, b.instrument, t.net_profit_to_parent_shareholders_ttm / l.total_equity_to_parent_shareholders_lf AS roe_ttmFROM cn_stock_bar1d bASOF JOIN (SELECT * FROM cn_stock_financial_ttm_shift WHERE shift = 0) t ON b.instrument = t.instrument AND b.date >= t.dateASOF JOIN (SELECT * FROM cn_stock_financial_lf_shift WHERE shift = 0) l ON b.instrument = l.instrument AND b.date >= l.dateWHERE b.date >= '2024-01-01'ORDER BY b.date, b.instrument""", filters={"date": ["2023-01-01", "2024-12-31"]}).pl()filters 的起点要早于第一个需要的交易日,这里提前一年,这样起点之前已经公告的财报也能取到。cn_stock_financial_profitability 的 roe_avg_ttm、roe_period_ttm 等字段。平台还提供过已按日频处理好的财务表 cn_stock_factors_financial_items,以 002473.SZ 的流动资产(total_current_assets)数据举例(该表已不建议使用,建议基于衍生数据自行计算):
import daiimport pandas as pdpd.set_option('display.float_format', '{:.2f}'.format)
dai.query("""SELECT date, instrument, total_current_assets_lyFROM cn_stock_factors_financial_itemsWHERE instrument='002473.SZ'AND ((date>'2020-04-25' and date<'2020-05-05')OR (date>'2020-08-25' and date<'2020-09-01'))""").df().sort_values("date")通过上述代码,我们得到以下数据。可以看出,当日期来到 2020 年 4 月 30 日这一天时,我们能获取到最新的流动资产(年报)数据是 223449880.95,这个数值一直保持到 2020 年 8 月 27 日,最新一期年报的流动资产变为了 228470428.90,符合预期。
| date | instrument | total_current_assets_ly |
|---|---|---|
| 2020-04-27 | 002473.SZ | 330113974.90 |
| 2020-04-28 | 002473.SZ | 330113974.90 |
| 2020-04-29 | 002473.SZ | 330113974.90 |
| 2020-04-30 | 002473.SZ | 223449880.95 |
| 2020-08-26 | 002473.SZ | 223449880.95 |
| 2020-08-27 | 002473.SZ | 228470428.90 |
| 2020-08-28 | 002473.SZ | 228470428.90 |
| 2020-08-31 | 002473.SZ | 228470428.90 |
shift 的含义都与衍生数据相同,字段名带 _lf、_mrq、_ttm 后缀。各指标的计算公式见各表文档的“字段说明”。report_date 的月份筛选出 06-30 和 12-31 的记录。非经常性损益等少数科目在一季报、三季报中也有数据。import daidf = dai.query(""" SELECT date, instrument, report_date, eps_basic_lf FROM cn_stock_financial_lf_shift WHERE instrument = '002039.SZ' AND shift = 0 ORDER BY date, report_date""", filters={"date": ["2020-01-01", "2023-12-31"]}).df()import daidf = dai.query(""" SELECT date, instrument, report_date, shift, moneytary_assets_lf FROM cn_stock_financial_lf_shift WHERE instrument = '000012.SZ' AND report_date = '2005-12-31' ORDER BY date, report_date""", full_db_scan=True).df()import daidf = dai.query(""" SELECT date, instrument, report_date, total_assets_lf / total_owner_equity_lf as em FROM cn_stock_financial_lf_shift WHERE shift = 0 ORDER BY date,instrument,report_date""", filters={"date": ["2020-01-01", "2023-12-31"]}).df()SELECT date, instrument, report_date, shift, moneytary_assets_lf, settlment_reserves_lf, loans_to_banks_and_fin_institutions_lf FROM cn_stock_financial_lf_shift WHERE date >= '2026-10-06' ORDER BY date LIMIT 100
SELECT date, instrument, report_date, shift, moneytary_assets_lf, settlment_reserves_lf, loans_to_banks_and_fin_institutions_lf FROM cn_stock_financial_lf_shift WHERE date >= '2026-10-06' ORDER BY date LIMIT 100