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