11 files modified
570 ■■■■■ changed files
src/main/java/com/xcong/excoin/modules/newPrice/OkxNewPriceWebSocketClient.java 4 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/okxNewPrice/OKX_QUANT_DOCUMENTATION.md 503 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/okxNewPrice/OkxNewPriceWebSocketClient.java 6 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/okxNewPrice/OkxQuantWebSocketClient.java 2 ●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/okxNewPrice/celue/CaoZuoServiceImpl.java 6 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/PositionsWs.java 9 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/TradeOrderWs.java 3 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/enums/CoinEnums.java 8 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/enums/ExchangeInfoEnum.java 14 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/wanggeList/WangGeListEnum.java 10 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/wanggeList/WangGeListServiceImpl.java 5 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/newPrice/OkxNewPriceWebSocketClient.java
@@ -30,7 +30,7 @@
 */
@Slf4j
@Component
@ConditionalOnProperty(prefix = "app", name = "quant", havingValue = "true")
@ConditionalOnProperty(prefix = "app", name = "websocket", havingValue = "true")
public class OkxNewPriceWebSocketClient {
    @Resource
    private WebsocketPriceService websocketPriceService;
@@ -301,7 +301,7 @@
     */
    private void reconnectWithBackoff() throws InterruptedException {
        int attempt = 0;
        int maxAttempts = 5;
        int maxAttempts = 3;
        long delayMs = 5000;
        while (attempt < maxAttempts) {
src/main/java/com/xcong/excoin/modules/okxNewPrice/OKX_QUANT_DOCUMENTATION.md
@@ -1,254 +1,333 @@
# OKX量化交易模块技术文档
# OKX 量化交易系统文档
## 1. 包结构
## 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参数构建工具
com.xcong.excoin.modules.okxNewPrice/
├── celue/                    # 策略实现模块
│   ├── CaoZuoService.java    # 策略接口
│   └── CaoZuoServiceImpl.java # 策略实现类
├── jiaoyi/                   # 交易相关模块
├── okxWs/                    # OKX WebSocket 相关类
│   ├── enums/                # WebSocket 相关枚举
│   ├── param/                # WebSocket 请求参数
│   ├── wanggeList/           # 网格列表管理
│   ├── AccountWs.java        # 账户信息处理
│   ├── BalanceAndPositionWs.java # 余额和持仓处理
│   ├── InstrumentsWs.java    # 合约信息处理
│   ├── LoginWs.java          # 登录处理
│   ├── OrderInfoWs.java      # 订单信息处理
│   ├── PositionsWs.java      # 持仓信息处理
│   └── TradeOrderWs.java     # 交易订单处理
├── okxpi/                    # OKX API 接口封装
├── utils/                    # 工具类
├── wangge/                   # 网格相关模块
├── zhanghu/                  # 账户相关模块
├── OkxNewPriceWebSocketClient.java # 价格 WebSocket 客户端
├── OkxQuantWebSocketClient.java # 量化交易 WebSocket 客户端
├── OkxWebSocketClientManager.java # WebSocket 客户端管理器
└── OKX_QUANT_DOCUMENTATION.md # 本文档
```
## 2. 核心组件说明
### 2.1 WebSocket客户端管理
### 2.1 WebSocket 客户端管理
#### OkxWebSocketClientManager
- **功能**:管理所有OKX WebSocket客户端实例,包括价格客户端和多账号量化客户端
- **核心特性**:
  - 统一初始化、连接和销毁管理
  - 多账号客户端映射(accountName → OkxQuantWebSocketClient)
  - 单一价格客户端管理
- **关键方法**:
  - `init()`:初始化所有客户端
  - `destroy()`:销毁所有客户端
  - `getAllClients()`:获取所有账号客户端
### 2.2 WebSocket客户端
**功能**:集中管理多个 OKX WebSocket 客户端实例,包括价格客户端和账号客户端。
**核心属性**:
- `quantClientMap`: 存储所有账号的 `OkxQuantWebSocketClient` 实例
- `newPriceClient`: 存储价格数据的 `OkxNewPriceWebSocketClient` 实例
**主要方法**:
- `init()`: 初始化所有 WebSocket 客户端
- `destroy()`: 销毁所有 WebSocket 客户端资源
- `getClient()`: 获取指定账号的 WebSocket 客户端
- `getAllClients()`: 获取所有账号的 WebSocket 客户端
**使用流程**:
1. Spring 容器启动时自动调用 `init()` 方法
2. 初始化 `OkxNewPriceWebSocketClient` 用于获取价格数据
3. 为每个账号创建 `OkxQuantWebSocketClient` 实例
4. 所有客户端统一由管理器进行生命周期管理
### 2.2 价格 WebSocket 客户端
#### OkxNewPriceWebSocketClient
- **功能**:连接OKX公共WebSocket接口,获取实时标记价格
- **核心特性**:
  - 心跳检测和自动重连
  - 价格数据解析和Redis存储
  - 价格变化触发策略执行
- **关键流程**:
  - `init()` → `connect()` → `subscribeChannels()` → 接收价格数据 → `processPushData()` → `triggerQuantOperations()`
**功能**:连接 OKX 公共 WebSocket 接口,实时获取标记价格数据,并触发量化交易操作。
**核心属性**:
- `webSocketClient`: WebSocket 连接客户端
- `isConnected/isConnecting/isInitialized`: 连接状态标志
- `lastMessageTime`: 最后收到消息的时间
**主要方法**:
- `init()`: 初始化 WebSocket 客户端
- `destroy()`: 销毁 WebSocket 客户端资源
- `connect()`: 建立 WebSocket 连接
- `startHeartbeat()`: 启动心跳检测
- `processPushData()`: 处理价格推送数据
- `triggerQuantOperations()`: 触发量化交易操作
**价格处理流程**:
1. 连接 OKX WebSocket 公共接口
2. 订阅标记价格通道
3. 收到价格数据后保存到 Redis
4. 调用 `triggerQuantOperations()` 触发量化交易
5. 实现心跳检测和自动重连机制
### 2.3 账号 WebSocket 客户端
#### OkxQuantWebSocketClient
- **功能**:连接OKX私有WebSocket接口,处理账号相关数据
- **核心特性**:
  - 账号登录认证
  - 订阅账号、订单、仓位等私有频道
  - 处理私有数据推送
- **关键流程**:
  - `init()` → `connect()` → `websocketLogin()` → 订阅私有频道 → 接收数据
### 2.3 策略执行层
**功能**:连接 OKX 私有 WebSocket 接口,处理账号登录、持仓、订单等私有数据。
#### CaoZuoService
- **功能**:执行量化交易策略,决定买卖操作方向
- **核心方法**:
  - `caoZuo(String accountName)`:根据账号执行策略
  - `caoZuoLong(String accountName, String markPx)`:多头策略执行
  - `caoZuoShort(String accountName, String markPx)`:空头策略执行
- **策略逻辑**:
  - 根据当前价格确定所在网格位置
  - 结合网格方向参数决定操作方向
  - 考虑仓位状态和风险控制
**核心属性**:
- `account`: 账号信息枚举
- `webSocketClient`: WebSocket 连接客户端
- `isConnected/isConnecting`: 连接状态标志
### 2.4 数据管理
**主要方法**:
- `init()`: 初始化 WebSocket 客户端
- `destroy()`: 销毁 WebSocket 客户端资源
- `connect()`: 建立 WebSocket 连接
- `websocketLogin()`: 账号登录
- `subscribeChannels()`: 订阅私有通道
- `processPushData()`: 处理数据推送
#### PositionsWs
- **功能**:管理账户仓位数据,支持多空方向分离
- **核心特性**:
  - 双层Map存储:accountName → dataKey → value
  - 支持多空方向分离(accountName_posSide)
  - 数据就绪状态标记
- **关键方法**:
  - `initAccountName(String accountName, String posSide)`:初始化带多空方向的账号名
  - `handleEvent(JSONObject response, String accountName)`:处理仓位数据推送
**登录与订阅流程**:
1. 连接 OKX WebSocket 私有接口
2. 发送登录请求
3. 登录成功后订阅账户、持仓、订单等通道
4. 接收并处理私有数据推送
5. 实现心跳检测和自动重连机制
### 2.5 网格策略
## 3. 网格策略实现
### 3.1 网格配置
#### WangGeListEnum
- **功能**:定义网格策略参数
- **核心参数**:
  - `jiage_shangxian`:价格上限
  - `jiage_xiaxian`:价格下限
  - `fang_xiang`:操作方向(long/short)
  - `jian_ju`:网格间距
- **关键方法**:
  - `getGridByPrice(BigDecimal price)`:根据当前价格获取匹配的网格
## 3. 业务流程
**功能**:定义不同价格区间的网格参数,包括价格上下限、方向、步距等。
### 3.1 系统初始化流程
**核心属性**:
- `name`: 网格名称
- `jiage_shangxian`: 价格上限
- `jiage_xiaxian`: 价格下限
- `jian_ju`: 网格步距
- `fang_xiang`: 持仓方向 (long/short)
- `zhi_sun_dian`: 止损点
```
1. Spring容器启动,OkxWebSocketClientManager初始化
2. 创建OkxNewPriceWebSocketClient实例并初始化
3. 遍历ExchangeInfoEnum,为每个账号创建OkxQuantWebSocketClient实例
4. 所有客户端建立WebSocket连接并进行认证
5. 订阅相应的WebSocket频道
```
**主要方法**:
- `getGridByPrice()`: 根据当前价格获取对应的网格
### 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");
CENTER("中间做多", "2", "3000", "2900", "2", "long", "2900"),
CENTER_ONE("中间做空", "2", "2900", "2870", "2", "short", "2870"),
DOWN("下层做多", "2", "2870", "2850", "2", "long", "2850");
```
**扩展建议**:
- 将网格参数迁移到数据库或配置文件
- 实现动态加载和更新网格策略
- 支持网格策略的增删改查操作
### 3.2 策略实现
### 6.2 账号配置
账号信息通过`ExchangeInfoEnum`配置,每个枚举值对应一个交易账号。
#### CaoZuoService/CaoZuoServiceImpl
### 6.3 性能优化
- **线程池管理**:合理配置线程池大小,避免资源浪费
- **连接复用**:考虑连接复用策略,减少连接数量
- **数据缓存**:合理使用缓存,减少重复计算
**功能**:实现量化交易策略逻辑,包括加仓、减仓、止损等操作。
## 7. 开发与维护
**核心方法**:
- `caoZuoHandler()`: 主要策略逻辑入口
- `caoZuoZhiSunEvent()`: 止损事件处理
- `caoZuoInitEvent()`: 初始化订单处理
- `chooseEvent()`: 事件选择处理
- `caoZuoLong()`: 多头策略处理
- `caoZuoShort()`: 空头策略处理
### 7.1 开发流程
1. 理解现有策略逻辑和数据流
2. 根据需求修改或扩展策略
3. 更新相关配置(如网格参数)
4. 测试策略有效性
5. 部署到生产环境
**策略执行流程**:
1. 检查账户状态和系统开关
2. 判断当前价格所在网格
3. 检查是否需要止损
4. 检查持仓状态:
   - 无持仓:执行初始化订单
   - 有持仓:根据网格策略决定加仓或减仓
5. 根据多空方向执行相应策略
### 7.2 常见问题
### 3.3 订单执行
**问题1**:WebSocket连接频繁断开
**解决**:检查网络环境,调整心跳间隔和重连策略
#### TradeOrderWs
**问题2**:策略执行不符合预期
**解决**:检查网格参数配置,分析策略执行日志,调整策略逻辑
**功能**:构建和发送订单请求到 OKX WebSocket 接口。
**问题3**:订单执行失败
**解决**:检查账号权限,查看订单执行日志,分析失败原因
**核心方法**:
- `orderEvent()`: 执行订单事件
### 7.3 日志与监控
- 关键操作日志:记录WebSocket连接、策略执行、订单操作等关键事件
- 错误日志:记录异常情况,便于问题排查
- 性能监控:监控系统性能指标,及时发现性能瓶颈
**订单执行流程**:
1. 验证下单参数和账户状态
2. 检查账户和持仓通道是否就绪
3. 构建订单请求 JSON
4. 发送订单到 WebSocket 接口
5. 更新订单状态和就绪标志
## 8. 未来规划
## 4. 系统交互流程
1. **动态策略配置**:支持通过后台管理系统动态配置网格策略
2. **策略回测**:实现策略回测功能,提高策略有效性
3. **风险控制增强**:增加更完善的风险控制机制
4. **多交易所支持**:扩展支持其他交易所
5. **数据可视化**:实现交易数据可视化展示
### 4.1 启动流程
---
```
[Spring 容器启动] → OkxWebSocketClientManager.init() → 初始化 newPriceClient → 初始化所有 quantClient → 建立 WebSocket 连接
```
**版本**:1.0
**更新日期**:2025-12-17
**维护人**:开发团队
### 4.2 价格触发交易流程
```
OkxNewPriceWebSocketClient.onMessage() → processPushData() → triggerQuantOperations() → WangGeListEnum.getGridByPrice() →
  对每个账号执行:
    1. 检查反向持仓并止损 → caoZuoZhiSunEvent()
    2. 执行当前网格策略 → caoZuoHandler() → chooseEvent() → caoZuoLong()/caoZuoShort()
    3. 发送订单 → TradeOrderWs.orderEvent()
```
### 4.3 订单执行流程
```
TradeOrderWs.orderEvent() → 验证参数 → 检查就绪状态 → 构建订单JSON → 发送订单 → 更新状态标志
```
## 5. 数据结构
### 5.1 订单请求参数
#### TradeRequestParam
**功能**:封装交易订单请求参数。
**核心属性**:
- `accountName`: 账号名称
- `markPx`: 标记价格
- `instId`: 合约ID
- `tdMode`: 交易模式
- `posSide`: 持仓方向
- `ordType`: 订单类型
- `side`: 买卖方向
- `sz`: 数量
- `clOrdId`: 客户订单ID
- `tradeType`: 交易类型
### 5.2 数据存储结构
系统使用双层 Map 结构存储不同账号的数据:
```java
// 第一层 key 为账号名称,第二层 key 为数据项
Map<String, Map<String, String>> accountDataMap = new ConcurrentHashMap<>();
```
主要数据存储类:
- `AccountWs.ACCOUNTWSMAP`: 账户信息
- `PositionsWs.POSITIONSWSMAP`: 持仓信息
- `OrderInfoWs.ORDERINFOWSMAP`: 订单信息
- `TradeOrderWs.TRADEORDERWSMAP`: 交易订单信息
## 6. 网格策略核心算法
### 6.1 网格匹配算法
```java
public static WangGeListEnum getGridByPrice(BigDecimal price) {
    for (WangGeListEnum grid : WangGeListEnum.values()) {
        BigDecimal upperLimit = new BigDecimal(grid.jiage_shangxian);
        BigDecimal lowerLimit = new BigDecimal(grid.jiage_xiaxian);
        if (upperLimit.compareTo(lowerLimit) > 0) {
            if (price.compareTo(lowerLimit) > 0 && price.compareTo(upperLimit) <= 0) {
                return grid;
            }
        }
    }
    return null;
}
```
### 6.2 交易决策算法
```java
public TradeRequestParam caoZuoHandler(String accountName, String markPx, String posSide) {
    // 1. 检查系统开关和账户状态
    // 2. 判断止损条件
    // 3. 检查保证金和仓位情况
    // 4. 根据持仓数量决定操作类型
    // 5. 返回交易请求参数
}
```
## 7. 错误处理与容错机制
### 7.1 WebSocket 连接管理
- 实现心跳检测机制,定期发送 ping 请求
- 自动重连机制,连接断开后使用指数退避策略重连
- 连接状态管理,避免重复连接
### 7.2 订单执行保障
- 订单参数验证,确保参数完整性
- 账户和持仓通道就绪检查
- 订单状态跟踪,避免重复下单
### 7.3 风险控制
- 止损机制,限制单次交易亏损
- 保证金检查,避免满仓操作
- 系统开关,支持紧急暂停交易
## 8. 扩展与定制
### 8.1 网格参数配置
可通过修改 `WangGeListEnum` 枚举值来配置不同的网格参数:
```java
// 格式:名称, 小数位数, 价格上限, 价格下限, 步距, 方向, 止损点
NEW_GRID("新网格", "2", "4000", "3500", "5", "long", "3500")
```
### 8.2 策略扩展
可通过实现 `CaoZuoService` 接口来扩展新的交易策略:
```java
public class CustomCaoZuoServiceImpl implements CaoZuoService {
    // 实现自定义策略逻辑
}
```
### 8.3 多账号支持
系统天然支持多账号管理,只需在 `ExchangeInfoEnum` 中添加新的账号配置即可。
## 9. 性能优化
1. **并发处理**:使用 `ConcurrentHashMap` 存储账号数据,支持高并发访问
2. **线程管理**:使用线程池处理异步任务,避免线程泄漏
3. **连接复用**:多个账号共享相同的 WebSocket 连接参数,减少连接开销
4. **数据缓存**:使用 Redis 缓存价格数据,提高数据访问效率
## 10. 监控与日志
系统使用 SLF4J 日志框架,记录关键操作和错误信息:
- WebSocket 连接状态
- 价格变化和网格匹配
- 订单执行过程
- 错误和异常信息
通过日志可以监控系统运行状态和排查问题。
## 11. 总结
OKX 量化交易系统是一个基于 WebSocket 的实时交易系统,实现了多网格策略、自动交易执行和风险控制功能。系统采用模块化设计,各组件职责明确,便于维护和扩展。
核心功能包括:
- 多网格策略配置和管理
- 实时价格监控和网格匹配
- 自动交易决策和执行
- 多账号管理和统一控制
- 完善的错误处理和风险控制
系统可以根据市场价格变化自动执行交易策略,实现量化交易的自动化和智能化。
src/main/java/com/xcong/excoin/modules/okxNewPrice/OkxNewPriceWebSocketClient.java
@@ -110,7 +110,7 @@
    private static final String WS_URL_MONIPAN = "wss://wspap.okx.com:8443/ws/v5/public";
    private static final String WS_URL_SHIPAN = "wss://ws.okx.com:8443/ws/v5/public";
    private static final boolean isAccountType = false;
    private static final boolean isAccountType = true;
    /**
     * 建立与 OKX WebSocket 服务器的连接。
@@ -319,7 +319,7 @@
                     *      如果不一致则需要处理
                     */
                    String fangXiang = gridByPriceNew.getFang_xiang();
                    String fangXiangOld = CoinEnums.POSSIDE_LONG.equals(fangXiang) ? CoinEnums.POSSIDE_SHORT.getCode() : CoinEnums.POSSIDE_LONG.getCode();
                    String fangXiangOld = CoinEnums.POSSIDE_LONG.getCode().equals(fangXiang) ? CoinEnums.POSSIDE_SHORT.getCode() : CoinEnums.POSSIDE_LONG.getCode();
                    log.info("历史网格方向为:{}", fangXiangOld);
                    if (!fangXiang.equals(fangXiangOld)){
                        TradeRequestParam tradeRequestParamOld = caoZuoService.caoZuoZhiSunEvent(accountName, markPx, fangXiangOld);
@@ -430,7 +430,7 @@
     */
    private void reconnectWithBackoff() throws InterruptedException {
        int attempt = 0;
        int maxAttempts = 5;
        int maxAttempts = 3;
        long delayMs = 5000;
        while (attempt < maxAttempts) {
src/main/java/com/xcong/excoin/modules/okxNewPrice/OkxQuantWebSocketClient.java
@@ -485,7 +485,7 @@
        }
        
        int attempt = 0;
        int maxAttempts = 5;
        int maxAttempts = 3;
        long delayMs = 1000;
        while (attempt < maxAttempts && !isConnected.get()) {
src/main/java/com/xcong/excoin/modules/okxNewPrice/celue/CaoZuoServiceImpl.java
@@ -198,6 +198,8 @@
        tradeRequestParam.setClOrdId(clOrdId);
        String sz = InstrumentsWs.getAccountMap(accountName).get(CoinEnums.BUY_CNT_INIT.name());
        tradeRequestParam.setSz(sz);
        WsMapBuild.saveStringToMap(OrderInfoWs.getAccountMap(accountName), "orderPrice", String.valueOf(markPx));
        return tradeRequestParam;
    }
@@ -273,7 +275,7 @@
                    if (pingCang != null && avgPx.compareTo(pingCang.getValue()) < 0) {
                        log.info("开始卖出平多...卖出平多队列价格大于开仓价格{}>{}", pingCang.getValue(), avgPx);
                        // 手续费
                        BigDecimal feeValue = PositionsWs.getAccountMap(positionAccountName).get("fee");
                        BigDecimal feeValue = PositionsWs.getAccountMap(positionAccountName).get("fee").multiply(new BigDecimal(2));
                        //未实现收益
                        BigDecimal uplValue = PositionsWs.getAccountMap(positionAccountName).get("upl");
                        //已实现收益
@@ -422,7 +424,7 @@
                    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();
                        String side = CoinEnums.SIDE_SELL.getCode();
                        tradeRequestParam.setSide(side);
                        String clOrdId = WsParamBuild.getOrderNum(side);
                        tradeRequestParam.setClOrdId(clOrdId);
src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/PositionsWs.java
@@ -3,6 +3,7 @@
import com.alibaba.fastjson.JSONArray;
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.okxpi.MallUtils;
import com.xcong.excoin.modules.okxNewPrice.utils.WsMapBuild;
import com.xcong.excoin.modules.okxNewPrice.utils.WsParamBuild;
@@ -10,6 +11,7 @@
import org.java_websocket.client.WebSocketClient;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@@ -129,6 +131,11 @@
        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()));
        BigDecimal ordFrozImr = PositionsWs.getAccountMap(accountNamePositons).get("imr");
        BigDecimal totalOrderUsdt = WsMapBuild.parseBigDecimalSafe(AccountWs.getAccountMap(accountName).get(CoinEnums.TOTAL_ORDER_USDT.name()))
                .divide(new BigDecimal("2"), RoundingMode.DOWN);
        if (ordFrozImr.compareTo(totalOrderUsdt) <= 0){
            WsMapBuild.saveBigDecimalToMap(accountMap, CoinEnums.READY_STATE.name(), WsMapBuild.parseBigDecimalSafe(CoinEnums.READY_STATE_YES.getCode()));
        }
    }
}
src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/TradeOrderWs.java
@@ -49,7 +49,8 @@
        String clOrdId = tradeRequestParam.getClOrdId();
        String side = tradeRequestParam.getSide();
        String sz = tradeRequestParam.getSz();
        log.info("账户:{},触发价格:{},币种:{},方向:{},买卖:{},数量:{},是否允许下单:{},编号:{},", accountName, markPx, instId, posSide,side,  sz, tradeType, clOrdId);
        log.info("账户:{},触发价格:{},币种:{},方向:{},买卖:{},数量:{},是否允许下单:{},编号:{},",
                accountName, markPx, instId, posSide,side,  sz, tradeType, clOrdId);
        //验证是否允许下单
        if (StrUtil.isNotEmpty(tradeType) && OrderParamEnums.TRADE_NO.getValue().equals(tradeType)) {
            log.warn("账户{}不允许下单,取消发送", accountName);
src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/enums/CoinEnums.java
@@ -42,16 +42,16 @@
    READY_STATE_YES("准备就绪ready_state", "1"),
    READY_STATE_NO("未准备就绪ready_state", "0"),
    PING_CANG_SHOUYI("平仓收益比例", "0.1"),
    PING_CANG_SHOUYI("平仓收益比例", "0.5"),
    //下单的总保障金为账户总金额cashBal * TOTAL_ORDER_USDT用来做保证金
    TOTAL_ORDER_USDTPECENT("总保证金比例total_order_usdtpecent","0.1"),
    TOTAL_ORDER_USDTPECENT("总保证金比例total_order_usdtpecent","0.06"),
    TOTAL_ORDER_USDT("总保证金totalOrderUsdt","0"),
    KANG_CANG("抗压比例KANG_CANG","0.9"),
    ZHI_SUN("止损比例ZHI_SUN","0.8"),
    //每次下单的张数
    BUY_CNT("每次开仓的张数buyCnt","0.1"),
    BUY_CNT_INIT("每次初始化开仓张数的基础值buyCntInit","0.2"),
    BUY_CNT_TIME("每次开仓张数的倍数基础值buyCntTime","2"),
    BUY_CNT_INIT("每次初始化开仓张数的基础值buyCntInit","0.05"),
    BUY_CNT_TIME("每次开仓张数的倍数基础值buyCntTime","20"),
    OUT("是否允许下单out","操作中"),
    CTVAL("合约面值ctVal","0.1"),
    TICKSZ("下单价格精度tickSz","2"),
src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/enums/ExchangeInfoEnum.java
@@ -13,14 +13,14 @@
     * 模拟盘账户1信息
     * 存储了模拟盘交易所需的API密钥、秘钥和通过码
     */
//    OKX_PRD_xiao("f512673b-2685-4fcb-9bb1-2ae8db745d62",
//            "B0C1CC8F39625B41140D93DC25039E33",
//            "Aa12345678@",
//            true),
    OKX_UAT_ceshi("ffb4e79f-fcf5-4afb-82c5-2fbb64123f61",
            "AA06C5ED1D7C7F5AFE6484052E231C55",
    OKX_PRD_xiao("f512673b-2685-4fcb-9bb1-2ae8db745d62",
            "B0C1CC8F39625B41140D93DC25039E33",
            "Aa12345678@",
            false);
            true);
//    OKX_UAT_ceshi("ffb4e79f-fcf5-4afb-82c5-2fbb64123f61",
//            "AA06C5ED1D7C7F5AFE6484052E231C55",
//            "Aa12345678@",
//            false);
//
//    /**
//     * 模拟盘账户2信息
src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/wanggeList/WangGeListEnum.java
@@ -11,12 +11,10 @@
 */
@Getter
public enum WangGeListEnum {
    UP("上层做空", "2", "3100", "3000", "2", "short", "3100"),
    CENTER("中间做多", "2", "3000", "2900", "2", "long", "2900"),
    CENTER_ONE("中间做空", "2", "2900", "2870", "2", "short", "2870"),
    DOWN("下层做多", "2", "2870", "2850", "2", "long", "2850"),
    DOWN_ONE("下层做多", "2", "2850", "2820", "2", "long", "2820"),
    DOWN_TWO("下层做空", "2", "2820", "2800", "2", "short", "2820");
    UP("上层做空", "2", "3100", "3000", "4", "short", "3100"),
    CENTER("中间做空", "2", "3000", "2700", "4", "short", "2700"),
    DOWN("下层做多", "2", "2700", "2500", "4", "long", "2500"),
    DOWN_ONE("下层做空", "2", "2500", "2200", "4", "short", "2500");
    private String name;
    private String xiaoshu_weishu;
src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/wanggeList/WangGeListServiceImpl.java
@@ -41,13 +41,9 @@
        }
        String shangxianValue = gridByPrice.getJiage_shangxian();
        log.info("价格上限: {}", shangxianValue);
        String xiaxianValue = gridByPrice.getJiage_xiaxian();
        log.info("价格下限: {}", xiaxianValue);
        String jianjuValue = gridByPrice.getJian_ju();
        log.info("价格间隔: {}", jianjuValue);
        String weishuValueStr = gridByPrice.getXiaoshu_weishu();
        log.info("价格位数: {}", weishuValueStr);
        try {
            BigDecimal shangxian = new BigDecimal(shangxianValue);
@@ -77,7 +73,6 @@
                return null;
            }
            log.info("网格初始化成功");
            return queueAsc;
        } catch (NumberFormatException e) {
            log.error("解析价格参数失败", e);