# 技术文档(gold_monitor) ## 1. 架构 ``` Browser (复盘大屏) ──SSE/HTTP:5800──► Flask(gunicorn threads) + SQLite ▲ Windows exe (心跳约2s + 成交上报) ───────┘ │ └── MetaTrader5 (本机) 总览秒级:`GET /api/dashboard/stream`(SSE,约 1 秒一帧);在线判定约 8 秒无心跳为离线。 ``` - **不直连数据库**:多机只走 HTTP API。 - **通用包 + 首次激活**:下载同一 exe;激活后获得 `token` 绑定 `account_id` / `machine_id`。 ## 2. 技术栈 | 层 | 选型 | |----|------| | Web/API | Flask 3 + Jinja2 | | 进程 | gunicorn + PM2 | | 存储 | SQLite(`data/gold_monitor.db`) | | 前端复盘图 | 自研轻量 canvas 蜡烛图(无 CDN 依赖) | | 客户端 | Python/Tk + MetaTrader5(见 `desktop/`,逻辑迁移自既有方案) | ## 3. 主要数据表 | 表 | 用途 | |----|------| | `users` | 登录用户:`role`=admin/user,普通用户必绑唯一 `account_id` | | `accounts` | 交易账户与标注(仅管理员创建,禁止自助注册) | | `machines` | 机器、指纹、在线时间 | | `activations` | 激活码、token、状态、`created_by` 发放人 | | `trades` | 成交与复盘字段(entry_style / review_note / snapshot_json) | | `bars` | K 线缓存(symbol+timeframe+ts 唯一) | **权限**:管理员看全部;普通用户复盘/激活码仅限自己的 `account_id`。激活码可由 admin 与 user 发放(user 仅自己账户)。 ## 4. HTTP API ### 健康检查 `GET /health` → `{ ok, service, port }` ### 激活 `POST /api/v1/activate` ```json { "code": "xxxx", "fingerprint": "stable-machine-id", "machine_name": "书房PC" } ``` 响应:`{ ok, token, account_id, machine_id, public_base }` ### 心跳 `GET /api/v1/ping` Header:`X-Device-Token: ` ### 上报成交 `POST /api/v1/trades` Header:`X-Device-Token` ```json { "ticket": "2700219994", "symbol": "XAUUSDm", "side": "buy", "volume": 0.1, "open_price": 4175.02, "close_price": 4178.10, "open_time": 1729000000, "close_time": 1729001000, "profit": 12.5, "sl": 4170.0, "tp": 4190.0, "entry_style": "", "snapshot": { "m15_dir": 1, "m1_engulf": true } } ``` ### 上报 / 查询 K 线 `POST /api/v1/bars`(需 token) ```json { "symbol": "XAUUSDm", "timeframe": "M15", "bars": [ { "ts": 1729000000, "open": 1, "high": 2, "low": 0.5, "close": 1.5, "volume": 0 } ] } ``` `GET /api/v1/bars?symbol=&timeframe=&start=&end=`(需网页登录 Session) ## 5. 安全建议 - 修改默认管理员密码与 `FLASK_SECRET_KEY` - 仅局域网开放 5800;如需外网务必加 HTTPS 反代与强密码 - 激活码一次性绑定后状态为 `active`;可在后续版本增加作废接口 - token 等同设备凭证,泄露需重新签发 ## 6. 目录与入口 | 路径 | 说明 | |------|------| | `wsgi.py` | 应用入口 | | `app/factory.py` | create_app | | `app/routes.py` | 页面与 API | | `app/db.py` | SQLite 访问 | | `deploy/ecosystem.config.cjs` | PM2 | | `deploy/manage.sh` | 交互部署 | ## 7. 用户与密码 - 表 `users`:密码为 Werkzeug hash;首次启动用 `.env` 的 `ADMIN_USER` / `ADMIN_PASSWORD` 种子管理员 - 网页「系统设置」改当前用户密码,**不写回 .env** - 普通用户由管理员在 `/users` 创建并绑定账户 ## 8. 客户端(desktop/) | 文件 | 说明 | |------|------| | `gold_order_app.py` | 下单主程序;含「打开复盘」→ 浏览器 `/login` | | `activation_dialog.py` | 首次激活 UI | | `hub_client.py` | HTTP 激活/上报 | | `device_store.py` | `~/.gold_monitor/device.json` | 开仓/平仓成功返回 `(消息, report_dict)`,后台线程上报 trades + 四周期 bars。 ## 9. 企业微信推送 - 模块:`app/wecom.py`(Webhook 文本消息);`app/scheduler.py`(北京时间日报,默认 23:00) - 配置:网页系统设置(管理员)或 `.env` 的 `WECOM_WEBHOOK_URL` / `WECOM_DAILY_HOUR` - 触发:`POST /api/v1/trades` 且 `snapshot.event` 为 `open` / `close` / `history_close`(浮盈与改单不推) - 多 worker:日报用 `data/wecom_daily_YYYY-MM-DD.sent` 锁文件去重 ## 10. 后续扩展(规划) - 复盘筛选、统计面板、AI 点评(可对齐 crypto_monitor) - PostgreSQL 替换 SQLite(多写高并发时) - Nginx 反代与 HTTPS