From d663147264d0fc97e9e7ddbd4aeee69e833ad025 Mon Sep 17 00:00:00 2001
From: Administrator <15274802129@163.com>
Date: Tue, 02 Jun 2026 15:14:02 +0800
Subject: [PATCH] fix(okxNewPrice): 修复合约面值配置错误并更新文档

---
 src/main/java/com/xcong/excoin/modules/okxNewPrice/OKX网格策略架构文档.md |  469 +++++++++++++++++++++++++++++++++++++---------------------
 1 files changed, 297 insertions(+), 172 deletions(-)

diff --git "a/src/main/java/com/xcong/excoin/modules/okxNewPrice/OKX\347\275\221\346\240\274\347\255\226\347\225\245\346\236\266\346\236\204\346\226\207\346\241\243.md" "b/src/main/java/com/xcong/excoin/modules/okxNewPrice/OKX\347\275\221\346\240\274\347\255\226\347\225\245\346\236\266\346\236\204\346\226\207\346\241\243.md"
index ebd8fa0..e141645 100644
--- "a/src/main/java/com/xcong/excoin/modules/okxNewPrice/OKX\347\275\221\346\240\274\347\255\226\347\225\245\346\236\266\346\236\204\346\226\207\346\241\243.md"
+++ "b/src/main/java/com/xcong/excoin/modules/okxNewPrice/OKX\347\275\221\346\240\274\347\255\226\347\225\245\346\236\266\346\236\204\346\226\207\346\241\243.md"
@@ -4,105 +4,246 @@
 
 ```
 okxNewPrice/
-├── OkxConfig.java              # 全局配置(Builder模式)
-├── OkxGridTradeService.java    # 核心策略引擎
-├── OkxTradeExecutor.java       # REST API 异步执行器
-├── OkxGridElement.java         # 网格价格层级 + 8个全局O(1)索引
-├── OkxTraderParam.java         # 单笔挂单参数
-├── OkxGridWsClient.java        # WebSocket 客户端(双连接)
-├── OkxWebSocketClientManager.java  # Spring容器入口 + WS组装
+├── OkxConfig.java              # 全局配置(Builder模式,策略唯一参数入口)
+├── OkxGridTradeService.java    # 核心策略引擎(状态机 + 事件驱动循环)
+├── OkxTradeExecutor.java       # REST API 异步执行器(单线程池 + 背压)
+├── OkxGridElement.java         # 网格价格层级 + 8个全局O(1)静态索引
+├── OkxTraderParam.java         # 单笔挂单参数(方向/触发价/数量/订单ID)
+├── OkxGridWsClient.java        # WebSocket 客户端(双连接:business + private)
+├── OkxWebSocketClientManager.java  # Spring容器入口 + Bean组装 + 生命周期
 ├── ExchangeInfoEnum.java       # 账户枚举
 │
 ├── gridWs/
-│   ├── OkxGridChannelHandler.java       # 频道处理器接口
-│   ├── OkxKlineChannelHandler.java      # candle1m → onKline()
-│   ├── OkxPositionsChannelHandler.java  # positions → onPositionUpdate()
-│   ├── OkxOrdersChannelHandler.java     # orders → onOrderUpdate()(替代orders-algo)
-│   └── OkxAlgoOrdersChannelHandler.java # orders-algo(测试网不可用,保留备用)
+│   ├── OkxGridChannelHandler.java        # 频道处理器接口
+│   ├── OkxKlineChannelHandler.java       # candle1m → onKline(closePrice)
+│   ├── OkxPositionsChannelHandler.java   # positions → onPositionUpdate()
+│   ├── OkxOrdersChannelHandler.java      # orders → onOrderUpdate() (替代orders-algo)
+│   └── OkxAlgoOrdersChannelHandler.java  # orders-algo(测试网60018不可用,备用)
 │
-└── okxpi/config/              # OKX API 底层HTTP/签名工具
+└── okxpi/config/              # OKX V5 API 底层HTTP签名/请求工具链
+    ├── Account.java / OKXAccount.java
+    ├── RequestHandler.java / ResponseHandler.java
+    └── utils/ (SignUtils, UrlBuilder, OkHttpUtils...)
 ```
 
-## 二、策略生命周期
+## 二、Spring 容器入口
 
-```
-┌─────────────────────────────────────────────────────────────────┐
-│  init() → startGrid() → WAITING_KLINE                          │
-│    ↓                                                            │
-│  onKline(首根K线) → OPENING → 市价双开基底                      │
-│    ├── openLong(baseQuantity张)                                 │
-│    └── openShort(baseQuantity张)                                │
-│    ↓                                                            │
-│  onPositionUpdate() → 双基底成交 → tryGenerateQueues()          │
-│    ├── generateShortQueue()   空仓队列(基准价向下步进)         │
-│    ├── generateLongQueue()    多仓队列(基准价向上步进)         │
-│    ├── updateGridElements()   构建OkxGridElement双向链表         │
-│    ├── 多仓止损 -2~-11: algo(sell+long, slTriggerPx, sz=qty)   │
-│    └── 空仓止损  2~11: algo(buy+short, slTriggerPx, sz=qty)    │
-│    ↓                                                            │
-│  state = ACTIVE                                                 │
-└─────────────────────────────────────────────────────────────────┘
+`OkxWebSocketClientManager` 是 `@Component + @PostConstruct` 驱动的组装点。
+
+### 2.1 激活条件
+
+```yaml
+# application-test.yml
+app:
+  quant: true   # @ConditionalOnProperty 控制是否启动
 ```
 
-### 状态机
-
-| 状态 | 含义 | 进入条件 |
-|------|------|---------|
-| `WAITING_KLINE` | 等待首根K线 | startGrid() |
-| `OPENING` | 基底开仓中 | 首根K线到达 |
-| `ACTIVE` | 策略运行中 | 网格初始化完成 |
-| `STOPPED` | 已停止(等待重启) | 盈亏达标/持仓归零 |
-
-## 三、WS连接架构
+### 2.2 初始化顺序 (@PostConstruct)
 
 ```
-┌──────────────────────────────────────────────────────┐
-│  OkxWebSocketClientManager (@PostConstruct)           │
-│                                                       │
-│  ┌─ gridWsClientPublic ───────────────────────────┐  │
-│  │  URL: /ws/v5/business  (无需登录,直连订阅)     │  │
-│  │  ├── OkxKlineChannelHandler (candle1m)          │  │
-│  └────────────────────────────────────────────────┘  │
-│                                                       │
-│  ┌─ gridWsClientPrivate ──────────────────────────┐  │
-│  │  URL: /ws/v5/private  (先登录再订阅)           │  │
-│  │  ├── OkxPositionsChannelHandler (positions)     │  │
-│  │  └── OkxOrdersChannelHandler (orders)           │  │
-│  └────────────────────────────────────────────────┘  │
-└──────────────────────────────────────────────────────┘
+1. ExchangeInfoEnum 取首个账户
+2. 构建 OkxAccount(baseUrl + apiKey/secretKey/passphrase)
+3. OkxConfig.builder() 构建配置(BTC-USDT-SWAP, 100x, cross, gridRate=0.001)
+4. OkxGridTradeService.init()
+   ├── GET /api/v5/account/balance → 取 USDT details[].eq 作为初始本金
+   ├── POST /api/v5/trade/cancel-algos → 清旧条件单
+   ├── GET /api/v5/account/positions → 遍历平已有仓位
+   └── POST /api/v5/account/set-leverage → 设置杠杆
+5. 创建双 WS 客户端并注册频道处理器:
+   ├── gridWsClientPublic  → /v5/business  → candle1m (无需登录)
+   └── gridWsClientPrivate → /v5/private   → positions + orders (先登录)
+6. gridTradeService.startGrid() → WAITING_KLINE
 ```
 
-| 连接 | URL | 频道 | 是否登录 | 回调 |
-|------|-----|------|---------|------|
-| 业务WS | `/ws/v5/business` | `candle1m` | 否 | `onKline(closePrice)` |
-| 私有WS | `/ws/v5/private` | `positions` | 是 | `onPositionUpdate(instId, posSide, pos, avgPx)` |
-| 私有WS | `/ws/v5/private` | `orders` | 是 | `onOrderUpdate(algoId, state, ordType)` |
-
-> **注意**:`orders-algo` 频道在测试网不可用(60018),已替换为 `orders` 频道。algo触发后生成普通订单,fill数据中带 `algoId` 字段可匹配回原始条件单。
-
-## 四、网格ID体系
+### 2.3 销毁顺序 (@PreDestroy)
 
 ```
-价格方向:  低 ←────────────────── 基准价 ──────────────────→ 高
-ID:        -N ... -3  -2  -1    0    1   2   3 ... N
-用途:      多仓止损区           基底     空仓止损区
-           (初始化: -2~-11)           (初始化: 2~11)
+stopGrid() → cancelAllAlgoOrders + shutdown → gridWsClientPublic.destroy() → gridWsClientPrivate.destroy()
+```
+
+### 2.4 当前活跃配置
+
+| 参数 | 值 | 说明 |
+|------|-----|------|
+| `instId` | `BTC-USDT-SWAP` | 合约 |
+| `leverage` | `100` | 杠杆 |
+| `tdMode` | `cross` | 全仓 |
+| `gridRate` | `0.001` | 网格间距 0.1% |
+| `expectedProfit` | `20` USDT | 盈亏达标重置线 |
+| `maxLoss` | `30` USDT | 亏损风控告警线 |
+| `quantity` | `1` | 每格下单张数 |
+| `baseQuantity` | `10` | 基底开仓张数 |
+| `priceScale` | `2` | 价格精度 |
+| `ctVal` | `0.1` | 合约面值 |
+| `gridQueueSize` | `300` | 价格队列容量 |
+
+## 三、WS 连接架构
+
+```
+┌──────────────────────────────────────────────────────────┐
+│                 OkxWebSocketClientManager                │
+│                                                          │
+│  gridWsClientPublic (isPublic=true)                     │
+│  ├── URL: wss://wspap.okx.com:8443/ws/v5/business       │
+│  ├── 连接后立即 subscribeAllHandlers()(无需登录)       │
+│  └── OkxKlineChannelHandler(candle1m, instId)            │
+│                                                          │
+│  gridWsClientPrivate (isPublic=false)                    │
+│  ├── URL: wss://wspap.okx.com:8443/ws/v5/private        │
+│  ├── 连接后 wsLogin() → 登录成功 → subscribeAllHandlers()│
+│  ├── OkxPositionsChannelHandler(positions, instType:SWAP)│
+│  └── OkxOrdersChannelHandler(orders, instType:SWAP)     │
+└──────────────────────────────────────────────────────────┘
+```
+
+| 连接 | URL | 频道 | 订阅参数 | 回调方法 |
+|------|-----|------|---------|---------|
+| business | `/v5/business` | `candle1m` | `instId` | `onKline(closePrice)` |
+| private | `/v5/private` | `positions` | `instType:SWAP` | `onPositionUpdate(instId, posSide, pos, avgPx)` |
+| private | `/v5/private` | `orders` | `instType:SWAP` | `onOrderUpdate(algoId, state, ordType)` |
+
+> **orders 频道替代 orders-algo**:`orders-algo` 在测试网不可用(60018),改订阅 `orders` 频道。
+> algo 触发后生成普通市价单,fill 数据中 `algoId` 字段非空时可匹配回原始条件单。
+> `OkxOrdersChannelHandler` 过滤逻辑:`state=filled` AND `algoId` 非空。
+
+### 3.1 心跳机制
+
+```
+10s 无消息 → send("ping") → server reply "pong" → 重置计时器
+25s 定时检查 → 超时则 send("ping")
+LostConnectionChecker: setConnectionLostTimeout(0) 已关闭(协议级ping OKX不响应)
+```
+
+## 四、策略生命周期
+
+### 4.1 状态机
+
+| 状态 | 含义 | 进入条件 | 退出动作 |
+|------|------|---------|---------|
+| `WAITING_KLINE` | 等待首根K线 | startGrid() | 首根K线→OPENING |
+| `OPENING` | 基底开仓中 | 首根K线 | 双基底成交→ACTIVE |
+| `ACTIVE` | 策略运行 | 网格初始化完成 | 盈亏达标/持仓归零→STOPPED |
+| `STOPPED` | 已停止 | 重置/达标 | 下根K线自动 startGrid() |
+
+### 4.2 完整流程
+
+```
+┌──────────────────────────────────────────────────────────────┐
+│  init() → startGrid() → WAITING_KLINE                       │
+│    ↓                                                         │
+│  onKline(首根) → OPENING → executor.openLong/Short(10张)     │
+│    ↓                                                         │
+│  onPositionUpdate → 基底成交 → tryGenerateQueues()           │
+│    ├── generateShortQueue(): shortBasePrice - step 向下步进  │
+│    ├── generateLongQueue():  shortBasePrice + step 向上步进  │
+│    ├── updateGridElements(): 构建 601个 OkxGridElement       │
+│    │   ├── ID≤-1: 空仓区(降序)  ID=0:基底  ID≥1:多仓区(升序)│
+│    │   └── ID索引 + 价格索引 + 6个订单ID索引 (O(1))          │
+│    ├── 多仓止损 -2~-11: POST order-algo                      │
+│    │   ordType=conditional, side=sell, posSide=long,         │
+│    │   slTriggerPx=网格价, slOrdPx=-1, sz=quantity           │
+│    └── 空仓止损 +2~+11: POST order-algo                      │
+│        ordType=conditional, side=buy, posSide=short,         │
+│        slTriggerPx=网格价, slOrdPx=-1, sz=quantity           │
+│    ↓                                                         │
+│  state = ACTIVE ─────────────────────────────────────────────│
+└──────────────────────────────────────────────────────────────┘
+```
+
+## 五、事件驱动循环 (ACTIVE 状态)
+
+### 5.1 K线回调 `onKline(closePrice)`
+
+```
+lastKlinePrice = closePrice
+updateUnrealizedPnl()
+
+if STOPPED:
+    cancelAllAlgoOrders() + closeExistingPositions() + startGrid() → WAITING_KLINE
+
+if WAITING_KLINE:
+    市价双开 baseQuantity 张 (openLong + openShort) → OPENING
+
+if ACTIVE:
+    checkProfitAndReset()  // 每根K线检查盈亏达标
+```
+
+### 5.2 仓位推送 `onPositionUpdate`
+
+```
+long 有仓位:
+  首次(基底) → 记录 baseLongOpened + 均价 → tryGenerateQueues()
+  后续       → 更新 positionSize / entryPrice
+  归零       → handlePositionZeroAndReset("多仓")
+
+short 有仓位:
+  首次(基底) → 记录 baseShortOpened + 均价 → tryGenerateQueues()
+  后续       → 更新 positionSize / entryPrice
+  归零       → handlePositionZeroAndReset("空仓")
+```
+
+### 5.3 订单成交 `onOrderUpdate(algoId, state, ordType)` — 核心事件
+
+触发条件:`state == "filled"` (来自 `orders` 频道的成交推送)
+
+```
+                    ┌─ findByLongStopLossOrderId(algoId)
+                    │  → handleLongStopLossTriggered()
+                    │    止损-ID=-N → 清空止损ID
+                    │    → 在 -(N-1) 挂 count×qty 张多单
+                    │       (ordType=trigger, triggerPx, orderPx=-1)
+                    │    → N>2 时取消 -(N-2) 旧多单
+                    │
+                    ├─ findByShortStopLossOrderId(algoId)
+                    │  → handleShortStopLossTriggered()
+                    │    止损ID=N → 清空止损ID
+                    │    → 在 N-1 挂 count×qty 张空单
+                    │       (ordType=trigger, triggerPx, orderPx=-1)
+                    │    → N>2 时取消 N-2 旧空单
+algoId 匹配 ────────┤
+                    ├─ findByShortOrderId(algoId) && hasShortOrder
+                    │  → shortEntryTraderIdParam(null, false)
+                    │  → extendShortStopLoss(filledQty)
+                    │    到最远空仓止损外扩 stopLossCount 个网格
+                    │    每格挂 quantity 张止损
+                    │
+                    └─ findByLongOrderId(algoId) && hasLongOrder
+                       → longEntryTraderIdParam(null, false)
+                       → extendLongStopLoss(filledQty)
+                         到最远多仓止损外扩 stopLossCount 个网格
+                         每格挂 quantity 张止损
+```
+
+### 5.4 平仓推送 `onPositionClose`
+
+```
+cumulativePnl += pnl
+总盈亏 ≤ -maxLoss → 钉钉告警(仅通知,不停止)
+```
+
+## 六、网格ID体系
+
+```
+价格方向:  低 ←────────────── 基底价 ──────────────→ 高
+ID:        ... -3  -2  -1    0    1   2   3 ...
+用途:      多仓止损/追单区    基底    空仓止损/追单区
+           初始化止损:-2~-11        初始化止损:2~11
 
 链表: ... ← -3 ← -2 ← -1 ← 0 → 1 → 2 → 3 → ...
-         (通过 upId/downId + INDEX 实现 O(1) 遍历)
+      (upId/downId + INDEX → O(1) 遍历)
 ```
 
-### GridElement 字段
+### 6.1 GridElement 字段
 
 | 类别 | 字段 | 说明 |
 |------|------|------|
 | 标识 | `id`, `gridPrice`, `upId`, `downId` | 编号、价格、双向链表指针 |
-| 多仓订单 | `hasLongOrder`, `longOrderId`, `longTraderParam` | 多仓条件单状态 |
-| 空仓订单 | `hasShortOrder`, `shortOrderId`, `shortTraderParam` | 空仓条件单状态 |
+| 多仓 | `hasLongOrder`, `longOrderId`, `longTraderParam` | 多仓挂单状态 |
+| 空仓 | `hasShortOrder`, `shortOrderId`, `shortTraderParam` | 空仓挂单状态 |
 | 止盈 | `longTakeProfitOrderId`, `shortTakeProfitOrderId` | 止盈algoId |
 | 止损 | `longStopLossOrderId`, `shortStopLossOrderId` | 止损algoId |
 
-### 8个全局O(1)索引
+### 6.2 8个全局O(1)索引
 
 ```
 INDEX                  → findById(int)
@@ -115,134 +256,118 @@
 SHORT_SL_ORDER_ID_INDEX→ findByShortStopLossOrderId(String)
 ```
 
-## 五、事件驱动循环(ACTIVE状态)
+每次订单状态变更后调用 `OkxGridElement.refreshIndices()` 增量重建,同时 `logAll()` 打印全量网格数据。
 
-### 5.1 K线回调 `onKline(closePrice)`
+## 七、关键公式
+
+### 7.1 网格步长
 
 ```
-更新 lastKlinePrice → updateUnrealizedPnl()
-→ STOPPED: 清条件单+平仓+startGrid()
-→ WAITING_KLINE: 市价双开基底
-→ ACTIVE: checkProfitAndReset()(每根K线检查盈亏达标)
+step = shortBaseEntryPrice × gridRate    (priceScale 精度对齐)
 ```
 
-### 5.2 仓位推送 `onPositionUpdate(instId, posSide, posSize, avgPx)`
-
-```
-基底首次成交 → tryGenerateQueues()
-后续仓位变化 → 更新 positionSize/entryPrice
-仓位归零     → handlePositionZeroAndReset()
-```
-
-### 5.3 订单成交 `onOrderUpdate(algoId, state, ordType)`
-
-```
-state == "filled" 时:
-
-  ┌─ findByLongStopLossOrderId(algoId) → handleLongStopLossTriggered()
-  │   清空止损ID → grid -(N-1) 挂 count×qty 张多单
-  │              → 若 N>2, 取消 grid -(N-2) 旧多单
-  │
-  ├─ findByShortStopLossOrderId(algoId) → handleShortStopLossTriggered()
-  │   清空止损ID → grid N-1 挂 count×qty 张空单
-  │              → 若 N>2, 取消 grid N-2 旧空单
-  │
-  ├─ findByShortOrderId(algoId) → extendShortStopLoss(filledQty)
-  │   从最远空仓止损向外扩展 stopLossCount 个网格止损
-  │
-  └─ findByLongOrderId(algoId) → extendLongStopLoss(filledQty)
-      从最远多仓止损向外扩展 stopLossCount 个网格止损
-```
-
-### 5.4 平仓推送 `onPositionClose(side, pnl)`
-
-```
-cumulativePnl += pnl
-→ 总盈亏 ≤ -maxLoss → 钉钉告警(不停止,仅通知)
-```
-
-## 六、关键公式
-
-### 6.1 网格步长
-
-```
-step = shortBaseEntryPrice × gridRate    (对齐到 priceScale 精度)
-```
-
-### 6.2 止损触发 → 追单数量
+### 7.2 止损触发 → 追单
 
 ```
 priceDiff = |avgEntryPrice - newEntryGridPrice|.abs()
-count     = priceDiff / step  (DOWN取整, 最小1)
-entryQty  = count × quantity
+count     = priceDiff / step           (RoundingMode.DOWN, 最小1)
+entryQty  = count × quantity           → 挂 ordType=trigger 条件单
 ```
 
-### 6.3 挂单成交 → 追挂止损
+### 7.3 挂单成交 → 追挂止损
 
 ```
 stopLossCount = filledQty / quantity
-从最远止损ID向外扩展 stopLossCount 个网格,每格挂 1个 quantity张的止损单
+从最远止损ID向外扩展 stopLossCount 个网格
+每格挂 1 个 quantity 张止损 (ordType=conditional, slTriggerPx)
 ```
 
-### 6.4 未实现盈亏
+### 7.4 未实现盈亏
 
 ```
-多仓Pnl = longPositionSize × ctVal × (lastKlinePrice - longEntryPrice)
-空仓Pnl = shortPositionSize × ctVal × (shortEntryPrice - lastKlinePrice)
-unrealizedPnl = 多仓Pnl + 空仓Pnl
+longPnl  = longPositionSize × ctVal × (lastKlinePrice - longEntryPrice)
+shortPnl = shortPositionSize × ctVal × (shortEntryPrice - lastKlinePrice)
+unrealizedPnl = longPnl + shortPnl
 ```
 
-### 6.5 盈亏达标检查
+### 7.5 盈亏达标检查
 
 ```
-upl + availEq > initialPrincipal + expectedProfit  →  重置策略
+GET balance → upl (未实现盈亏) + availEq (可用保证金)
+if upl + availEq > initialPrincipal + expectedProfit → STOPPED → 平仓+清条件单+startGrid()
 ```
 
-## 七、REST API 映射
+## 八、REST API 映射
 
-| OkxTradeExecutor方法 | OKX API | 用途 |
-|------|---------|------|
-| `openLong(size)` / `openShort(size)` | `POST /api/v5/trade/order` (market) | 市价基底开仓 |
-| `marketClose(side, posSide, sz)` | `POST /api/v5/trade/order` (market, reduceOnly) | 市价平仓 |
-| `placeConditionalEntryOrder(tp, side, posSide, sz)` | `POST /api/v5/trade/order-algo` (triggerPx) | 条件开仓单 |
-| `placeTakeProfit(tp, side, posSide, sz)` | `POST /api/v5/trade/order-algo` (slTriggerPx) | 止损/止盈条件单 |
-| `cancelAlgoOrder(algoId)` | `POST /api/v5/trade/cancel-algos` | 取消单个条件单 |
-| `getBalance()` | `GET /api/v5/account/balance` | 查询余额 |
-| `getPositions()` | `GET /api/v5/account/positions` | 查询持仓 |
-| `setLeverage(lever)` | `POST /api/v5/account/set-leverage` | 设置杠杆 |
+| 方法 | OKX API | ordType | 触发参数 | 用途 |
+|------|---------|---------|---------|------|
+| `openLong(size)` | `POST /api/v5/trade/order` | `market` | — | 市价开多 |
+| `openShort(size)` | `POST /api/v5/trade/order` | `market` | — | 市价开空 |
+| `marketClose(s,p,sz)` | `POST /api/v5/trade/order` | `market` | reduceOnly | 市价平仓 |
+| `placeConditionalEntryOrder` | `POST /api/v5/trade/order-algo` | **`trigger`** | `triggerPx` | 计划委托开仓 |
+| `placeTakeProfit` | `POST /api/v5/trade/order-algo` | **`conditional`** | `slTriggerPx` | 止损/止盈平仓 |
+| `cancelAlgoOrder(id)` | `POST /api/v5/trade/cancel-algos` | — | array body | 取消单个条件单 |
+| `cancelAllAlgoOrders()` | `POST /api/v5/trade/cancel-algos` | — | array body | 清除全部条件单 |
+| `getBalance()` | `GET /api/v5/account/balance` | — | ccy=USDT | 查询余额 |
+| `getPositions()` | `GET /api/v5/account/positions` | — | instId | 查询持仓 |
+| `setLeverage(l)` | `POST /api/v5/account/set-leverage` | — | lever+mgnMode | 设置杠杆 |
 
-## 八、配置参数(OkxConfig.Builder默认值)
+### 8.1 ordType 对照表
 
-| 参数 | 默认值 | 说明 |
-|------|--------|------|
-| `instId` | `ETH-USDT-SWAP` | 合约名称 |
-| `leverage` | `100` | 杠杆倍数 |
-| `tdMode` | `cross` | 全仓保证金 |
-| `gridRate` | `0.0025` | 网格间距 0.25% |
-| `expectedProfit` | `2` | 预期收益 2 USDT |
-| `maxLoss` | `15` | 最大亏损 15 USDT |
-| `quantity` | `1` | 每格下单张数 |
-| `baseQuantity` | `10` | 基底开仓张数 |
-| `priceScale` | `2` | 价格精度 |
-| `ctVal` | `0.1` | 合约面值 |
-| `gridQueueSize` | `300` | 队列容量 |
-| `marginRatioLimit` | `0.2` | 保证金占比上限 20% |
+| ordType | OKX含义 | 我们用途 | 触发价参数 |
+|---------|--------|---------|-----------|
+| `trigger` | 计划委托 | **开仓挂单**(等价格到位开仓) | `triggerPx` |
+| `conditional` | 单向止盈止损 | **止损单**(等价格到位平仓) | `slTriggerPx` |
 
-## 九、线程模型
+## 九、网格ID示例(BTC-USDT, step≈70)
 
 ```
-WS回调线程(串行)             Executor线程(单线程池)
-  │                              │
-  ├─ onKline()                   ├─ openLong/openShort
-  ├─ onPositionUpdate()          ├─ marketClose
-  ├─ onOrderUpdate() ──下单──→   ├─ placeConditionalEntryOrder
-  │                              ├─ placeTakeProfit
-  │                              └─ cancelAlgoOrder
+ID=-11  price=69309.67 ← 最远多仓止损
+ID=-10  price=69379.97
+ID= -9  price=69450.27
+ID= -8  price=69520.57
+ID= -7  price=69590.87
+ID= -6  price=69661.17
+ID= -5  price=69731.47
+ID= -4  price=69801.77
+ID= -3  price=69872.07
+ID= -2  price=69942.37  ← 多仓止损起点
+ID= -1  price=70012.67
+ID=  0  price=70082.97  ← 基底 (shortBaseEntryPrice)
+ID=  1  price=70153.27
+ID=  2  price=70223.57  ← 空仓止损起点
+ID=  3  price=70293.87
+ID=  4  price=70364.17
+ID=  5  price=70434.47
+ID=  6  price=70504.77
+ID=  7  price=70575.07
+ID=  8  price=70645.37
+ID=  9  price=70715.67
+ID= 10  price=70785.97
+ID= 11  price=70856.27  ← 最远空仓止损
+```
+
+## 十、线程模型
+
+```
+[ctReadThread-XX] WS回调线程(串行)     [okx-trade-worker] Executor(单线程池)
+  │                                        │
+  ├─ onKline(closePrice)                   ├─ openLong / openShort
+  │   └─ updateUnrealizedPnl()             ├─ marketClose
+  │   └─ checkProfitAndReset()(同步REST)   ├─ placeConditionalEntryOrder (trigger)
+  │                                        ├─ placeTakeProfit (conditional)
+  ├─ onPositionUpdate(...)                 └─ cancelAlgoOrder / cancelAllAlgoOrders
+  │   └─ tryGenerateQueues() → 批量挂止损
+  │   └─ handlePositionZeroAndReset()
   │
-  └─ checkProfitAndReset() (REST同步查余额)
+  └─ onOrderUpdate(algoId, state, ordType)
+      ├─ handleLongStopLossTriggered → placeConditionalEntryOrder
+      ├─ handleShortStopLossTriggered → placeConditionalEntryOrder
+      ├─ extendLongStopLoss → placeTakeProfit
+      └─ extendShortStopLoss → placeTakeProfit
 ```
 
-- WS回调在 `[ctReadThread-XX]` 中**串行**执行,避免并发问题
-- REST API 提交到 `okx-trade-worker` 单线程池异步执行,避免阻塞WS线程
-- `closeExistingPositions()` 和 `handlePositionZeroAndReset()` 在WS线程中同步调用REST,需注意耗时
-- `LostConnectionChecker` 已关闭(`setConnectionLostTimeout(0)`),由应用层 `ping`/`pong` 心跳接管
+- WS 回调线程串行执行,天然线程安全
+- REST 提交到 `okx-trade-worker` 单线程异步执行,避免阻塞 WS
+- `closeExistingPositions()` / `handlePositionZeroAndReset()` 在 WS 线程中同步调用 REST(IOC 市价单,秒级完成)
+- `LostConnectionChecker(0)` 已禁用,由应用层 `send("ping")`/`handle "pong"` 接管

--
Gitblit v1.9.1