7.2 KiB
7.2 KiB
迁移 Tushare PostgreSQL 同步
Goal
把旧项目中面向当前上市股票的 Tushare 日线获取能力迁移到 zhixing-server,形成可由外部调度器重复执行的一次性同步任务。同步结果以 PostgreSQL 为策略查询事实源,同时保留按股票拆分的六年 qfq CSV 落地快照,以可靠识别和修复历史复权数据变化。
User Value
- 每个交易日收盘后可以稳定更新当前股票池的日线、股票主数据和每日估值/交易指标。
- 后续选股策略读取结构化、可查询且有覆盖率保障的市场数据,不再直接依赖散落 CSV。
- Tushare 修订历史 qfq 时,可以只修复受影响股票,而不会默默保留过期历史价格。
Background and Confirmed Facts
- 当前
zhixing-server只有 FastAPI 基础工程,尚无数据库连接、迁移、任务队列或市场数据 bounded context。 - 旧项目按股票调用
pro_bar(adj="qfq")并写 CSV,但初始化流程总是全量覆盖,没有 PostgreSQL 行情存储和可审计同步批次。 - 旧项目把最新总市值复制到所有历史 K 线行,不满足按交易日分析估值条件的需求;新实现必须把每日估值/交易指标按交易日保存。
- 已接受 PostgreSQL 主存储决策 和 六年快照同步决策。
Requirements
R1. 数据范围
- 同步当前上市的沪深非 ST A 股股票主数据;排除 ST/风险警示股和北交所股票。
- 每只股票同步最近六年的日线行情,价格口径只保留 Tushare
qfq。 - 同步按交易日归属的估值与交易指标,至少满足后续市值、流动性和换手率筛选。
- 只支持日线收盘数据,不包含分钟级、盘中实时行情或长期无幸存者偏差回测数据。
R2. 存储职责
- PostgreSQL 是运行时和策略查询的市场数据事实源。
- CSV 是 Tushare 落地快照、导出和恢复介质,不承担策略在线查询。
- 日线数据以 Tushare
(ts_code, trade_date)唯一标识;重复同步必须幂等。 - PostgreSQL 与正式 CSV 均按目标交易日滚动保留最近六年;成功同步新窗口时清理窗口起点之前的行情、每日指标和日期快照。
- 某个对象同步失败时不得因本次运行提前删除其原有数据或替换其正式 CSV。
R3. 六年快照与修订检测
- 每次同步按股票重新请求最近六年 qfq 日线,而不是只请求最新日期。
- 新旧 CSV 必须在规范化后的完整历史重叠区间计算并比较指纹。
- 指纹相同时,只向 PostgreSQL 插入新交易日。
- 指纹不同时,只对发生变化的股票执行最近六年完整 upsert,不触发全市场回写。
- 指纹字段不得包含同步时间、批次 ID 或会使历史行每天变化的当前快照字段。
R4. 原子性与恢复
- 单只股票按“临时 CSV → 校验和指纹比较 → PostgreSQL 事务提交 → 原子替换正式 CSV”的顺序处理。
- PostgreSQL 失败时不得替换该股票的正式 CSV。
- PostgreSQL 批量修复必须使用批量装载和集合式 upsert,不得通过 ORM 逐行更新六年数据。
R5. 批次、部分成功与重试
- 单只股票是事务和重试边界。
- 同步批次支持
success、partial_success和failed状态,并记录每只股票行情及每日指标日期的插入、更新、未变化或失败结果。 - 部分失败不得回滚成功对象;后续可以只重试失败股票或失败指标日期。
R6. 数据新鲜度与后续选股
- 有效选股股票必须同时具备目标交易日的行情和所需估值数据,旧日期数据不得冒充当天数据。
- 自动选股最低数据覆盖率默认
99%,并可配置。 - 覆盖率不足时不自动运行策略;人工强制运行必须把结果标记为不完整。
- 本任务只建立覆盖率与新鲜度契约,不迁移或实现具体选股策略。
R7. 运行边界
- 同步由外部调度器触发,FastAPI 进程内部不运行定时器。
- 项目在 Docker Compose 中定义复用后端镜像的一次性同步 Job,并通过 CLI 执行可重复的一次性同步用例。
- 生产宿主机 cron 使用
docker compose run --rm定时启动 Job;本任务提供配置示例,但不直接修改宿主机 crontab。 - Tushare 凭据和 PostgreSQL 连接信息通过项目统一配置入口注入,不写入代码、日志或响应。
Technical Notes
- Tushare
pro_bar(adj="qfq")内部组合日线与复权因子;六年范围的每股请求适合作为 qfq 修订检测来源。 - Tushare
daily_basic支持按trade_date获取全市场、单次最多 6000 行,更新时间为交易日 15:00~17:00;首次初始化应按交易日回补,日常只同步目标交易日,不需要每天重拉六年估值指标。 - PostgreSQL 批量修复计划使用 Psycopg 3
COPY FROM STDIN加 staging 表和集合式 upsert;数据库 schema 使用独立迁移管理,不在 FastAPI 启动时自动建表。 - Docker Compose Job 使用 profile 与
docker compose run --rm,宿主机 cron 仅负责触发。
Acceptance Criteria
- 可在空 PostgreSQL 中完成当前目标股票池的六年 qfq 日线、股票主数据和每日估值/交易指标初始化。
- 目标股票池只包含当前上市的沪深非 ST A 股,不包含 ST/风险警示股和北交所股票。
- 对相同 Tushare 返回重复执行同步,不产生重复行或无意义历史更新。
- 只有新交易日时,仅新增对应日期数据。
- 任意历史重叠行变化时,只对该股票执行六年修复,PostgreSQL 最终与新 CSV 一致。
- PostgreSQL 写入失败时,该股票正式 CSV 保持旧版本;重试后可以幂等完成。
- 少数股票失败时批次为
partial_success,成功股票保留结果,失败股票可单独重试。 - 同步结果能够报告目标数、有效数、覆盖率、插入数、更新数、未变化数和失败列表。
- 覆盖率低于默认
99%时不会自动触发选股;人工强制运行具有显式不完整标记。 - Compose 一次性 Job 可以复用生产后端镜像、数据库连接和 CSV 数据卷,正常
docker compose up -d不会常驻启动该 Job。 - 项目文档提供宿主机 cron 调用
docker compose run --rm的示例,周末、节假日和重复触发保持安全幂等。 - 成功同步后 PostgreSQL 与正式 CSV 不包含目标六年窗口之前的数据;失败对象仍保留上一次成功发布的数据。
- 单元测试覆盖指纹、差异判定、幂等写入、失败恢复和覆盖率计算;PostgreSQL 集成测试覆盖迁移、唯一约束和批量 upsert。
- 后端 Ruff、Pyright 和 pytest 质量门禁通过。
Out of Scope
- 分钟级、盘中实时行情和 WebSocket 数据。
- 未复权、后复权或复权因子长期保存。
- 退市股票历史成员资格和无幸存者偏差的长期回测股票池。
- 具体选股策略、信号持久化、图表和前端管理页面。
- FastAPI 进程内定时器或本任务直接配置生产调度平台。
- 六年以上历史的长期保存、退市样本回补和长期回测支持。