main
- QmtBridgeSource: provides 增加 index_daily,新增 fetch_index_daily 方法 - task_kline_index: 优先级改为 qmt_bridge → mairui → sina 三级降级 - task_kline_5min: 优先用 qmt_bridge,不可用时降级 mairui - task_kline_daily: 优先级加入 qmt_bridge(首位) - config: 新增 qmt_bridge_url 配置项 - registry: qmt_bridge 注册信息同步更新 - docs: 新增 DATASETS_AND_SOURCES.md,完整说明数据集与数据源依赖关系 - AGENTS.md: 同步更新指数数据源描述
market_data_sync
A 股市场数据定时同步与管理框架。
把 akshare / baostock / 新浪 / 雪球 / 麦蕊智数 等多个数据源接入到 PostgreSQL 库,提供:
- 后台线程调度器(time-based + interval-based,交易日感知)
- 多数据源 + 自动降级 + 健康度监控
dataset_registry同步状态机(运行中 / 成功 / 失败 / 中断恢复)- FastAPI 管理接口(手动触发、状态查询、失败重试)
- CLI 入口(手动跑任务、查看状态)
📖 详细架构说明见 docs/ARCHITECTURE.md
运行模式
项目支持两种互斥的运行模式,由环境变量 RUNTIME_MODE 控制:
| 模式 | 值 | 适用场景 | 调度方式 |
|---|---|---|---|
| Docker 模式 | docker |
docker compose up 单容器部署 |
进程内 scheduler(uvicorn + daemon thread) |
| systemd 模式 | systemd |
Linux 宿主机长期运行 | systemd timer/service |
⚠️ 两种模式不能同时启用,否则同一个 task 会被两边各触发一次,造成状态机抖动和重复 IO。
Docker 模式
# 1. 准备环境(首次)
cp .env.example .env # 编辑 .env 填写真实 PG 凭据 + XUEQIU_TOKEN + MAIRUI_LICENCE
# 2. 启动(包含 postgres + market_sync 服务)
docker compose up -d
# 3. 查看日志
docker compose logs -f market_sync
# 4. 手动触发一次任务
docker compose exec market_sync python -m app.entrypoints.cli sync kline_daily
Docker 模式下 RUNTIME_MODE=docker 已写在 deploy/docker/docker-compose.yml 中,容器内会启动进程内 scheduler 负责所有同步任务。
systemd 模式
# 1. 准备环境(首次)
cp .env.example .env # 编辑 .env 填写真实 PG 凭据
# 并在 .env 中加上 RUNTIME_MODE=systemd
# 2. 部署 systemd units
sudo bash deploy/systemd/deploy.sh
# 3. 查看 timer
systemctl list-timers market-sync*
# 4. 查看 worker / 任务日志
journalctl -u market-sync -f
journalctl -u market-sync-moneyflow -f
systemd 模式下:
- 所有 14 个 task 都由 systemd timer 触发
market-sync-worker.service会被部署脚本自动 stop / disable / mask,避免进程内 scheduler 与 systemd timers 重叠- 每日 23:00
market-sync-daily-check.timer跑巡检,失败时 POST webhook
本地开发模式
# 1. 准备环境(首次)
cp .env.example .env # 编辑 .env 填写凭据
chmod +x start.sh
# 2. 启动 API + scheduler(默认 docker 行为,等价于本地单进程)
./start.sh # http://localhost:8100
# 3. 常用命令
./start.sh worker # 仅启动调度器(无 web)
./start.sh list # 列出所有同步任务
./start.sh sync kline_daily # 手动触发一次(dataset_id 即可)
./start.sh status # 查看调度器/数据源/同步任务状态
./start.sh datasources # 查看数据源健康度
./start.sh reseed # 重新 seed 默认配置到 config 表
# 4. 一键全量同步(首次接入)
python bin/runall_once.py
# 5. 跑测试
.venv/bin/pytest tests/ -v
项目结构
app/ # 应用源码
├── core/ # 核心抽象(config / db / sync / scheduler / datasource base)
├── sources/ # 数据源实现
├── tasks/ # 同步任务实现(14 个)
├── api/ # FastAPI 管理接口
└── entrypoints/ # 进程入口(cli + worker)
bin/ # 通用脚本(运行入口、CLI、一次性任务)
config/ # 配置文件、secrets
deploy/ # 部署相关
├── docker/ # Dockerfile + docker-compose.yml
└── systemd/ # systemd units + 部署脚本
│ ├── units/ # *.service / *.timer
│ └── deploy.sh # 一键部署脚本
docs/ # 架构文档
logs/ # 日志输出
tests/ # 单元测试
Dockerfile -> deploy/docker/Dockerfile
docker-compose.yml -> deploy/docker/docker-compose.yml
bin/deploy_systemd.sh -> deploy/systemd/deploy.sh
bin/systemd_deploy.sh -> deploy/systemd/deploy.sh
内置同步任务
| dataset_id | systemd 触发时间 | Docker scheduler 时间 | 说明 |
|---|---|---|---|
stock_basic |
工作日 09:00 | 09:00 | 全市场股票基础信息 + 股本 |
kline_index |
工作日 15:30 | 15:30 | 六大指数日线 |
kline_daily |
工作日 15:30(runall) | 15:40 | 增量日 K 线(OHLCV,多源交叉) |
kline_5min |
工作日 15:30(runall) | 16:00 | 增量 5 分钟 K 线 |
market_regime |
工作日 15:30(runall) | 16:15 | 市场情绪(衍生源) |
share_snapshot |
工作日 15:30(runall) | 16:20 | 股本快照(雪球) |
mairui_ma_daily |
工作日 16:30 | 16:30 | 日 K MA5/10/20/60(本地派生) |
mairui_indicators |
工作日 16:40 | 16:40 | 日 K MACD/KDJ/BOLL(mairui) |
moneyflow |
工作日 21:35 | 21:35 | 资金流(主力/大/中/小单净额) |
tick_trade |
工作日 21:05 | 21:05 | 当天逐笔成交(mairui) |
longhubang |
工作日 22:00 | 22:00 | 龙虎榜(akshare / 东方财富) |
stock_node |
周六 11:30 | 周六 11:30 | 股票-节点映射(mairui) |
添加新数据源
- 在
app/sources/新建my_source.py,继承DataSource - 在
app/core/datasource/registry.py的build_default_registry()注册
添加新同步任务
- 在
app/tasks/新建task_xxx.py,继承SyncTask,设置dataset_id - 在
app/tasks/__init__.py的TASKS字典注册 - 在
app/core/sync/registry.py的SYNC_DEFINITIONS加条目 - 如果使用 systemd 模式,在
deploy/systemd/units/新增对应的.service和.timer - 如果使用 Docker 模式,在
app/core/scheduler/scheduler.py的DEFAULT_SCHEDULES新增调度项
License
私有
Description
Languages
Python
94.6%
Shell
5.4%