Repository navigation
Releases
0.24.0 · 最低要求升到 Python 3.11 与 DuckDB 2.0,新增实验性的湖目录
最低要求升到 Python 3.11 与 DuckDB 2.0,新增实验性的湖目录
CNEquity 0.24.0 已发布至 PyPI。开源 A 股本地数据湖,用于量化研究、回测与 AI Agent。
python -m pip install --upgrade cnequity==0.24.0- 升级步骤: 先确认环境是 Python 3.11 或更高,再
pip install -U cnequity,然后重启cne serve和已在运行的cne mcp。数据集的列、主键和分区都没有变,本版没有迁移要跑。extends = "builtin"的配置不用改;完整展开的旧配置运行cne config upgrade改写改过名的键,并手动把name_history从 core 组里去掉,否则日更仍会读 Tushare。升级后第一次日更会把option_greeks和minute_bars_15m/30m/60m的全部历史重算一遍,之后只重算内容变了的交易日。湖目录(lake/)是实验性的:不建它,读写与以前完全一样;[storage].publish = "catalog"对每个数据集单向生效,打开前先做快照,暂不建议用在不能重建的湖上。 - 发布进湖目录的一次运行现在只产生一个快照,并且这个快照本身就能按文件直接读取:替换某个分区时,持有这些行的数据文件整体换掉,文件里不属于该分区的行原样重写,不再留下删除记录等事后合并。此前一次发布要三个快照(写入、合并删除记录、登记历史),后两步之间中断会丢掉「修订对应哪个快照」的记录,而只存在于湖目录里的修订没有别处可读。修订所在的快照改由
_revisions表中该行自带的快照号给出,与数据同时提交。代价是重抓已有日期时变慢:真实湖克隆上重抓一天分钟线(所在月文件 2,970 万行)4.1 秒,旧写法 1.1 秒,全表内容逐行一致;新增日期的追加不受影响。 - 新增
cne storage verify-catalog [--dataset 名称]:发布进湖目录的每个修订现在随数据记下所改分区的行内容摘要(行数加逐行哈希的异或与求和,与文件布局和行顺序无关),这个命令在修订自己的快照上重算并比对,有不一致时退出 1。此前回执里的 SHA-256 只对应运行暂存的文件,湖目录入库时会重排重写,核对不了实际存储的内容。摘要用 DuckDB 的行哈希,换了 DuckDB 主次版本后记下的摘要报告为other_algorithm,不判为不一致;快照已过期的报告为expired。 cne snapshot create复制文件时不再持有湖锁:持锁期间只读取各数据集的状态、指针和回执并列出要复制的文件,放锁后再复制。代目录和原始响应存档写入后不再改动,所以复制到的仍是持锁时看到的内容;复制前后文件的大小或修改时间变了、或文件被清理掉,快照失败并提示重试。此前整个复制过程都持锁,原始存档放在网络盘上时会让日更和事件流等上几个小时。- 新增实验性开关
[storage].publish = "catalog":压缩步骤从湖目录取出本次要改的分区,合并后在一个目录事务里替换这些分区,同一次运行的数据集同一快照发布,不再写代目录。真实湖克隆上的同一次运行,两种方式发布的 8 个数据集逐行一致。默认仍为"generation"。开启后湖在meta/storage.json记下这一点,派生和修复此后也从核对过的工作目录发布进目录。 - 修复北交所涨跌幅越限检查自 11-05 起失效:
daily_bars改按月分区后,检查从分区目录名推算市场交易日,结果总是空,单日日更里每一行都被当成「前一交易日不明」而不判断。现在交易日取自交易日历。 - 新增
[sources.eastmoney].proxy_hosts:只让列出的主机(含子域名)走proxy,其余东财主机直连。可以只把 push2 留在代理上,数据中心、公告等直连可达的主机不再因代理停掉而失败。未设时与以前一样,所有东财主机都走代理。 - 日更不再读 Tushare:
name_history移出默认 core 组,sector_fund_flow在 push2 暂停时也不再改从 Tushare 取当日数据。Tushare 只用于按需补全历史(cne backfill <数据集>),令牌过期不会再让日更失败;所有以 Tushare 为主来源的数据集都不计入新鲜度。 - 新增
cne storage catalog-retention:湖目录为每个数据集保留最近的修订([storage.retention].keep_generations,默认 5 个)和被cne storage hold保护的修订,其余快照过期,不再引用的文件等 24 小时后才删除;cne run maintain每天执行。湖目录保存了创建时的绝对数据路径,搬迁、恢复或复制过的湖会去读原湖的文件,现在总是读湖目录自身目录下的文件。 option_greeks与minute_bars_15m/30m/60m判断哪些交易日要重算时,改为比较当天数据的内容摘要,不再比较分区文件和修改时间;只挪动文件、合并文件不会再触发重算。计算规则改用显式版本号,代码重构不再让全部历史重算。升级后第一次运行会重算一遍全部历史(期权希腊值约 50 分钟),之后只重算内容变了的交易日。- MCP
query_dataset和控制台行查看器的读取预算从「64 MiB Parquet」改为「400 万行」。内存随读取的行数增长,同样的行在湖目录里占的字节可以少 60%,按字节算会放过实际很大的读取。拒绝信息里的大小也改为行数。 load()的行顺序现在完全确定:仍按日期和代码排序,并列的行再按主键其余列排序。此前并列行的先后取决于文件和扫描顺序。- 新增实验性的湖目录(
lake/):cne storage sync-catalog --create把每个数据集的已发布版本复制进一个带快照的目录库,之后每次发布都会把变动的分区同步进目录,cne run maintain每天再核对一遍。建了湖目录的湖,读取在目录与所读版本一致时改从目录取数,否则照旧扫描;CNE_READ_CATALOG=0可关闭。质量检查、派生和日更步骤内部的扫描,以及cne query与 MCPrun_sql背后的 SQL 视图,也一样改读目录里的数据文件。读取结果的行内容不变。 - 不兼容变更:最低 Python 版本从 3.10 提高到 3.11,DuckDB 最低版本从 1.5 提高到 2.0。DuckDB 2.0 不再支持 Python 3.10;仍在 3.10 上的环境请先升级 Python 再升级 CNEquity。
- 修复
economic_calendar日更失败:回补过早年历史后,早年文件没有withdrawn列,日更读取时报SchemaError: extra column ... withdrawn。现在逐文件读取并按列名对齐,已标记撤回的事件不会被重复标记。 - 修复公告高峰日回补失败(#59):
announcement_index的某一桶按板块、行业、公告分类拆到底后仍超过巨潮 100 页上限时(如 2026-04-29 深市主板 + 制造业 + 日常经营,共 3024 条),不再报slice exceeded 100 pages退出,而是以默认翻页结果为底,按代码排序翻页补齐缺的行,凑齐即停;每页都要求总数与原查询一致,合并后仍按巨潮总数精确对账,对不上照样失败。超过两次翻页能读到的条数时直接报错。分区之间的缺口也改用同一逻辑补齐,并且凑齐即停,不再四种排序全部翻完。原始响应存档可重放这类补齐。 - 公告索引新增按股票分组的最后一级拆分(#59):排序翻页仍凑不齐,或一桶超过两次翻页能读到的条数时,按巨潮股票目录把当前板块的股票每 40 只分为一组查询,合并后同样按总数精确对账。巨潮在一次传入超过约 50 只股票时会忽略股票条件、返回整桶结果,因此一旦返回组外股票的公告就直接失败。股票目录里没有的股票(如早已退市的公司)会造成短缺,结果仍是失败,不会少数据入库。
- 修复安全问题:
cne serve未设--token时,只有操作页和存储页检查请求的 Host,数据接口(/api/datasets、/api/read、/rows、运行记录、质量、事件流等)和页面不检查。恶意网页可借 DNS 重绑定把自己的域名指向 127.0.0.1,以同源身份读取湖数据和运行记录。现在未设令牌时,Host 不是 localhost、127.0.0.1 或 ::1 的请求一律返回 403;在本机浏览器打开不受影响,远程访问仍需--token。 - 网页控制台(
cne serve)的操作页改版,先给出今天的状况,再给出要做的事:- 「今日」新增任务时间线,按北京时间画出今天或昨天每个任务的起止和结果,标出定时日更、收尾补抓和备份的时间;
- 新增近 14 个交易日的日更矩阵:每格是一个调度组在一个交易日的最后一次尝试,按成功、降级、失败着色,重试过的格子另有标记,点开进入那次运行;
- 落后的数据集直接列在操作页,按落后天数排列:按日期的数据集给出预填起止日期的回填,快照数据集给出补抓落后,并注明漏掉的日子补不回来;
- 「要做什么」只保留跑日更、补一段历史、补抓落后三个主按钮,其余收进「更多」;表单改在右侧抽屉里打开,不再把页面往下推,执行计划默认折叠;填写时当场检查:起点晚于终点、交易日晚于今天时不预览,给快照数据集填旧起点或终点晚于今天时给出提醒;
- 最近的任务把同一天的事件流合成一行,写明成功和部分交付的次数及常缺的数据集;日更任务写明哪些组失败或降级,收尾补抓等任务写明哪些数据集失败及原因;每条带耗时、写入行数和到运行的链接;可以按类型和「有问题」筛选。此前最近 50 条几乎全是每小时一次的事件流,日更和回填看不到;
- 「巡检」改成卡片,每项写明上次结果;命令模板和只能在终端运行的命令收进「命令参考」;
- 标签从四个合成三个:今日、巡检,以及定时、数据源与备份;今天是否交易日、定时会话有没有跑过只写在日更状态卡里,不再在操作区重复;
- 每个数据源开关旁标出今天的状态(开启、关闭、暂停、熔断或缺少密钥),写明东财各主机的今日请求数和预算,以及主源为它的数据集今天失败了几批;定时任务的检查时间改按北京时间显示;push2 暂停只在数据源状态卡里提示一次,不再在页面顶部重复。
- 新增只读接口
GET /api/runs/daily-matrix?sessions=N,返回每个日更调度组在最近 N 个交易日的最后一次尝试;GET /api/ops/jobs新增since、op、exclude_op参数,limit上限从 50 提高到 500,每个任务带上rows_written和failed_datasets;GET /api/ops的occupancy.sources增加各主机请求数、付费源是否配置了密钥(不含密钥本身)和今日按数据源统计的失败批次。 - 付费数据源(Tushare、同花顺官方接口)在取数设置里单列一组,默认关闭,可以单独开关,开关只改各自的
enabled,令牌和密钥不动。每个付费源标出是否配置了密钥和上次检测的结果(可用、有效但套餐不含检测接口、被拒绝或没有结果);「检测密钥」只发一次小请求,不改湖里的数据,结果记在meta/sources/key-checks.json,只存密钥的短摘要,换了密钥就重新算作未检测。新增接口POST /api/ops/sources/{source}/check-key,occupancy.sources.key_checks带上次检测结果。 - 只由
cne backfill采集的 Tushare 数据集不再算落后:没有打开 Tushare、没有令牌、令牌检测被拒绝,或者这个数据集没有排进日更时,概览、操作页和cne status都不再把它列为落后,也不按它的水位提示。此前默认安装也会把这些数据集算进落后。 cne serve在当天定时日更时间之前,仍按上一个交易日判断数据集是否落后;当天日更已经跑完则立即按当天判断。此前一到 15:05 就按当天判断,日更开始前的两个多小时里,所有日更数据集都显示为落后。cne status --datasets和网页控制台改用同一套规则判断数据集是否落后,结果一致。此前两边各有一份判断,已经不一致:- 源端已停更的数据集(如 2024-08-16 之后的
northbound_flows),cne status标为retired,控制台却显示「最新」。现在控制台显示「源已停更」,/api/health新增retired、removed、sample三个计数; - 样例湖(
profile = "sample")的合成数据,控制台此前按真实日期判断,现在与cne status一样标为样例数据; cne status --datasets也像控制台一样,在当天定时日更开始或完成之前按上一个交易日判断,不再在收盘后、日更前把所有日更数据集报为落后。
- 源端已停更的数据集(如 2024-08-16 之后的
cne check和cne audit改用同一条规则判断审计 error 是否不合格,同一份审计结果不再一个通过、一个失败。此前cne check不计「缺数据」一类的覆盖 error,核心数据集daily_bars缺了交易日时cne audit失败,cne check却给出「湖可用」。现在核心数据集的覆盖 error 也让cne check退出 1;核心之外数据集的 error 仍不计入cne check,但会报出条数,由cne audit列出。发布和日更的 audit 步骤仍只计数据本身有误的 error,缺数据不影响已有行。- 旧版本清理只保留一种规则:回补和日更后每个数据集保留最近
[storage.retention].keep_generations代(默认 5),更早的代当场删除;要提前删除选定的历史,仍在网页存储页勾选并确认。原先并存的「标记后等 7 天再删」已移除:自动清理会在 7 天到期前就删掉被标记的代,观察期形同虚设,已有的标记在读取登记时丢弃。- 只合并文件、行内容不变的版本(
cne storage merge-files发布的)不再占用保留名额:它夹在保留的代之间时一起保留,随它们一起过期。此前每次合并都会挤掉一个真实的历史版本; cne storage plan改为只读预览,输出keep、candidate_ids、logical_bytes_selected,--keep默认取配置值;--phase不再使用。cne storage apply已移除,调用时报错并说明替代做法。cne storage inspect --keep也默认取配置值;- 网页存储页去掉「检查到期项目」「检查待标记项目」,页头写明保留几代,超出保留代数的版本标为「下次回补或日更时删除」。此前页头写着「不自动删除」,与实际不符。
/api/storage不再返回grace_days和not_before,新增automatic_retention,keep取配置值;版本的status改为scheduled、deletable或protected,暂存的unmarked改为deletable;POST /api/storage/reviews必须带object_ids或resume_plan_id,不再接受phase: "mark"; cne run clean的 JSON 去掉总为 0 的revision_generations[].marked。
- 只合并文件、行内容不变的版本(
- 修复
cne repair valuation-outage每次运行都报错退出(AttributeError: 'tuple' object has no attribute 'split'),预览和--apply都无法使用。 cne backfill financial_statement_items --source tdx_fin --plan不再直接开始回补:此前--source tdx_fin先于--plan处理,加了--plan也会下载并写入。现在只打印起止日期和要下载的报告期。cne backfill的--source、--refetch、--workers是否可用,改由各数据集自己声明,回补命令和各个cne repair子命令共用同一处检查。行为不变,只有报错措辞变了:- 给不支持的数据集用
--source时,报错列出所有支持的数据集及其来源(含此前漏写的option_bars (tushare));给financial_statement_items或option_bars传了它们不接受的来源时,改为指出该数据集可用的来源,退出码由 1 变为 2(参数错误); --refetch不适用时列出的数据集按注册表顺序排列。
- 给不支持的数据集用
futures_continuous(期货连续合约)写入和体检时也按期货行情的规则校验:结算价必须为正,成交量和持仓量不能缺失或为负,有完整 K 线时最高、最低价必须包住开盘和收盘。此前只有futures_bars、option_bars、futures_minute_bars校验,连续合约照单全收。现有数据全部通过(41.5 万行),无需迁移。- 访问新浪的四处重试改用同一套规则:遇到限流(HTTP 429/456)先让所有新浪通道一起冷却 30 秒再重试,遇到 5xx 依次等 5 秒、10 秒再重试,最多 3 次。此前退市股历史恢复遇到限流只在本线程睡几秒就再次请求,容易招致更长的封禁;美元离岸人民币(USD/CNH)和国内期货行情遇到 5xx 则立即重试,不做等待。日线补缺在同一只股票第二次被限流时停止本次补缺的做法保持不变。
- 自行构造
DatasetSpec的代码不能再传pit和pit_grade:二者改由pit_quality推出(strict与reconstructed为点时数据集),读取这两个属性的结果不变,导出的数据集契约逐字节不变。每个数据集的支持级别、取值规则、单位和data_version也都写回各自的注册项,不再分散在按名字查找的旁表里。 - 复权因子的
stock_event_factor和fund_share_factor发现项补上了说明文字(哪只证券、哪天、因子是保留、按比例修正还是核对无误),此前没有message,在cne audit和网页控制台上显示为空行,而它们占了发现项的大多数。审计写入发现项前统一检查:严重级别只能是 error、warning、info,必须有检查名;缺说明的发现项改用检查名代替并记一条日志,不会让审计失败。 cne run maintain每天清理中断的提交留下的东西:复制中途断掉留下的临时目录、写完收据却没来得及切换指针的未发布代(收据保留,作为失败记录;人工保留的不删),并按当前指针重建对不上的状态文件;没有收据的代只列出不删。此前代码注释说这些由gc回收,但并没有这个命令。cne status --datasets新增--json:stdout 只输出一个 JSON(last_trading_day、各数据集的 freshness 等列,freshness 为小写,以及--hide-empty折叠掉的folded),之后的截面核对与门禁说明改走 stderr,退出码不变,脚本不必再解析表格。cne启动更快:读 Excel 和 PDF 的适配器改为用到时才导入 pandas 和 pypdf(连带 pyarrow),cne --help、cne status等不解析表格的命令不再为此等待。- 移除两个只做转发的内部模块:
cnequity.query.canonical改从cnequity.domain.canonical导入,cnequity.adapters.calendar.holidays_cn改从cnequity.domain.holidays_cn导入,内容不变。Config上旧的_backfill*和修复开关私有属性也已去掉,改用cnequity.run_scope的backfill_of/set_backfill和run_flags_of/set_run_flags;旧名字记录的重试范围仍能读取。 - 移除
cnequity.universe_profiles,改从cnequity.domain.universe_profiles导入(文档早已改用这个路径)。 cne config upgrade把改了名的配置项改成现名:[orchestrator] tdx_daily_executor→tdx_daily_backend,[derive] workers→[orchestrator] derive_workers,[sources.<名>]里的concurrency/max_in_flight/workers→max_concurrency;现名已经写了时旧名本来不起作用,直接删掉。旧名仍然有效,加载时提示运行cne config upgrade。- wheel 只带当前版本的数据集契约(
share/cnequity/contracts/v<版本>.json),不再附带全部历史契约,安装后少占约 3.3 MB;历史契约仍在仓库和源码包(sdist)的contracts/目录。运行时不读这些文件。 - 文档首页的覆盖范围卡片和「与同类项目对比」页把数据集数写成 55(47 个采集),已改为当前的 86(78 个采集 + 8 个派生)。README、首页、指南、对比页和运维手册里引用的数据集数今后由
scripts/dev/sync_docs.py按注册表生成,不再手改。 - 修复数据湖目录路径含
#或?时读不到运行记录:控制台、操作页任务、cne schedule、存储统计、发布门禁等以只读方式打开manifest.db时把路径直接拼进 SQLite URI,#/?之后被当成片段或参数,打开的是另一个空库,不报错只显示没有运行。现在统一按 URI 转义路径。 cnequity.query/cnequity.domain里画像函...
0.23.0 · 供应商占位 0 改为空值,日线等数据集改为按月存放
供应商占位 0 改为空值,日线等数据集改为按月存放
CNEquity 0.23.0 已发布至 PyPI。开源 A 股本地数据湖,用于量化研究、回测与 AI Agent。
python -m pip install --upgrade cnequity==0.23.0-
升级步骤:
pip install -U cnequity后重启cne serve和已在运行的cne mcp。daily_bars、adj_factors、margin_trading、valuation_metrics升到 schema 版本 2:列和主键不变,分区从按日改为按月(目录trade_date=YYYY-MM)。旧湖先cne migrate预览,再cne migrate --apply。本版迁移为daily-bars-month-partitions、adj-factors-month-partitions、margin-trading-month-partitions、valuation-metrics-month-partitions、limit-prices-month-partitions、fund-flow-tushare-month-partitions、chip-distribution-month-partitions(历史改写成月文件,行不变)和vendor-zero-nulls(把供应商用来占位的 0 改写成空值)。迁移前cne audit会报告stored_value_placeholders;月文件和旧的日目录并存时,每周体检会报mixed_partition_granularity。直接读 Parquet 的程序对这几张表要关掉 Hive 分区推断,按文件里的日期列过滤。说明见contracts/migrations/0.23.0/。extends = "builtin"的配置不用改;完整展开的旧配置运行cne config upgrade,把name_history加进 core 组。新增的 Tushare 数据集需要自己的令牌,多数只由cne backfill采集、不进日更。升级前中断且尚未跑完的sector_bars回补,用cne backfill sector_bars --force重跑一次。日更曾写出没有对应公司行为的因子跳变时,用cne repair adj-factors --apply改写整段历史。停牌行的 ST 标记用cne derive trading_status --start <日期> --end <日期>按年更新。配置里有集合项时,升级后第一次运行会得到新的config_fingerprint,此后不变。 -
MCP
run_sql在 DuckDB 2 上可以计数了:Relation 不再提供fetchone(),总数改为取limit(1).fetchall()的一行。DuckDB 1.5 照常可用。新安装会解析到 DuckDB 2,此前这条命令直接报query failed。 -
旧版本清理恢复自动运行:只要登记过的引用目录(湖的
meta/和private/)里有任何文本文件改动,清理就一直报Reference inventory changed而什么都不删,自 10-31 起每天如此。现在清理前会自动重新扫描引用目录,给其中提到的每个版本加上保留,再按保留代数清理;重新扫描只增加保留、从不解除,所以不会删掉任何仍被引用的版本。新增cne storage refresh可手动执行同样的扫描。Tushare 权限缓存(meta/tushare)也不再计入引用扫描,它每次体检都会被改写。 -
新增
cne snapshot delete <名称>:删除快照,并解除由快照内文件带来的、已失效的保留引用。手动保留和来自其他位置的引用照旧保留;快照曾保住的旧版本会在下次清理时回收。删除前需要确认,--yes可跳过。此前快照只能创建不能删除,只能手动删除目录后再逐个解除保留。 -
新增
cne storage release <版本…> --note <说明>,用来解除不再需要的版本保留。它只去掉手动保留,以及引用文件已删除或不再提到该版本的引用保留;案例依赖和仍然有效的引用照旧保留,并会列在输出里。每次解除都会记入保留登记表。此前保留只能增加、无法解除,被保留的旧版本永远无法被清理。 -
供应商用 0 表示“没有值”的字段,统一存为空值,不再当作真实数值:可转债日线的开高低收和前收、同花顺/东财人气榜的价格、筹码分布的价位、
fund_flow_ths_tushare和limit_events的收盘价、涨跌停价、一致预期目标价、卖方预测的目标价区间、回购价格区间,以及原有的估值指标和东财/中证指数权重。此前这些 0 会被当作价格读出,例如跨过收盘价为 0 的一天算收益率会得到 −100%;同花顺可转债、ETF、港美股和板块榜单上 99% 的价格都是 0。可转债没有成交的交易日保留该行,开高低收为空。规则写在数据集注册表里,在统一的写入和读取校验中执行,不再由各个 adapter 和看板各自维护:读取时立即生效,已有的湖升级后运行一次cne migrate --apply(迁移vendor-zero-nulls),把存量的 0 改写为空值并作为新版本发布;迁移前cne audit会报告stored_value_placeholders。可转债日线也开始执行与日线相同的价格合理性检查。 -
看板按交易日判断缺口、日期选择和热力图的数据集改由注册表决定:除原有的几个外,
index_bars、adj_factors、industry_index和market_breadth也按交易日判断,此前它们按年或按月目录判断,缺了某一天看不出来。 -
cne backfill announcement_index改为逐日拉取、逐日入库(#58):此前每个约 31 天的窗口要整月拉完才写入,中途停止时已拉的页全部作废,下次要向巨潮重新拉取,公告密集的 4、8、12 月一次中断就损失数小时。现在每天单独请求、单独留证、拉完即暂存,中断最多损失正在拉的那一天,重跑时自动跳过已入库的日期;某一天失败也不再连带重拉同一窗口的其他日期。没有公告的日子每天多一次请求。 -
逐日回补(
margin_trading、limit_prices、fund_flow_tushare、broker_forecasts、market_breadth、各 Tushare 补充数据集、futures_bars、option_bars等)按 Ctrl-C 或被终止时,先把已拉完的日期写入再退出:这些回补每 60 天写入一次,此前中断会丢掉最近一次写入后已拉的最多 59 天,下次要重新请求;拉取出错时本来就会先写入,中断现在与之一致。 -
financial_statement_items、share_structure、shareholder_counts、top_holders的回补中断后重跑,不再从头重拉:此前已完成的“报告期 × 报表”或时间窗只在同一次运行内跳过,重新执行cne backfill会从 2001 年起全部重新请求,而这些数据入湖时又会被去重。现在 7 天内已入湖的单元会被跳过(按 schema 版本和证券范围区分,限定证券的修复不会代替全市场),财报的完整性检查对跳过的报告期按湖里已有的数据判断。cne backfill <名称> --refetch可忽略这些记录、全部重拉。 -
cne backfill financial_statement_items不再在 F10 现金流表处报invalid report unit …|RPT_F10_FINANCE_GCASHFLOW退出(#57):0.21.0 起回补会拉取 F10 四张现金流表(取期末现金),但回补校验只认原来的四张报表,第一个 F10 单元就让整次回补中止。现在校验直接按拉取的报表清单判断,以后新增报表也不会再出现这个问题;日更不受影响。 -
派生
adj_factors时,share_structure也算作输入:股改窗口的因子要读它,但它此前不在输入清单里,计算期间它发布了新版本也照常发布结果,它的部分覆盖状态也不会传到adj_factors。现在它和其他输入一样会被记录、校验和传递;派生和因子修复共用同一份输入清单。 -
网页控制台(
cne serve)补齐 29 个数据集的中文名称:此前这几个版本新增的数据集(多为 Tushare 数据集,以及limit_prices、name_history)只显示英文 ID,按中文名也搜不到。健康页 TDX 探针的覆盖列表补上corporate_actions、trading_calendar和minute_bars_5m。 -
sector_fund_flow_ths的行业行往前补到 2024-09-10:来自 Tusharemoneyflow_ind_ths,标source=tushare,每天附原始响应作证据;金额只精确到 1 亿元,比同花顺页面的 0.01 亿元粗。 -
再新增十三个可选的 Tushare 数据集,同样只由
cne backfill采集、不排日更:游资名录与每日交易(hot_money_traders、hot_money_trades)、可转债赎回、转股与票息(convertible_bond_calls、convertible_bond_conversions、convertible_bond_coupons)、同花顺与东财人气榜(popularity_ranks)、连板天梯(limit_ladder)、最强板块(strongest_sectors)、开盘啦涨停榜(kpl_limit_ups)、同花顺口径分单资金流(fund_flow_ths_tushare)、互动问答(investor_qa)、董监高与薪酬持股(executives、executive_compensation)。 -
巨潮公告回补的续传断点改为压缩存储(有 zstd 时用 zstd,否则用标准库 gzip):一个长时间窗口的断点包含所有已整理的分页,原来是明文 JSON、每抓一页就整份重写一次,单个文件达 239 MB,全部合计 7.2 GB;zstd 压缩后约小 19 倍,回补时的写入量也相应减少。旧的明文断点照常读取,下次写入时替换。超过有效期(默认 7 天)的断点不会再被续用,公告步骤运行时会自动删除;有效期设为不限时不删除。
-
margin_trading、valuation_metrics、limit_prices、fund_flow_tushare、chip_distribution也改为按月分区:合计约 2.4 万个日文件改写为约 1,060 个月文件,读取单只股票的完整历史从 0.3–0.7 秒降到 0.05–0.3 秒。看板对这几个数据集的缺口、日期选择和热力图仍按交易日判断。cne repair repartition修复估值口径(valuation-basis)时改为按数据中的交易日读取日线,按日或按月存放都能正确处理。已有的湖升级后运行一次cne migrate --apply,五个迁移(*-month-partitions)逐个把历史改写为月文件并作为新版本发布,数据不变。 -
adj_factors也改为按月分区:8,758 个日文件改写为约 430 个月文件,体积从约 225 MB 降到约 81 MB;带adjust="hfq"读取单只股票的完整历史从约 0.9 秒降到约 0.2 秒。复权因子派生改为按分区周期读写,按月存放时仍从最新一个月的数据里读出已派生到哪天,日更只追加新的交易日。已有的湖升级后运行一次cne migrate --apply(迁移adj-factors-month-partitions),历史逐月改写并作为一个新版本发布,数据不变。 -
新增五个可选的 Tushare 数据集,只由
cne backfill采集、不排日更:limit_events(2020 起每日涨停、跌停与炸板)、futures_member_positions(2010 起各交易所期货会员成交量与多空持仓排名)、earnings_forecasts(2004 起业绩预告)、business_segments(2004 起按产品、地区、行业的主营业务构成)和investor_visits(2021-08 起机构调研)。 -
daily_bars改为按月分区:历史从 1.1 万个日文件(平均 44 KiB)改写为约 430 个月文件,读取单只股票的完整日线历史从约 0.9 秒降到约 0.12 秒,DuckDB 按股票或按日查询从约 1 秒降到 0.1 秒以内;每日整理把当天合并进当月文件,多花约 30 毫秒。已有的湖升级后运行一次cne migrate --apply(迁移daily-bars-month-partitions)把历史改写为月文件:逐月改写并作为一个新版本发布,数据不变;改写前新写入的月文件会与旧的日目录并存,读取不受影响,但每周体检会报mixed_partition_granularity。 -
cne snapshot create对发布过多个版本的数据集不再报dataset contains unsupported link or special file(s):0.21.0 起,各版本之间未改动的文件用硬链接共享。快照此前只在复制版本目录时放行硬链接,在复制数据集当前目录时仍拒绝它们,所以真实湖上的daily_bars等数据集无法做快照。现在这些文件按普通文件逐个复制成独立文件;符号链接和特殊文件仍被拒绝,快照包里的硬链接在校验时也仍被拒绝。 -
cne repair repartition对已发布(有版本)的数据集改为逐个周期重写历史并作为一个经过发布闸门的新版本提交;此前它直接替换工作目录,读取方看到的仍是旧版本,下一次整理还会把改写覆盖掉。重写只合并同一主键的重复行(与整理一致),不改动数据,每次只在内存中保留一个周期。 -
读取单只股票的完整日线历史快了一半多:
load("daily_bars", symbols=[...])在本机湖上从约 2.3 秒降到约 0.9 秒(同一进程里的后续读取),带adjust="hfq"从约 4.1 秒降到约 1.6 秒。日线的 1.1 万个日分区文件有新旧两种列结构(早期缺pre_close),按日期交错,读取时原来要拼接约 4,000 段扫描;现在一次扫描补齐缺列,同一进程内也不再重复读取每个文件的元数据。返回的数据逐行一致。 -
修订回执和湖快照里记录的
config_fingerprint不再每次运行都变:配置里像[datasets] best_effort这样的集合项此前按进程随机的顺序参与哈希,同一份配置每次算出不同指纹,来源记录看起来像是配置一直在改。现在先排序再哈希;含集合项的配置在升级后的第一次运行会得到一个新指纹,此后保持不变。 -
MCP
query_dataset不再为一页结果把整个数据集读进内存:一次调用要读的 Parquet 超过 64 MiB、又没有给 20 个以内的 symbol 时,直接拒绝,并说明这个数据集覆盖的日期和能装下的最近窗口(如start=2023-03-29 end=2026-11-03 fits)。此前不带日期范围调用会先加载全部数据再切出 200 行:margin_trading要占约 2.6 GB 内存,option_greeks约 4.8 GB,trade_ticks则根本装不下。带日期范围或少量 symbol 的调用不受影响。 -
新增 7 个可选的 Tushare 数据集,都需要你自己的 Tushare 令牌,只由
cne backfill <名称>采集,不进任何日更组;没有令牌时不发请求:convertible_bonds:可转债与可交换债条款(cb_basic+cb_issue),每只债一行;conversion_price是读取时的转股价,不是历史。convertible_bond_bars:可转债日线(cb_daily),2004 起;价格按每 100 元面值,量为张、额为元。holder_trades:重要股东与高管增减持公告(stk_holdertrade),2006 起;源里逐字重复的行只留一行,event_id为全部字段的哈希。share_repurchases:回购进展公告(repurchase),2005 起,每个阶段一行。pledge_stats:每周股权质押统计(pledge_stat),2014-03 起;股数换算为股。chip_distribution:Tushare 的筹码分布估计(cyq_perf),2018 起;是模型结果,不是交易所数据。northbound_top10:沪深股通每日十大成交股(hsgt_top10),2014-11-17 起;2024-08-16 后交易所不再公布净买入、买入、卖出额,这三列为空。
-
等待湖锁时会说明是谁占着:
compact.lock和各运行锁被占用时,日志的“waiting for …”一行、超时报错和“运行已被锁定”的提示现在写出持有者的进程号、正在跑的步骤、开始持有的时间和命令行,例如held by pid 4242, step derive_option_greeks, since … (12m03s)后接命令行;排队结束后再记一行实际等了多久。此前只能看到“被另一个进程占用”,一次等满 1 小时超时失败的运行事后查不出是谁占的锁。持有者信息记在锁旁的<锁名>.holder.json,释放锁时删除;进程崩溃留下的会被忽略,并随过期锁文件一起清理。Windows 上不再把已退出进程的说明当成仍有人持有。 -
cne serve和cne mcp --http的访问日志不再记下令牌:URL 里的/mcp/<token>和?token=会写成<redacted>,此前令牌原样出现在每一行访问日志里,也会进入转发 stdout 的隧道或代理日志。用 URL 传令牌的接入方式照常可用。 -
MCP
run_sql不再能读到未发布的数据:原始read_parquet只放行各数据集已提交的版本目录,此前整个curated/都可读,能读到未发布或被隔离的候选数据;目录前缀也不再误放行同名开头的其他数据集。查询结果只取当前页,总数单独计数,返回字段不变。query_dataset不给日期范围时仍会全量加载。 -
整理发布中某个数据集提交失败时,排在它前面、已经发布的数据集会照常更新覆盖台账和水位,然后再报错:此前这些数据集读取方已能看到新版本,台账却仍把那些日期记为缺失。失败的数据集及其后的数据集保持待补,重试仍会处理;全部提交成功时行为不变。
-
futures_bars和option_bars并行运行时,一方不会再清掉另一方已记下的被封主机;复用同一份配置的后续运行也不会再沿用上一次运行学到的停牌结论来豁免本次的日线缺口。 -
清理暂存时,台账里已删除运行的暂存记录一并清掉(运行中的不动),
meta/state/<数据集>.json不再随失败或部分整理的运行无限增长。缺失日期台账不受影响,最坏结果只是某天重新抓取一次。 -
DuckDB 视图(MCP
run_sql及直接用 DuckDB 读湖)的daily_bars、index_bars不再返回空的pre_close:同一主键有多条观测、胜出的一条没有前收盘时,视图现在和load()一样用较早观测的值补上。两条读取路径的取行规则改为同一张规则表生成,并有测试逐行对照。 -
单个数据集暂存量达到 256 MiB 的大回填,整理时按分区逐个合并,不再把整个运行的暂存一次读进内存:峰值内存约降为原来的四分之一,耗时相应增加,写出的文件与原路径完全相同。日常运行仍走原路径;分区列不在主键里的数据集和
trading_status始终整份合并。 -
注册两个同名步骤现在直接报错(
DuplicateStepError),此前后注册的静默覆盖前一个。 -
湖放在 exFAT/FAT 移动硬盘或部分网络盘上时,原始响应归档、派息缺口清单和持有人现金证据的写入不再失败:这类文件系统不支持硬链接,此前每个归档原始响应的数据集都会报
Operation not supported而无法写入。现在不支持硬链接时改为“目标不存在才放入”的方式写入,已有文件照旧不覆盖。 -
baostock 长时间扫描中途重新登录时若遇到连接重置等网络错误,已抓到的行会保留并照常落盘,剩余股票留待续跑:此前这类错误会让整次扫描的结果全部丢失。
-
DNS 解析失败、TLS 错误和 curl_cffi 的请求错误现在归为可重试的源端临时故障:它们是
OSError的子类,此前被当成存储故障,既不自动重试,也会跳过后续批次。 -
写入数据文件、派生文件或状态文件时按下 Ctrl-C,不再在目标旁留下隐藏的
.tmp临时文件;原文件本来就不受影响。 -
MCP 表格结果里的 NaN 和 ±Infinity 改为 JSON
null:此前它们以裸NaN/Infinity输出,严格的 JSON 解析器会拒收整个结果。 -
MCP 工具内部的
TypeError不再报成“参数错误”:现在先按工具签名核对参数,只有对不上时才说参数有误,工具自身的故障按TypeError: …报告,免得代理去改本来正确的参数。 -
某个数据集的
meta/state/<数据集>.json损坏时,list_datasets和 MCPdescribe_lake照常返回其他数据集,损坏的那个带上state_error说明原因,不把它的水位显示成“没有”。需要水位的读取仍会直接报错。 -
冷却后的恢复探测进行中按下 Ctrl-C,不再算作探测失败:此前会让该数据源再冷却 5 分钟,现在探测机会原样交还,下次运行立即探测。
-
cne backfill在各批次跑完之后才出错(例如写审计记录时磁盘已满)时,这次运行会立即记为失败并写明原因:此前会一直显示“运行中”,直到超过孤儿运行的宽限期。 -
`val...
0.22.0 · Linux 日更不再卡死,回补和日更只写改动的数据
Linux 日更不再卡死,回补和日更只写改动的数据
CNEquity 0.22.0 已发布至 PyPI。开源 A 股本地数据湖,用于量化研究、回测与 AI Agent。
python -m pip install --upgrade cnequity==0.22.0- 升级步骤:
pip install -U cnequity后重启cne serve和已在运行的cne mcp。数据集契约没有变化,不需要迁移数据;配置不用改,[orchestrator]可选新增batch_stall_seconds(默认 600)。为绕过 #56 临时加的tdx_daily_backend = "thread"可以删掉,恢复 Linux 默认的进程池。 直接读取 Parquet 文件的外部程序要读分区目录下的所有文件:一个分区现在可以有多个文件(见下文)。 - 回补和日更只写改动的数据,不再重写整个分区:此前写入一个分区时,会把整个分区读出来、合并后整份重写成一个文件,写入成本取决于分区大小而不是改动多少。实测补 40 只股票一个月的日线要重写 159,192 行才写进 840 行;按年分区的行业指数每天追加约 1,200 行要重写约 29 万行;补一只股票的分钟线或逐笔要重写整天 170 万到 1,600 万行。现在一个分区可以有多个文件,各文件主键互不重叠:新增的键写成新文件,旧文件不读也不重写;修改只重写包含这些键的文件。同样的 40 只一个月补缺,现在只写 840 行(一个新文件),合并部分耗时 0.4 秒,新版本也只多出新写的文件,其余文件硬链接共享。分区越大、磁盘越慢,省下的时间越多;整理发布里与写入量无关的水位和覆盖检查仍要二三十秒。复权因子和行业指数的派生写入同样改为这种方式。
- 整理发布前不再把整个数据集复制一遍:此前每次整理发布和派生前,都会把当前版本整份复制到工作目录,在不支持克隆的文件系统(如 Linux 常用的 ext4)上是逐字节复制并对每个文件 fsync,与改动多少无关——
daily_bars453MB、7,201 个文件,minute_bars4.1GB,trade_ticks5.6GB。现在只复制和当前版本不一致的文件,正常情况下什么都不用复制。 cne run maintain每天把文件数达到 4 个的分区合并回一个文件,也可以手动运行新命令cne storage merge-files(不加--apply只报告)。合并不改变行内容时不再跑全湖发布审计(实测 21 个分区从 243 秒降到 5 秒);合并掉旧版遗留的重复键或清洗掉的行时照常审计。- 超过 20 万行的分区整份写入时按代码分桶成多个文件(如
part-b003-of-064.parquet):修改已有的键只重写所在的桶,不再重写整个分区——一天 1,400 万行的逐笔、170 万行的分钟线,以前改一只股票就要重写整天。20 万行以下的分区(如每天约 7,600 行的日线)仍是一个文件。分桶只决定文件布局,读取和查询不受影响。 - 整理发布中与写入量无关的固定开销大幅减少:判断日线覆盖到哪天、哪些股票有成交,改为按分区缓存结果,只重算文件有变化的分区,不再每次解码全部约 1,900 万行;北交所 ST 观察收据在输入数据集没有新版本时直接沿用;DuckDB 视图只在对应数据集的版本指针、配置或代码变化时重建,并且只重新定义变化的数据集;基金无成交证明的原始报文按文件指纹缓存解析结果。实测在同一个湖上,没有新数据的 40 只一个月回补从约 29 秒降到 10 秒;补缺口时,交易状态那一次整理发布从约 15 秒降到 2–4 秒,日线那一次仍需约 25–30 秒,主要花在重建依赖日线的视图、重新核验 ST 收据和更新水位上。
- 行为变化:整理发布只清洗它重写的文件。旧版遗留的非交易日行、同一文件里的重复键,此前在分区任何一次写入时都会被清掉;现在要等写入涉及这个文件(修改其中的键)或分区被合并时才清掉。一个分区内多个文件之间重复的键,在下一次写入该分区时就会合并。
- Linux 上
cne run daily不再卡在daily_bars:通达信日线的进程池此前用 fork 启动 worker(Python 3.13 及以下在 Linux 上的默认方式),而主进程在此之前已经用过 polars,子进程继承了 polars 线程池的状态却没有它的线程,第一次并行运算就永远等下去。worker 没有退出,进程池察觉不到,日志只剩每分钟一条still working,一个批次也不会完成(#56)。现在改用 forkserver(不支持时用 spawn)启动 worker,不需要改配置。macOS、Windows 和 Python 3.14 不受影响。 daily_bars的进程池卡住时不再一直等下去:此前 worker 挂住但没有退出,进程池察觉不到,只能手动中止。现在连续 10 分钟既没有批次完成、也没有 worker 心跳,就结束这些 worker,在当前进程内重跑未完成的批次,并在日志里写出卡住的批次号。时长由[orchestrator].batch_stall_seconds控制(默认 600,0关闭)。只作用于 Linux 默认的进程池,macOS 和 Windows 用的线程池不受影响。- 并行运行的 baostock 步骤不再把 30 秒的 socket 超时留给整个进程:此前每次 baostock 抓取都会改进程级的默认超时、结束时再还原,几个步骤同时运行时会按错误的顺序互相还原,实测 4 个并发抓取 200 轮里有 163 轮把超时留了下来,此后这次运行新开的所有 socket 都带着它。现在超时只加在 baostock 自己打开的 socket 上,其他代码不受影响。
- 每次日更和回补不再把仲裁改用 baostock 的股票重新抓一遍复权因子:判断缓存是否过期时,这些股票此前看的是从不更新的新浪缓存,所以每次都被当成过期,逐只登录 baostock 重抓。实测同一个湖上,复权因子派生从 200 秒降到 27 秒,每次少重写约 3.7 万行因子;40 只股票一个月的回补因此从约 285 秒降到约 2 分钟。日志里这类股票也不再写成“新浪不可用”,改为注明是仲裁指定。
- 等待文件锁的提示不再一律说“另一个进程持有”:同一次运行里的多个线程排队等 baostock 唯一的连接时也会出现这条提示,现在写成“另一个进程或本次运行的另一个线程持有”。
- macOS 上
cne serve取消任务后,任务不再在面板里长时间显示为“运行中”:任务进程退出后没有被及时回收,macOS 又无法像 Linux 那样从/proc认出已退出的进程。现在服务启动任务后会立即回收退出的进程。 - 卡住的运行能看出卡在哪里:
daily_bars运行期间,每条still working后面多一行,写出在跑的批次数、最久没有报告进度的批次、它停了多久和它包含的代码。Linux 和 macOS 上,cne命令和daily_bars的 worker 子进程收到kill -USR1 <pid>时会把所有线程的调用栈写到 stderr,不必先装 py-spy;第一条still working会提示这条命令。 macro_indicators新增usdcnh:美元兑离岸人民币日收盘,来自新浪外汇日 K(source=sina,2014-11-07 起),日更和回填都会写入。它是离岸收盘,不是在岸中间价,也不和东财的收盘拼接;新浪拒绝请求时只停这一列,国债和 Shibor 照常写入。cne backfill macro_indicators按区间回补时也会写入美国 10 年期国债收益率usbond_yield_10y(与中国 10 年期来自同一张东财报表),此前只有日更会写。
0.21.0 · 修订改为硬链接并默认只留 5 代,验收只看核心数据集
修订改为硬链接并默认只留 5 代,验收只看核心数据集
CNEquity 0.21.0 已发布至 PyPI。开源 A 股本地数据湖,用于量化研究、回测与 AI Agent。
python -m pip install --upgrade cnequity==0.21.0- 升级步骤:
pip install -U cnequity后重启cne serve和已在运行的cne mcp。share_structure升到 schema 版本 2,新增可空列float_a_shares(见下文);已有行为空,按窗口cne backfill share_structure补,不为这一列做迁移。economic_calendar也升到 schema 版本 2:历史从“只能积累快照”改为可以回补,并新增可空列indicator_code、withdrawn;已有行不用改写,缺的日子用cne backfill economic_calendar补,说明见contracts/migrations/0.21.0/economic_calendar.md。旧湖运行cne migrate预览、再cne migrate --apply,补齐本版三步:delist-dates、bar-listing-window、financial-comparatives。升级后第一次cne backfill或cne run daily会删掉每个数据集第 5 代以前、没有 hold 的代目录;要留住更老的代,先cne storage hold,或把[storage.retention].keep_generations设为0。extends = "builtin"的配置里,尽力而为档默认不再调度,要继续采集就在[datasets] best_effort列出,或写["all"];完整展开的旧配置行为不变。financial_statement_items和share_structure进入默认 core 组,完整展开的旧配置运行cne config upgrade。自定义了corporate_actions主备源的配置,把通达信改为主源、东财改为备源。读取收据里coverage.gaps整份列表的脚本改读sample或数据集状态。list_datasets()多了support和enabled两列。 - 通达信除权除息记录里的金额和比例不再带着单精度浮点尾巴:这些数是 float32,转成双精度后会多出不超过 4e-8 的误差(0.42 变成 0.41999998688697815,3.348 变成 3.3480000495910645)。写入前按四舍五入收到 6 位小数,每 10 股的分红、送转、配股再除以 10;配股价和份额折算比例同样收到 6 位小数。下次日更和每周复扫会把因此变化的行重写一次。
- 每次发布新版本不再整份复制未变化的分区:新一代与上一代以硬链接共享这些文件,并沿用已记录的校验和,只有本次变化的分区写入新文件。此前在 Linux(ext4 等不支持写时复制的文件系统)上,
daily_bars每补一批就新增一份约 87MB 的完整副本(#54)。文件系统不支持硬链接时照旧复制。快照和增量包仍把这些文件复制成独立副本,不把硬链接带出数据湖。 cne run clean在交互终端里预览之后分两次询问,默认都不删。第一次只删超出保留数的历史版本,第二次只删已经合并且不在使用中的 staging。正在使用的一代、hold、收据不能用的代、正在运行或被锁住的 staging、orphan、未合并的 run、来源快照和日志都不删。回补和日更不会删 staging,也不会删当前正在使用的一代。--dry-run、管道和定时任务不提问。cne storage apply --phase purge仍然不能绕过网页确认。- 磁盘放不下这次发布时,回补会说明缺多少空间,而不是只退出 1:发布前按“这次要新写的文件 + 1MB 收据余量”和磁盘剩余比较,不够就报
DiskSpaceError,并删掉写了一半的代。硬链接沿用的文件不计入需要的空间。写入中途空间耗尽同样报这个错,并清掉未发布的代。cne storage inspect的每一代增加exclusive_bytes,表示删掉这一代能腾出的字节,和其他代共享的硬链接不计(#54)。 - 回补和日更之后只保留每个数据集最近 5 代:
cne backfill和cne run daily结束会删掉更早的代目录([storage.retention].keep_generations,默认 5,与存储页“最近 5 代”同一口径)。当前版本、cne storage hold保住的版本、收据不完整的版本不删;收据保留,但再读取已删除的代会失败,不会悄悄改读更新的代。释放的字节只计删除后没有其他代还共享的文件。设为0则不删除。cne run clean仍只预览,网页确认删除不变。引用清单过期或还有未完成的删除时,这一步跳过并在 stderr 说明,已经发布的数据不受影响。升级后第一次回补或日更就会按这个数量清理,要留住更老的代请先 hold 或把该值设为0(#54)。 - 修订收据不再内联整个数据集的缺口清单:
metadata.coverage.gaps改为各类缺口的条数和前 20 条样例(counts、sample、truncated),完整清单仍以数据集状态为准(gaps_source: "dataset_state")。此前欠账越多,每份收据越大,daily_bars回补时单份可达 135MB(#54)。读取收据中coverage.gaps.<类型>列表的脚本请改读sample或数据集状态;已有收据不变。 - 东财数据中心超过 100 页的报表现在能读全:翻过页数上限要在筛选条件后追加
SECUCODE>"…",此前用AND连接,东财会悄悄丢掉AND之后的条件,续页又从头读,最终在 100 页处停下(十大股东top_holders2026 年中报只读到约 5% 的股票,三季报一条没有)。现在改为相邻括号连接、字符串用双引号(单引号会被拒绝)。十大股东另外加入每周的基本面组:此前只能手动回补,8 月后一直没有更新。已回补 2026-03 起的数据。 - 审计不再为修不了的事报警告:配置里已撤下的数据集(如 9-21 停用的
sector_fund_flow)最后一个分区停在半月,行数突变降为提示;已退市证券缺的分钟线(来源已不再提供,如 301139.SZ 退市前两天)单独计为提示minute_bars_missing_session_delisted,其余缺口照常警告。 - 新退市的股票在下一次日更就收入退市目录:此前只有手动运行
scripts/delisted_ops.py discover才会收录,期间研究窗口的幸存者偏差检查一直报“有代码待探测”(10-30 的 301139.SZ 元道退因此挡住了下游的研究就绪)。现在instruments写完后,用同一套可续跑的探测检查最多 20 个尚未归类的代码;探测失败的代码保留待处理,并记一条delisted_discovery_incomplete警告。离线模拟(tdx_allow_mock)或关闭新浪来源时不探测。 - 走 baostock 备源的股票,复权因子不再每天整段重写:baostock 的因子是后复权价除以原始价,再按最新交易日的比值缩放到 1.0;最新交易日每往后移一天,这个比值在浮点末位就会变,整段历史跟着差一个比特(10-30 的修订 124 因此重写了 4,810 个分区,7 只股票相对差约 1e-16)。现在缩放后的因子保留 12 位有效数字。下次日更会把这些股票按新精度重写一次,之后不再变动。
- 股票复权因子的股权分置改革告警不再每天成批出现:2005-04-29 至 2007-12-31 的事件此前不论新浪因子是否和除权条款一致都报警告,现在只在两者不一致时才检查。不一致时用湖里
share_structure的流通 A 股股数变化作为独立证据(股改对价让流通股东每股变成多少股,股数比就是多少):股数比和通达信条款一致就按条款修正因子,和新浪一致就保留并记为提示,都不一致才报警告。因此这一项的警告从约 3,400 条降到 25 条,约 50 个股改事件的后复权因子会在下次日更时改正(如 000036.SZ 2006-03-28 由 3.4375 改为 2.875)。 - 股本结构对照通达信(
share_structure_peer)不再把通达信的期末股本刷新和错开几天的同一变动算成差异:通达信每个报告期末等时点会记一条“股本变化”,数值只差单精度舍入,按湖里当时已生效的股本核对后单独计为restated;两边股本相同、日期相差 10 天以内的计为date_shifted。这两类都不再进入东财过期时的通达信补写。10-30 的对照因此从 7 处不一致、142 次仅通达信有,降到 5 处不一致、2 次仅通达信有;同一公告日的东财重述行取较晚抓取的版本。 daily_bars的增量水位只从 2016-01-01 起找连续区间,和index_bars一致:退市回补补入的单只 1990 年代历史(如 000508.SZ 1993–1997)此前会让水位被“纠正”回 1993 年,下次日更会从那里重抓。2016 年以前的缺口照常作为审计发现报告;全市场缺日检查从 2001-01-01(深度历史起点)算起,这类单只早年历史不再把 1997–2000 年误报为 952 个缺失交易日。instruments.delist_date统一为文档约定的“最后一个上市交易日”:baostock 补入的退市股此前直接写入其outDate(摘牌日,当天已不再上市),比约定晚一个交易日,按delist_date >= trade_date筛选的股票池会在摘牌日多纳入这些股票。新写入的行改为摘牌日前一个交易日。原始摘牌日仍保存在退市证据中。新增迁移delist-dates修正已有行,随后的迁移bar-listing-window删掉退市日之后的零成交量日线(baostock 在摘牌日当天写的占位行,以及已终止上市基金后来的通达信占位行);有成交的行不会删除,只报告。cne migrate预览,确认后--apply(保留旧版本)。- 公告索引
announcement_index回补不再卡在披露高峰日:巨潮单个查询最多返回 3,000 条,高峰日要按板块、行业、公告分类拆开读,但不属于任何分类的公告(如未上市公司的招股意向书)拆完会漏掉,2020-04-28 每种拆法都正好少 3 条,核对通不过,回补停在这一天,2021 年起的历史一直没读到。现在拆分差几条时,再按代码、时间正反方向翻页补上这些公告,只有合计去重后正好等于巨潮报的总数才接受,离线回放同样适用。巨潮不同服务器对同一查询给的总数不一样(有的列出已取消的公告,如 2020-04-28 创业板建筑业 126 和 128 条随机出现),此前翻页中途总数一变就判为失败;现在每页重试到和第 1 页同一个总数,一组完整包含另一组、且等于它自己报的总数时保留大的那组(实测少的一边缺已取消公告,也缺正常年报),不是包含关系仍判为失败;大的那组所在服务器很少被分到、某页始终取不到时,退回用小的那组并记警告。 - 财报对照同花顺的审计不再把会计准则重述当成数据错误:同花顺把较早报告期的数值改成后一年年报重述后的口径,却仍挂在首次披露日期下,湖里保留的是首次披露的数值。实测 1,250 处差异中 1,246 处落在这类可能被重述的报告期(如 2017 年研发费用从管理费用拆出、2022 年解释 16 号递延所得税),现在单独以提示(
financial_statement_peer_restated)计数,只有其余差异才报警告。 - 财报的营业总收入(
revenue)和归母净利润(net_profit)开始收录更正和追溯调整后的版本:这两项此前只取东财业绩报表,那里永远保留首次公告的数字,公司发更正公告(如 300152.SZ 2024 年报)或同一控制下合并追溯调整(如 688121.SH)后湖里仍是旧数。现在也从利润表取,数字变了就以利润表的重新披露日期另存一个版本,首次披露的数字不动,按时点查询不会提前看到。历史上已经发生的更正一次性补齐。 cne serve的日线详情页不再把 2001 年以前没有日线的 952 个交易日列为缺口,口径和审计的缺日检查一致。另外一次性给 1,037 个有成交但缺状态行的“证券-交易日”补了“正常交易”。- 财报和同花顺的对照:湖里同一科目后来出现过不同数值的版本(即已记录的更正),差异计入“重述”提示,不再报警告。例如 000909.SZ 2024 年报的营业成本在 2026-09-28 做过会计差错更正,同花顺只保留首发值。
- 交易状态的历史 ST 证据检查(
trading_status_coverage_start):其余证券都已覆盖、只剩北交所 359 只没有免费数据源时,记为提示而不是每天的警告,并提示可用 Tushare Pro 补齐。 - 审计的“行数骤降”(
row_count_mutation)不再误报停采的数据集:没有任何分区包含审计日时(例如 push2 被封后停采的sector_fund_flow),最新分区变小是因为没再采数,现在按“落后”处理,记为提示。监管事件regulatory_events补派生了 2018–2022 年 7 月和 2024–2025 年(此前湖里完全没有 2018–2025 年)。 - 交易状态
trading_status:每天在复权因子派生之后,用当天成交量大于 0 的日线给没有状态行的证券补一行“正常交易”(此前要手动运行cne repair status-traded);零成交的占位日线不算证据,没成交的基金仍然没有状态行。另外一次性改写了退市日之后的 7,990 行错误状态:其中 7,233 行是 2026-07 至 09 东财给已退市代码报的“正常交易”,其余是旧退市日口径下推导或 baostock 的“停牌”,以及 301139.SZ 退市后被沿用的 3 行,现在都改为“已退市”。 - 财经日历
economic_calendar和财经事件economic_events新增withdrawn列:金十给改期或重发的事件换了新编号,旧编号的行此前会一直留在湖里,看起来像一次从未公布的事件(例如日本 10 月制造业 PMI 终值,旧行排在 11-05,新行排在 11-02)。现在每天抓取窗口时,窗口内湖里有、金十这次没返回的事件会标记为withdrawn = true,不删除;central_bank_rates视图会排除这些行。财经日历回补也会重新抓取有缺指标编号的日子。 cne check和cne status不再提示“15/30/60 分钟线有 N 个交易日待重算”:这几张表本来就是按需派生,每天提示只是噪音。待重算的交易日仍在cne serve的数据集页面显示,需要时运行cne derive。- 公告索引
announcement_index回补不再因巨潮总数少算一条而卡住:按板块、分类拆开读取后,合计比不拆分时的总数多出几条(最多 5 条,且不超过 0.1%),并且仍包含不拆分时看到的每一条,就接受结果并记一条警告。2022-08-31 深市拆分合计 5,854 条、总数 5,853 条,几小时内重试 4 次都一样。少于总数仍然报错。 - 财报日更读取东财时,如果遇到行数和声明不符(披露高峰期边读边有数据变动),先重试两次再切到通达信备源:10-30 东财业绩报表声明 5,577 行、实际读到 5,568 行,整天的三季报因此只拿到通达信数据,缺期末现金和每股指标。
- 新增 DuckDB 视图
central_bank_rates:按金十指标编号从财经日历取出 23 家央行(美联储、欧洲央行、英国、日本、中国人民银行等)2008 年以来的利率决议,附变动幅度change和超预期幅度surprise;policy标出各央行的主要政策利率。 - 财报的期末现金及现金等价物(
end_cash)补齐:原来取自东财 DMSK 现金流量表的END_CCE,这个字段几乎全为空,湖里 2023 年以来每季只有约 200 条。现在改取东财 F10 现金流量表,一般企业、银行、保险、券商四类都覆盖。F10 在 2005 年以前没有这一项。 - 财经日历
economic_calendar可以回补历史:cne backfill economic_calendar --start --end按月回补 2008 年以来的数据,只抓湖里缺的日子。新增indicator_code列(金十的指标编号),同一指标在不同年份、措辞变化后仍是同一序列;2026-10-30 之前写入的行这一列为空。 - 新增两张金十数据快照表,和财经日历走同一个接口、同一套请求头:
economic_events收录财经事件(央行议息、官员讲话、重要会议),窗口同财经日历,时间未定的事件event_time为空、time_status为“待定”;market_holidays收录全球交易所休市安排,每日抓取当日起的 30 条(约两个月),note注明港股通南、北向是否关闭。两张表都属于best_effort,只能从启用之日起积累。 - 财经日历
economic_calendar恢复采集,数据源换成金十数据:东财的RPT_ECONOMICCALENDAR已下线。每日抓取前 2 天到后 14 天的事件,字段包括发布时间、国家、指标、星级、预测值、前值(有修正值时取修正值)、实际值和单位;同一事件以金十的data_id为键,公布实际值后更新同一行。新增数据源jin10,可在[sources]中关闭。 - 通达信财务包的营业收入纳入财报:每日对照把它和湖里的营业总收入单向比较,只有营业收入大于营业总收入才算不一致(含金融子公司的公司本来就应该是营业总收入更大);东财失败、由通达信补写时,只给上一期营业收入等于营业总收入的公司写入
revenue,其余公司留空,不用营业收入冒充。2026Q3 实测可写入的公司 2,491 家,和东财同期都有值的 1,661 家全部一致。 - 财报每天对照通达信:core 组在 compact 之后新增
financial_statement_tdx_peer一步,下载当前披露季的通达信财务包(按 MD5 缓存,未变不重复下载),把近 14 天东财新披露的数值逐项比对(容差 0.1%),并列出通达信已有、披露日早于当天、湖里却没有的报告,结果写入审计。只报告,不写数据。10-27 实测 34,121 个值有 34,118 个一致,没有漏抓的报告。 - 数据集契约变更(0.21.0):
share_structure升到 schema 版本 2,新增float_a_shares(流通A股,来自东财LISTED_A_SHARES)。float_shares对 A+H 公司把 H 股也算在内(兖矿能源 600188.SH:76.6 亿对 59.6 亿 A 股),算 A 股流通市值或换手率要用新列。已有行这一列为空,可用cne backfill share_structure --start … --end …按窗口补;不需要迁移。 share_structure有了备源:每周复扫读取的通达信除权除息记录里本来就有股本变动(变动后的总股本和流通A股),现在顺带存为对照快照,每周和湖里对照(审计share_structure_peer),不另发请求;300 只抽样里两边同日的 1,435 个变动有 1,430 个总股本一致。东财超过 4 天没有更新时,补写近 90 天只有通达信有的变动:announce_date取复扫当天(通达信没有公告日),float_shares只在确认等于流通A股时填写,限售股留空(share_structure_backup)。share_structure移入默认core调度组,每天更新(此前在可设为每周的 fundamentals 组)。用extends = "builtin"的配置自动生效。trading_status改以交易所行情板为主源:先问沪深交易所的股票与基金行情板和北交所行情板,东财只补行情板没答到的代码(push2 暂停时跳过),都答不到的才沿用最近一次一手读数。行情板请求遇到连接错误会退避重试两次——10-27 深交所断开一次连接,2,906 只深市股票因此只能沿用前一天的状态。沿用行按原来源标注(如exchange_cached、bse_cached),不再一律记作eastmoney_cached;已存的旧标签不改。审计trading_status_cached_fallback把没有上市日期、行情板也不列出的占位代码单独计数,不再算作缺状态(10-27 报的 97 个里有 89 个是这类)。- 每周复扫
actions_sweep不再给已有送转拆分的事件重复写一行:通达信把送股和转增合记为一个bonus比例,湖里已有东财或同花顺分开记录的送股、转增时,复扫此前仍会写入通达信这一行,同一事件的股数乘数被算两次。现在和日更一样,两边总数一致时保留已拆分的记录(容差放宽到 1e-4,通达信比例只有 5 位小数)。 - 按股票补抓公司行为(
cne backfill corporate_actions)、补漏的除权事件和基金历史补扫,也和日更一样不再写入通达信合并的送转行:此前定向补抓会把 920021.BJ 2021-11-05 的 0.51471 写回到同花顺已拆分的 0.5147058 旁边,复权因子的水平随之改变,日更时与旧历史在 10-28 接不上。 cne backfill开始前不再重新发布已经发布过的暂存数据:此前只把状态为成功的合并发布当作已完成,带警告完成的运行(湖里有 1,301 次)每次补抓都会被再发布一遍,把之后修复删掉的行写回来(如 920021.BJ 的重复送转行)。- 东财除权数据同一天有多个分红方案时不再只保留一个:如 30...
0.20.0 · 新增行业层级、支持原始财务报表解析
新增行业层级、支持原始财务报表解析
CNEquity 0.20.0 已发布至 PyPI。开源 A 股本地数据湖,用于量化研究、回测与 AI Agent。
python -m pip install --upgrade cnequity==0.20.0- 升级步骤:
pip install -U cnequity后重启cne serve和已在运行的cne mcp。数据集契约只有兼容变更:industry_members升到 schema 版本 2,新增 6 列层级列(见下文),新写入的东财行industry_code固定为三级行业;按固定层级统计请读l1_*..l3_*。旧湖运行cne migrate预览、再cne migrate --apply,补齐本版四步一次性迁移:industry-levels(在线读取东财当前板块层级)、sw-delisted、offshore-final(在线读取新浪 COMEX 黄金最终日线)和sw-never-listed。基金派生状态行要标为非 ST 的,另按窗口运行cne repair status-traded --start … --end … --apply。时点读取的截点改按北京时间日期判定,as_of=T不再包含 T 日公告。EquityLab 等下游的消费契约无需改动。 load_profile新增pit_mode="published":只认记录了发布时间的值,不用公告日或入湖日代替,且不早于值生效日;cutoff指定截至日的北京时间截点(收盘信号用 15:00),过了截点的发布从下一天起可见。另加canonical(按当日生效代码匹配)、data_root和revision_map(固定版本读取)。- 新增
cnequity.query.load_profile:一次取多只证券、多个截至日的多项时点资料(上市、交易状态与 ST、股本、股东户数、财报科目、申万/东财各级行业),每个值带它描述的日期、最早可知日、来源和时点质量(strict/reconstructed/snapshot_only),缺失的值给出原因(上市前、退市后、超出覆盖、尚未公布、值未知、无时点证据、无记录),过旧的值标stale。每个数据集只读一次。 - 申万行业快照不再包含从未上市的证券:申万在 IPO 审核阶段就给公司定行业,且文件没有剔除日期,IPO 未完成的公司会一直留在之后每个月的快照里。这类代码在证券主表、日线、交易状态和公告里都没有任何记录,东财也不列出。只有四类记录全都没有才剔除;回填时剔除,旧湖用
cne migrate --apply删除。剔除的证券记在meta/sw_never_listed.json,cne verify --industry以excluded_never_listed继续列出。 - 新增
cne migrate一步offshore-final:替换 COMEX 黄金(GC0.CMX)在 CME 交易时段结束前存入的日线。写入端已改为收盘后才写、并重读最近 7 天,但更早的盘中值没有被替换,部分收盘价与新浪最终值不同,个别交易日缺行。迁移在线读取新浪最终日线一次,只改有差异或缺失的行。 - 新增
cne derive industry_crosswalk:在申万与东财都有完整快照的同一天,按层级比较两边行业的成员,写出每对行业的成员数、重叠数、Jaccard、相互包含比例和关系(等价、被包含、部分重叠)到meta/industry_crosswalk.parquet。只用同日证据、只比较两边当天都有的股票;0.20 之前的东财快照层级不全,不作证据。每次运行追加当天证据、保留更早的日期,不合并任何行业。 - 申万行业和国证指数成分按月回填只取已经结束的月份:此前当月最后一个已知交易日也被当作“月末”,周日运行会生成日期为下一个(尚未开盘的)交易日的快照。
- 新增
cne derive industry_taxonomy:为每个行业写一个稳定身份industry_id = 体系:版本:代码到meta/industry_taxonomy.parquet,带层级、名称、上级、首末出现日期和最大成员数。申万 2021 年 7 月换代时复用了代码字符串(两版都有的 161 个三级代码下,只有 54% 的股票代码没变),单凭代码分不清是哪一版,所以版本是身份的一部分:sw:2014:480101与sw:2021:480101是两个行业。东财板块代码在所有快照里名称不变,身份为eastmoney:board:代码。申万文件不发布名称,名称列为空。 - 申万行业历史展开为月度快照时按
instruments的退市日剔除已退市股票:申万文件只有计入日期、没有剔除日期,退市股票的最后一个行业会一直带到之后每个月,退市多年的股票仍带着申万 2014 的旧代码出现在之后的快照里。旧湖用cne migrate --apply删除这些行;东财行是来源当天的实际观察,不改。cne verify --industry新增unexpected_members,按原因(退市后、未知证券、非股票、上市前)列出不该出现的成员;上市前的行是申万在首个交易日前就给新股定了行业,只报告、不判为缺口。CDR 同样计入应有集合。 - 新增
cne verify --industry:只读检查industry_members的完整性。每个分类体系的每个快照对照当天上市的股票(沪深、北交所分开),每个层级的每个行业对照上一个快照,报出成员缺失、整个行业消失或成员减半以上;分类体系整体换代(如申万 2014→2021,2021-07-30 有 66% 股票换码)单独列出,不当作缺失;0.20 之前写入的东财快照层级不全,标为部分快照、不参与行业对比。有缺口时退出码为 1。 - 数据集契约变更:
industry_members升到 schema 版本 2、data_version=v2,新增l1_code..l3_name六列,industry_code/industry_name固定为三级行业。此前东财每只股票的三个行业板块只留一个,留哪个取决于分页顺序,同一只股票逐日在一、二、三级之间跳动,按行业统计时看起来像整组行业漏采。现在三级都保存。旧湖运行cne migrate --apply为已有行补层级列(东财行需在线读取当前板块层级);旧东财行只能补出所存板块及其上级,其余为空。迁移说明见contracts/migrations/0.20.0/industry_members.md。 cne repair status-traded补的 ETF/基金状态行写risk_warning=false:ST 制度不适用于基金,此前写成未知(null),下游把整个基金池当成“ST 未知”。股票行仍为未知。已入湖的基金派生行用同一命令按窗口预览、--apply改正。- 时点(PIT)读取按北京时间日期比较
available_at、source_published_at和观察时间,不再按 UTC 日期。此前巨潮公告标为次日 00:00(北京时间)起可用,却会出现在当天as_of的结果里;修复后as_of=T不再看到 T 日公告。严格模式下,UTC 16:00 以后(即北京时间已到次日)抓取的行,观察日按北京时间算作次日,当天的as_of不再收录。 - 资产负债表恒等式检查改为每个来源各自核对:此前按条目取最新值,会把巨潮原始年报(首次披露)的资产和数据商重述后的权益拼在一起,产生大量误报;改后只报来源自身不平的。
- 巨潮原始报表解析能识别折行的权益标签(「所有者权益(或股东权 / 益)合计」),此前大量报告期因此缺
total_equity,查询视图会把原始年报的资产与重述后的权益配在同一期。已入湖的数据用cne repair financial-originals --reparse --apply补齐。 - 分钟线与日线成交量核对允许整手取整误差:通达信成交量以 100 股为单位,日线截掉零股、每根分钟线各自取整,冷门 LOF 一天只成交几百股时比值会偏离 5% 以上,而成交额完全一致。差额不超过每根有成交的分钟线一手(再加一手)时不再报
minute_bars_daily_outliers。 cne run maintain每天先对欠账里还有键的数据集运行cne backfill <数据集> --outstanding,再做审计和门禁。此前欠账只有手动修复才会重试,来源晚几天才有数据(如 Baostock 停牌记录约晚一周)的键会一直挂着;重试失败只报告,不判维护失败。- 日线覆盖判断停牌时,上市公司自己的停牌公告也算证据:停牌公告与之后 10 个交易日内的进展或复牌公告之间的交易日(不含公告当天)视为停牌,第一手的交易记录仍可否决。push2 不可用期间沪市停牌不再要等约一周后的 Baostock 核对才从欠账里消掉。提示性公告、风险警示停牌、临时停牌和可转债转股停牌不计入;在 2015–2026 全湖上回测,3,929 个由公告推出的停牌日没有一天有成交。
- 数据集来源登记补齐:
adj_factors的派生因子(北交所与基金份额变动)登记为补充来源,financial_statement_items的巨潮原始报表与index_constituents的交易所指数快照登记为修复来源。审计不再对它们报unrouted_source,cne sources列出的条款也包含这些写入方。
0.19.0 · 强化数据的准确性,提供数据迁移入口
强化数据的准确性,提供数据迁移入口
CNEquity 0.19.0 已发布至 PyPI。开源 A 股本地数据湖,用于量化研究、回测与 AI Agent。
python -m pip install --upgrade cnequity==0.19.0- 升级步骤:
pip install -U cnequity后重启cne serve和已在运行的cne mcp。数据集契约没有变化。旧湖先运行cne migrate预览、再cne migrate --apply补齐一次性迁移(取代已移除的 11 个cne repair迁移命令);调度或脚本里用到下文已移除命令和cne backfill开关的,按对应替代改写。现有完整配置照旧可用,可用cne config upgrade --minimize --dry-run预览改为继承默认值;用scripts/scheduler/的,先运行uninstall_scheduler.sh再cne schedule install。不在项目目录运行时,配置可放在~/.config/cnequity/config.toml,cne config path显示实际使用的配置。 - 移除不再使用的命令与开关(不兼容):
- 11 个一次性
cne repair迁移命令(missing-values、financial-announcements、daily-bar-coverage、fund-factors、fund-listing-dates、valuation-basis、orphan-symbols、stale-suspensions、status-outages、status-listing-window、misdated-valuation):0.17 及更早版本的湖用cne migrate修正; cne derive bse_code_migration和cne derive valuation_orphans(valuation_metrics回填会自动清理孤立行);cne backfill的--eastmoney-bj-repair、--bj-amount-repair、--tdx-volume-repair,以及已迁出的开关(--payment-date-repair等改用cne repair <名称>,--shfe-annual-archive改用cne import shfe-archive,--refresh/--force改用--refetch,--margin-source改用--source,--retry-failed不再需要);- 仓库
scripts/migrations/:分区改写改为随包提供的cne repair repartition(默认预览,--apply改写);0.12 及更早版本写入的湖请先用 0.19 或更早版本迁移再升级。
- 11 个一次性
- 期货/期权最新交易日截面可以证明完整了:交易所有当天的官方合约文件、且文件里当天在市的合约都有行情时判为
OK(此前即使一个不缺也只能是 UNVERIFIED,cne check因此一直 ✗)。默认走新浪的大商所无法证明,作为限制写在结果旁,不判失败;缺当天官方文件时仍为 UNVERIFIED。 cne run maintain检查最近收盘交易日各日更组的运行:[job.maintenance] gate_groups(默认core)失败立即判失败,其他组连续失败soft_fail_max_days(默认 3)个交易日才判失败,与旧日更脚本的规则一致并沿用其计数。- 配置用
steps_remove或enabled = false有意移出调度、且没有别的组再跑的数据集,新鲜度显示为removed(保留真实的最后日期),不再判为 STALE;cne check、cne status --gate、审计、cne run maintain、收尾补抓和控制台对此一致。把 step 加回调度后又会按期判断。 - 新增
[[job.events.schedules]]:在配置里写多条事件流计划,每条有自己的事件组、间隔、随机延迟和北京时间静默时段,打包定时任务按计划运行(cne schedule install --events),控制台只读展示。没写计划时仍用控制台设置的单个事件组。 - 新增
[source_health] vantage:在配置里写一次网络出口标签,源探针、源健康记录和cne run maintain都会带上它;CNE_SOURCE_VANTAGE和--vantage仍可在单次运行时覆盖。 fund_flow_ths/sector_fund_flow_ths默认仍是不判新鲜度的兜底表;配置的日更调度组里排了它们(push2 不可用时用steps_add换入)时,改为要求最近收盘交易日有数据,收尾补抓会重试缺的那天,新鲜度门禁也会报出来。cne backfill只保留通用选项(帮助里的选项从 32 个减到 11 个)。数据集专属的修复改为cne repair子命令,默认预览、--apply运行:payment-dates、delisted-actions、ex-dates、bar-amounts、bar-turnover、bse-tip-turnover、valuation-outage;上期所年度包导入改为cne import shfe-archive。新增通用的--refetch(取代衍生品的--refresh和sector_bars的--force)和--source(取代--margin-source);--retry-failed本来就是默认行为,不再需要。旧开关已移除(见下文)。- 新增
cne migrate:一次找出并运行这个湖还欠的一次性数据迁移(默认预览,--apply运行),结果记在meta/state/lake.json。新建的湖会记下建湖版本,不欠早于它的迁移;cne doctor会提示还没检查的迁移。弃用的一次性cne repair命令改由它统一运行(命令本身已移除,见下文)。 - 新增
cne schedule install|status|remove:在命令行为当前用户安装、查看、移除定时任务(macOS launchd、Linux crontab、Windows 任务计划程序),与cne serve操作页是同一个任务;没给出的选项保留面板里的设置。 - 新增
cne run maintain,定时任务在每个交易日日更后自动运行:运行审计([job.maintenance] full_audit_weekday那天做全湖审计)、新鲜度门禁、源探针与 SLO、运行证据核验、元数据备份和过期预览。此前只有仓库脚本做元数据备份,用cne init --schedule或控制台装定时任务的湖没有 manifest 备份;备份改用 SQLite 备份接口,不再依赖sqlite3命令。 scripts/scheduler/弃用,打包定时任务覆盖它的全部功能(多条事件流计划、出口标签、按日核对的兜底表)并经过验证后才移除;迁移时先运行uninstall_scheduler.sh,再cne schedule install。backup_meta.sh已改为调用同一份备份代码。- 凭证读取顺序改为环境变量 → 文件 → 配置里的值:新增
[sources.tushare].token_file和[sources.ths_official].api_key_file(定时任务读不到 shell 环境变量时用它),环境变量现在优先于配置里直接写的值。cne doctor会提示写在配置里的凭证和其他用户可读的配置文件。 - 修复同花顺官方 API Key 参与配置指纹计算的问题:所有凭证字段只按「是否设置」计入指纹,轮换 Key 不再改变指纹。设置了这个 Key 的湖,指纹会在升级后变化一次。东财代理地址也不再出现在
Config的 repr 里。 - 配置可以继承内置默认值:
cne config create和首次cne init写出的配置只有extends = "builtin"和[data].root,其余设置来自当前安装版本,新版本的设置和调度 step 升级后直接生效,不再需要cne config upgrade。调度组新增steps_add/steps_remove/enabled = false,换掉一个 step 不会冻结整组。没有extends的完整配置照旧工作。 - 新增
cne config show(生效配置,标出文件里写的值,凭证打码;--defaults打印全部设置)和cne config upgrade --minimize(把完整配置改写成继承默认值的形式,先列出加载后会变化的设置,--dry-run只预览,原文件自动备份)。 - 配置查找统一:未给
--config时依次找CNE_CONFIG、当前目录的configs/cnequity.toml、用户级~/.config/cnequity/config.toml(Windows 为%APPDATA%\cnequity\config.toml)。CLI、load()、MCP 用同一套规则,在任何目录运行都指向同一个湖。首次cne init/cne config create在当前目录没有项目配置时写用户级配置;新增cne config path显示实际生效的配置、选中原因和数据目录。 - 配置里的相对路径(
data.root、duckdb.path)改为按配置文件所在目录解析,不再随工作目录变化。旧配置按工作目录写的相对data.root在新位置不存在时继续沿用并警告;运行cne config upgrade会把它固定为原来的绝对路径,湖不会移动。 - 兼容 DuckDB 2.0 与 Polars 2.0:查询结果改用两边都支持的 Arrow 接口(DuckDB 2.0 移除了
.pl()/.arrow()),依赖下限改为duckdb>=1.5。 - 恢复 0.18.0 误删的
cnequity.domain.security_identifiers(证券代码延续注册表)。它是下游直接导入的公开接口,0.18.0 删除后 EquityLab 无法导入;内容与 0.17.1 逐字节相同,见 Python API。 - 东财走本地代理时,代理没启动(如 Clash 随登出退出)导致的连接被拒不再被当作东财拒绝本机 IP:push2 和 datacenter 的熔断器不会触发,报错直接写明代理地址。
- 东财不可用的日更里,
trading_status现在用沪深交易所的基金行情板块给当日有成交的 ETF/LOF 补写normal行(source=exchange)。无成交的基金仍不写行,不会被记为停牌;此前东财不可用时约 2,000 只 ETF 没有状态行,健康检查因此持续报错。已缺失的历史日期仍可用cne repair status-traded补派生行。 - 修复增量
adj_factors派生在停牌期间断档:停牌第二个交易日起,当日只有零成交占位行,派生误判为从未交易而跳过,停牌期 hfq 因子从此缺失,自愈检查也看不到。现在会沿用上一个因子,自愈检查也覆盖停牌占位行;已有缺口在下次日更时自动重取补齐。在补齐之前,load(adjust=...)对这些停牌行沿用最近一个因子,hfq、qfq、total_return 三种口径结果一致(此前 qfq 和 total_return 会按 1.0 回退为原价并标记为不精确)。 - 东财不可用时,
trading_status从深交所行情板块读出的停牌股不再被写成normal:深交所对停牌股的开高低收都填前收、成交量为 0,此前只按开高低为 0(上交所的写法)判断停牌。2026-09-23 起东财不可用期间的深市停牌行会在后续 Baostock 停牌核对中改正,也可对相应日期重跑trading_status。 - 日线「两个独立来源都返回空」和「代码尚未上市」的证据不再在同一次日更里失效:此前证据绑定全市场证券表和
trading_status文件,同一 run 的入湖整理一改写交易状态,证据就作废,cne check因此把已核实无数据的证券(如摘牌当天的 000016.SZ、尚未上市的 001381.SZ)报成覆盖缺口,下一次日更也会把它们重新向各来源请求一遍。现在证据只随该证券自己的上市、退市日期失效;由交易状态推出的无数据证据仍随交易状态文件变化而失效。cne check读取证据时也不再改写状态文件。 - 没有上市日期、也从未成交的新代码,若数据源只返回成交量为 0 的占位 K 线(通达信在上市前按发行价给出),不再被当作已上市写入日线,也不再为窗口内更早的交易日记欠账;这些占位行转入隔离区,代码按「尚未上市」处理。
- 证券从证券列表中消失后推断的
delist_date改为它首次缺席前最后一根日线的日期,即最后一个上市交易日,不再是确认缺席的那次快照日期;此前会晚 1–4 个交易日(如信达证券 10-19 摘牌,最后上市日 10-16,曾记为 10-20)。已记录的日期不自动改写。查询指南中的在市条件更正为delist_date >= trade_date。 - 期货「待补交易日」不再包含补不回的日期:郑商所官方档案缺 2010-06-21、2010-07-01、2010-08-13 三个交易日的文件(当天 404、前后正常),与上期所 2004-06-25、2007-06-04 一样豁免;2019 年起上期能源合约随上期所文件发布,旧路由留下的 INE 回执不再记欠账;交易所文件本身不自洽的行(如 2021-07-28 LU2108 收盘价 3450 高于最高价 3180)仍隔离不入湖,但不再让该交易日一直欠着。
cne audit对已落盘 Parquet 的行情检查改为与写入时同一套规则:新增覆盖minute_bars_15m/30m/60m、pre_close <= 0以及期货/期权 bar 的不变量。旧湖里此前漏检的坏行现在会报出,按提示重取对应分区即可。- 每日交易所状态快照(仅写入快照库,不改变
trading_status的权威来源)现在也记录当日有成交的沪深 ETF/LOF;无成交的基金不写行。 - 东财本地代理探测到未运行后,30 秒内不再逐个请求重复探测;代理恢复后第一次成功响应即解除。
- MCP 的 stdio 与 HTTP 传输使用同一套批量请求规则:空数组
[]返回 JSON-RPC Invalid Request 错误(此前 HTTP 返回 202、stdio 不回复),批量里的非法成员只让该成员报错。 - 东财热门榜中被标成
SZ920xxx的北交所股票按 BJ 代码保留,不再丢弃;榜单不足所需条数时按数据源载荷错误上报。东财 clist 翻页失败保留底层错误类别,运行结果里的失败原因不再统一显示为 execution_error。 - 整数字段转换不再经过浮点,超过 2^53 的整数保持精度,越界值不会被舍入回 Int64 范围内。
- CLI 遇到数据湖生命周期冲突(如
cne clean时引用已变化)只打印原因,不再输出 traceback。 - 移除若干无调用方的内部辅助函数(如
sweep_stock_bars、fetch_adj_factor_series_baostock_many、finish_metrics)。下游公开导入面由测试锁定,见 Python API。
0.18.0 · 精简修复命令与优化存储
精简修复命令与优化存储
CNEquity 0.18.0 已发布至 PyPI。开源 A 股本地数据湖,用于量化研究、回测与 AI Agent。
python -m pip install --upgrade cnequity==0.18.0- 升级步骤:
pip install -U cnequity后重启cne serve和已在运行的cne mcp。数据集契约没有变化,不需要迁移数据或改配置。调度或脚本里依赖cne backfill退出 0 的,按下方「退出码变化」改为读取usable_result/coverage_status;调用了已移除的cne storage试验与归档子命令的,需要删去这些调用;仍需运行已弃用迁移命令的旧湖,请在升级到 0.20.0 之前完成。 - 弃用: 11 个一次性迁移命令
cne repair missing-values、financial-announcements、fund-factors、daily-bar-coverage、fund-listing-dates、valuation-basis、orphan-symbols、stale-suspensions、status-outages、status-listing-window、misdated-valuation已弃用,将在 0.20.0 移除。它们只修 0.17 及更早版本写入的数据,当前版本采集时已不再产生这些问题,新建的湖不需要运行。旧湖如需迁移(包括 0.17.0 升级步骤里的status-outages和misdated-valuation),请在升级到 0.20.0 之前用 0.18 或 0.19 运行。cne repair --help中这些命令标有「已弃用」,运行时在 stderr 打印警告,stdout 的 JSON 报告不变。 - 弃用:
cne derive bse_code_migration、cne derive valuation_orphans,以及cne backfill的--eastmoney-bj-repair、--tdx-volume-repair、--bj-amount-repair同样将在 0.20.0 移除,规则同上;--bj-amount-repair请改用--tdx-amount-repair,孤立估值行在valuation_metrics回填时会自动清理。--ths-repair和--bse-tip-repair对新建的湖仍然有用,继续保留,帮助中去掉了「历史迁移用」的说法。 - 移除:
cne storage的试验与归档子命令(experiment-create、archive、experiment-seal、artifact-verify、resolve、experiment-plan、experiment-apply),以及 serve 存储页的「试验目录」清理。版本保留、标记与网页确认删除不受影响;旧注册表里登记的试验照常读取,其目录不会被删除,不再需要时可自行处理。 - 新增
cne storage raw-external:把财报 PDF 等大原文登记到独立磁盘或 iCloud Drive 等外置目录,本地保留来源、观察时间和哈希记录;只登记,不移动或删除已有文件。 cne init与日更、事件任务不再同时运行;Ctrl-C 中断写湖命令时说明已完成的部分会保留,以及如何续跑。cne serve把进程已退出、仍记为运行中的 run 显示为中断。cne query和 MCP 改为在内存中建立 DuckDB 视图,不再依赖磁盘上的视图库;配置文件 TOML 写错时报错指明行号和列号。cne init --profile sample默认写入data/cnequity-sample/与configs/cnequity.sample.toml,不再与 demo 共用目录和配置。- 事件任务的启动时间加入随机偏移,北京时间 01–07 点改为每小时一次;新闻连续 3 次被拒后暂停到本地午夜。
- 修复新用户和小数据湖上的一批问题:
--profile demo --research因新浪未启用而崩溃;空数据集预览修复时报错或登记版本;缺少输入数据集时打印堆栈而不是一行说明;--only、--symbols等选项重复给出时只保留最后一个;backfill --symbols在未分标的数据集上崩溃;demo 湖误报事件数据集过期,或对 demo 湖执行run daily --stale-only时抓取全市场快照。 - 退出码变化(升级须知):
cne backfill(含--outstanding)一行都没补上时改为退出 1:状态不是success、usable_result为 false 且写入 0 行,包括数据源全部不可用,以及数据源无法提供该范围(如对只有快照的数据集做历史回填、北交所trading_status)。以前这类回填退出 0,结尾还打印「✓ 日线没有变化,无需重算」;现在改为说明没有取到可用数据。JSON 结果不变。依赖回填退出 0 的脚本请改为读取usable_result/coverage_status;日更和其他取数命令的退出码不变。cne sources substitutes在所有来源都被跳过时说明没有可比较的探测结果,不再显示「所有端点可用」。 cne verify和cne status按最近一次完整查询来源的时间判断事件数据是否新鲜,补抓没有新数据时不再一直报过期;cne run retry遇到已成功的 run 时说明无需重试,不再重跑整个任务;指标正确统计步骤发出的东财请求数。
0.17.1 · 控制台与文档站体验修复
控制台与文档站体验修复
CNEquity 0.17.1 已发布至 PyPI。开源 A 股本地数据湖,用于量化研究、回测与 AI Agent。
python -m pip install --upgrade cnequity==0.17.1- 升级步骤:
pip install -U cnequity后重启cne serve。数据集契约没有变化,不需要迁移数据或改配置。 cne serve启动任务少点几步,概览页更紧凑;修正面板中英文文案。- 文档站切换语言时停留在当前页面;中文站内搜索按词切分,搜索中文词能命中;首页、导航与 CLI、schema 参考重新整理,更易浏览。
0.17.0 · 首次建湖更快更稳
首次建湖更快更稳
CNEquity 0.17.0 已发布至 PyPI。开源 A 股本地数据湖,用于量化研究、回测与 AI Agent。
python -m pip install --upgrade cnequity==0.17.0- 升级步骤:
pip install -U cnequity后重启cne serve和已在运行的cne mcp。除institutional_holdings的单位声明外,数据集契约没有变化,不需要迁移数据或改配置。经历过东财中断的湖,升级后对受影响窗口运行一次cne repair status-outages --start <起> --end <止>(先预览,再加--apply);补跑过估值的湖运行cne repair misdated-valuation。两条命令都发布新版本,旧版本保留。 - 数据契约变化:
institutional_holdingsschema 升至 2,holding_ratio的单位声明由比例改为百分数(8.5即 8.5%),与已存值及字段文档一致;已存值不缩放,需要比例的读者自行除以 100,见迁移与回滚说明。 - 第一次建湖不再被非关键阶段挡住:公司行为、指数日线或交易状态阶段失败时,
cne init照常抓日线、入湖并派生复权因子,退出码为 0,结束时列出没完成的步骤;重跑同一条cne init只补这些。证券目录、交易日历或日线失败仍停在原处并保留已下载的部分。 - 全市场
cne init先抓日线、再扫公司行为:公司行为逐只拉取全部除权除息记录,与窗口长短无关,以前让日线多等很久。原样保留旧默认阶段顺序的配置自动换成新顺序,自定义顺序和已开始的 init 不受影响。 cne init(quick / full)开跑前做最多 8 秒的网络预检:通达信连不上时几秒内停下并给出中文原因,交易所和东财只报告不阻断;--no-preflight或CNE_SKIP_PREFLIGHT=1跳过。通达信选主机改为第一个可用主机即返回,不再等最慢的候选超时。- 证券目录步骤(
instruments)逐段打印进度:开始取通达信列表、北交所、基金与股票上市日期、退市名录和写入时各打一行,并带已用时间,全市场初始化里不再静默数分钟。 - 日线入湖之后的复权因子、行业指数、质量审计或停牌派生出错,不再把已发布的湖判为不可用,也不再跳过后面的阶段;摘要列出没完成的步骤,重跑
cne init只补它们。 - 修复交易日历在节假日表最后一年(2027 年)内必然失败的问题:日历步骤要向后多写一年,超出内置表就报错,从 2027-01-01 起每次
cne init第一阶段和日更日历都会失败;现在写到表的最后一天为止,剩余天数不足时由审计提示。 - 证券目录取通达信列表时,连接和每个市场的请求失败各重试一次,一次网络抖动不再让
cne init在第一步就停下;Baostock 证券基础信息在同一步内只查询一次(以前补上市日期和补退市名录各查一次)。 - macOS 和 Windows 上
cne init运行期间阻止系统空闲睡眠(合盖或手动睡眠仍生效,进程结束即解除);设CNE_ALLOW_SLEEP=1关闭。 - 修复同一窗口里第二次向 Baostock 核对停牌时覆盖第一次暂存的停牌证据:日线已据第一次结果判为「停牌、无需补」,证据却被替换掉,这些证券既没有停牌记录也不进欠账,
cne check因此对整月停牌的证券判覆盖不全。现在每次核对单独暂存。 - 调度脚本在仓库没有
.venv时改用 PATH 上的python3(可用CNE_PYTHON指定),不再因找不到解释器而拿不到调度锁。 - Windows 上 serve 存储页删除 staging 的计划与记录统一用
/分隔路径,同一计划在各平台一致。 cne init不再在终端打印 Baostock 的login success!/logout success!;--json的 stdout 只剩结果。- 修复周末或节假日运行
cne init建出的湖缺北交所证券和交易状态:此前以当天日期为准,北交所板块和交易所状态页对非交易日不返回数据,cne check报「新鲜度证明不了」。不带--trade-date时现在以最近一个已收盘交易日为准,与 demo 一致。 - 全市场
cne init在抓日线和扫公司行为期间于后台把复权因子预取到本地缓存,收尾派生改读缓存,没取完的部分由派生接着请求。此前收尾时才逐只请求新浪,受限速约束耗时很长;现在收尾派生大幅缩短。预取不写入数据湖,失败的证券由派生时再请求,也不计入初始化的完成条件。 - 没开基金采集时,全量公司行为扫描不再请求 ETF/LOF,全市场少约四分之一请求。以后开启基金采集,日更的公司行为步骤会自动补扫从没扫过历史的基金,每次最多 500 只,扫完前告警(
fund_history_unswept)列出还缺历史的基金;新上市基金同样补扫一次。 - 公司行为全市场扫描改为多条 TDX 连接并行(按
[source_concurrency].tdx_protocol,最多 4 条),请求仍受原有 TDX 限速和并发上限约束,全市场扫描明显加快。失败分块照常留待重跑,Ctrl-C 后各连接在下一只证券前停下。 - 复权因子日常派生提速并停止整表重写:以前每天把全部日期分区重写一遍(只为更新
fetched_at),每个修订都另存整表一份;现在只写真正变化的分区,平常一天只新增一个分区。股票事件修正按证券一次性分组、只取用到的价格,日线日期少读一遍。派生耗时约减半,输出与原来逐行一致。 - 证券目录每天不再重新向 Baostock 查询全部上市日期:湖里已有的日期(包括人工修复的)直接沿用,只为还没有日期的证券查询,各来源都给不出日期的证券 7 天内不重复查询。日常证券目录因此明显加快。
- 修复日线每天都按深度对账跑的问题:
daily_bars走自己的取数路径,从未记录每周深度复核已完成,自 2026-10-08 起每次日更都逐只重抓最近一周,而不是用交易所整版行情和 TDX 批量报价只取新交易日。现在深度复核跑完即记录,平时恢复只取新交易日,每周一次深度复核;未结清的证券仍由欠账账本单独补抓。配置说明里deep_reconciliation_dow的取值也更正为 1=周一 … 7=周日,0表示每次都深度对账。 - 日线的无数据证据(负缓存)不再每次逐行哈希全部交易状态历史来判断是否失效:以前每次日线运行要做三次;现在以交易状态的修订号和已提交文件的路径、大小、修改时间判断,结果只会更保守。只取新交易日的日线因此明显加快。旧的负缓存会在升级后失效一次。
- 期权 IV 与 Greeks 派生(
option_greeks)只重算真正受影响的交易日:以前合约表或利率表任一重发都会让全部交易日失效,每次全量重算耗时很长,并在整个计算期间持有湖锁,其他任务的入湖发布只能排队等待。现在每个交易日只记录它用到的合约条款和适用利率,计算期间不持锁,只在写入时加锁;平常一天只算新交易日。升级后第一次运行会全量重算一次。 - 期货期权交易所文件的磁盘缓存(
meta/derivatives/http_cache)自动清除超过最长有效期(30 天)的条目:这些条目不会再被复用,以前从不删除,一次回补就会留下大量缓存文件。每个进程第一次请求时扫描一次。 - 原始归档里的 PDF(如
cne repair financial-originals归档的巨潮定期报告)改为不压缩保存:gzip 只能缩小约 1%,却要花大量 CPU。已经压缩保存的 PDF 保持原样,读取不受影响。 cne init结束时改为打印简短摘要:湖是否可用、还差哪些步骤、日志位置和下一步命令(cne check、cne serve、Python 读取、MCP 接入)。完整结果不再刷屏(全市场可达数万行),改存到{data.root}/logs/cne-init-<run_id>.json;脚本需要时加--json,serve 操作页已自动使用。cne check只列有数据或已陈旧的数据集,还没有数据的折成一行,新湖不再显示几十行empty;cne status --datasets --hide-empty提供同样的视图。- 终端里的进度日志改为简短格式:只留时分秒,警告和错误前加标记,不再带日志器名;中文环境下步骤开始与结束、心跳、批次进度、初始化阶段和重试提示显示中文。只在交互终端生效,重定向到文件或被调度器捕获的输出、以及日志目录里的日志文件仍是完整英文格式。
- CLI 改为中英双语:帮助、提示、报错和
cne init结束摘要按语言显示,依次取环境变量CNE_LANG(en或zh_CN)、系统语言,都没有时用英文。中文系统上看到的中文与以前一致;系统语言是英文、但想继续看中文的,设CNE_LANG=zh_CN。JSON 输出(含--plan和--json里的说明文字)、HEALTHY/STALE等标记词、退出码和日志文件不随语言变化,说明文字统一为英文。 cne serve控制台没有选过语言时跟随浏览器语言(简体中文显示中文,其余显示英文);服务端的报错、提示和后台任务输出按页面所选语言返回,英文页面不再夹带中文提示。- 定时任务沿用安装时的语言:
cne init --schedule和控制台设置的定时任务会记下当时的语言,由 launchd、cron 或任务计划程序拉起时照用,不再因为这些环境没有LANG而变成英文。仓库里的scripts/scheduler安装脚本会把安装时 shell 里的CNE_LANG写进 launchd 任务;已安装的定时任务重新保存一次设置即可。 - 诊断、质量、研究包、配置对照和存储运维的提示也改为中英双语:
cne doctor、cne sources probe/substitutes、/source-health页面、cne check --pack、cne config diff和存储清理的报错在中文环境下与以前一致,英文环境不再夹带中文。写进湖里的探测报告、cne doctor --json、cne sources limits的说明、衍生品质量发现和 MCP 返回的数据集分层名改为英文,cne config upgrade写进配置文件的注释也改为英文。 - 修复 Windows 中文环境下
cne mcp(stdio)的中文乱码:管道固定按 UTF-8 读写,不再跟随 GBK 控制台编码;中文名称查询恢复命中,非 UTF-8 的请求行返回解析错误而不中断会话。 cne serve操作页显示当前使用的数据目录。配置文件里的data.root被改成别的目录时,每页顶部对照显示两个目录并给出可复制的重启命令;文件读不出来时指出出错的行和列。在那之前控制台继续使用启动时的数据湖,但不能启动任务、修改取数设置或定时任务,避免任务按新配置写入页面看不到的湖。- 新增
cne repair index-snapshots:回放或显式采集沪深 300、科创 50、深证成指、创业板指的官方带日期成分与权重文件;--apply按文件实际日期替换完整快照,百分数权重转为比例。成分与权重不跨日期互补,不把当前名单倒推到历史。 - 新增
cne repair index-history:回放已核验的深证成指(默认)或科创50(--index-symbol 000688.SH)官方调样公告目录,--refresh-sources只补采未归档附件。--apply在每个实际生效日写完整名单,未知历史权重为空,同日已验证的官方权重保留;附件缺失、内容摘要变化或与既有官方名单冲突时停止更新。 - 新增
cne repair stock-listing-dates:以有成交但上市日期未知的股票首日或可重复的--event-date定位巨潮 IPO 日历,只接受代码、日期匹配且不与更早成交矛盾的上市事件;默认回放归档,--max-sessions分批。--apply保留已有日期,并在同一修订中清除早于官方上市日期的残留退市日期。 - 新增
cne repair financial-originals:按股票、年份和报告期(--quarter,默认年报)回放巨潮原始定期报告,--refresh-sources归档完整查询与原始 PDF,--max-reports/--after分批接续。--apply只追加能明确识别科目和人民币单位的合并报表当期数与累计数;--reparse重放旧报告并保留未变行的首次观测时间,未识别的布局或科目保留缺口,不回填采集时间。 - 新增
cne repair fund-volume:用上交所行情服务的完整历史 K 线修复沪深场内基金零成交量、正成交额的行;默认离线回放,--apply只替换上市窗口内价格及舍入金额一致的行并保留旧版本。湖中金额冲突时须有归档的东财未复权日线同时证实价格和金额才替换整行;不用成交额倒算成交量,之后重抓的零量行不会覆盖已恢复的成交量。 - 新增
cne repair fund-no-print:回放或显式采集沪深交易所历史基金报表;深交所以明确零成交额、上交所以明确不存在的竞价开高低提供日线覆盖证明(不否认汇总口径成交),结清对应日线欠账。证据可回放,失效时重新打开欠账;不把无成交当作停牌,不生成行情数值。 - 新增
cne repair adj-factors:离线预览、显式联网采证、分批历史进度、计划复查及版本化发布;统一基金份额折算、股票事件修正和原始来源覆盖恢复,证据不足时保留原值。独立证据随修订保留,重复应用不累乘。 - 复权读收据、MCP 和行浏览提供所读版本的因子来源及非阻断历史诊断,诊断出错时读取照常返回;普通
load()不做诊断,不增加开销;strict_adj/adj_is_exact仅表示覆盖,不承诺历史准确性。 - 混合 Parquet 历史按连续相同 schema 合并扫描,保持文件次序并避免大量优化器分支。
- serve 存储运维页支持勾选删除已成功 compact、无未完成批次的终态 staging。网页确认时复查运行锁、引用保留和逐文件指纹;中断可凭收据重新审核并恢复。未完成、未合并和 orphan 暂存继续保留,CLI 与定时清理仍只预览。
- 通达信和东财日线不再把有成交额、手数取整为零的尾单写成零成交量;该键继续向其他来源补查,不能据此判定停牌。
- 日线采集规划和批次缺口检查与覆盖报告统一停牌证据要求:推断、沿用和回溯套用的状态不能让缺失行情免于补查;相互矛盾的一手记录也不能证明停牌。
- 历史因子派生排除退市日后的零成交占位日期,保留退市前历史;实际成交与退市日期冲突时保留数据供核查。
- 旧 staging 合并时拦截退市日之后的正常交易状态;成交记录否定目录退市日期时保留该证券供核查。
- 已上市基金采集启用时,证券目录从交易所完整 ETF/LOF 名录补未知上市日期,并归档来源响应;新增
cne repair fund-listing-dates用于旧湖。确认上市日期后,覆盖对账结清上市前的日线请求,未知或被成交历史否定的日期不能销账。 - 日线补缺和停牌核验只向 Baostock 请求其覆盖的沪深股票;基金、指数及北交所代码不再贡献该来源的空响应证据,旧负缓存自动失效。
cne backfill daily_bars --outstanding每个月度修复后也同步受影响的复权因子和停牌派生,派生失败即使日线已销账也会显示未完整完成。- 新浪日线窗口统一用上海日期,serve token 使用常量时间比较。
- 调度脚本和操作页统一使用含主机、进程启动身份及释放 token 的锁标记。自动回收已退出或 PID 已被复用的本机所有者,只有 PID 的旧格式标记在进程退出后同样回收,无标记的锁目录超过 60 秒后回收;远程主机的锁须由维护者核验后移除。Mac 以硬件 UUID 标识主机,换网络改主机名不会让锁卡住。
- 生命周期引用扫描补充排除湖自动写入的修复与派生收据、因子仲裁缓存和统计缓存,日常更新不再使清理登记失效;人工审查引用仍须重新登记。
- 重审保留采集步骤的告警,重新计算的湖检查结果单独更新;
cne audit --run-id可重复指定,定时健康检查合并本轮各组及补抓运行的证据。旧格式报告的未分类证据在首次重审时保留。 - 初始化恢复先重开运行,再完成剩余阶段,重试汇总不会提前关闭父运行。
- 东财 K 线和新闻接口的
data: null、缺失列表不再认证为空数据或分页完成;只有结构有效的空列表可作为空响应。日线旧负缓存随响应契约升级自动失效,后续采集重新核验。 - 新增
cne repair missing-values valuation_metrics|index_constituents:把估值源以零表示缺失的 PE、PB、PS 和总/流通市值,以及东财、国证快照缺失的指数权重改为空值,负估值比率保留。预览同时列出各指数、来源的快照起止与数量;--apply经修复门禁发布并保留旧版本,不制造缺失的历史成分或权重。 - 新增
cne repair financial-announcements:财报NOTICE_DATE可能是再公告日,原始披露日改从 LICO 解析;--apply只为有原始公告日证据的已有科目追加eastmoney_backfill重建版本,保留实际公告版本和旧湖版本。重建值在best_effort读取时返回pit_is_exact=false,strict排除;缺少的历史科目仍需cne backfill financial_statement_items补采。 - 新增
[universe].ingest_listed_funds:按证券目录采集已上市 ETF/LOF,研究资格只用于筛选;上市区间仍受检查,未知上市日期单独报告。基金目录失败、缺失或过期(含旧的研究资格采集开关)时,当天只暂停基金日线并记为 warning(fund_bar_scope_unavailable),股票日线照常采集;重试已计划的基金批次不会因此被撤销。 - ETF/LOF 日常因子派生补入已记录的拆分和转增;历史漏跳可用
cne repair fund-factors预览、--apply发布修正版本,来源为derived_fund_actions。从原始来源序列重建,保留其他台阶和现金分红口径,旧版本保留。 - 日线发布后按已提交的正成交量日线或独立停牌证据结清已补齐的北交所整日欠账。旧湖可用
cne repair daily-bar-coverage --apply刷新覆盖水位;未知上市日期仍是逐证券覆盖报告中的未核实项。 - Python
load()省略pit_mode或传None时,默认使用best_effort,在as_of之后采集的历史回填不再被采集时间过滤为空,返回的重建行标为pit_is_exact=false;读取收据记录实际模式。公告及已知可用/发布时间仍受截止日约束。依赖旧默认采集时间过滤的研究调用,升级后应显式传pit_mode="strict"。 - 修复东财不可用时
trading_status把正常交易的证券记成停牌。兜底现在只沿用每只证券前 5 个交易日内最近的一手记录(按交易日计,长假不再让缓存过期),不再沿用兜底自己写的缓存行;没有一手记录的证券不写行,而不是记成停牌,严格模式的股票池会因此拒绝这一天。用到兜底的运行记为warning,有证券没有记录时覆盖记为partial,告警逐日列出交易所板块、沿用和缺失的数量。 - 东财中断时沿用的状态行(
eastmoney_cached)一律按转述排序。此前兜底在收盘后写入的沿用行会被当成当日一手记录,压过日线缺口推断的停牌,并被日线覆盖检查当作可信停牌。 trading_status不再写证券上市日之前的行。东财会把尚未上市的代码报成正常交易,追赶多个交易日时这些行此前会写入;instruments上的退市日早于上市日时也不再当作退市。cne repair status-outages不再把状态沿用到上市日之前。- 新增
cne repair status-listing-window:删除上市日之前的状态行,以及当前instruments已不记退市的derived_delisted行。旧版合并曾把尚无日线的新证券推断为退市,它们上市后的头几个交易日因此被记成已退市。日线在上市日之前就有成交时,上市日视为有误,行保留。升级后运行一次(先预览,再加--apply)。 - 新增
cne repair status-traded --start --end:离线预览用正成交量日线补缺失股票/ETF 状态键,--apply发布derived_traded行并保留旧版本;不覆盖已有状态,ST 保持未知。显式的risk_warning=null在状态规范化及合并后保持未知,不再转成 false。全湖检查增加按类别和月份的成交状态覆盖报告,包含首次状态记录之前的历史,单列 ST 未知及上市日期等排除原因。 - staging 清理预览列出完整运行清单、大小和保留原因;清理执行器在删除期间持有运行锁,正在重试的运行即使指定 force 也保留。未完成批次不按年龄自动淘汰。
- 合并旧 staging 的状态批次时重新检查上市窗口及退市依据,防止已修复的错误行在重试后重新入湖;被实际成交否定的上市日期仍保留供核查。
- 修复以湖的
meta目录为引用根导入生命周期清单后,staging、来源快照和日志的清理(包括每晚的cne run clean预览)从下一次运行起一律报「References changed」。以该目录为根时,湖每次运行都会改写的内容(来源缓存、state、checkpoints、quality、source_snapshots、衍生品抓取记录等)不再计入引用。这样导入过的湖升级后要重新生成引用清单并运行一次cne storage import;其他引用根不受影响。集成程序调用reference_files()/reference_fingerprint()时传meta_root=。 - MCP
query_fundamentals与 serve 行浏览带as_of时默认 `pit_mode="best_e...
0.16.0 · MCP 远程 HTTP 接入与 uvx 启动
MCP 远程 HTTP 接入与 uvx 启动
CNEquity 0.16.0 已发布至 PyPI。开源 A 股本地数据湖,用于量化研究、回测与 AI Agent。
python -m pip install --upgrade cnequity==0.16.0- 升级步骤:
pip install -U cnequity后重启cne serve和已在运行的cne mcp。数据集契约没有变化,不需要迁移已有数据,也不需要改配置。 cne mcp --http用 Streamable HTTP 在127.0.0.1:8788/mcp上提供同样的六个只读工具,供只接远程网址的客户端(如 ChatGPT)配合 cloudflared、ngrok 等隧道使用。--token设置后每个请求都必须带令牌(Authorization: Bearer、/mcp/<令牌>路径或?token=);不设令牌时只接受本机直连,经隧道或代理的请求和其他站点的网页请求都返回 403。非回环地址必须配--token。stdio 用法不变。- MCP 工具声明
readOnlyHint,ChatGPT 等客户端据此把它们当作只读操作。 - 新增与
cne等价的cnequity命令,uvx cnequity mcp --config <配置>无需先安装即可启动 MCP 服务。仓库根目录新增server.json,用于登记到官方 MCP Registry。 - 修复 MCP 的
run_sql在已发布不可变版本的数据集上一律报Permission Error。查询沙箱此前只放行curated/和derived/,而这类数据集的视图读的是meta/revisions/data/;现在放行该目录,meta/下的其他文件仍不可读。 cne init --profile demo/sample结束时打印可直接复制的 MCP 接入命令(带配置的绝对路径),并当场生成度量表。此前用cne serve打开 demo 湖,概览显示 0 行,并把 demo 本来就不采的数据集标成「必需数据集为空」;现在面板与cne status一致,只评估 demo 湖实际持有的数据集。- 湖第一次成功建好时,在终端提示一次欢迎 Star;日志、管道和定时任务不会显示。
- 控制台切到 English 后整页都是英文:操作页的卡片标题、说明、表单项和确认语句,取数设置、定时任务、数据备份、存储运维和首次配置页面,此前都有只显示中文的文字。服务端返回的报错和诊断说明仍是中文。
- 文档分成中英文两套独立站点:中文仍在 https://rootsunc.github.io/CNEquity/ ,英文在
/en/,页眉可切换语言。源文件分别在docs/zh/和docs/en/,中文页原有网址不变。两套页面一一对应,英文版的 CLI 参数表、命令副作用清单、字段表和衍生品能力表与中文版一样由代码生成,CLI 帮助的英文对照放在scripts/dev/i18n/。「股票池画像」补上了中文版。中文页面改动后,若英文页没有同步更新,tests/unit/test_docs_i18n.py会报出落后的页面;更新英文后用scripts/dev/doc_translations.py --mark登记。 - MCP 指南新增 Claude Code、Claude Desktop、ChatGPT、Codex、Gemini CLI、Cursor、VS Code、Windsurf 等客户端的接入写法。