From b779f4884d55f8bcb24c0d13ca34795d1003c296 Mon Sep 17 00:00:00 2001
From: Administrator <15274802129@163.com>
Date: Fri, 05 Jun 2026 13:16:00 +0800
Subject: [PATCH] fix(okxNewPrice): 解决网格交易价格精度计算问题

---
 src/main/java/com/xcong/excoin/modules/okxNewPrice/OkxGridTradeService.java |   31 +++++++++++++++++++++++--------
 1 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/src/main/java/com/xcong/excoin/modules/okxNewPrice/OkxGridTradeService.java b/src/main/java/com/xcong/excoin/modules/okxNewPrice/OkxGridTradeService.java
index b8a94ce..aa9f09b 100644
--- a/src/main/java/com/xcong/excoin/modules/okxNewPrice/OkxGridTradeService.java
+++ b/src/main/java/com/xcong/excoin/modules/okxNewPrice/OkxGridTradeService.java
@@ -267,10 +267,12 @@
             executor.openLong(config.getBaseQuantity(), (orderId) -> {
                 OkxTraderParam baseLongTp = OkxTraderParam.builder().entryOrderId(orderId).build();
                 config.setBaseLongTraderParam(baseLongTp);
+                tryGenerateQueues(); // 异步回调到达后重试,防止 WS 推送先到导致 NPE
             }, null);
             executor.openShort(config.getBaseQuantity(), (orderId) -> {
                 OkxTraderParam baseShortTp = OkxTraderParam.builder().entryOrderId(orderId).build();
                 config.setBaseShortTraderParam(baseShortTp);
+                tryGenerateQueues(); // 异步回调到达后重试,防止 WS 推送先到导致 NPE
             }, null);
             return;
         }
@@ -300,9 +302,10 @@
                     baseLongOpened = true;
                     log.info("[OKX] 基底多成交价: {}", longBaseEntryPrice);
                     tryGenerateQueues();
-                } else {
-                    longPositionSize = posSize;
-                }
+            } else {
+                longPositionSize = posSize;
+                tryGenerateQueues(); // 后续 WS 推送触发重试,兜底此前 NPE 失败的情况
+            }
             } else {
                 if (longActive && state == StrategyState.ACTIVE) {
                     log.info("[OKX] 多仓持仓归零,重置策略");
@@ -321,9 +324,10 @@
                     baseShortOpened = true;
                     log.info("[OKX] 基底空成交价: {}", shortBaseEntryPrice);
                     tryGenerateQueues();
-                } else {
-                    shortPositionSize = posSize;
-                }
+            } else {
+                shortPositionSize = posSize;
+                tryGenerateQueues(); // 后续 WS 推送触发重试,兜底此前 NPE 失败的情况
+            }
             } else {
                 if (shortActive && state == StrategyState.ACTIVE) {
                     log.info("[OKX] 空仓持仓归零,重置策略");
@@ -394,17 +398,28 @@
     // ---- 网格队列处理 ----
 
     private void tryGenerateQueues() {
+        // 防止重复执行:一旦已进入 ACTIVE 状态不再重复初始化
+        if (state == StrategyState.ACTIVE) {
+            return;
+        }
         if (baseLongOpened && baseShortOpened) {
+            // 防御异步竞态:openLong/openShort 的回调可能还未设置 trader param
+            OkxTraderParam baseLongTp = config.getBaseLongTraderParam();
+            OkxTraderParam baseShortTp = config.getBaseShortTraderParam();
+            if (baseLongTp == null || baseShortTp == null) {
+                log.warn("[OKX] tryGenerateQueues 等待异步回调: longTp={}, shortTp={}",
+                        baseLongTp != null, baseShortTp != null);
+                return;
+            }
+
             generateShortQueue();
             generateLongQueue();
             updateGridElements();
 
             // 标记基座挂单
             OkxGridElement baseGridElement = OkxGridElement.findById(0);
-            OkxTraderParam baseLongTp = config.getBaseLongTraderParam();
             baseGridElement.setLongOrderId(baseLongTp.getEntryOrderId());
             baseGridElement.setHasLongOrder(true);
-            OkxTraderParam baseShortTp = config.getBaseShortTraderParam();
             baseGridElement.setShortOrderId(baseShortTp.getEntryOrderId());
             baseGridElement.setHasShortOrder(true);
 

--
Gitblit v1.9.1