Files
market_sync/README.md
T
gao 8f016f25df chore: baseline — ORM migration + systemd deploy + MCP server + daily check
- ORM migration: models/ops 重构
- deploy: 标准化 systemd timer/service 部署体系
- MCP server: 5 个只读工具(任务/状态/数据集)
- daily check: 数据一致性巡检
- watch: task_watch 后台监控
- kline_daily: 麦蕊优先,时间门禁15:00
- 删除: task_industry_sector, task_sector_features
2026-07-21 16:37:00 +08:00

149 lines
6.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# market_data_sync
A 股市场数据**定时同步与管理**框架。
`akshare` / `baostock` / 新浪 / 雪球 / 麦蕊智数 等多个数据源接入到 PostgreSQL 库,提供:
- 后台线程调度器(time-based + interval-based,交易日感知)
- 多数据源 + 自动降级 + 健康度监控
- `dataset_registry` 同步状态机(运行中 / 成功 / 失败 / 中断恢复)
- FastAPI 管理接口(手动触发、状态查询、失败重试)
- CLI 入口(手动跑任务、查看状态)
> 📖 详细架构说明见 [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)
## 运行模式
项目支持两种互斥的运行模式,由环境变量 `RUNTIME_MODE` 控制:
| 模式 | 值 | 适用场景 | 调度方式 |
|---|---|---|---|
| **Docker 模式** | `docker` | `docker compose up` 单容器部署 | 进程内 scheduleruvicorn + daemon thread |
| **systemd 模式** | `systemd` | Linux 宿主机长期运行 | systemd timer/service |
> ⚠️ 两种模式**不能同时启用**,否则同一个 task 会被两边各触发一次,造成状态机抖动和重复 IO。
### Docker 模式
```bash
# 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 模式
```bash
# 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
### 本地开发模式
```bash
# 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:30runall| 15:40 | 增量日 K 线(OHLCV,多源交叉) |
| `kline_5min` | 工作日 15:30runall| 16:00 | 增量 5 分钟 K 线 |
| `market_regime` | 工作日 15:30runall| 16:15 | 市场情绪(衍生源) |
| `share_snapshot` | 工作日 15:30runall| 16:20 | 股本快照(雪球) |
| `mairui_ma_daily` | 工作日 16:30 | 16:30 | 日 K MA5/10/20/60(本地派生) |
| `mairui_indicators` | 工作日 16:40 | 16:40 | 日 K MACD/KDJ/BOLLmairui |
| `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 |
## 添加新数据源
1.`app/sources/` 新建 `my_source.py`,继承 `DataSource`
2.`app/core/datasource/registry.py``build_default_registry()` 注册
## 添加新同步任务
1.`app/tasks/` 新建 `task_xxx.py`,继承 `SyncTask`,设置 `dataset_id`
2.`app/tasks/__init__.py``TASKS` 字典注册
3.`app/core/sync/registry.py``SYNC_DEFINITIONS` 加条目
4. 如果使用 systemd 模式,在 `deploy/systemd/units/` 新增对应的 `.service``.timer`
5. 如果使用 Docker 模式,在 `app/core/scheduler/scheduler.py``DEFAULT_SCHEDULES` 新增调度项
## License
私有