# 2026-07-03 — work #06: 新增 mairui 历史分时 MA(日 K 级别)同步 ## 需求 user 请求:"添加同步数据 https://mairui.club/hsdata 历史分时MA,日K线级别" ## 探测 mairui API 尝试 mairui 提供的 MA 端点(用现有 .env 里的 licence fb3ea07350729a2b3f): | 端点 | 状态 | |---|---| | `/hsstock/history/{code}.{ex}/d/ma/` | ✅ HTTP 200,但 body `{"error":"数据不存在"}` | | `/hsstock/history/{code}.{ex}/d/ma5/` | ✅ HTTP 200,`{"error":"数据不存在"}` | | `/hsstock/history/{code}.{ex}/d/ma10/` | ✅ 同上 | | `/hsstock/history/{code}.{ex}/d/ma20/` | ✅ 同上 | | `/hsstock/history/{code}.{ex}/15/ma/` | ✅ 同上 | | `/hsstock/history/{code}.{ex}/30/ma/` | ✅ 同上 | | `/hsstock/history/{code}.{ex}/60/ma/` | ✅ 同上 | | `/hsstock/history/{code}.{ex}/d/n/` | ✅ 返正常 OHLCV | | `/hsstock/history/{code}.{ex}/15/n/` | ✅ 15min K | | `/hsstock/history/{code}.{ex}/30/n/` | ✅ 30min K | | `/hsstock/history/{code}.{ex}/60/n/` | ✅ 60min K | **结论**:MA 端点结构存在但**当前免费 licence 没数据**。基础 K 线(OHLCV)正常。 ## 解决 mairui 端点不可用,但**用户要的"日 K 级别 MA"完全可以本地从已有 kline_stock 派生**: - 输入:market_data.kline_stock(已有 ~1170w 行日 K 线) - 操作:按 stock_code 分组,对 close 做 `rolling(5/10/20/60).mean()` - 写新表 `market_data.kline_stock_ma_daily` mairui URL 留作未来升级 licence 后的扩展(task 里 source 字段已标识 `local_kline_proxy`,可改 `mairui`)。 ## 变更清单 1. **新 ORM model** `KlineStockMADaily`(models.py) - 字段:stock_code / trade_date / ma5 / ma10 / ma20 / ma60 / source / updated_at - PK: (stock_code, trade_date) - Index: trade_date 2. **新 ops 函数** `upsert_kline_stock_ma_daily_rows`(ops.py) - PG upsert 模式与 sector_features 一致 - 批量 5000 行/批 - 用 `pd_isna` 避开 import pandas 3. **新 task** `task_mairui_ma_daily.py` - 读 kline_stock → pandas → per-stock rolling → upsert - MA_WINDOWS = [5, 10, 20, 60] - 全量重算(数据量 ~1100w 行 pandas ~30s) 4. **注册**: - `app/tasks/__init__.py` 加 `SyncMairuiMADaily` 到 TASKS - `app/core/sync/registry.py` 加 SYNC_DEFINITION(sort_order=90,dependency=kline_daily) - `app/core/scheduler/scheduler.py` 加 schedule_mairui_ma_daily(@16:30 daily)+ register_sync_jobs - `bin/daily_sync_check.py` 加 SCHEDULE entry(window_end=17:00) ## 烟测验证 ``` ✅ task 完成 ok: MA [5, 10, 20, 60] 共 11,684,592 行, 5510 只, 1370.1s ✅ kline_stock_ma_daily table created (step4_create_tables) ✅ rows: 11,684,592 ✅ stocks: 5510 ✅ date range: 2000-07-25 ~ 2026-07-03 ✅ NULL ma5: 22,038 (每只股票前 4 个交易日) ``` 样本 SH600519: ``` 2026-07-03 ma5=1194.18 ma10=1191.03 ma20=1211.94 ma60=1296.20 2026-07-02 ma5=1189.02 ma10=1190.27 ma20=1214.16 ma60=1300.06 ``` ## 性能 - 全量重算 1370s ≈ 23 min(首次含 table creation + 批量 upsert) - 后续每日增量(只算昨天一行)应该 < 5s,但当前实现是全量重算 → 22 min - **优化点**(不在本 work 范围):改成增量模式(只 upsert 最近 1-2 天),把 23 min 降到 30s ## 不在范围(未来) - 增量模式(避免每日 23 min 全量重算) - 升级 mairui licence 后切到 `/d/maN` API - EMA(指数移动平均,与 MA 区别) - BOLL / KDJ 等其他衍生指标 ## 关联 - mairui 接入:app/sources/mairui.py - daily_check:bin/daily_sync_check.py - 数据依赖:本任务依赖 kline_daily,所以应排在 kline_daily 之后(16:00 后跑)