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
This commit is contained in:
gao
2026-07-21 16:37:00 +08:00
parent 91e83a3b0b
commit 8f016f25df
94 changed files with 4117 additions and 1176 deletions
@@ -0,0 +1,32 @@
[Unit]
Description=Market data MACD/KDJ/BOLL indicators sync (mairui, daily 16:40)
Documentation=file:///home/gao/Development/quant_home/market_sync/bin/market_sync_mairui_indicators_run.sh
After=network-online.target market-sync.service
Wants=network-online.target
[Service]
Type=oneshot
WorkingDirectory=/home/gao/Development/quant_home/market_sync
User=gao
Group=gao
# 入口脚本:单独跑 mairui_indicators 一个 task
# mairui 16:30 后发布指标数据 → 16:40 触发留 buffer
ExecStart=/home/gao/Development/quant_home/market_sync/bin/market_sync_mairui_indicators_run.sh
# 硬上限 3h(5204 只 × 3 指标,正常 ~20min,全量时可能更久)
TimeoutStartSec=10800
# 不要 Restart=oneshot 失败就让 OnFailure= 发通知,别自动重跑)
# Restart=no 是 oneshot 默认值
# 日志走 journald
StandardOutput=journal
StandardError=journal
SyslogIdentifier=market-sync-mairui-indicators
# 环境
Environment=PYTHONUNBUFFERED=1
[Install]
WantedBy=multi-user.target
@@ -0,0 +1,14 @@
[Unit]
Description=Schedule MACD/KDJ/BOLL indicators sync — Mon..Fri 16:40 Asia/Shanghai
# market-sync-mairui-indicators.service 是这个 timer 的执行单元
[Timer]
# mairui 16:30 后发布指标数据 → 16:40 触发留 buffer
OnCalendar=Mon..Fri 16:40:00 Asia/Shanghai
# 系统关机 / 错过执行时,下次开机补跑一次(避免漏数据)
Persistent=true
# 单位(service)的精确名称
Unit=market-sync-mairui-indicators.service
[Install]
WantedBy=timers.target
@@ -0,0 +1,32 @@
[Unit]
Description=Market data MA daily sync (local derivative, daily 16:30)
Documentation=file:///home/gao/Development/quant_home/market_sync/bin/market_sync_mairui_ma_daily_run.sh
After=network-online.target market-sync.service
Wants=network-online.target
[Service]
Type=oneshot
WorkingDirectory=/home/gao/Development/quant_home/market_sync
User=gao
Group=gao
# 入口脚本:单独跑 mairui_ma_daily 一个 task
# 本地派生任务,依赖 kline_stock 已更新
ExecStart=/home/gao/Development/quant_home/market_sync/bin/market_sync_mairui_ma_daily_run.sh
# 硬上限 2h(正常 ~30min,留 buffer
TimeoutStartSec=7200
# 不要 Restart=oneshot 失败就让 OnFailure= 发通知,别自动重跑)
# Restart=no 是 oneshot 默认值
# 日志走 journald
StandardOutput=journal
StandardError=journal
SyslogIdentifier=market-sync-mairui-ma-daily
# 环境
Environment=PYTHONUNBUFFERED=1
[Install]
WantedBy=multi-user.target
@@ -0,0 +1,14 @@
[Unit]
Description=Schedule MA daily sync — Mon..Fri 16:30 Asia/Shanghai
# market-sync-mairui-ma-daily.service 是这个 timer 的执行单元
[Timer]
# kline_daily 15:40 / kline_index 15:30 跑完后,16:30 计算 MA
OnCalendar=Mon..Fri 16:30:00 Asia/Shanghai
# 系统关机 / 错过执行时,下次开机补跑一次(避免漏数据)
Persistent=true
# 单位(service)的精确名称
Unit=market-sync-mairui-ma-daily.service
[Install]
WantedBy=timers.target
+3 -3
View File
@@ -1,5 +1,5 @@
[Unit]
Description=Market sync morning pre-market — stock_basic + industry_sector
Description=Market sync morning pre-market — stock_basic
Documentation=file:///home/gao/Development/quant_home/market_sync/bin/market_sync_morning_run.sh
After=network-online.target
Wants=network-online.target
@@ -10,10 +10,10 @@ WorkingDirectory=/home/gao/Development/quant_home/market_sync
User=gao
Group=gao
# 早盘前只跑 stock_basic + industry_sector(避免和 15:30 runall 重复
# 早盘前只跑 stock_basic(确保最新股票列表+股本快照
ExecStart=/home/gao/Development/quant_home/market_sync/bin/market_sync_morning_run.sh
# stock_basic ~9min + industry_sector ~16min + sleep 5s + buffer = 1h 够用
# stock_basic ~9min + buffer = 1h 够用
TimeoutStartSec=3600
# 不要 Restart=oneshot 失败就让 OnFailure= 发通知,别自动重跑)
+2 -2
View File
@@ -1,10 +1,10 @@
[Unit]
Description=Schedule market sync morning — Mon..Fri 09:00 Asia/Shanghai
# market-sync-morning.service 是这个 timer 的执行单元
# 早盘前 09:00 触发:跑 stock_basic + industry_sector,给 09:30 开盘留 30min buffer
# 早盘前 09:00 触发:跑 stock_basic,给 09:30 开盘留 30min buffer
[Timer]
# A 股开盘 09:3009:00 跑 stock_basic (~9min) + industry_sector (~16min) = ~25min
# A 股开盘 09:3009:00 跑 stock_basic (~9min) 即可
OnCalendar=Mon..Fri 09:00:00 Asia/Shanghai
# 关机/错过时下次开机补跑
Persistent=true
+31
View File
@@ -0,0 +1,31 @@
[Unit]
Description=Market data 股本快照 sync (雪球源, weekly Sat 11:30)
Documentation=file:///home/gao/Development/quant_home/market_sync/bin/market_sync_share_run.sh
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
WorkingDirectory=/home/gao/Development/quant_home/market_sync
User=gao
Group=gao
# 入口脚本:单独跑 share_snapshot 一个 task
ExecStart=/home/gao/Development/quant_home/market_sync/bin/market_sync_share_run.sh
# 硬上限 30min(全市场 5200 只雪球 quote_detail10 worker 约 3-8min,留 buffer
TimeoutStartSec=1800
# 不要 Restart=oneshot 失败就让 OnFailure= 发通知,别自动重跑)
# Restart=no 是 oneshot 默认值
# 日志走 journaldjournalctl -u market-sync-share.service -f
StandardOutput=journal
StandardError=journal
SyslogIdentifier=market-sync-share
# 环境(不读 /etc/environment,只带这几个;.env 由 cli 内部 load_dotenv
Environment=PYTHONUNBUFFERED=1
[Install]
WantedBy=multi-user.target
+16
View File
@@ -0,0 +1,16 @@
[Unit]
Description=Schedule share_snapshot sync — Sat 11:30 Asia/Shanghai
# market-sync-share.service 是这个 timer 的执行单元
# 股本快照每周跑一次即可(雪球 quote_detail,周末收盘后数据稳定)
[Timer]
# 周六 11:30(和 stock_node 同时段)
OnCalendar=Sat *-*-* 11:30:00 Asia/Shanghai
# 系统关机 / 错过执行时,下次开机补跑一次(避免漏数据)
Persistent=true
# 单位(service)的精确名称
Unit=market-sync-share.service
# 不要 AccuracySec(默认 1min 漂移够用)
[Install]
WantedBy=timers.target
+1 -1
View File
@@ -1,7 +1,7 @@
[Unit]
Description=Market data 股票-节点映射 sync (mairui /hszg, weekly Sat 11:30)
Documentation=file:///home/gao/Development/quant_home/market_sync/bin/market_sync_stock_node_run.sh
After=network-online.target
After=network-online.target market-sync-morning.service
Wants=network-online.target
[Service]
+25
View File
@@ -0,0 +1,25 @@
[Unit]
Description=Market Data Sync Worker (PostgreSQL, scheduler + health monitor)
Documentation=file:///home/gao/Development/quant_home/market_sync/app/entrypoints/worker.py
# 依赖 network 和 PG
After=network-online.target postgresql.service
Wants=network-online.target
[Service]
Type=simple
WorkingDirectory=/home/gao/Development/quant_home/market_sync
User=gao
Group=gao
# 入口:启动进程内 scheduler + health monitor + recover 卡死任务
# 注意:实际入口是 app/entrypoints/worker.py,不是 app/worker.py
# 2026-07-12 修复: 把 python -m app.worker 改为 python -m app.entrypoints.worker
ExecStart=/home/gao/Development/quant_home/market_sync/.venv/bin/python -m app.entrypoints.worker
# 明确标记运行模式,让 worker.py 知道不要启动 scheduler
# systemd 模式下同步由 timer 触发,避免双调度器重叠)
Environment=PYTHONUNBUFFERED=1
Environment="RUNTIME_MODE=systemd"
[Install]
WantedBy=multi-user.target
+5 -4
View File
@@ -13,10 +13,11 @@ Group=gao
# 入口脚本(runall_once.py + structured_watch.sh 二合一)
ExecStart=/home/gao/Development/quant_home/market_sync/bin/market_sync_run.sh
# 硬上限 4h(实际 ~80min + kline_5min 增量 70min, 总 ~2.5h, 留 buffer 给 retry / 慢任务
# 历史 bug2026-07-02):2h 超时截断,share_snapshot / market_regime 没跑成
# 详见 docs/works/2026-07-03-01-market-sync-timeout.md
TimeoutStartSec=14400
# 硬上限 3h(实际 ~80min + kline_5min 增量 70min, 总 ~2.5h, 留 30min buffer
# 2026-07-08 教训: 之前 4h 让 kline_daily 单点卡死拖 4h,runall 链全部受影响。
# runall_once.py 已加 per-task multiprocessing timeout(单 task 最长 75min),
# 这里 3h 是 systemd 层兜底。
TimeoutStartSec=10800
# 不要 Restart=oneshot 失败就让 OnFailure= 发通知,别自动重跑——
# 重跑会撞外部 API 限流窗口,浪费 1.5h)