Files
MoFin/docs/TDX_RELAY_COLLAB.md
T

298 lines
9.7 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.
# MoFin / TDX-Relay 协作文档
> 最后更新:2026-06-12
> 维护人:知微 + 小小莫(xxm)
> 铁律:任何 relay 相关改动必须先读本文档,改完必须同步更新
---
## 一、什么是 tdx-relay
tdx-relay 是小小莫(xxm)开发的 Windows 端通达信中继程序。
作用:通过 opentdx 协议直连招商证券 7727 扩展行情服务器,
为 MoFin 系统提供港股低延迟实时行情。
### 为什么需要它
原本 MoFin 的港股行情来源是腾讯 APIqt.gtimg.cn),
存在约 15 分钟延迟,对于盘中决策不够及时。
tdx-relay 将港股行情延迟从约 15 分钟降到接近实时(1~3 秒)。
---
## 二、系统架构
```
Windows 端(小小莫负责)
┌─────────────────────────────────────────┐
│ tdx-relay 项目 │
│ │
│ tdx_client.py │
│ └─ opentdx MacExtendedClient │
│ └─ 直连 招商证券 7727 扩展行情服务器 │
│ → 拉取 17 只港股实时行情 │
│ │
│ run_relay.py │
│ └─ 断线自动重连(5s/15s/30s 三次退避) │
│ └─ 推送 → POST /api/update/realtime │
│ │
│ start_tdx_relay.bat │
│ └─ 一键启动脚本 │
└───────────────┬─────────────────────────┘
│ HTTP POST (JSON)
Linux 端(知微负责)
┌─────────────────────────────────────────┐
│ MoFin 系统 (web-dashboard) │
│ │
│ server.py │
│ ├─ /api/update/realtime (POST) │
│ │ ← 接收 tdx-relay 推送的实时行情 │
│ │ → 更新 portfolio.json + watchlist │
│ │ → 写入 data_source = "tdx_relay" │
│ │ │
│ ├─ /api/relay/status (GET) │
│ │ ← 查询 relay 状态(在线/离线/时间) │
│ │ │
│ price_monitor.py │
│ └─ relay_active 检测 │
│ ├─ relay 在线 → 跳过港股腾讯API拉取 │
│ │ (保留 tdx-relay 的实时价不覆盖) │
│ └─ relay 掉线 → 回退腾讯 API 兜底 │
│ │
│ 数据文件 │
│ ├─ data/portfolio.json │
│ │ └─ 每只港股: data_source=txton/tdx │
│ ├─ data/watchlist.json │
│ └─ data/relay_state.json (新增) │
│ └─ online: true/false │
│ └─ last_ping: 时间戳 │
└─────────────────────────────────────────┘
```
## 三、职责边界
### 小小莫(xxm)— Windows 端
负责:
1. tdx_client.py 的开发维护
- 直连券商行情服务器的稳定性
- 港股代码列表的维护(当前 17 只)
- 行情数据的正确性验证
2. run_relay.py 的重连机制
- 断线自动恢复(3 次退避重连)
- relan 状态上报
3. 行情推送的稳定性
- 每 X 秒推送一次实时行情
- 推送失败的处理
4. Windows 端部署维护
- 开机自启动
- 日志管理
- 异常告警
不负责:
- MoFin API 的修改(但需要配合 server.py 新增端点)
- Linux 端 price_monitor 的回退逻辑
- 持仓分析和策略制定
### 知微(zhiwei)— Linux 端(MoFin
负责:
1. MoFin API 的 relay 兼容
- /api/update/realtime 端点(已实现)
- /api/relay/status 端点(待实现)
- relay_state 持久化(待实现)
2. price_monitor 的 relay 检测(待实现)
- relay 在线 → 跳过港股腾讯 API 拉取
- relay 掉线 → 回退腾讯 API 兜底
3. tdx-relay 接入后的数据一致性保障
- 腾讯 API 和 tdx-relay 的数据源标记区分
- 价格更新不互相覆盖
4. 行情来源对分析层的透明化
- 分析层(cron prompt)不需要关心行情来源
- 直接读 portfolio.json 即可
- 数据源标记在 data_source 字段中
不负责:
- Windows 端程序的开发和部署
- 通达信协议的细节
- 券商行情服务器的维护
### 共同维护
1. 港股代码列表 — 两边保持一致
2. 数据格式 — tdx-relay 推送的 JSON 格式与 MoFin 期望的格式
3. 接口联调 — 新端点上线后的验证
---
## 四、数据流详解
### 正常流程(relay 在线)
```
tdx-relay (Windows)
│ 每 X 秒推送 {stocks: [{code, price, change_pct, ...}]}
│ POST → http://192.168.1.246:8899/api/update/realtime
server.py 接收
├─ 更新 portfolio.json(港股 data_source = "tdx_relay"
├─ 更新 watchlist.json(港股 data_source = "tdx_relay"
└─ 更新 relay_state.jsononline=true, last_ping=now
price_monitor.py(每分钟运行)
├─ A股 → 腾讯 API(不变)
├─ 港股 → 检查 relay_state
│ ├─ relay 在线 → 跳过(保留 tdx-relay 的实时价)
│ └─ relay 离线(>60秒无推送)→ 回退腾讯 API
└─ 数据源标记 → 写入 portfolio/watchlist
```
### 异常流程(relay 离线)
```
tdx-relay 断线
│ 60秒内无推送
price_monitor.py 检测到 relay_state.online=false
│ 或 last_ping > 60秒前
├─ 港股 → 回退腾讯 API 拉取
├─ 写入时 data_source = "tencent"
└─ 记录日志 "relay offline, fallback to tencent"
tdx-relay 恢复
│ 推送到达 /api/update/realtime
server.py 接收更新
├─ 更新 relay_state.jsononline=true
└─ 正常接收行情
```
---
## 五、接口规范
### POST /api/update/realtime (已实现)
接收 tdx-relay 推送的实时行情。
请求格式:
```json
{
"stocks": [
{
"code": "00700",
"price": 467.20,
"change_pct": 3.09,
"high": 470.00,
"low": 460.00,
"open": 462.00,
"volume": 15000000
}
],
"source": "tdx_relay"
}
```
响应:
```json
{
"status": "ok",
"updated": 15,
"source": "tdx_relay",
"timestamp": "2026-06-12T14:30:00"
}
```
### GET /api/relay/status (待实现)
查询 tdx-relay 当前状态。
响应:
```json
{
"online": true,
"source": "tdx_relay",
"last_ping": "2026-06-12T14:29:55",
"age_seconds": 5,
"stocks_count": 15,
"fallback_active": false
}
```
---
## 六、当前实现状态
### 已完成(全部 ✅)
- server.py `/api/update/realtime` 端点 ✅
- server.py `/api/relay/status` GET 端点 ✅
- relay_state.json 持久化 ✅
- price_monitor.py relay_active 检测 ✅
- price_monitor 回退逻辑(relay 离线→腾讯 API 兜底)✅
- tdx-relay 心跳上报(每15秒推送)✅
- 断线自动重连(3次退避)✅
- 17只港股全量推送 ✅
- 数据层重构:JSON+SQLite 双写 + 消费者切 SQLite 优先 ✅
### 2026-06-20 数据层重构(小小莫完成)
**新增文件**
- `mofin_db.py` — 统一 SQLite 访问层(13张表 + 18个查询函数 + 4个写入函数)
- `migrate_all.py` — 一次性 JSON→SQLite 迁移脚本
- `mofin_query.py` — 通用查询工具
- `docs/DATABASE_ARCHITECTURE.md` — 完整架构文档
**修改文件**
- `market_watch.py` — JSON+SQLite 双写
- `multi_timeframe.py` — K线双写
- `price_monitor.py` — 价格事件双写
- `server.py` — SQLite 优先读取(/api/portfolio, /api/watchlist, /api/overview, /api/market
- `strategy_lifecycle.py` — SQLite 优先读取(stock_sector_map, market_context, holdings, watchlist
- `market_insight.py` — SQLite 优先读取
- `strategy_feedback.py` — SQLite 优先读取 price_events
- `system_health_check.py` — SQLite 优先读取 price_events
**设计原则**
- 所有消费者:SQLite 优先 → 失败回退 JSON,系统不中断
- 所有写入:JSON+SQLite 双写,SQLite 失败不影响 JSON 管道
- 迁移脚本幂等可重跑,JSON 文件不修改
---
## 七、港股代码列表(双方保持一致)
当前 17 只港股(来自 portfolio.json + watchlist.json):
| 代码 | 名称 | 持仓/自选 |
|------|------|----------|
| 00700 | 腾讯控股 | 持仓 |
| 00981 | 中芯国际 | 持仓 |
| 01211 | 比亚迪股份 | 持仓 |
| 09988 | 阿里巴巴 | 持仓 |
| 02202 | 万科企业 | 持仓 |
| 02388 | 中银香港 | 持仓 |
| 01478 | 丘钛科技 | 持仓 |
| 09868 | 小鹏集团 | 自选(已清仓) |
| 01088 | 中国神华 | 持仓 |
| 02359 | 药明康德 | 自选 |
| 01888 | 建滔积层板 | 自选 |
| 00968 | 信义光能 | 自选 |
| 01070 | TCL电子 | 自选 |
| 02318 | 中国平安 | 自选 |
| 02628 | 中国人寿 | 自选 |
| 06160 | 百济神州 | 自选(已清仓) |
| 06869 | 长飞光纤 | 自选 |
---
## 八、故障处理
| 现象 | 可能原因 | 处理方式 |
|------|---------|---------|
| relay 显示离线 | Windows 端掉线 | 检查 Windows 端运行状态,双击 start_tdx_relay.bat |
| relay 在线但数据不更新 | 推送异常 | 查 Windows 端日志,重启 tdx-relay |
| 港股价格异常 | 数据源错乱 | 检查 data_source 字段,确认 relay 是否覆盖了错误数据 |
| 港股价格用腾讯旧数据 | relay 离线超过 60s 自动回退 | 正常行为,relay 恢复后自动切回 |