From 86a73a6274f9c5938c39c03198f11df9b1735320 Mon Sep 17 00:00:00 2001
From: Administrator <15274802129@163.com>
Date: Thu, 18 Dec 2025 17:35:01 +0800
Subject: [PATCH] feat(okx): 实现新的交易策略与账户保证金逻辑

---
 src/main/java/com/xcong/excoin/modules/okxNewPrice/README.md                          |  285 +++++++++++
 src/main/java/com/xcong/excoin/modules/okxNewPrice/OkxWebSocketClientManager.java     |    5 
 src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/enums/CoinEnums.java         |    6 
 src/main/java/com/xcong/excoin/modules/okxNewPrice/celue/CaoZuoServiceImpl.java       |  608 +++++++++++++-----------
 src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/enums/OrderParamEnums.java   |    4 
 src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/PositionsWs.java             |    6 
 src/main/java/com/xcong/excoin/modules/okxNewPrice/celue/CaoZuoService.java           |   28 +
 src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/OrderInfoWs.java             |   10 
 src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/TradeOrderWs.java            |  153 ++---
 src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/AccountWs.java               |   15 
 src/main/java/com/xcong/excoin/modules/okxNewPrice/OkxNewPriceWebSocketClient.java    |   57 +
 src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/param/TradeRequestParam.java |   32 +
 src/main/java/com/xcong/excoin/modules/okxNewPrice/OKX_QUANT_DOCUMENTATION.md         |  254 ++++++++++
 13 files changed, 1,070 insertions(+), 393 deletions(-)

diff --git a/src/main/java/com/xcong/excoin/modules/okxNewPrice/OKX_QUANT_DOCUMENTATION.md b/src/main/java/com/xcong/excoin/modules/okxNewPrice/OKX_QUANT_DOCUMENTATION.md
new file mode 100644
index 0000000..f4897c8
--- /dev/null
+++ b/src/main/java/com/xcong/excoin/modules/okxNewPrice/OKX_QUANT_DOCUMENTATION.md
@@ -0,0 +1,254 @@
+# OKX量化交易模块技术文档
+
+## 1. 包结构
+
+```
+com.xcong.excoin.modules.okxNewPrice
+├── OkxWebSocketClientManager.java      # WebSocket客户端管理器
+├── OkxNewPriceWebSocketClient.java     # 公共价格WebSocket客户端
+├── OkxQuantWebSocketClient.java        # 多账号量化交易WebSocket客户端
+├── README.md                           # 模块说明文档
+├── celue/                              # 策略执行层
+│   ├── CaoZuoService.java              # 策略执行接口
+│   └── CaoZuoServiceImpl.java          # 策略执行实现
+├── okxWs/                              # OKX WebSocket通信层
+│   ├── AccountWs.java                  # 账户信息处理
+│   ├── BalanceAndPositionWs.java       # 余额和仓位处理
+│   ├── LoginWs.java                    # 登录处理
+│   ├── OrderInfoWs.java                # 订单信息处理
+│   ├── PositionsWs.java                # 仓位信息处理
+│   ├── TradeOrderWs.java               # 交易订单处理
+│   ├── enums/                          # 枚举定义
+│   └── wanggeList/                     # 网格策略配置
+│       ├── WangGeListEnum.java         # 网格参数枚举
+│       └── WangGeListServiceImpl.java  # 网格策略服务
+├── okxpi/                              # OKX API工具
+└── utils/                              # 工具类
+    ├── SSLConfig.java                  # SSL配置
+    ├── WsMapBuild.java                 # Map构建工具
+    └── WsParamBuild.java               # WebSocket参数构建工具
+```
+
+## 2. 核心组件说明
+
+### 2.1 WebSocket客户端管理
+
+#### OkxWebSocketClientManager
+- **功能**:管理所有OKX WebSocket客户端实例,包括价格客户端和多账号量化客户端
+- **核心特性**:
+  - 统一初始化、连接和销毁管理
+  - 多账号客户端映射(accountName → OkxQuantWebSocketClient)
+  - 单一价格客户端管理
+- **关键方法**:
+  - `init()`:初始化所有客户端
+  - `destroy()`:销毁所有客户端
+  - `getAllClients()`:获取所有账号客户端
+
+### 2.2 WebSocket客户端
+
+#### OkxNewPriceWebSocketClient
+- **功能**:连接OKX公共WebSocket接口,获取实时标记价格
+- **核心特性**:
+  - 心跳检测和自动重连
+  - 价格数据解析和Redis存储
+  - 价格变化触发策略执行
+- **关键流程**:
+  - `init()` → `connect()` → `subscribeChannels()` → 接收价格数据 → `processPushData()` → `triggerQuantOperations()`
+
+#### OkxQuantWebSocketClient
+- **功能**:连接OKX私有WebSocket接口,处理账号相关数据
+- **核心特性**:
+  - 账号登录认证
+  - 订阅账号、订单、仓位等私有频道
+  - 处理私有数据推送
+- **关键流程**:
+  - `init()` → `connect()` → `websocketLogin()` → 订阅私有频道 → 接收数据
+
+### 2.3 策略执行层
+
+#### CaoZuoService
+- **功能**:执行量化交易策略,决定买卖操作方向
+- **核心方法**:
+  - `caoZuo(String accountName)`:根据账号执行策略
+  - `caoZuoLong(String accountName, String markPx)`:多头策略执行
+  - `caoZuoShort(String accountName, String markPx)`:空头策略执行
+- **策略逻辑**:
+  - 根据当前价格确定所在网格位置
+  - 结合网格方向参数决定操作方向
+  - 考虑仓位状态和风险控制
+
+### 2.4 数据管理
+
+#### PositionsWs
+- **功能**:管理账户仓位数据,支持多空方向分离
+- **核心特性**:
+  - 双层Map存储:accountName → dataKey → value
+  - 支持多空方向分离(accountName_posSide)
+  - 数据就绪状态标记
+- **关键方法**:
+  - `initAccountName(String accountName, String posSide)`:初始化带多空方向的账号名
+  - `handleEvent(JSONObject response, String accountName)`:处理仓位数据推送
+
+### 2.5 网格策略
+
+#### WangGeListEnum
+- **功能**:定义网格策略参数
+- **核心参数**:
+  - `jiage_shangxian`:价格上限
+  - `jiage_xiaxian`:价格下限
+  - `fang_xiang`:操作方向(long/short)
+  - `jian_ju`:网格间距
+- **关键方法**:
+  - `getGridByPrice(BigDecimal price)`:根据当前价格获取匹配的网格
+
+## 3. 业务流程
+
+### 3.1 系统初始化流程
+
+```
+1. Spring容器启动,OkxWebSocketClientManager初始化
+2. 创建OkxNewPriceWebSocketClient实例并初始化
+3. 遍历ExchangeInfoEnum,为每个账号创建OkxQuantWebSocketClient实例
+4. 所有客户端建立WebSocket连接并进行认证
+5. 订阅相应的WebSocket频道
+```
+
+### 3.2 价格触发交易流程
+
+```
+1. OkxNewPriceWebSocketClient接收价格数据
+2. 调用`processPushData()`处理价格数据
+3. 调用`triggerQuantOperations()`触发策略执行
+4. 遍历所有账号客户端:
+   a. 获取账号名称
+   b. 调用`CaoZuoService.caoZuo(accountName)`确定操作方向
+   c. 调用`TradeOrderWs.orderEvent()`执行订单操作
+```
+
+### 3.3 网格策略执行流程
+
+```
+1. 获取当前价格
+2. 调用`WangGeListEnum.getGridByPrice(price)`确定网格位置
+3. 根据网格的`fang_xiang`参数确定操作方向
+4. 结合当前仓位状态和市场情况,决定最终操作(买/卖/止损/初始化)
+5. 返回操作方向给调用者
+```
+
+## 4. 技术架构
+
+### 4.1 客户端架构
+
+```
+┌─────────────────────────────────────────────────────────┐
+│                     应用层                               │
+├─────────────────────────────────────────────────────────┤
+│  OkxWebSocketClientManager                              │
+├─────────────────┬───────────────────────────────────────┤
+│                 │                                       │
+│ OkxNewPrice     │  OkxQuantWebSocketClient (多实例)     │
+│ WebSocketClient │  ┌─────────┐ ┌─────────┐ ┌─────────┐  │
+│                 │  │ Account1│ │ Account2│ │ AccountN│  │
+│                 │  └─────────┘ └─────────┘ └─────────┘  │
+├─────────────────┴───────────────────────────────────────┤
+│                     WebSocket通信层                      │
+├─────────────────────────────────────────────────────────┤
+│                     OKX WebSocket API                   │
+└─────────────────────────────────────────────────────────┘
+```
+
+### 4.2 数据流向
+
+```
+1. OKX公共WebSocket → OkxNewPriceWebSocketClient → Redis存储价格
+2. OKX私有WebSocket → OkxQuantWebSocketClient → 私有数据处理
+3. 价格变化 → CaoZuoService策略执行 → TradeOrderWs订单执行
+4. 订单结果 → OrderInfoWs处理 → 更新订单状态
+5. 仓位变化 → PositionsWs处理 → 更新仓位数据
+```
+
+## 5. 关键特性
+
+### 5.1 WebSocket连接管理
+- **心跳检测**:定期发送ping请求,检测连接有效性
+- **自动重连**:连接断开时,使用指数退避算法自动重连
+- **连接状态监控**:实时监控连接状态(connected/connecting/initialized)
+
+### 5.2 多账号支持
+- **独立客户端**:每个账号拥有独立的WebSocket客户端实例
+- **账号隔离**:账号数据隔离存储,避免数据冲突
+- **统一管理**:通过OkxWebSocketClientManager统一管理所有账号客户端
+
+### 5.3 网格策略
+- **多网格支持**:支持设置多个网格区域
+- **方向控制**:每个网格可配置独立的操作方向(long/short)
+- **动态匹配**:根据当前价格自动匹配对应的网格策略
+
+### 5.4 多空支持
+- **仓位分离**:多头和空头仓位数据分离存储
+- **独立操作**:多空方向可独立进行策略执行
+- **风险控制**:针对多空方向独立设置风险控制参数
+
+## 6. 配置与扩展
+
+### 6.1 网格策略配置
+当前网格策略通过`WangGeListEnum`硬编码配置:
+
+```java
+UP("上层做空", "2", "3100", "3000", "2", "short", "3100"),
+CENTER("中间指定一个方向", "2", "3000", "2950", "2", "long", "2950"),
+DOWN("下层做空", "2", "2950", "2920", "2", "short", "2950"),
+DOWN_ONE("下层做多", "2", "2920", "2900", "2", "long", "2900");
+```
+
+**扩展建议**:
+- 将网格参数迁移到数据库或配置文件
+- 实现动态加载和更新网格策略
+- 支持网格策略的增删改查操作
+
+### 6.2 账号配置
+账号信息通过`ExchangeInfoEnum`配置,每个枚举值对应一个交易账号。
+
+### 6.3 性能优化
+- **线程池管理**:合理配置线程池大小,避免资源浪费
+- **连接复用**:考虑连接复用策略,减少连接数量
+- **数据缓存**:合理使用缓存,减少重复计算
+
+## 7. 开发与维护
+
+### 7.1 开发流程
+1. 理解现有策略逻辑和数据流
+2. 根据需求修改或扩展策略
+3. 更新相关配置(如网格参数)
+4. 测试策略有效性
+5. 部署到生产环境
+
+### 7.2 常见问题
+
+**问题1**:WebSocket连接频繁断开
+**解决**:检查网络环境,调整心跳间隔和重连策略
+
+**问题2**:策略执行不符合预期
+**解决**:检查网格参数配置,分析策略执行日志,调整策略逻辑
+
+**问题3**:订单执行失败
+**解决**:检查账号权限,查看订单执行日志,分析失败原因
+
+### 7.3 日志与监控
+- 关键操作日志:记录WebSocket连接、策略执行、订单操作等关键事件
+- 错误日志:记录异常情况,便于问题排查
+- 性能监控:监控系统性能指标,及时发现性能瓶颈
+
+## 8. 未来规划
+
+1. **动态策略配置**:支持通过后台管理系统动态配置网格策略
+2. **策略回测**:实现策略回测功能,提高策略有效性
+3. **风险控制增强**:增加更完善的风险控制机制
+4. **多交易所支持**:扩展支持其他交易所
+5. **数据可视化**:实现交易数据可视化展示
+
+---
+
+**版本**:1.0
+**更新日期**:2025-12-17
+**维护人**:开发团队
\ No newline at end of file
diff --git a/src/main/java/com/xcong/excoin/modules/okxNewPrice/OkxNewPriceWebSocketClient.java b/src/main/java/com/xcong/excoin/modules/okxNewPrice/OkxNewPriceWebSocketClient.java
index f079744..181ecd0 100644
--- a/src/main/java/com/xcong/excoin/modules/okxNewPrice/OkxNewPriceWebSocketClient.java
+++ b/src/main/java/com/xcong/excoin/modules/okxNewPrice/OkxNewPriceWebSocketClient.java
@@ -4,19 +4,21 @@
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.xcong.excoin.modules.okxNewPrice.celue.CaoZuoService;
-import com.xcong.excoin.modules.okxNewPrice.OkxWebSocketClientManager;
 import com.xcong.excoin.modules.okxNewPrice.okxWs.TradeOrderWs;
 import com.xcong.excoin.modules.okxNewPrice.okxWs.enums.CoinEnums;
+import com.xcong.excoin.modules.okxNewPrice.okxWs.param.TradeRequestParam;
+import com.xcong.excoin.modules.okxNewPrice.okxWs.wanggeList.WangGeListEnum;
+import com.xcong.excoin.modules.okxNewPrice.okxWs.wanggeList.WangGeListService;
 import com.xcong.excoin.modules.okxNewPrice.utils.SSLConfig;
-import com.xcong.excoin.rabbit.pricequeue.WebsocketPriceService;
-import com.xcong.excoin.utils.CoinTypeConvert;
 import com.xcong.excoin.utils.RedisUtils;
+import java.math.BigDecimal;
 import lombok.extern.slf4j.Slf4j;
 import org.java_websocket.client.WebSocketClient;
 import org.java_websocket.handshake.ServerHandshake;
 
 import java.net.URI;
 import java.net.URISyntaxException;
+import java.util.Collection;
 import java.util.concurrent.*;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicReference;
@@ -32,6 +34,7 @@
     private final RedisUtils redisUtils;
     private final CaoZuoService caoZuoService;
     private final OkxWebSocketClientManager clientManager;
+    private final WangGeListService wangGeListService;
 
     private WebSocketClient webSocketClient;
     private ScheduledExecutorService heartbeatExecutor;
@@ -56,10 +59,12 @@
     });
 
     public OkxNewPriceWebSocketClient(RedisUtils redisUtils,
-                                      CaoZuoService caoZuoService, OkxWebSocketClientManager clientManager) {
+                                      CaoZuoService caoZuoService, OkxWebSocketClientManager clientManager,
+                                      WangGeListService wangGeListService) {
         this.redisUtils = redisUtils;
         this.caoZuoService = caoZuoService;
         this.clientManager = clientManager;
+        this.wangGeListService = wangGeListService;
     }
 
     /**
@@ -287,18 +292,46 @@
      */
     private void triggerQuantOperations(String markPx) {
         try {
+            // 1. 判断当前价格属于哪个网格
+            WangGeListEnum gridByPriceNew = WangGeListEnum.getGridByPrice(new BigDecimal(markPx));
+            if (gridByPriceNew == null) {
+                log.error("当前价格{}不在任何网格范围内,无法触发量化操作", markPx);
+                return;
+            }
+            /**
+             * 获取当前网格信息
+             *      根据当前网格的持仓方向获取反方向是否存在持仓
+             *      如果持有,直接止损
+             */
+            Collection<OkxQuantWebSocketClient> allClients = clientManager.getAllClients();
+            //如果为空,则直接返回
+            if (allClients.isEmpty()) {
+                return;
+            }
             // 获取所有OkxQuantWebSocketClient实例
             for (OkxQuantWebSocketClient client : clientManager.getAllClients()) {
-                // 由于OkxQuantWebSocketClient没有直接暴露账号名称的方法,我们需要从clientManager中获取
-                // 这里可以通过遍历clientMap的方式获取账号名称
-                // 或者修改OkxQuantWebSocketClient,添加getAccountName方法
-                // 暂时使用这种方式获取账号名称
                 String accountName = getAccountNameFromClient(client);
                 if (accountName != null) {
-                    // 调用CaoZuoService的caoZuo方法,触发量化操作
-                    String side = caoZuoService.caoZuo(accountName);
-                    TradeOrderWs.orderEvent(client.getWebSocketClient(), side, accountName);
-                    log.info("价格变化触发量化操作: 账号={}, 价格={}, 操作方向={}", accountName, markPx, side);
+                    /**
+                     * 处理历史网格的订单
+                     * 根据历史网格的开单方向,是否需要止损处理
+                     *      如果方向一致就不需要处理
+                     *      如果不一致则需要处理
+                     */
+                    String fangXiang = gridByPriceNew.getFang_xiang();
+                    String fangXiangOld = CoinEnums.POSSIDE_LONG.equals(fangXiang) ? CoinEnums.POSSIDE_SHORT.getCode() : CoinEnums.POSSIDE_LONG.getCode();
+                    log.info("历史网格方向为:{}", fangXiangOld);
+                    TradeRequestParam tradeRequestParamOld = caoZuoService.caoZuoZhiSunEvent(accountName, markPx, fangXiangOld);
+                    TradeOrderWs.orderEvent(client.getWebSocketClient(), tradeRequestParamOld);
+
+                    /**
+                     * 处理当前网格的订单,触发量化操作
+                     */
+                    log.info("当前价格{}属于网格: {}-{}({}-{})", markPx, gridByPriceNew.getName(),gridByPriceNew.getFang_xiang(), gridByPriceNew.getJiage_xiaxian(), gridByPriceNew.getJiage_shangxian());
+                    wangGeListService.initWangGe(markPx);
+                    TradeRequestParam tradeRequestParam = caoZuoService.caoZuoHandler(accountName, markPx, gridByPriceNew.getFang_xiang());
+                    TradeOrderWs.orderEvent(client.getWebSocketClient(), tradeRequestParam);
+                    log.info("价格变化触发量化操作: 账号={}, 价格={}",  accountName, markPx);
                 }
             }
         } catch (Exception e) {
diff --git a/src/main/java/com/xcong/excoin/modules/okxNewPrice/OkxWebSocketClientManager.java b/src/main/java/com/xcong/excoin/modules/okxNewPrice/OkxWebSocketClientManager.java
index 21dc07e..be64554 100644
--- a/src/main/java/com/xcong/excoin/modules/okxNewPrice/OkxWebSocketClientManager.java
+++ b/src/main/java/com/xcong/excoin/modules/okxNewPrice/OkxWebSocketClientManager.java
@@ -2,6 +2,7 @@
 
 import com.xcong.excoin.modules.okxNewPrice.celue.CaoZuoService;
 import com.xcong.excoin.modules.okxNewPrice.okxWs.enums.ExchangeInfoEnum;
+import com.xcong.excoin.modules.okxNewPrice.okxWs.wanggeList.WangGeListService;
 import com.xcong.excoin.modules.okxNewPrice.wangge.WangGeService;
 import com.xcong.excoin.rabbit.pricequeue.WebsocketPriceService;
 import com.xcong.excoin.utils.RedisUtils;
@@ -26,6 +27,8 @@
     private CaoZuoService caoZuoService;
     @Autowired
     private RedisUtils redisUtils;
+    @Autowired
+    private WangGeListService wangGeListService;
 
     // 存储所有OkxQuantWebSocketClient实例,key为账号类型名称
     private final Map<String, OkxQuantWebSocketClient> quantClientMap = new ConcurrentHashMap<>();
@@ -43,7 +46,7 @@
         
         // 初始化价格WebSocket客户端
         try {
-            newPriceClient = new OkxNewPriceWebSocketClient(redisUtils, caoZuoService, this);
+            newPriceClient = new OkxNewPriceWebSocketClient(redisUtils, caoZuoService, this, wangGeListService);
             newPriceClient.init();
             log.info("已初始化OkxNewPriceWebSocketClient");
         } catch (Exception e) {
diff --git a/src/main/java/com/xcong/excoin/modules/okxNewPrice/README.md b/src/main/java/com/xcong/excoin/modules/okxNewPrice/README.md
new file mode 100644
index 0000000..cb6e715
--- /dev/null
+++ b/src/main/java/com/xcong/excoin/modules/okxNewPrice/README.md
@@ -0,0 +1,285 @@
+# OKX 新价格量化交易模块文档
+
+## 1. 包结构
+
+```
+okxNewPrice/
+├── celue/                    # 策略层
+│   ├── CaoZuoService.java      # 操作服务接口
+│   └── CaoZuoServiceImpl.java  # 操作服务实现
+├── jiaoyi/                   # 交易层
+│   ├── IMQService.java         # 消息队列服务接口
+│   └── IMQServiceImpl.java     # 消息队列服务实现
+├── okxWs/                    # OKX WebSocket 处理层
+│   ├── enums/                  # WebSocket 相关枚举
+│   │   ├── CoinEnums.java         # 币相关枚举
+│   │   ├── ExchangeInfoEnum.java  # 交易所信息枚举
+│   │   └── OrderParamEnums.java   # 订单参数枚举
+│   ├── wanggeList/             # 网格列表相关
+│   │   ├── WangGeListEnum.java     # 网格枚举
+│   │   ├── WangGeListQueue.java    # 网格队列
+│   │   ├── WangGeListService.java  # 网格服务接口
+│   │   └── WangGeListServiceImpl.java  # 网格服务实现
+│   ├── AccountWs.java          # 账户信息处理
+│   ├── BalanceAndPositionWs.java   # 余额和持仓处理
+│   ├── InstrumentsWs.java      # 合约信息处理
+│   ├── LoginWs.java            # 登录处理
+│   ├── OrderInfoWs.java        # 订单信息处理
+│   ├── PositionsWs.java        # 持仓信息处理
+│   └── TradeOrderWs.java       # 交易订单处理
+├── okxpi/                     # OKX API 相关
+│   ├── config/                 # 配置相关
+│   ├── enumerates/             # 枚举
+│   ├── order/                  # 订单相关
+│   ├── query/                  # 查询相关
+│   ├── trade/                  # 交易相关
+│   ├── verify/                 # 验证相关
+│   └── ...                     # 其他API工具类
+├── utils/                     # 工具类
+│   ├── FebsException.java      # 异常类
+│   ├── FebsResponse.java       # 响应类
+│   ├── SSLConfig.java          # SSL配置
+│   ├── SignUtils.java          # 签名工具
+│   ├── WsMapBuild.java         # WebSocket Map构建工具
+│   └── WsParamBuild.java       # WebSocket 参数构建工具
+├── wangge/                    # 网格相关
+│   ├── WangGeEnum.java         # 网格枚举
+│   ├── WangGeQueue.java        # 网格队列
+│   ├── WangGeService.java      # 网格服务接口
+│   └── WangGeServiceImpl.java  # 网格服务实现
+├── zhanghu/                   # 账户相关
+│   ├── ApiMessageServiceImpl.java  # API消息服务实现
+│   ├── IApiMessageService.java     # API消息服务接口
+│   └── ZhangHuEnum.java            # 账户枚举
+├── OkxNewPriceWebSocketClient.java  # 价格WebSocket客户端
+├── OkxQuantWebSocketClient.java     # 量化WebSocket客户端
+├── OkxWebSocketClientMain.java      # WebSocket客户端主类
+└── OkxWebSocketClientManager.java   # WebSocket客户端管理器
+```
+
+## 2. 核心组件说明
+
+### 2.1 WebSocket 客户端管理
+
+#### OkxWebSocketClientManager
+- **作用**:统一管理所有 OKX WebSocket 客户端实例
+- **核心功能**:
+  - 初始化价格 WebSocket 客户端和多账号量化客户端
+  - 提供客户端的获取和销毁功能
+  - 管理客户端生命周期
+- **关键方法**:
+  - `init()`:初始化所有客户端
+  - `destroy()`:销毁所有客户端
+  - `getAllClients()`:获取所有量化客户端实例
+
+#### OkxNewPriceWebSocketClient
+- **作用**:价格 WebSocket 客户端,负责获取实时价格数据
+- **核心功能**:
+  - 连接 OKX 公共 WebSocket 接口获取标记价格
+  - 将价格数据保存到 Redis
+  - 价格变化时触发量化操作
+  - 支持心跳检测和自动重连
+- **关键方法**:
+  - `init()`:初始化客户端
+  - `destroy()`:销毁客户端
+  - `processPushData()`:处理价格推送数据
+  - `triggerQuantOperations()`:触发所有账号的量化操作
+
+#### OkxQuantWebSocketClient
+- **作用**:量化交易 WebSocket 客户端,每个账号对应一个实例
+- **核心功能**:
+  - 连接 OKX 私有 WebSocket 接口
+  - 处理账户、持仓、订单等私有数据
+  - 支持多账号独立操作
+  - 支持心跳检测和自动重连
+- **关键方法**:
+  - `init()`:初始化客户端
+  - `destroy()`:销毁客户端
+  - `websocketLogin()`:登录 WebSocket
+  - `subscribeChannels()`:订阅相关频道
+
+### 2.2 策略层
+
+#### CaoZuoService
+- **作用**:交易策略服务接口
+- **核心功能**:
+  - 决定是否进行交易操作
+  - 根据价格和网格信息决定交易方向
+  - 处理多头和空头策略
+
+#### CaoZuoServiceImpl
+- **作用**:交易策略服务实现类
+- **核心功能**:
+  - 检查账户和持仓状态
+  - 根据当前价格获取对应的网格
+  - 实现多头和空头的具体交易逻辑
+  - 管理网格队列和交易决策
+- **关键方法**:
+  - `caoZuo()`:主交易逻辑
+  - `caoZuoLong()`:多头交易逻辑
+  - `caoZuoShort()`:空头交易逻辑
+
+### 2.3 网格策略
+
+#### WangGeListEnum
+- **作用**:网格数据枚举,定义不同价格区间的网格参数
+- **核心参数**:
+  - `name`:网格名称
+  - `jiage_shangxian`:价格上限
+  - `jiage_xiaxian`:价格下限
+  - `jian_ju`:网格间距
+  - `fang_xiang`:交易方向(long/short)
+- **关键方法**:
+  - `getGridByPrice()`:根据价格获取对应的网格
+
+#### WangGeListService
+- **作用**:网格服务接口,提供网格相关操作
+- **核心功能**:
+  - 初始化网格队列
+  - 管理网格的开仓和平仓队列
+
+### 2.4 持仓管理
+
+#### PositionsWs
+- **作用**:持仓信息处理类
+- **核心功能**:
+  - 管理持仓数据(双层 Map 结构:账号_方向 -> 数据)
+  - 提供持仓数据的获取和更新方法
+  - 支持多账号多方向持仓管理
+- **关键方法**:
+  - `initAccountName()`:初始化带方向的账号名
+  - `handleEvent()`:处理持仓数据推送
+  - `getAccountMap()`:获取指定账号的持仓数据
+
+## 3. 工作流程
+
+### 3.1 系统初始化流程
+
+1. **客户端初始化**:
+   - Spring 容器启动时,`OkxWebSocketClientManager` 自动初始化
+   - 创建并初始化 `OkxNewPriceWebSocketClient` 实例
+   - 为每个账号创建并初始化 `OkxQuantWebSocketClient` 实例
+
+2. **WebSocket 连接**:
+   - `OkxNewPriceWebSocketClient` 连接公共价格 WebSocket
+   - 每个 `OkxQuantWebSocketClient` 连接私有 WebSocket 并登录
+   - 订阅相关频道(价格、账户、持仓、订单等)
+
+### 3.2 价格触发交易流程
+
+```
+┌─────────────────────────┐     ┌─────────────────────────┐
+│ OkxNewPriceWebSocketClient │     │ WangGeListEnum         │
+│ └─ processPushData()    │────▶│ └─ getGridByPrice()     │
+└─────────────────────────┘     └─────────────────────────┘
+         ▲                              ▼
+         │                     ┌─────────────────────────┐
+         │                     │ CaoZuoServiceImpl      │
+         │                     │ └─ caoZuo()            │
+         │                     └─────────────────────────┘
+         │                              ▼
+         │                     ┌─────────────────────────┐
+         │                     │ TradeOrderWs           │
+         │                     │ └─ orderEvent()        │
+         │                     └─────────────────────────┘
+         │                              ▼
+┌────────┴─────────────────────────────────────────────┐
+│ OkxQuantWebSocketClient                              │
+│ └─ handleWebSocketMessage()                          │
+└──────────────────────────────────────────────────────┘
+```
+
+1. **价格接收**:
+   - `OkxNewPriceWebSocketClient` 接收实时价格推送
+   - 调用 `processPushData()` 处理价格数据
+
+2. **策略决策**:
+   - 根据当前价格获取对应的网格参数(`WangGeListEnum.getGridByPrice()`)
+   - 调用 `CaoZuoServiceImpl.caoZuo()` 进行策略决策
+   - 根据网格方向调用对应的多头或空头策略
+
+3. **订单执行**:
+   - 调用 `TradeOrderWs.orderEvent()` 执行交易订单
+   - 通过 `OkxQuantWebSocketClient` 发送订单指令
+
+### 3.3 持仓数据管理流程
+
+1. **数据接收**:
+   - `OkxQuantWebSocketClient` 接收持仓数据推送
+   - 调用 `PositionsWs.handleEvent()` 处理持仓数据
+
+2. **数据存储**:
+   - 使用双层 Map 存储持仓数据:`accountName_posSide -> data`
+   - 支持多头和空头方向的独立存储
+
+3. **数据使用**:
+   - 策略层通过 `PositionsWs.getAccountMap()` 获取持仓数据
+   - 根据持仓数据和当前价格决定交易操作
+
+## 4. 关键特性
+
+### 4.1 多网格策略
+
+- **实现方式**:通过 `WangGeListEnum` 定义多个价格区间的网格
+- **核心功能**:
+  - 每个网格可设置独立的交易方向(多头/空头)
+  - 根据当前价格自动匹配对应的网格
+  - 支持跨网格的仓位迁移和止损
+
+### 4.2 多账号管理
+
+- **实现方式**:每个账号对应一个 `OkxQuantWebSocketClient` 实例
+- **核心功能**:
+  - 支持多个交易所账号独立操作
+  - 每个账号可设置独立的交易参数
+  - 账号间数据隔离,互不影响
+
+### 4.3 长/空头策略支持
+
+- **实现方式**:通过 `PositionsWs` 的双层 Map 结构
+- **核心功能**:
+  - 支持多头和空头方向的独立持仓管理
+  - 每个方向有独立的交易逻辑
+  - 支持方向切换时的仓位调整
+
+### 4.4 自动重连和心跳机制
+
+- **实现方式**:在 WebSocket 客户端中实现
+- **核心功能**:
+  - 定时发送心跳包维持连接
+  - 连接断开时自动重连(指数退避策略)
+  - 异常处理和资源清理
+
+## 5. 配置与扩展
+
+### 5.1 网格参数配置
+
+- **当前实现**:通过 `WangGeListEnum` 硬编码配置
+- **扩展建议**:
+  - 将网格参数改为可配置项(数据库或配置文件)
+  - 支持动态调整网格参数
+  - 提供网格参数管理界面
+
+### 5.2 交易参数配置
+
+- **核心参数**:
+  - 网格间距
+  - 交易方向(多头/空头)
+  - 止损点
+  - 交易数量
+- **扩展建议**:
+  - 支持每个账号独立配置交易参数
+  - 提供参数优化建议
+  - 支持回测功能
+
+## 6. 总结
+
+`okxNewPrice` 包是一个完整的 OKX 量化交易系统,具有以下特点:
+
+1. **模块化设计**:清晰的分层结构,便于维护和扩展
+2. **多账号支持**:每个账号独立运行,互不影响
+3. **多网格策略**:根据价格自动切换网格,支持多头和空头策略
+4. **实时响应**:基于 WebSocket 的实时数据推送和交易执行
+5. **高可靠性**:支持心跳检测、自动重连和异常处理
+
+该系统实现了从价格获取、策略决策到订单执行的完整流程,为量化交易提供了稳定可靠的基础架构。
\ No newline at end of file
diff --git a/src/main/java/com/xcong/excoin/modules/okxNewPrice/celue/CaoZuoService.java b/src/main/java/com/xcong/excoin/modules/okxNewPrice/celue/CaoZuoService.java
index 0d700c3..e53aa38 100644
--- a/src/main/java/com/xcong/excoin/modules/okxNewPrice/celue/CaoZuoService.java
+++ b/src/main/java/com/xcong/excoin/modules/okxNewPrice/celue/CaoZuoService.java
@@ -1,13 +1,35 @@
 package com.xcong.excoin.modules.okxNewPrice.celue;
 
+import com.xcong.excoin.modules.okxNewPrice.okxWs.param.TradeRequestParam;
+
 /**
  * @author Administrator
  */
 public interface CaoZuoService {
 
-    String caoZuo(String accountName);
+    TradeRequestParam caoZuoHandler(String accountName, String markPx, String posSide);
 
-    String caoZuoLong(String accountName,String markPx);
+    /**
+     * 止损 事件
+     * @param accountName
+     * @param markPx
+     * @param posSide
+     * @return
+     */
+    TradeRequestParam caoZuoZhiSunEvent(String accountName, String markPx, String posSide);
 
-    String caoZuoShort(String accountName,String markPx);
+    /**
+     * 初始化 事件
+     * @param accountName
+     * @param markPx
+     * @param posSide
+     * @return
+     */
+    TradeRequestParam caoZuoInitEvent(String accountName, String markPx, String posSide);
+
+    TradeRequestParam chooseEvent(TradeRequestParam tradeRequestParam);
+
+    TradeRequestParam caoZuoLong(TradeRequestParam tradeRequestParam);
+
+    TradeRequestParam caoZuoShort(TradeRequestParam tradeRequestParam);
 }
diff --git a/src/main/java/com/xcong/excoin/modules/okxNewPrice/celue/CaoZuoServiceImpl.java b/src/main/java/com/xcong/excoin/modules/okxNewPrice/celue/CaoZuoServiceImpl.java
index 9328774..31191b4 100644
--- a/src/main/java/com/xcong/excoin/modules/okxNewPrice/celue/CaoZuoServiceImpl.java
+++ b/src/main/java/com/xcong/excoin/modules/okxNewPrice/celue/CaoZuoServiceImpl.java
@@ -5,10 +5,12 @@
 import com.xcong.excoin.modules.okxNewPrice.okxWs.*;
 import com.xcong.excoin.modules.okxNewPrice.okxWs.enums.CoinEnums;
 import com.xcong.excoin.modules.okxNewPrice.okxWs.enums.OrderParamEnums;
+import com.xcong.excoin.modules.okxNewPrice.okxWs.param.TradeRequestParam;
 import com.xcong.excoin.modules.okxNewPrice.okxWs.wanggeList.WangGeListEnum;
 import com.xcong.excoin.modules.okxNewPrice.okxWs.wanggeList.WangGeListQueue;
 import com.xcong.excoin.modules.okxNewPrice.okxWs.wanggeList.WangGeListService;
 import com.xcong.excoin.modules.okxNewPrice.utils.WsMapBuild;
+import com.xcong.excoin.modules.okxNewPrice.utils.WsParamBuild;
 import com.xcong.excoin.rabbit.pricequeue.AscBigDecimal;
 import com.xcong.excoin.rabbit.pricequeue.DescBigDecimal;
 import com.xcong.excoin.utils.RedisUtils;
@@ -42,91 +44,33 @@
      * @return 返回操作类型字符串(如买入BUY、卖出SELL等),如果无有效操作则返回null
      */
     @Override
-    public String caoZuo(String accountName) {
-        String accountReadyState = AccountWs.getAccountMap(accountName).get(CoinEnums.READY_STATE.name());
-        if (!CoinEnums.READY_STATE_YES.getCode().equals(accountReadyState)) {
-            log.info("账户通道未就绪,取消发送");
-            return null;
-        }
-        String markPx = ObjectUtil.isEmpty(redisUtils.getString(CoinEnums.HE_YUE.getCode())) ? "0" : redisUtils.getString(CoinEnums.HE_YUE.getCode());
+    public TradeRequestParam caoZuoHandler(String accountName, String markPx, String posSide) {
+        TradeRequestParam tradeRequestParam = new TradeRequestParam();
+        tradeRequestParam.setAccountName(accountName);
+        tradeRequestParam.setMarkPx(markPx);
+        tradeRequestParam.setInstId(CoinEnums.HE_YUE.getCode());
+        tradeRequestParam.setTdMode(CoinEnums.CROSS.getCode());
+        tradeRequestParam.setPosSide(posSide);
+        tradeRequestParam.setOrdType(CoinEnums.ORDTYPE_MARKET.getCode());
 
-        log.info("当前价格: {}", markPx);
-        WangGeListEnum gridByPrice = WangGeListEnum.getGridByPrice(new BigDecimal(markPx));
-        if (gridByPrice == null){
-            log.error("没有获取到网格参数......");
-            return null;
-        }
-        log.info("当前网格: {}", gridByPrice.name());
-
-        PriorityBlockingQueue<AscBigDecimal> ascBigDecimals = wangGeListService.initWangGe(markPx);
-        if (ascBigDecimals == null){
-            log.error("没有获取到网格队列......");
-            return null;
-        }
+        log.info("操作账户:{},当前价格: {},仓位方向: {}", accountName,markPx,posSide);
         /**
-         * 如果下单的网格不属于同一个网格,则先止损掉老的网格的仓位
+         * 准备工作
+         * 1、准备好下单的基本信息
          */
-        Map<String, String> accountMap = InstrumentsWs.getAccountMap(accountName);
-        String wanggeName = accountMap.get(CoinEnums.WANG_GE_OLD.name());
-        if (StrUtil.isNotEmpty(wanggeName) && !wanggeName.equals(gridByPrice.name())){
-            log.error("正在止损老的网格仓位......");
-            WangGeListEnum oldWangge = WangGeListEnum.getByName(wanggeName);
-            if (oldWangge != null){
-                WsMapBuild.saveStringToMap(accountMap, CoinEnums.POSSIDE.name(), oldWangge.getFang_xiang());
-                return OrderParamEnums.OUT.getValue();
-            }
-        }
-        String posSide = gridByPrice.getFang_xiang();
-        log.info("仓位方向: {}", posSide);
-        WsMapBuild.saveStringToMap(accountMap, CoinEnums.POSSIDE.name(), posSide);
-        String positionAccountName = PositionsWs.initAccountName(accountName, posSide);
-        BigDecimal positionsReadyState = PositionsWs.getAccountMap(positionAccountName).get(CoinEnums.READY_STATE.name()) == null
-                ? BigDecimal.ZERO : PositionsWs.getAccountMap(positionAccountName).get(CoinEnums.READY_STATE.name());
-        if (WsMapBuild.parseBigDecimalSafe(CoinEnums.READY_STATE_YES.getCode()).compareTo(positionsReadyState) != 0) {
-            log.info("仓位{}通道未就绪,取消发送",positionAccountName);
-            // 判断是否保证金超标
-            if (PositionsWs.getAccountMap(positionAccountName).get("imr") == null){
-                log.error("没有获取到持仓信息,等待初始化......");
-                return null;
-            }
-            BigDecimal ordFrozImr = PositionsWs.getAccountMap(positionAccountName).get("imr");
-            BigDecimal totalOrderUsdt = WsMapBuild.parseBigDecimalSafe(AccountWs.getAccountMap(accountName).get(CoinEnums.TOTAL_ORDER_USDT.name()));
-            if (ordFrozImr.compareTo(totalOrderUsdt) >= 0){
-                log.error("已满仓......");
-                return OrderParamEnums.HOLDING.getValue();
-            }
-            if (PositionsWs.getAccountMap(positionAccountName).get("pos") == null){
-                log.error("没有获取到持仓信息,等待初始化......");
-                return null;
-            }
-            BigDecimal pos = PositionsWs.getAccountMap(positionAccountName).get("pos");
-            if (BigDecimal.ZERO.compareTo( pos) >= 0) {
-                log.error("持仓数量为零,进行初始化订单");
-                return OrderParamEnums.INIT.getValue();
-            }else{
-                log.error("仓位有持仓,等待持仓更新");
-                return null;
-            }
-        }
         // 系统设置的开关,等于冷静中,则代表不开仓
         String outStr = InstrumentsWs.getAccountMap(accountName).get(CoinEnums.OUT.name());
         if (OrderParamEnums.OUT_YES.getValue().equals(outStr)){
             log.error("冷静中,不允许下单......");
-            return null;
+            tradeRequestParam.setTradeType(OrderParamEnums.TRADE_NO.getValue());
+            return chooseEvent(tradeRequestParam);
         }
         BigDecimal cashBal = WsMapBuild.parseBigDecimalSafe(AccountWs.getAccountMap(accountName).get("cashBal"));
-
-        // 判断账户余额是否充足
-        if (cashBal.compareTo(BigDecimal.ZERO) <= 0){
-            log.error("账户没有钱,请充值......");
-            return null;
-        }
         /**
          * 判断止损抗压
          */
-        // 实际亏损金额
         BigDecimal realKuiSunAmount = WsMapBuild.parseBigDecimalSafe(AccountWs.getAccountMap(accountName).get("upl"));
-        log.info("未实现盈亏: {}", realKuiSunAmount);
+        log.info("实际盈亏金额: {}", realKuiSunAmount);
         String zhiSunPercent = InstrumentsWs.getAccountMap(accountName).get(CoinEnums.ZHI_SUN.name());
         BigDecimal zhiSunAmount = cashBal.multiply(new BigDecimal(zhiSunPercent));
         log.info("预期亏损金额: {}", zhiSunAmount);
@@ -140,56 +84,268 @@
             if (realKuiSunAmount.compareTo(zhiSunAmount) > 0){
                 log.error("账户冷静止损......");
                 WsMapBuild.saveStringToMap(InstrumentsWs.getAccountMap(accountName), CoinEnums.OUT.name(),  OrderParamEnums.OUT_YES.getValue());
-                return OrderParamEnums.OUT.getValue();
+                tradeRequestParam.setTradeType(OrderParamEnums.TRADE_YES.getValue());
+                return caoZuoZhiSunEvent(accountName, markPx, posSide);
             }
             // 判断抗压
             if (realKuiSunAmount.compareTo(kangYaAmount) > 0 && realKuiSunAmount.compareTo(zhiSunAmount) <= 0){
                 log.error("账户紧张扛仓......");
-                return OrderParamEnums.HOLDING.getValue();
+                tradeRequestParam.setTradeType(OrderParamEnums.TRADE_NO.getValue());
+                return chooseEvent(tradeRequestParam);
             }
         }
+
+        String positionAccountName = PositionsWs.initAccountName(accountName, posSide);
         // 判断是否保证金超标
         if (PositionsWs.getAccountMap(positionAccountName).get("imr") == null){
             log.error("没有获取到持仓信息,等待初始化......");
-            return null;
+            tradeRequestParam.setTradeType(OrderParamEnums.TRADE_NO.getValue());
+            return chooseEvent(tradeRequestParam);
         }
         BigDecimal ordFrozImr = PositionsWs.getAccountMap(positionAccountName).get("imr");
-        BigDecimal totalOrderUsdt = WsMapBuild.parseBigDecimalSafe(AccountWs.getAccountMap(accountName).get(CoinEnums.TOTAL_ORDER_USDT.name()));
+        BigDecimal totalOrderUsdt = WsMapBuild.parseBigDecimalSafe(AccountWs.getAccountMap(accountName).get(CoinEnums.TOTAL_ORDER_USDT.name()))
+                .divide(new BigDecimal("2"), RoundingMode.DOWN);
         if (ordFrozImr.compareTo(totalOrderUsdt) >= 0){
             log.error("已满仓......");
-            return OrderParamEnums.HOLDING.getValue();
+            tradeRequestParam.setTradeType(OrderParamEnums.TRADE_NO.getValue());
+            return chooseEvent(tradeRequestParam);
         }
 
         if (PositionsWs.getAccountMap(positionAccountName).get("pos") == null){
             log.error("没有获取到持仓信息,等待初始化......");
-            return null;
+            tradeRequestParam.setTradeType(OrderParamEnums.TRADE_NO.getValue());
+            return chooseEvent(tradeRequestParam);
         }
         BigDecimal pos = PositionsWs.getAccountMap(positionAccountName).get("pos");
         if (BigDecimal.ZERO.compareTo( pos) >= 0) {
             log.error("持仓数量为零,进行初始化订单");
-            return OrderParamEnums.INIT.getValue();
+            return caoZuoInitEvent(accountName, markPx, posSide);
         }
+
+        tradeRequestParam.setTradeType(OrderParamEnums.TRADE_YES.getValue());
+        return chooseEvent(tradeRequestParam);
+    }
+
+    @Override
+    public TradeRequestParam caoZuoZhiSunEvent(String accountName, String markPx, String posSide) {
+
+        log.info("历史网格:操作账户:{},当前价格: {},仓位方向: {}", accountName,markPx,posSide);
+        /**
+         * 初始化订单请求参数
+         *      获取仓位数量
+         *      获取仓位方向
+         */
+        TradeRequestParam tradeRequestParam = new TradeRequestParam();
+        tradeRequestParam.setAccountName(accountName);
+        tradeRequestParam.setMarkPx(markPx);
+        tradeRequestParam.setInstId(CoinEnums.HE_YUE.getCode());
+        tradeRequestParam.setTdMode(CoinEnums.CROSS.getCode());
+        tradeRequestParam.setPosSide(posSide);
+        tradeRequestParam.setOrdType(CoinEnums.ORDTYPE_MARKET.getCode());
+
+        tradeRequestParam.setTradeType(OrderParamEnums.TRADE_YES.getValue());
+        String side = null;
         if (CoinEnums.POSSIDE_LONG.getCode().equals(posSide)){
-            return caoZuoLong(accountName,markPx);
-        }else if (CoinEnums.POSSIDE_SHORT.getCode().equals(posSide)){
-            return caoZuoShort(accountName,markPx);
-        }else{
-            log.error("账户未设置持仓方向......");
-            return null;
+            side = CoinEnums.SIDE_SELL.getCode();
+        }
+        if (CoinEnums.POSSIDE_SHORT.getCode().equals(posSide)){
+            side = CoinEnums.SIDE_BUY.getCode();
+        }
+        tradeRequestParam.setSide(side);
+
+        String clOrdId = WsParamBuild.getOrderNum(side);
+        tradeRequestParam.setClOrdId(clOrdId);
+
+        String positionAccountName = PositionsWs.initAccountName(accountName, posSide);
+        BigDecimal pos = PositionsWs.getAccountMap(positionAccountName).get("pos");
+        if (BigDecimal.ZERO.compareTo( pos) >= 0) {
+            log.error("历史网格止损方向没有持仓");
+            tradeRequestParam.setTradeType(OrderParamEnums.TRADE_NO.getValue());
+        }
+        tradeRequestParam.setSz(String.valueOf( pos));
+        return tradeRequestParam;
+
+    }
+
+    @Override
+    public TradeRequestParam caoZuoInitEvent(String accountName, String markPx, String posSide) {
+
+        log.info("当前网格初始化:操作账户:{},当前价格: {},仓位方向: {}", accountName,markPx,posSide);
+        /**
+         * 初始化订单请求参数
+         *      获取仓位数量
+         *      获取仓位方向
+         */
+        TradeRequestParam tradeRequestParam = new TradeRequestParam();
+        tradeRequestParam.setAccountName(accountName);
+        tradeRequestParam.setMarkPx(markPx);
+        tradeRequestParam.setInstId(CoinEnums.HE_YUE.getCode());
+        tradeRequestParam.setTdMode(CoinEnums.CROSS.getCode());
+        tradeRequestParam.setPosSide(posSide);
+        tradeRequestParam.setOrdType(CoinEnums.ORDTYPE_MARKET.getCode());
+
+        tradeRequestParam.setTradeType(OrderParamEnums.TRADE_YES.getValue());
+        String side = null;
+        if (CoinEnums.POSSIDE_LONG.getCode().equals(posSide)){
+            side = CoinEnums.SIDE_BUY.getCode();
+        }
+        if (CoinEnums.POSSIDE_SHORT.getCode().equals(posSide)){
+            side = CoinEnums.SIDE_SELL.getCode();
+        }
+        tradeRequestParam.setSide(side);
+
+        String clOrdId = WsParamBuild.getOrderNum(side);
+        tradeRequestParam.setClOrdId(clOrdId);
+        String sz = InstrumentsWs.getAccountMap(accountName).get(CoinEnums.BUY_CNT_INIT.name());
+        tradeRequestParam.setSz(sz);
+        return tradeRequestParam;
+    }
+
+    @Override
+    public TradeRequestParam chooseEvent(TradeRequestParam tradeRequestParam) {
+        log.info("开始执行chooseEvent......");
+        if (OrderParamEnums.TRADE_NO.getValue().equals(tradeRequestParam.getTradeType())){
+            return tradeRequestParam;
+        }
+        if (OrderParamEnums.TRADE_YES.getValue().equals(tradeRequestParam.getTradeType())){
+            String posSide = tradeRequestParam.getPosSide();
+            if (CoinEnums.POSSIDE_LONG.getCode().equals(posSide)){
+                tradeRequestParam = caoZuoLong(tradeRequestParam);
+            }else if (CoinEnums.POSSIDE_SHORT.getCode().equals(posSide)){
+                tradeRequestParam = caoZuoShort(tradeRequestParam);
+            }
+        }
+        return tradeRequestParam;
+    }
+
+    @Override
+    public TradeRequestParam caoZuoLong(TradeRequestParam tradeRequestParam) {
+        log.info("开始做{}执行操作CaoZuoServiceImpl......",tradeRequestParam.getPosSide());
+
+        String accountName = tradeRequestParam.getAccountName();
+        String markPxStr = tradeRequestParam.getMarkPx();
+        String posSide = tradeRequestParam.getPosSide();
+
+        try {
+
+            String positionAccountName = PositionsWs.initAccountName(accountName, posSide);
+            // 获取标记价格和平均持仓价格
+            BigDecimal markPx = new BigDecimal(markPxStr);
+            BigDecimal avgPx = PositionsWs.getAccountMap(positionAccountName).get("avgPx");
+            log.info("持仓价格: {}, 当前价格:{},匹配队列中......", avgPx, markPx);
+            // 初始化网格队列
+            PriorityBlockingQueue<AscBigDecimal> queueAsc = WangGeListQueue.getQueueAsc();
+            PriorityBlockingQueue<DescBigDecimal> queueKaiCang = wangGeListService.initKaiCang(avgPx, queueAsc);
+            PriorityBlockingQueue<AscBigDecimal> queuePingCang = wangGeListService.initPingCang(avgPx, queueAsc);
+
+            // 处理订单价格在队列中的情况
+            String orderPrice = OrderInfoWs.getAccountMap(accountName).get("orderPrice");
+            log.info("上一次网格触发价格: {}", orderPrice);
+            handleOrderPriceInQueues(orderPrice, queueKaiCang, queuePingCang);
+            // 判断是加仓还是减仓
+            if (avgPx.compareTo(markPx) > 0) {
+                log.info("开始买入开多...");
+                if (!queueKaiCang.isEmpty()) {
+                    DescBigDecimal kaiCang = queueKaiCang.peek();
+                    log.info("买入开多队列价格{}", kaiCang.getValue());
+                    if (kaiCang != null && markPx.compareTo(kaiCang.getValue()) <= 0 && avgPx.compareTo(kaiCang.getValue()) >= 0) {
+                        log.info("开始买入开多...买入开多队列价格价格大于当前价格{}>{}", kaiCang.getValue(), markPx);
+                        WsMapBuild.saveStringToMap(OrderInfoWs.getAccountMap(accountName), "orderPrice", String.valueOf(markPx));
+                        String side = CoinEnums.SIDE_BUY.getCode();
+                        tradeRequestParam.setSide(side);
+                        String clOrdId = WsParamBuild.getOrderNum(side);
+                        tradeRequestParam.setClOrdId(clOrdId);
+                        String sz = buyCntTimeLongEvent(accountName, avgPx, markPx);
+                        tradeRequestParam.setSz(sz);
+                        log.info("买入开多参数准备成功......");
+                    } else {
+                        log.info("未触发加仓......,等待");
+                    }
+                }else{
+                    // 队列为空
+                    log.info("超出了网格设置...");
+                }
+            } else if (avgPx.compareTo(markPx) < 0) {
+                log.info("开始卖出平多...");
+                if (!queuePingCang.isEmpty()) {
+                    AscBigDecimal pingCang = queuePingCang.peek();
+                    log.info("卖出平多队列价格:{}", pingCang.getValue());
+                    if (pingCang != null && avgPx.compareTo(pingCang.getValue()) < 0) {
+                        log.info("开始卖出平多...卖出平多队列价格大于开仓价格{}>{}", pingCang.getValue(), avgPx);
+                        // 手续费
+                        BigDecimal feeValue = PositionsWs.getAccountMap(positionAccountName).get("fee");
+                        //未实现收益
+                        BigDecimal uplValue = PositionsWs.getAccountMap(positionAccountName).get("upl");
+                        //已实现收益
+                        BigDecimal realizedPnlValue = PositionsWs.getAccountMap(positionAccountName).get("realizedPnl");
+                        realizedPnlValue = realizedPnlValue.add(feeValue);
+
+                        //持仓保证金
+                        BigDecimal imr = PositionsWs.getAccountMap(positionAccountName).get("imr");
+                        String pingCangImr = InstrumentsWs.getAccountMap(accountName).get(CoinEnums.PING_CANG_SHOUYI.name());
+                        BigDecimal imrValue = imr.multiply(new BigDecimal(pingCangImr));
+
+                        if (realizedPnlValue.compareTo(BigDecimal.ZERO) <= 0) {
+                            BigDecimal realizedPnlValueZheng = realizedPnlValue.multiply(new BigDecimal("-1"));
+                            if (uplValue.compareTo(realizedPnlValue) > 0 && uplValue.compareTo(imrValue.add(realizedPnlValueZheng))  >= 0) {
+                                log.info("当前未实现盈亏:{}大于预计收益>{},赚钱咯", uplValue, imrValue.add(realizedPnlValueZheng));
+                                WsMapBuild.saveStringToMap(OrderInfoWs.getAccountMap(accountName), "orderPrice", String.valueOf(markPx));
+                                String side = CoinEnums.SIDE_SELL.getCode();
+                                tradeRequestParam.setSide(side);
+                                String clOrdId = WsParamBuild.getOrderNum(side);
+                                tradeRequestParam.setClOrdId(clOrdId);
+                                BigDecimal sz = PositionsWs.getAccountMap(positionAccountName).get("pos");
+                                tradeRequestParam.setSz(String.valueOf( sz));
+                                log.info("卖出平多参数准备成功......");
+                            }else{
+                                log.info("当前未实现盈亏:{}没有大于预计收益>{},钱在路上了", uplValue, imrValue.add(realizedPnlValueZheng));
+                            }
+                        }else {
+                            if (uplValue.compareTo(imrValue.add(feeValue))  >= 0) {
+                                log.info("当前未实现盈亏:{}大于预计收益>{},赚钱咯", uplValue, imrValue.add(feeValue));
+                                WsMapBuild.saveStringToMap(OrderInfoWs.getAccountMap(accountName), "orderPrice", String.valueOf(markPx));
+                                String side = CoinEnums.SIDE_SELL.getCode();
+                                tradeRequestParam.setSide(side);
+                                String clOrdId = WsParamBuild.getOrderNum(side);
+                                tradeRequestParam.setClOrdId(clOrdId);
+                                BigDecimal sz = PositionsWs.getAccountMap(positionAccountName).get("pos");
+                                tradeRequestParam.setSz(String.valueOf( sz));
+                                log.info("卖出平多参数准备成功......");
+                            }else{
+                                log.info("当前未实现盈亏:{}没有大于预计收益>{},钱在路上了", uplValue, imrValue.add(feeValue));
+                            }
+                        }
+                    } else {
+                        log.info("未触发减仓......,等待");
+                    }
+                }else{
+                    // 队列为空
+                    log.info("超出了网格设置...");
+                }
+            } else {
+                log.info("价格波动较小......,等待");
+            }
+            return tradeRequestParam;
+        } catch (NumberFormatException e) {
+            log.error("开多方向异常", e);
+            return tradeRequestParam;
         }
     }
 
     @Override
-    public String caoZuoLong(String accountName,String markPxStr) {
-        log.info("开始看涨执行操作CaoZuoServiceImpl......");
-        try {
+    public TradeRequestParam caoZuoShort(TradeRequestParam tradeRequestParam) {
+        log.info("开始做{}执行操作CaoZuoServiceImpl......",tradeRequestParam.getPosSide());
 
-            String positionAccountName = PositionsWs.initAccountName(accountName, CoinEnums.POSSIDE_LONG.getCode());
+        String accountName = tradeRequestParam.getAccountName();
+        String markPxStr = tradeRequestParam.getMarkPx();
+        String posSide = tradeRequestParam.getPosSide();
+
+        try {
+            String positionAccountName = PositionsWs.initAccountName(accountName, posSide);
             // 获取标记价格和平均持仓价格
-//            BigDecimal markPx = PositionsWs.getAccountMap(positionAccountName).get("markPx");
             BigDecimal markPx = new BigDecimal(markPxStr);
             BigDecimal avgPx = PositionsWs.getAccountMap(positionAccountName).get("avgPx");
-            log.info("开仓价格: {}, 当前价格:{},匹配队列中......", avgPx, markPx);
+            log.info("持仓价格: {}, 当前价格:{},匹配队列中......", avgPx, markPx);
 
             // 初始化网格队列
             PriorityBlockingQueue<AscBigDecimal> queueAsc = WangGeListQueue.getQueueAsc();
@@ -198,196 +354,99 @@
 
             // 处理订单价格在队列中的情况
             String orderPrice = OrderInfoWs.getAccountMap(accountName).get("orderPrice");
-            log.info("订单价格: {}", orderPrice);
+            log.info("上一次网格触发价格:{}", orderPrice);
             handleOrderPriceInQueues(orderPrice, queueKaiCang, queuePingCang);
             // 判断是加仓还是减仓
             if (avgPx.compareTo(markPx) > 0) {
-                log.info("开始加仓...");
-                if (queueKaiCang.isEmpty()) {
-                    // 队列为空
-                    log.info("开始加仓,但是超出了网格设置...");
-                    return OrderParamEnums.HOLDING.getValue();
-                }
-                DescBigDecimal kaiCang = queueKaiCang.peek();
-                log.info("下限队列价格{}", kaiCang.getValue());
-                if (kaiCang != null && markPx.compareTo(kaiCang.getValue()) <= 0 && avgPx.compareTo(kaiCang.getValue()) >= 0) {
-                    log.info("开始加仓...下限队列价格大于当前价格{}>{}", kaiCang.getValue(), markPx);
-                    WsMapBuild.saveStringToMap(OrderInfoWs.getAccountMap(accountName), "orderPrice", String.valueOf(markPx));
-                    boolean buyCntTimeFlag = buyCntTimeLongEvent(accountName, avgPx, markPx);
-                    if (buyCntTimeFlag){
-                        log.info("加仓参数准备成功......");
-                        return OrderParamEnums.BUY.getValue();
-                    }else{
-                        log.error("加仓参数准备失败......");
-                        return null;
+                log.info("开始买入平空...");
+                if (!queueKaiCang.isEmpty()) {
+                    DescBigDecimal kaiCang = queueKaiCang.peek();
+                    log.info("买入平空队列价格{}", kaiCang.getValue());
+                    if (kaiCang != null && avgPx.compareTo(kaiCang.getValue()) >= 0) {
+                        log.info("开始买入平空...买入平空队列价格小于开仓价格{}<{}", kaiCang.getValue(), avgPx);
+
+                        // 手续费
+                        BigDecimal feeValue = PositionsWs.getAccountMap(positionAccountName).get("fee");
+                        //未实现收益
+                        BigDecimal uplValue = PositionsWs.getAccountMap(positionAccountName).get("upl");
+                        //已实现收益
+                        BigDecimal realizedPnlValue = PositionsWs.getAccountMap(positionAccountName).get("realizedPnl");
+                        realizedPnlValue = realizedPnlValue.add(feeValue);
+
+                        //持仓保证金
+                        BigDecimal imr = PositionsWs.getAccountMap(positionAccountName).get("imr");
+                        String pingCangImr = InstrumentsWs.getAccountMap(accountName).get(CoinEnums.PING_CANG_SHOUYI.name());
+                        BigDecimal imrValue = imr.multiply(new BigDecimal(pingCangImr));
+
+                        if (realizedPnlValue.compareTo(BigDecimal.ZERO) <= 0) {
+                            BigDecimal realizedPnlValueZheng = realizedPnlValue.multiply(new BigDecimal("-1"));
+                            if (uplValue.compareTo(realizedPnlValue) > 0 && uplValue.compareTo(imrValue.add(realizedPnlValueZheng))  >= 0) {
+                                log.info("当前未实现盈亏:{}大于预计收益>{},赚钱咯", uplValue, imrValue.add(realizedPnlValueZheng));
+                                WsMapBuild.saveStringToMap(OrderInfoWs.getAccountMap(accountName), "orderPrice", String.valueOf(markPx));
+                                String side = CoinEnums.SIDE_BUY.getCode();
+                                tradeRequestParam.setSide(side);
+                                String clOrdId = WsParamBuild.getOrderNum(side);
+                                tradeRequestParam.setClOrdId(clOrdId);
+                                BigDecimal sz = PositionsWs.getAccountMap(positionAccountName).get("pos");
+                                tradeRequestParam.setSz(String.valueOf( sz));
+                                log.info("买入平空参数准备成功......");
+                            }else{
+                                log.info("当前未实现盈亏:{}没有大于预计收益>{},钱在路上了", uplValue, imrValue.add(realizedPnlValueZheng));
+                            }
+                        }else {
+                            if (uplValue.compareTo(imrValue.add(feeValue))  >= 0) {
+                                WsMapBuild.saveStringToMap(OrderInfoWs.getAccountMap(accountName), "orderPrice", String.valueOf(markPx));
+                                log.info("当前未实现盈亏:{}大于预计收益>{},赚钱咯", uplValue, imrValue.add(feeValue));
+                                String side = CoinEnums.SIDE_BUY.getCode();
+                                tradeRequestParam.setSide(side);
+                                String clOrdId = WsParamBuild.getOrderNum(side);
+                                tradeRequestParam.setClOrdId(clOrdId);
+                                BigDecimal sz = PositionsWs.getAccountMap(positionAccountName).get("pos");
+                                tradeRequestParam.setSz(String.valueOf( sz));
+                                log.info("买入平空参数准备成功......");
+                            }else{
+                                log.info("当前未实现盈亏:{}没有大于预计收益>{},钱在路上了", uplValue, imrValue.add(feeValue));
+                            }
+                        }
+                    } else {
+                        log.info("未触发减仓......,等待");
                     }
-                } else {
-                    log.info("未触发加仓......,等待");
-                    return OrderParamEnums.HOLDING.getValue();
+                }else{
+                    log.info("开始减仓,但是超出了网格设置...");
                 }
             } else if (avgPx.compareTo(markPx) < 0) {
-                log.info("开始减仓...");
-                if (queuePingCang.isEmpty()) {
-                    // 队列为空
-                    log.info("开始减仓,但是超出了网格设置...");
-                    return OrderParamEnums.HOLDING.getValue();
-                }
-                AscBigDecimal pingCang = queuePingCang.peek();
-                log.info("上限队列价格:{}", pingCang.getValue());
-                if (pingCang != null && avgPx.compareTo(pingCang.getValue()) < 0) {
-                    log.info("开始减仓...上限队列价格大于开仓价格{}>{}", pingCang.getValue(), avgPx);
-                    // 手续费
-                    BigDecimal feeValue = PositionsWs.getAccountMap(positionAccountName).get("fee");
-                    //未实现收益
-                    BigDecimal uplValue = PositionsWs.getAccountMap(positionAccountName).get("upl");
-                    //已实现收益
-                    BigDecimal realizedPnlValue = PositionsWs.getAccountMap(positionAccountName).get("realizedPnl");
-                    realizedPnlValue = realizedPnlValue.add(feeValue);
-
-                    //持仓保证金
-                    BigDecimal imr = PositionsWs.getAccountMap(positionAccountName).get("imr");
-                    String pingCangImr = InstrumentsWs.getAccountMap(accountName).get(CoinEnums.PING_CANG_SHOUYI.name());
-                    BigDecimal imrValue = imr.multiply(new BigDecimal(pingCangImr));
-
-                    if (realizedPnlValue.compareTo(BigDecimal.ZERO) <= 0) {
-                        BigDecimal realizedPnlValueZheng = realizedPnlValue.multiply(new BigDecimal("-1"));
-                        if (uplValue.compareTo(realizedPnlValue) > 0 && uplValue.compareTo(imrValue.add(realizedPnlValueZheng))  >= 0) {
-                            log.info("当前未实现盈亏:{}大于预计收益>{},赚钱咯", uplValue, imrValue.add(realizedPnlValueZheng));
-                            WsMapBuild.saveStringToMap(OrderInfoWs.getAccountMap(accountName), "orderPrice", String.valueOf(markPx));
-                            return OrderParamEnums.SELL.getValue();
-                        }else{
-                            log.info("当前未实现盈亏:{}没有大于预计收益>{},钱在路上了", uplValue, imrValue.add(realizedPnlValueZheng));
-                            return OrderParamEnums.HOLDING.getValue();
-                        }
-                    }else {
-                        if (uplValue.compareTo(imrValue.add(feeValue))  >= 0) {
-                            WsMapBuild.saveStringToMap(OrderInfoWs.getAccountMap(accountName), "orderPrice", String.valueOf(markPx));
-                            log.info("当前未实现盈亏:{}大于预计收益>{},赚钱咯", uplValue, imrValue.add(feeValue));
-                            return OrderParamEnums.SELL.getValue();
-                        }else{
-                            log.info("当前未实现盈亏:{}没有大于预计收益>{},钱在路上了", uplValue, imrValue.add(feeValue));
-                            return OrderParamEnums.HOLDING.getValue();
-                        }
+                log.info("开始卖出开空...");
+                if (!queuePingCang.isEmpty()) {
+                    AscBigDecimal pingCang = queuePingCang.peek();
+                    log.info("上限队列价格: {}", pingCang.getValue());
+                    if (pingCang != null && markPx.compareTo(pingCang.getValue()) >= 0 && avgPx.compareTo(pingCang.getValue()) < 0) {
+                        log.info("开始加仓...上限队列价格小于当前价格{}<={}", pingCang.getValue(), markPx);
+                        WsMapBuild.saveStringToMap(OrderInfoWs.getAccountMap(accountName), "orderPrice", String.valueOf(markPx));
+                        String side = CoinEnums.SIDE_BUY.getCode();
+                        tradeRequestParam.setSide(side);
+                        String clOrdId = WsParamBuild.getOrderNum(side);
+                        tradeRequestParam.setClOrdId(clOrdId);
+                        String sz = buyCntTimeShortEvent(accountName, avgPx, markPx);
+                        tradeRequestParam.setSz(sz);
+                        log.info("卖出开空参数准备成功......");
+                    } else {
+                        log.info("未触发加仓......,等待");
                     }
-                } else {
-                    log.info("未触发减仓......,等待");
+                }else{
+                    // 队列为空
+                    log.info("超出了网格设置...");
                 }
             } else {
                 log.info("价格波动较小......,等待");
             }
-            return null;
+            return tradeRequestParam;
         } catch (NumberFormatException e) {
-            log.error("解析价格失败,请检查Redis中的值是否合法", e);
-            return null;
+            log.error("开空方向异常", e);
+            return tradeRequestParam;
         }
     }
 
-    @Override
-    public String caoZuoShort(String accountName,String markPxStr) {
-        log.info("开始看空执行操作CaoZuoServiceImpl......");
-        try {
-
-
-            String positionAccountName = PositionsWs.initAccountName(accountName, CoinEnums.POSSIDE_SHORT.getCode());
-            // 获取标记价格和平均持仓价格
-//            BigDecimal markPx = PositionsWs.getAccountMap(positionAccountName).get("markPx");
-            BigDecimal markPx = new BigDecimal(markPxStr);
-            BigDecimal avgPx = PositionsWs.getAccountMap(positionAccountName).get("avgPx");
-            log.info("开仓价格: {}, 当前价格:{},匹配队列中......", avgPx, markPx);
-
-            // 初始化网格队列
-            PriorityBlockingQueue<AscBigDecimal> queueAsc = WangGeListQueue.getQueueAsc();
-            PriorityBlockingQueue<DescBigDecimal> queueKaiCang = wangGeListService.initKaiCang(avgPx, queueAsc);
-            PriorityBlockingQueue<AscBigDecimal> queuePingCang = wangGeListService.initPingCang(avgPx, queueAsc);
-
-            // 处理订单价格在队列中的情况
-            String orderPrice = OrderInfoWs.getAccountMap(accountName).get("orderPrice");
-            log.info("订单价格:{}", orderPrice);
-            handleOrderPriceInQueues(orderPrice, queueKaiCang, queuePingCang);
-            // 判断是加仓还是减仓
-            if (avgPx.compareTo(markPx) > 0) {
-                log.info("开始减仓...");
-                if (queueKaiCang.isEmpty()) {
-                    // 队列为空
-                    log.info("开始减仓,但是超出了网格设置...");
-                    return OrderParamEnums.HOLDING.getValue();
-                }
-                DescBigDecimal kaiCang = queueKaiCang.peek();
-                log.info("下限队列价格{}", kaiCang.getValue());
-                if (kaiCang != null && avgPx.compareTo(kaiCang.getValue()) >= 0) {
-                    log.info("开始减仓...下限队列价格小于开仓价格{}<{}", kaiCang.getValue(), avgPx);
-
-                    // 手续费
-                    BigDecimal feeValue = PositionsWs.getAccountMap(positionAccountName).get("fee");
-                    //未实现收益
-                    BigDecimal uplValue = PositionsWs.getAccountMap(positionAccountName).get("upl");
-                    //已实现收益
-                    BigDecimal realizedPnlValue = PositionsWs.getAccountMap(positionAccountName).get("realizedPnl");
-                    realizedPnlValue = realizedPnlValue.add(feeValue);
-
-                    //持仓保证金
-                    BigDecimal imr = PositionsWs.getAccountMap(positionAccountName).get("imr");
-                    String pingCangImr = InstrumentsWs.getAccountMap(accountName).get(CoinEnums.PING_CANG_SHOUYI.name());
-                    BigDecimal imrValue = imr.multiply(new BigDecimal(pingCangImr));
-
-                    if (realizedPnlValue.compareTo(BigDecimal.ZERO) <= 0) {
-                        BigDecimal realizedPnlValueZheng = realizedPnlValue.multiply(new BigDecimal("-1"));
-                        if (uplValue.compareTo(realizedPnlValue) > 0 && uplValue.compareTo(imrValue.add(realizedPnlValueZheng))  >= 0) {
-                            log.info("当前未实现盈亏:{}大于预计收益>{},赚钱咯", uplValue, imrValue.add(realizedPnlValueZheng));
-                            WsMapBuild.saveStringToMap(OrderInfoWs.getAccountMap(accountName), "orderPrice", String.valueOf(markPx));
-                            return OrderParamEnums.BUY.getValue();
-                        }else{
-                            log.info("当前未实现盈亏:{}没有大于预计收益>{},钱在路上了", uplValue, imrValue.add(realizedPnlValueZheng));
-                            return OrderParamEnums.HOLDING.getValue();
-                        }
-                    }else {
-                        if (uplValue.compareTo(imrValue.add(feeValue))  >= 0) {
-                            WsMapBuild.saveStringToMap(OrderInfoWs.getAccountMap(accountName), "orderPrice", String.valueOf(markPx));
-                            log.info("当前未实现盈亏:{}大于预计收益>{},赚钱咯", uplValue, imrValue.add(feeValue));
-                            return OrderParamEnums.BUY.getValue();
-                        }else{
-                            log.info("当前未实现盈亏:{}没有大于预计收益>{},钱在路上了", uplValue, imrValue.add(feeValue));
-                            return OrderParamEnums.HOLDING.getValue();
-                        }
-                    }
-                } else {
-                    log.info("未触发减仓......,等待");
-                    return OrderParamEnums.HOLDING.getValue();
-                }
-            } else if (avgPx.compareTo(markPx) < 0) {
-                log.info("开始加仓...");
-                if (queuePingCang.isEmpty()) {
-                    // 队列为空
-                    log.info("开始加仓,但是超出了网格设置...");
-                    return OrderParamEnums.HOLDING.getValue();
-                }
-                AscBigDecimal pingCang = queuePingCang.peek();
-                log.info("上限队列价格: {}", pingCang.getValue());
-                if (pingCang != null && markPx.compareTo(pingCang.getValue()) >= 0 && avgPx.compareTo(pingCang.getValue()) < 0) {
-                    log.info("开始加仓...上限队列价格小于当前价格{}<={}", pingCang.getValue(), markPx);
-                    WsMapBuild.saveStringToMap(OrderInfoWs.getAccountMap(accountName), "orderPrice", String.valueOf(markPx));
-                    boolean buyCntTimeFlag = buyCntTimeShortEvent(accountName, avgPx, markPx);
-                    if (buyCntTimeFlag){
-                        log.info("加仓参数准备成功......");
-                        return OrderParamEnums.SELL.getValue();
-                    }else{
-                        log.error("加仓参数准备失败......");
-                        return null;
-                    }
-                } else {
-                    log.info("未触发加仓......,等待");
-                }
-            } else {
-                log.info("价格波动较小......,等待");
-            }
-            return null;
-        } catch (NumberFormatException e) {
-            log.error("解析价格失败,请检查Redis中的值是否合法", e);
-            return null;
-        }
-    }
-
-    private boolean buyCntTimeLongEvent(String accountName, BigDecimal avgPx, BigDecimal markPx){
+    private String buyCntTimeLongEvent(String accountName, BigDecimal avgPx, BigDecimal markPx){
         //判断当前价格和开仓价格直接间隔除以间距,取整,获取的数量是否大于等于0,如果大于0,则下单基础张数*倍数
         String buyCntTime = InstrumentsWs.getAccountMap(accountName).get(CoinEnums.BUY_CNT_TIME.name());
         log.info("倍数次数间隔{}", buyCntTime);
@@ -395,26 +454,21 @@
         log.info("倍数价格差距{}", subtract);
         BigDecimal divide = subtract.divide(new BigDecimal(buyCntTime), 0, RoundingMode.DOWN).add(BigDecimal.ONE);
         log.info("倍数次数{}", divide);
-        if (divide.compareTo(BigDecimal.ZERO) <= 0){
-            log.warn("加仓次数间隔时间小于0,不加仓");
-            return false;
-        }
-        return WsMapBuild.saveStringToMap(TradeOrderWs.getAccountMap(accountName), "buyCntTime",String.valueOf(divide));
+        String buyCntInit = InstrumentsWs.getAccountMap(accountName).get(CoinEnums.BUY_CNT_INIT.name());
+        return String.valueOf(divide.multiply(new BigDecimal(buyCntInit)));
     }
 
-    private boolean buyCntTimeShortEvent(String accountName, BigDecimal avgPx, BigDecimal markPx){
+    private String buyCntTimeShortEvent(String accountName, BigDecimal avgPx, BigDecimal markPx){
         //判断当前价格和开仓价格直接间隔除以间距,取整,获取的数量是否大于等于0,如果大于0,则下单基础张数*倍数
+
         String buyCntTime = InstrumentsWs.getAccountMap(accountName).get(CoinEnums.BUY_CNT_TIME.name());
         log.info("倍数次数间隔{}", buyCntTime);
         BigDecimal subtract = markPx.subtract(avgPx);
         log.info("倍数价格差距{}", subtract);
         BigDecimal divide = subtract.divide(new BigDecimal(buyCntTime), 0, RoundingMode.DOWN).add(BigDecimal.ONE);
         log.info("倍数次数{}", divide);
-        if (divide.compareTo(BigDecimal.ZERO) <= 0){
-            log.warn("加仓次数间隔时间小于0,不加仓");
-            return false;
-        }
-        return WsMapBuild.saveStringToMap(TradeOrderWs.getAccountMap(accountName), "buyCntTime",String.valueOf(divide));
+        String buyCntInit = InstrumentsWs.getAccountMap(accountName).get(CoinEnums.BUY_CNT_INIT.name());
+        return String.valueOf(divide.multiply(new BigDecimal(buyCntInit)));
     }
 
     /**
diff --git a/src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/AccountWs.java b/src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/AccountWs.java
index 1e60135..3d5fe77 100644
--- a/src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/AccountWs.java
+++ b/src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/AccountWs.java
@@ -115,6 +115,7 @@
     public static final String cashBalKey = "cashBal";
     public static final String eqKey = "eq";
     public static final String uplKey = "upl";
+    public static final String imrKey = "imr";
     private static void initParam(JSONObject detail, String accountName) {
         Map<String, String> accountMap = getAccountMap(accountName);
 
@@ -133,6 +134,8 @@
         String upl = WsMapBuild.parseStringSafe(detail.getString(uplKey));
         WsMapBuild.saveStringToMap(accountMap, uplKey, upl);
 
+        String imr = WsMapBuild.parseStringSafe(detail.getString(imrKey));
+        WsMapBuild.saveStringToMap(accountMap, imrKey, imr);
         BigDecimal cashBalDecimal = WsMapBuild.parseBigDecimalSafe(cashBal);
         // 根据可用余额计算下单总保证金
         String total_order_usdtpecent = InstrumentsWs.getAccountMap(accountName).get(CoinEnums.TOTAL_ORDER_USDTPECENT.name());
@@ -140,11 +143,17 @@
         BigDecimal totalOrderUsdt = cashBalDecimal.multiply(total_order_usdt_factor).setScale(2, RoundingMode.DOWN);
         WsMapBuild.saveStringToMap(accountMap, CoinEnums.TOTAL_ORDER_USDT.name(), String.valueOf(totalOrderUsdt));
 
-        WsMapBuild.saveStringToMap(accountMap, CoinEnums.READY_STATE.name(), CoinEnums.READY_STATE_YES.getCode());
+        /**
+         * 当前账户未满仓,并且账户余额不为0,才更新为已就绪
+         */
+        BigDecimal imrDecimal = WsMapBuild.parseBigDecimalSafe(imr);
+        if (BigDecimal.ZERO.compareTo(cashBalDecimal) < 0 && imrDecimal.compareTo(totalOrderUsdt) < 0){
+            WsMapBuild.saveStringToMap(accountMap, CoinEnums.READY_STATE.name(), CoinEnums.READY_STATE_YES.getCode());
+        }
 
         log.info(
-                "{}: 账户详情-币种: {}, 可用余额: {}, 现金余额: {}, 余额: {}, 全仓未实现盈亏: {}, 下单总保证金: {}",
-                accountName, ccy, availBal, cashBal, eq, upl, totalOrderUsdt
+                "{}: 账户详情-币种: {}, 可用余额: {}, 现金余额: {}, 余额: {}, 全仓未实现盈亏: {}, 下单总保证金: {},已使用保证金:{}",
+                accountName, ccy, availBal, cashBal, eq, upl, totalOrderUsdt,imr
         );
     }
 }
diff --git a/src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/OrderInfoWs.java b/src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/OrderInfoWs.java
index 6c68e71..92d76f8 100644
--- a/src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/OrderInfoWs.java
+++ b/src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/OrderInfoWs.java
@@ -67,7 +67,7 @@
     private static final String STATE_KEY = "state";
     public static void handleEvent(JSONObject response, RedisUtils redisUtils, String accountName) {
 
-//        log.info("开始执行OrderInfoWs......");
+        log.info("开始执行OrderInfoWs......");
         try {
             JSONArray dataArray = response.getJSONArray(DATA_KEY);
             if (dataArray == null || dataArray.isEmpty()) {
@@ -113,14 +113,6 @@
                         WsMapBuild.saveStringToMap(accountMap, "orderPrice",avgPx);
                     }
                     WsMapBuild.saveStringToMap(TradeOrderWs.getAccountMap(accountName), "state", CoinEnums.ORDER_LIVE.getCode());
-
-                    //保存上一个网格信息
-                    WangGeListEnum gridByPrice = WangGeListEnum.getGridByPrice(new BigDecimal(avgPx));
-                    if (gridByPrice != null){
-                        log.info("保存上一个网格: {}", gridByPrice.name());
-                        Map<String, String> instrumentsMap = InstrumentsWs.getAccountMap(accountName);
-                        WsMapBuild.saveStringToMap(instrumentsMap, CoinEnums.WANG_GE_OLD.name(), gridByPrice.name());
-                    }
 
                     // 使用账号特定的Map
                     String positionAccountName = PositionsWs.initAccountName(accountName, side);
diff --git a/src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/PositionsWs.java b/src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/PositionsWs.java
index a27dad2..73953c5 100644
--- a/src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/PositionsWs.java
+++ b/src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/PositionsWs.java
@@ -108,10 +108,6 @@
                             markPx,fee,fundingFee
                     );
                     initParam(posData, accountName,posSide);
-
-                    String accountNamePositons = initAccountName(accountName, posSide);
-                    Map<String, BigDecimal> accountMap = getAccountMap(accountNamePositons);
-                    WsMapBuild.saveBigDecimalToMap(accountMap, CoinEnums.READY_STATE.name(), WsMapBuild.parseBigDecimalSafe(CoinEnums.READY_STATE_YES.getCode()));
                 }
             }
         } catch (Exception e) {
@@ -132,5 +128,7 @@
         WsMapBuild.saveBigDecimalToMap(accountMap, "realizedPnl", WsMapBuild.parseBigDecimalSafe(posData.getString("realizedPnl")));
         WsMapBuild.saveBigDecimalToMap(accountMap, "fee", WsMapBuild.parseBigDecimalSafe(posData.getString("fee")));
         WsMapBuild.saveBigDecimalToMap(accountMap, "fundingFee", WsMapBuild.parseBigDecimalSafe(posData.getString("fundingFee")));
+
+        WsMapBuild.saveBigDecimalToMap(accountMap, CoinEnums.READY_STATE.name(), WsMapBuild.parseBigDecimalSafe(CoinEnums.READY_STATE_YES.getCode()));
     }
 }
diff --git a/src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/TradeOrderWs.java b/src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/TradeOrderWs.java
index be34982..6a7a700 100644
--- a/src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/TradeOrderWs.java
+++ b/src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/TradeOrderWs.java
@@ -5,6 +5,7 @@
 import com.alibaba.fastjson.JSONObject;
 import com.xcong.excoin.modules.okxNewPrice.okxWs.enums.CoinEnums;
 import com.xcong.excoin.modules.okxNewPrice.okxWs.enums.OrderParamEnums;
+import com.xcong.excoin.modules.okxNewPrice.okxWs.param.TradeRequestParam;
 import com.xcong.excoin.modules.okxNewPrice.utils.WsMapBuild;
 import com.xcong.excoin.modules.okxNewPrice.utils.WsParamBuild;
 import lombok.extern.slf4j.Slf4j;
@@ -32,113 +33,103 @@
 
     public static final String ORDERWS_CHANNEL = "order";
 
-    public static void orderEvent(WebSocketClient webSocketClient, String side, String accountName) {
+    public static void orderEvent(WebSocketClient webSocketClient, TradeRequestParam tradeRequestParam) {
 
-//        log.info("开始执行TradeOrderWs......");
-        String accountReadyState = AccountWs.getAccountMap(accountName).get(CoinEnums.READY_STATE.name());
-        if (!CoinEnums.READY_STATE_YES.getCode().equals(accountReadyState)) {
-            log.info("账户通道未就绪,取消发送");
+
+        log.info("开始执行TradeOrderWs......");
+        String accountName = tradeRequestParam.getAccountName();
+        String markPx = tradeRequestParam.getMarkPx();
+        String instId = tradeRequestParam.getInstId();
+        String tdMode = tradeRequestParam.getTdMode();
+        String posSide = tradeRequestParam.getPosSide();
+        String ordType = tradeRequestParam.getOrdType();
+
+        String tradeType = tradeRequestParam.getTradeType();
+
+        String clOrdId = tradeRequestParam.getClOrdId();
+        String side = tradeRequestParam.getSide();
+        String sz = tradeRequestParam.getSz();
+        log.info("账户:{},触发价格:{},币种:{},方向:{},买卖:{},数量:{},是否允许下单:{},编号:{},", accountName, markPx, instId, posSide,side,  sz, tradeType, clOrdId);
+        //验证是否允许下单
+        if (StrUtil.isNotEmpty(tradeType) && OrderParamEnums.TRADE_NO.getValue().equals(tradeType)) {
+            log.warn("账户{}不允许下单,取消发送", accountName);
             return;
         }
-        String posSide = InstrumentsWs.getAccountMap(accountName).get(CoinEnums.POSSIDE.name());
+        /**
+         * 校验必要参数
+         * 验证下单参数是否存在空值
+         */
+        if (
+                StrUtil.isBlank(accountName)
+                        || StrUtil.isBlank(instId)
+                        || StrUtil.isBlank(tdMode)
+                        || StrUtil.isBlank(posSide)
+                        || StrUtil.isBlank(ordType)
+                        || StrUtil.isBlank(clOrdId)
+                        || StrUtil.isBlank(side)
+                        || StrUtil.isBlank(sz)
+
+        ){
+            log.warn("下单参数缺失,取消发送");
+            return;
+        }
+
+        /**
+         * 检验账户和仓位是否准备就绪
+         * 开多:买入开多(side 填写 buy; posSide 填写 long )
+         * 开空:卖出开空(side 填写 sell; posSide 填写 short ) 需要检验账户通道是否准备就绪
+         * 平多:卖出平多(side 填写 sell;posSide 填写 long )
+         * 平空:买入平空(side 填写 buy; posSide 填写 short ) 需要检验仓位通道是否准备就绪
+         */
+
         String positionAccountName = PositionsWs.initAccountName(accountName, posSide);
-        BigDecimal positionsReadyState = PositionsWs.getAccountMap(positionAccountName).get(CoinEnums.READY_STATE.name()) == null
-                ? BigDecimal.ZERO : PositionsWs.getAccountMap(positionAccountName).get(CoinEnums.READY_STATE.name());
-        if (WsMapBuild.parseBigDecimalSafe(CoinEnums.READY_STATE_YES.getCode()).compareTo(positionsReadyState) != 0) {
-            log.info("仓位{}通道未就绪,取消发送",positionAccountName);
-            return;
-        }
-        // 校验必要参数
-        if (StrUtil.isBlank(side)) {
-            log.warn("下单参数 side 为空,取消发送");
-            return;
-        }
-        // 校验必要参数
-        if (StrUtil.isBlank(posSide)) {
-            log.warn("下单参数 posSide 为空,取消发送");
-            return;
-        }
-
-        String buyCnt = "";
-        if (CoinEnums.POSSIDE_LONG.getCode().equals(posSide)){
-            if (OrderParamEnums.HOLDING.getValue().equals(side)){
-                log.info("当前状态为持仓中,取消发送");
-                return;
-            }else if (OrderParamEnums.OUT.getValue().equals(side)){
-                log.info("当前状态为止损");
-                side = OrderParamEnums.SELL.getValue();
-                buyCnt = String.valueOf(PositionsWs.getAccountMap(positionAccountName).get("pos"));
-            }else if (OrderParamEnums.INIT.getValue().equals(side)){
-                log.info("当前状态为初始化");
-                side = OrderParamEnums.BUY.getValue();
-                buyCnt = InstrumentsWs.getAccountMap(accountName).get(CoinEnums.BUY_CNT_INIT.name());
-            }else if (OrderParamEnums.BUY.getValue().equals(side)){
-                log.info("当前状态为加仓");
-                String buyCntTime = getAccountMap(accountName).get("buyCntTime");
-                String buyCntStr = InstrumentsWs.getAccountMap(accountName).get(CoinEnums.BUY_CNT.name());
-                buyCnt = String.valueOf(new BigDecimal(buyCntTime).multiply(new BigDecimal(buyCntStr)));
-            }else if (OrderParamEnums.SELL.getValue().equals(side)){
-                log.info("当前状态为减仓");
-                buyCnt = String.valueOf(PositionsWs.getAccountMap(positionAccountName).get("pos"));
-            }else{
-                log.warn("交易状态异常,取消发送");
+        if (
+                (posSide.equals(CoinEnums.POSSIDE_LONG.getCode()) && side.equals(CoinEnums.SIDE_BUY.getCode()))
+                || (posSide.equals(CoinEnums.POSSIDE_SHORT.getCode()) && side.equals(CoinEnums.SIDE_SELL.getCode()))
+        ){
+            String accountReadyState = AccountWs.getAccountMap(accountName).get(CoinEnums.READY_STATE.name());
+            if (!CoinEnums.READY_STATE_YES.getCode().equals(accountReadyState)) {
+                log.info("账户通道未就绪,取消发送");
                 return;
             }
-        }else if (CoinEnums.POSSIDE_SHORT.getCode().equals(posSide)){
-            if (OrderParamEnums.HOLDING.getValue().equals(side)){
-                log.info("当前状态为持仓中,取消发送");
-                return;
-            }else if (OrderParamEnums.OUT.getValue().equals(side)){
-                log.info("当前状态为止损");
-                side = OrderParamEnums.BUY.getValue();
-                buyCnt = String.valueOf(PositionsWs.getAccountMap(positionAccountName).get("pos"));
-            }else if (OrderParamEnums.INIT.getValue().equals(side)){
-                log.info("当前状态为初始化");
-                side = OrderParamEnums.SELL.getValue();
-                buyCnt = InstrumentsWs.getAccountMap(accountName).get(CoinEnums.BUY_CNT_INIT.name());
-            }else if (OrderParamEnums.BUY.getValue().equals(side)){
-                log.info("当前状态为减仓");
-                buyCnt = String.valueOf(PositionsWs.getAccountMap(positionAccountName).get("pos"));
-            }else if (OrderParamEnums.SELL.getValue().equals(side)){
-                log.info("当前状态为加仓");
-                String buyCntTime = getAccountMap(accountName).get("buyCntTime");
-                String buyCntStr = InstrumentsWs.getAccountMap(accountName).get(CoinEnums.BUY_CNT.name());
-                buyCnt = String.valueOf(new BigDecimal(buyCntTime).multiply(new BigDecimal(buyCntStr)));
-            }else{
-                log.warn("交易状态异常,取消发送");
+        }else if (
+                (posSide.equals(CoinEnums.POSSIDE_LONG.getCode()) && side.equals(CoinEnums.SIDE_SELL.getCode()))
+                || (posSide.equals(CoinEnums.POSSIDE_SHORT.getCode()) && side.equals(CoinEnums.SIDE_BUY.getCode()))
+        ) {
+            BigDecimal positionsReadyState = PositionsWs.getAccountMap(positionAccountName).get(CoinEnums.READY_STATE.name()) == null
+                    ? BigDecimal.ZERO : PositionsWs.getAccountMap(positionAccountName).get(CoinEnums.READY_STATE.name());
+            if (WsMapBuild.parseBigDecimalSafe(CoinEnums.READY_STATE_YES.getCode()).compareTo(positionsReadyState) != 0) {
+                log.info("仓位{}通道未就绪,取消发送",positionAccountName);
                 return;
             }
-        }
-
-
-        if (StrUtil.isBlank(buyCnt)) {
-            log.warn("下单数量 buyCnt 为空,取消发送");
+        }else{
+            log.info("下单构建失败{},{},取消发送",posSide, side);
             return;
         }
 
         try {
-            String clOrdId = WsParamBuild.getOrderNum(side);
             JSONArray argsArray = new JSONArray();
             JSONObject args = new JSONObject();
-            args.put("instId", CoinEnums.HE_YUE.getCode());
-            args.put("tdMode", CoinEnums.CROSS.getCode());
+            args.put("instId", instId);
+            args.put("tdMode", tdMode);
             args.put("clOrdId", clOrdId);
             args.put("side", side);
 
             args.put("posSide", posSide);
-            args.put("ordType", CoinEnums.ORDTYPE_MARKET.getCode());
-            args.put("sz", buyCnt);
+            args.put("ordType", ordType);
+            args.put("sz", sz);
             argsArray.add(args);
 
             String connId = WsParamBuild.getOrderNum(ORDERWS_CHANNEL);
             JSONObject jsonObject = WsParamBuild.buildJsonObject(connId, ORDERWS_CHANNEL, argsArray);
             webSocketClient.send(jsonObject.toJSONString());
-            log.info("发送下单频道:{},数量:{}", side, buyCnt);
+            log.info("发送下单频道:{},数量:{}", side, sz);
 
-            WsMapBuild.saveStringToMap(getAccountMap(accountName), "buyCntTime",String.valueOf(BigDecimal.ONE));
             WsMapBuild.saveStringToMap(getAccountMap(accountName), "clOrdId", clOrdId);
             WsMapBuild.saveStringToMap(getAccountMap(accountName), "state", CoinEnums.ORDER_FILLED.getCode());
-
+            /**
+             * 将状态更新为未准备就绪
+             */
             WsMapBuild.saveBigDecimalToMap(PositionsWs.getAccountMap(positionAccountName), CoinEnums.READY_STATE.name(), WsMapBuild.parseBigDecimalSafe(CoinEnums.READY_STATE_NO.getCode()));
             WsMapBuild.saveStringToMap(AccountWs.getAccountMap(accountName), CoinEnums.READY_STATE.name(), CoinEnums.READY_STATE_NO.getCode());
 
diff --git a/src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/enums/CoinEnums.java b/src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/enums/CoinEnums.java
index 3e15849..061c17b 100644
--- a/src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/enums/CoinEnums.java
+++ b/src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/enums/CoinEnums.java
@@ -44,10 +44,10 @@
 
     PING_CANG_SHOUYI("平仓收益比例", "0.1"),
     //下单的总保障金为账户总金额cashBal * TOTAL_ORDER_USDT用来做保证金
-    TOTAL_ORDER_USDTPECENT("总保证金比例total_order_usdtpecent","0.05"),
+    TOTAL_ORDER_USDTPECENT("总保证金比例total_order_usdtpecent","0.1"),
     TOTAL_ORDER_USDT("总保证金totalOrderUsdt","0"),
-    KANG_CANG("抗压比例KANG_CANG","0.8"),
-    ZHI_SUN("止损比例ZHI_SUN","0.6"),
+    KANG_CANG("抗压比例KANG_CANG","0.9"),
+    ZHI_SUN("止损比例ZHI_SUN","0.8"),
     //每次下单的张数
     BUY_CNT("每次开仓的张数buyCnt","0.1"),
     BUY_CNT_INIT("每次初始化开仓张数的基础值buyCntInit","0.2"),
diff --git a/src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/enums/OrderParamEnums.java b/src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/enums/OrderParamEnums.java
index aa1256d..981203e 100644
--- a/src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/enums/OrderParamEnums.java
+++ b/src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/enums/OrderParamEnums.java
@@ -9,6 +9,10 @@
 
 @Getter
 public enum OrderParamEnums {
+
+    TRADE_YES("允许下单", "TRADE_YES"),
+    TRADE_NO("拒绝下单", "TRADE_NO"),
+
     OUT_NO("操作中", "操作中"),
     OUT_YES("冷静中", "冷静中"),
 
diff --git a/src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/param/TradeRequestParam.java b/src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/param/TradeRequestParam.java
new file mode 100644
index 0000000..14260d7
--- /dev/null
+++ b/src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/param/TradeRequestParam.java
@@ -0,0 +1,32 @@
+package com.xcong.excoin.modules.okxNewPrice.okxWs.param;
+
+import lombok.Data;
+
+/**
+ * @author Administrator
+ */
+@Data
+public class TradeRequestParam {
+    /**
+     * 这些参数由 caoZuoHandler方法提供
+     */
+    private String accountName;
+    private String markPx;
+
+    private String instId;
+    private String tdMode;
+    private String posSide;
+    private String ordType;
+
+    /**
+     * 决定是否进行下单操作
+     */
+    private String tradeType;
+    /**
+     * 这些参数由 caoZuoLong 或者 caoZuoShort 提供
+     */
+    private String side;
+    private String clOrdId;
+    private String sz;
+
+}

--
Gitblit v1.9.1