--- status: accepted --- # Tushare 同步采用六年落地快照与重叠区间指纹 每日同步由外部调度器触发;应用对当前目标股票池逐只获取最近六年的 Tushare qfq 日线,形成 CSV 落地快照。新旧快照先比较完整历史重叠区间:指纹相同时只向 PostgreSQL 插入新交易日,指纹不同时对该股票最近六年执行幂等 upsert;一只股票的数据变化不会触发全市场回写。 单只股票按“生成临时 CSV → 校验并比较重叠区间 → 提交 PostgreSQL 事务 → 原子替换正式 CSV”的顺序同步。PostgreSQL 提交失败时不替换正式 CSV,保证运行时事实源和已发布落地快照不会出现新旧倒置。 单只股票也是事务和重试边界。部分股票失败时,批次标记为 `partial_success`,已成功股票不回滚;失败股票保留旧 PostgreSQL 数据和旧 CSV,并在后续只重试失败集合。 `partial_success` 可以触发后续选股,但只能使用行情和所需估值数据均已到达目标交易日的有效股票;失败股票不得使用旧数据冒充当天行情,选股结果必须携带覆盖率和失败列表。 自动选股的默认最低数据覆盖率为 `99%`,并允许通过配置调整。低于阈值时只报告同步结果并优先重试失败股票;人工强制运行必须把选股结果标记为不完整。 六年窗口按目标交易日滚动。单只股票同步事务成功时删除窗口起点之前的 PostgreSQL 日线,并以只包含当前窗口的新文件原子替换正式 CSV;每日估值/交易指标及其日期快照采用相同的滚动保留边界。失败对象不发布新 CSV,也不因本次失败提前丢失其原有数据。该边界符合当前系统关注近期走势而非长期回测的定位。 ## Considered Options - **仅请求最新增量日期**:请求次数没有明显减少,却无法自然发现历史 qfq 修订。 - **只比较最近一周**:能发现常见的近期除权变化,但可能漏掉供应商对更早历史数据的修正。 ## Consequences - CSV 是同步落地快照,PostgreSQL 仍是策略查询的事实源。 - 指纹必须基于规范化、排序后的共同日期区间和固定字段集合,避免浮点文本差异造成误判。 - PostgreSQL 写入以 Tushare `(ts_code, trade_date)` 为唯一键;未变化时只写新日期,变化时仅回写发生变化的股票。 - 批量修复应通过 staging 表与批量装载完成,避免逐行 ORM 写入。 - 临时 CSV 只有在对应 PostgreSQL 事务提交成功后才能晋升为正式落地快照;重复执行同一批次必须保持幂等。 - 同步批次需要记录每只股票的成功、失败、插入、更新和未变化结果,以支持部分成功与定向重试。 - 选股批次需要关联对应同步批次,并记录实际参与股票数、目标股票数和数据覆盖率。 - PostgreSQL 与 CSV 都只承诺滚动保留最近六年;如果未来需要更长周期回测,应重新评估数据范围并回补历史数据。