diff --git a/docs/系统架构与技术实现.md b/docs/系统架构与技术实现.md new file mode 100644 index 0000000..7e7fb37 --- /dev/null +++ b/docs/系统架构与技术实现.md @@ -0,0 +1,478 @@ +# 系统架构与技术实现 + +> 定位:描述本仓库(OKX 币本位期权实例)的整体架构、运行时、模块划分与关键技术实现。 +> 配套文档: +> - 业务主链:[系统分析-期权主链条.md](./系统分析-期权主链条.md) +> - 盈亏规格:[规格-期权交易账户盈亏结算.md](./规格-期权交易账户盈亏结算.md) +> - 操作说明:[../使用说明.md](../使用说明.md) +> - 部署:[../部署文档.md](../部署文档.md) · 实盘:[实盘说明.md](./实盘说明.md) + +--- + +## 1. 系统定位 + +| 项 | 说明 | +|----|------| +| 角色 | 单交易所实例客户端(OKX),可独立使用,也可挂中控 `crypto_okx_hub` | +| 主业务 | **币本位期权**:USDT → 买 ETH/BTC → 开期权 → 平仓 → 卖回 → 按交易户 USDT 差分冻结盈亏 | +| 非目标 | 不再以永续实盘下单 / USDC 期权开仓 / 对冲计划为主路径(相关代码多已下线或残留) | + +三条控制面: + +```text +┌─────────────┐ ┌──────────────────┐ ┌─────────────────┐ +│ 浏览器面板 │ │ 本机监控守护线程 │ │ 中控 Hub │ +│ /options │ │ options-monitor │ │ /api/hub/* │ +│ /api/options│ │ 目标/翻倍/条件单 │ │ 快照/条件单/全平 │ +└──────┬──────┘ └────────┬─────────┘ └────────┬────────┘ + │ │ │ + └─────────────────────┼────────────────────────┘ + ▼ + Flask app.py(单进程) + │ + ┌──────────────┼──────────────┐ + ▼ ▼ ▼ + SQLite ccxt.okx 模拟 SimBroker + (crypto.db) (实盘/公开行情) (本地撮合) +``` + +--- + +## 2. 技术栈 + +| 层级 | 技术 | 说明 | +|------|------|------| +| 语言 / 运行时 | Python **3.10+** | 见 `README.md` / `requirements.txt` | +| Web 框架 | Flask ≥3、<4 | `threaded=True`;Jinja2 模板 | +| WSGI | Werkzeug | 开发/PM2 直跑 `app.py` | +| 交易所 SDK | **ccxt** ≥4.2(`ccxt.okx`) | 期权 `defaultType=option`;可配 SOCKS | +| HTTP / 代理 | requests、PySocks | `OKX_SOCKS_PROXY` | +| 持久化 | **SQLite** 单文件 | 默认 `DB_PATH=crypto.db` | +| 进程管理 | **PM2** | `ecosystem.config.cjs`:单实例、内存上限约 800M | +| 前端 | **原生 JS/CSS** | 无 React/Vue/`package.json`;静态资源在 `lib/common/static/` | +| 图像 | Pillow | 复盘/日记配图等 | + +部署约定(见部署文档):常见路径 `/opt/crypto_okx`,端口 **`APP_PORT=5004`**(代码未配时 fallback 5000)。 + +--- + +## 3. 仓库与目录结构 + +```text +crypto_okx/ +├── app.py # 应用入口:装配路由、线程、交易所句柄 +├── ecosystem.config.cjs # PM2 +├── requirements.txt +├── .env / .env.example +├── crypto.db # 运行时 SQLite(勿提交) +├── deploy/ # 安装 / 更新 / doctor 脚本 +├── docs/ # 规格、架构、实盘说明 +├── templates/ # Flask 默认模板目录(少量) +├── static/ # 上传等(如 images) +└── lib/ + ├── paths.py # 仓库根、静态/模板路径 + ├── options/ # 期权交易、监控、复盘、结算(核心) + ├── exchange/ # OKX 期权 API 封装、账本适配 + ├── sim/ # 模拟钱包与 API hook + ├── hub/ # 中控 Bridge 鉴权与路由 + ├── env/ # .env 读写、schema、配置页白名单 + ├── instance/ # 壳层 UI、设置、embed、备份、仪表盘 + ├── account_ledger/ # 资金流水同步 + ├── market/ # 行情、K 线、精度 + ├── trade/ # 入场模型/风控等(关键位等周边) + ├── key_monitor/ # 关键位监控 + └── common/ # 公共工具 + static 前端资源 +``` + +原则:**业务按包 install/register 挂到 Flask**,避免全部逻辑堆在 `app.py`;`app.py` 仍保留登录、部分关键位与全局交易所对象。 + +--- + +## 4. 启动与装配顺序 + +### 4.1 引导流程 + +```text +load_env_file(.env) → os.environ + → Flask(__name__) + Session(含中控 iframe SameSite=None/Secure) + → attach_embed_templates / install_common_static + → 构建 ccxt.okx(永续句柄 + options 句柄,可带代理) + → 初始化 SQLite 核心表 + → register_trade_records_api + → register_instance_dashboard_routes # 仪表盘缓存线程 + → install_account_ledger # 账本同步线程 + → register_instance_settings_routes + → start_backup_scheduler # 定时备份线程 + → install_sim_trading # 模拟模式 + hooks + → install_options_trading # 期权路由 + options-monitor + → install_options_review + → install_instance_data_stats # 资金采样线程 + → register_hub_bridge_routes + → register_embed_routes # /embed + live push + → __main__: key-monitor 后台线程 + app.run(threaded=True) +``` + +### 4.2 期权模块装配(要点) + +`install_options_trading`(`lib/options/options_register.py`): + +1. `_build_cfg(app_module)`:注入 DB、交易所、预算、报价/下单回调等。 +2. `register_options_routes`:页面与 `/api/options/*`。 +3. `_register_options_hub_bridge`:把 `options_snapshot_fn` 等写入 `app.config["HUB_CTX"]`。 +4. `_start_monitor_thread`:若 `OKX_OPTIONS_ENABLED`,拉起 `options-monitor`。 + +--- + +## 5. 运行时架构 + +### 5.1 进程模型 + +| 单元 | 数量 | 说明 | +|------|------|------| +| PM2 应用 `crypto_okx` | 1 | `python app.py`,`PYTHONPATH` 指向仓库根 | +| Flask 请求线程 | 多 | `threaded=True` | +| 守护线程 | 多个 | 见下表(均为 daemon) | + +### 5.2 守护线程一览 + +| 线程(逻辑名) | 启动位置 | 职责 | +|----------------|----------|------| +| `background_task` / 关键位监控 | `app.py` `__main__` | 按 `MONITOR_POLL_SECONDS` 轮询关键位规则 | +| `options-monitor` | `options_register` | 目标位平仓、翻倍出场、条件单 tick、持仓同步、卖回扫尾 | +| `okx-backup-scheduler` | `backup_lib` | 定时备份 | +| `account-ledger-okx` | `account_ledger` | 交易所资金流水同步 | +| `instance-dashboard-poll` | dashboard cache | 仪表盘数据缓存 | +| `instance-cash-sample` | data stats | 资金样本 | +| `instance-live-push` | embed live | SSE/推送类 | + +短生命周期线程:日记/复盘异步出图(`journal-chart-*`、`options-review-chart-*`)。 + +### 5.3 配置三层 + +```text +① .env 文件(启动 load + env 页写入) +② os.environ(进程环境) +③ SQLite app_runtime_settings + · trading.mode = sim | live + · display.* 导航显示偏好 + · env. 热更新覆盖(runtime_config_lib) +``` + +读取顺序(热更场景):运行时覆盖 → 环境变量 → 代码默认(`env_ui_manifest._RUNTIME_ENV_DEFAULTS`)。 +部分键改后需 **保存并重启**(见 `env_schema` 的 restart 标记)。 + +--- + +## 6. 分层架构 + +```text +┌──────────────────────────────────────────────────────────┐ +│ 表现层 Jinja 模板 + vanilla JS(options_panel.js 等) │ +├──────────────────────────────────────────────────────────┤ +│ 接入层 Flask routes(options_register / hub / settings) │ +├──────────────────────────────────────────────────────────┤ +│ 领域编排 coin_open / close_exec / cond_order / monitor │ +│ account_pnl / stats / review │ +├──────────────────────────────────────────────────────────┤ +│ 基础设施 okx_options_lib(ccxt) · SQLite · sim broker │ +│ env_file · wechat_notify · backup │ +└──────────────────────────────────────────────────────────┘ +``` + +| 层 | 代表路径 | 职责边界 | +|----|----------|----------| +| 表现 | `lib/options/templates/*`、`lib/common/static/options_*.js` | 交互、轮询、展示口径 | +| 接入 | `options_register.py`、`hub_bridge_register.py`、`instance_settings_register.py` | HTTP、鉴权、参数归一 | +| 编排 | `options_coin_open_lib.py`、`options_close_exec_lib.py`、`options_monitor_lib.py` | 多步业务流程、状态机 | +| 领域规则 | `options_margin_mode_lib.py`、`options_close_gate_lib.py`、`options_account_pnl_lib.py` | 预算、门控、结算真源 | +| 基础设施 | `okx_options_lib.py`、`options_db.py`、`sim/*` | IO 与持久化 | + +--- + +## 7. 核心业务技术实现 + +### 7.1 币本位开仓流水线 + +**入口:** `POST /api/options/open` → `open_coin_option_buy_full` +**尺寸归一:** `_normalize_size_mode`(币本位保留 `budget_full` / `compound_full`;USDC 遗留才落到 `sheets`) + +```text +门禁(模式 / 条件单锁 / 持仓上限 / 可卖币拒开) + → compute_coin_budget_usdt + plan_coin_open_by_budget + → fetch_trading_usdt → trading_usdt_before + → spot_market_buy_coin_with_usdt(× SPOT_BUY_BUFFER) + → options_spot_bridge = bought* + → place_option_limit_order(IOC @ 卖一)+ wait fill + 失败 → 回滚卖币 + 成功 → bridge=holding,写入 options_trades(open, pnl_settled=0) + → 可选 upsert 目标位 / 翻倍出场 / 企微通知 +``` + +关键文件: + +- `lib/options/options_coin_open_lib.py` +- `lib/options/options_spot_bridge_lib.py` +- `lib/options/options_margin_mode_lib.py` +- `lib/options/options_position_limit_lib.py` +- `lib/options/options_account_pnl_lib.py` + +### 7.2 平仓与自动出场 + +| 通道 | 实现 | 门控 | +|------|------|------| +| 手动 / Hub 全平 | `close_option_by_bid1`(`require_recycle_gate=False`) | 流动性 | +| 目标位 | `run_options_target_closes` → `close_option_by_bid_depth` | `options_close_gate_lib`(倍数 + 持续秒数) | +| 翻倍出场 | `run_options_profit_exits` → `close_option_by_bid_profit_exit` | 回收 ≥ 权利金×(1+mult) | + +平仓后:`settle_closed_pnl`(币/费用侧)→ `maybe_sell_spot_after_close` → `try_settle_after_sellback`: + +```text +realized_pnl_usdt = trading_usdt_after − trading_usdt_before +pnl_settled = 1 # 冻结,业务路径不再改写 +``` + +### 7.3 监控循环 + +`options_monitor_loop`(`options_monitor_lib.py`)周期性执行,大致包括: + +- 同步交易所持仓 ↔ 本地 `options_trades`(纠偏误关仓等) +- 跑目标位 / 翻倍 / 条件单 tick +- 平仓后卖回扫尾、推动账户结算 +- 历史盈亏回填(**跳过已冻结 U**) + +轮询间隔受期权相关 poll env / 内部 sleep 控制;与关键位监控线程相互独立。 + +### 7.4 模拟盘技术实现 + +| 组件 | 文件 | 作用 | +|------|------|------| +| 模式 | `sim/mode_lib.py` | `trading.mode` ∈ {sim, live};启动默认 `SIM_DEFAULT_MODE` | +| 撮合 | `sim/broker_lib.py` | `SimBroker`:公开买卖一进本地钱包/仓位 | +| 注入 | `sim/hooks.py` | `apply_sim_hooks` / `patch_options_cfg`:把下单、划转等切到模拟实现 | +| 表 | `sim/db_lib.py` | `sim_wallets`、`sim_option_positions`、`sim_ledger_entries` 等 | + +实盘闸门:`LIVE_TRADING_ENABLED`;模拟下即使有密钥也不应向交易所发真实期权单(由 hook 拦截)。 + +### 7.5 复盘与统计(只读结算真源) + +```text +options_trades(closed + settled) + → review sync → options_review_* + → stats:compute_options_stats_auto / header_options_stats_for_window +``` + +- 复盘:`options_review_lib.py` + `options_review_register.py` +- 统计:`options_stats_lib.py` +- 规则:未 `pnl_settled` 不计已实现;有账户快照的新单只读冻结 U + +--- + +## 8. 交易所集成 + +### 8.1 ccxt 句柄 + +`app.py` 构建: + +- `exchange`:通用 OKX(行情/部分账户) +- `exchange_options`:`defaultType=option` + +期权细节封装:`lib/exchange/okx_options_lib.py` + +| 能力 | 示例 | +|------|------| +| 期权链 | `build_option_chain` | +| 报价 | `quote_option_contract` | +| 下单/撤单/等成交 | `place_option_limit_order`、`wait_option_order_full_fill` | +| 持仓/余额 | `fetch_option_positions`、`fetch_options_balances` | +| 划转 | `transfer_ccy` | +| 流动性 | `option_buy_liquidity_ok`、买一深度裁剪 | + +凭证:`OKX_API_KEY` / `SECRET` / `PASSPHRASE`(遗留 `OKX_OPTIONS_API_*` 可回填)。 +代理:`build_okx_ccxt_proxies()` ← `OKX_SOCKS_PROXY`。 + +### 8.2 账户模式约束 + +程序现货侧按 **合约模式 + cash** 假设编写;跨币种/组合保证金易触发 `tdMode` / `51010`。详见实盘说明。 + +--- + +## 9. 数据模型(SQLite) + +单库文件,多模块 `CREATE TABLE IF NOT EXISTS`。 + +### 9.1 期权核心 + +| 表 | 用途 | +|----|------| +| `options_trades` | 开平流水;`trading_usdt_before/after`、`realized_pnl_usdt`、`pnl_settled` | +| `options_spot_bridge` | 买币/持币/待卖回/关闭 | +| `options_target_monitors` | 指数目标位 | +| `options_cond_orders` | 中控条件单状态机 | +| `options_exchange_pnl_freeze` | 实盘历史盈亏冻结辅助 | +| `options_transfer_log` / `options_convert_log` | 划转等日志 | +| `options_history_hidden` | 历史隐藏 | + +### 9.2 复盘 + +`options_review_trades`、`options_review_entries`、`options_review_sync_state`、`options_review_hidden` + +### 9.3 模拟 + +`sim_wallets`、`sim_option_positions`、`sim_option_orders`、`sim_ledger_entries` 等 + +### 9.4 实例壳层 + +`app_runtime_settings`、`key_monitors`、`trade_records`、`account_ledger_*`、`instance_cash_samples` 等 + +连接约定:业务路径多处 `sqlite3.connect(DB_PATH, timeout=…)` + `Row` factory;长事务与网络 IO 应拆分,避免「持锁等交易所」导致面板超时(历史踩坑点)。 + +--- + +## 10. 鉴权与中控 Bridge + +### 10.1 站点登录 + +| 项 | 实现 | +|----|------| +| 账号 | `APP_USERNAME` / `APP_PASSWORD` | +| Session | `session["logged_in"]`;`APP_SESSION_DAYS`;`FLASK_SECRET_KEY` | +| 装饰器 | `login_required`;`/api/*` 未登录返回 JSON 401 | +| 可关闭 | `APP_AUTH_DISABLED`(仅受信环境) | + +为支持中控 iframe:Cookie `SameSite=None` + `Secure`(按配置)。 + +### 10.2 Hub 鉴权(`lib/hub/hub_bridge_auth.py`) + +| 机制 | 用途 | +|------|------| +| `HUB_BRIDGE_TOKEN` | M2M:`X-Hub-Token` 或 `Bearer`;`hmac.compare_digest` | +| 短时 SSO | `/hub_sso?token=` → 建站内 session(TTL ~120s) | +| 长时 embed | `embed_sso`(约 7 天)应对 iframe 第三方 Cookie 限制 | +| 自动生成 | env 页首次打开可 `ensure_hub_bridge_token` 写入 `.env` | +| CSP | `HUB_EMBED_FRAME_ANCESTORS` → `frame-ancestors` | + +### 10.3 Hub API 面(`hub_bridge_register.py`) + +| 方法 | 路径 | 作用 | +|------|------|------| +| GET | `/api/hub/options/snapshot` | 持仓/资金/条件单/流动性摘要 | +| GET | `/api/hub/options/stats` | 窗口统计 | +| POST | `/api/hub/options/close` | 买一限价**全平** | +| GET/POST | `/api/hub/options/cond_orders` | 条件单 | +| POST | `.../cancel` · `.../exit` | 取消 / 改出场 | +| GET | `/api/hub/version` | 在线与版本 | +| POST | `/api/hub/update` | 远程 pull + PM2 重启 | +| GET | `/api/hub/backup/*` | 备份列表/下载 | + +快照构建:`options_hub_lib.build_options_hub_snapshot`。 + +--- + +## 11. 前端技术实现 + +### 11.1 资源加载 + +`install_common_static` 将 `lib/common/static/` 下白名单文件挂到 `/static/`。 +模板通过 `ChoiceLoader` 合并:`lib/instance/templates`、`lib/options/templates`、`lib/sim/templates` 等。 + +### 11.2 期权前端模块 + +| 文件 | 职责 | +|------|------| +| `options_panel.js` | 链、报价、下单尺寸模式、开平仓、轮询 | +| `options_position_cards.js` | 持仓卡 UI | +| `options_expiry_countdown.js` | 到期倒计时 | +| `options_settings.js` | 设置内期权相关 | +| `options_review.js` | 复盘页 | +| `options_data_stats.js` | 统计展示 | +| `hub_embed_auth.js` | 嵌入鉴权辅助 | +| `instance_settings_prefs.js` | 导航显示等偏好 | + +交互模式:REST 轮询为主(链/持仓/报价);无独立 Node 构建步骤。 + +### 11.3 关键 API 前缀 + +| 前缀 | 模块 | +|------|------| +| `/api/options/*` | 交易面板 | +| `/api/options/review/*` | 复盘 | +| `/api/sim/*` | 模拟资金 | +| `/api/settings/*` | env/显示/密码等 | +| `/api/hub/*` | 中控 | +| `/api/admin/*` | 重启等 | +| `/embed`、`/hub_sso` | 嵌入与 SSO | + +--- + +## 12. 部署与运维技术点 + +| 项 | 实现 | +|----|------| +| 进程 | PM2 `ecosystem.config.cjs`,`instances: 1` | +| 更新 | 本机脚本 / 中控 `POST /api/hub/update`(git pull + restart) | +| 备份 | `backup_lib` 定时 + 设置页手动;中控可下载 | +| 代理 | `OKX_SOCKS_PROXY`;SSH 动态转发不由 PM2 托管 | +| 日志 | PM2 日志 + Werkzeug;可静音 access log | +| 健康 | `deploy/lib/doctor.sh`;中控看 `/api/hub/version` | + +--- + +## 13. 关键设计决策(实现层) + +| 决策 | 原因 | 落点 | +|------|------|------| +| 单进程 + 多守护线程 | 部署简单、与 SQLite 单写者模型匹配 | PM2 instances=1 | +| 盈亏真源=交易户 USDT 差分 | 与钱包可对账、避免指数重算漂移 | `options_account_pnl_lib` | +| 一次一仓默认 | 差分对账前提 | `OKX_OPTIONS_MAX_ACTIVE_POSITIONS=1` | +| 现货桥表 | 买币/卖回与期权生命周期解耦可重试 | `options_spot_bridge` | +| Sim hook 而非第二套 UI | 同一面板切模拟/实盘 | `sim/hooks.py` | +| Hub Token + SSO 双通道 | 机器调用与 iframe 人机登录分离 | `hub_bridge_auth` | +| 前端无框架 | 运维机交付简单、无构建链 | `lib/common/static` | +| USDC 开仓下线 | 主路径币本位 | margin mode 固定 coin | + +--- + +## 14. 扩展与修改指引 + +1. **新开仓入口**:必须接条件单锁、持仓上限、可卖币检查、before 快照。 +2. **新统计展示**:只消费 `pnl_settled` 冻结值;勿在展示层重算账户差分。 +3. **新自动平仓**:明确是否走 close_gate;与手动通道权限分开。 +4. **改 env 默认**:同步代码默认、`env_ui_manifest` 文案与 `_RUNTIME_ENV_DEFAULTS`。 +5. **避免在持 DB 锁时调交易所**:网络与写库分阶段,防止面板 API 超时。 +6. **中控协议变更**:同步 `hub_bridge_register`、快照 `version` 与中控仓库解析逻辑。 + +--- + +## 15. 关键文件索引 + +| 主题 | 路径 | +|------|------| +| 入口 | `app.py` | +| 路径常量 | `lib/paths.py` | +| 期权路由/监控启动 | `lib/options/options_register.py` | +| 监控循环 | `lib/options/options_monitor_lib.py` | +| 开仓 | `lib/options/options_coin_open_lib.py` | +| 现货桥 | `lib/options/options_spot_bridge_lib.py` | +| 平仓执行 | `lib/options/options_close_exec_lib.py` | +| 账户结算 | `lib/options/options_account_pnl_lib.py` | +| 条件单 | `lib/options/options_cond_order_lib.py` | +| Hub 快照 | `lib/options/options_hub_lib.py` | +| Hub 路由/鉴权 | `lib/hub/hub_bridge_register.py`、`hub_bridge_auth.py` | +| 交易所 | `lib/exchange/okx_options_lib.py` | +| 模拟 | `lib/sim/register.py`、`hooks.py`、`broker_lib.py` | +| Env UI | `lib/env/env_ui_manifest.py`、`env_schema.py` | +| 静态资源注册 | `lib/instance/instance_static_lib.py` | +| PM2 | `ecosystem.config.cjs` | + +--- + +## 16. 文档关系 + +```text +使用说明.md ← 操作员怎么用 +实盘说明.md ← 交易所前置与实盘开关 +规格-…盈亏结算.md ← 盈亏产品规则(真源) +系统分析-期权主链条.md ← 业务功能链与数据流 +本文 ← 软件架构与技术实现 +部署文档.md ← 安装运维 +```