From 8b91d6757e37ee94187077e712552888ccd22099 Mon Sep 17 00:00:00 2001
From: Administrator <15274802129@163.com>
Date: Sat, 13 Dec 2025 15:50:07 +0800
Subject: [PATCH] feat(okxNewPrice): 实现动态开仓张数计算逻辑

---
 src/main/java/com/xcong/excoin/modules/okxNewPrice/okxWs/TradeOrderWs.java |  116 ++++++++++++++++++++++++++++++++++++++--------------------
 1 files changed, 76 insertions(+), 40 deletions(-)

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 7712098..2ae3e93 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,44 +5,59 @@
 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;
-import com.xcong.excoin.utils.RedisUtils;
 import lombok.extern.slf4j.Slf4j;
 import org.java_websocket.client.WebSocketClient;
 
+import java.math.BigDecimal;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
 /**
+ * 交易订单处理类,负责构建和发送订单请求到OKX WebSocket
+ * 
  * @author Administrator
  */
 @Slf4j
 public class TradeOrderWs {
 
+    public static  final Map<String,String> TRADEORDERWSMAP = new ConcurrentHashMap<>();
+
     public static final String ORDERWS_CHANNEL = "order";
 
-    public static void orderEvent(WebSocketClient webSocketClient, RedisUtils redisUtils, String side) {
+    public static void orderEvent(WebSocketClient webSocketClient, String side) {
 
-        String buyCnt = null;
-
-        if (OrderParamEnums.ORDERING.getValue().equals(side)) {
-            return;
-        } else if (OrderParamEnums.HOLDING.getValue().equals(side)) {
-            return;
-        } else if (OrderParamEnums.INIT.getValue().equals(side)) {
-            side = OrderParamEnums.BUY.getValue();
-            buyCnt = getRedisValue(redisUtils, InstrumentsWs.INSTRUMENTSWS_CHANNEL, ":ctVal");
-        } else if (OrderParamEnums.OUT.getValue().equals(side)) {
-            side = OrderParamEnums.SELL.getValue();
-            buyCnt = getRedisValue(redisUtils, PositionsWs.POSITIONSWS_CHANNEL, ":pos");
-        } else {
-            String buyCntNormal = getRedisValue(redisUtils, PositionsWs.POSITIONSWS_CHANNEL, ":buyCnt");
-            if (StrUtil.isNotBlank(buyCntNormal)) {
-                buyCnt = buyCntNormal;
-            }
-        }
-
+        log.info("开始执行TradeOrderWs......");
         // 校验必要参数
         if (StrUtil.isBlank(side)) {
             log.warn("下单参数 side 为空,取消发送");
+            return;
+        }
+        String buyCnt = "";
+        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.POSITIONSWSMAP.get("pos"));
+        }else if (OrderParamEnums.INIT.getValue().equals(side)){
+            log.info("当前状态为初始化");
+            side = OrderParamEnums.BUY.getValue();
+            String buyCntTime = OrderInfoWs.ORDERINFOWSMAP.get("buyCntTime");
+            String buyCntStr = InstrumentsWs.INSTRUMENTSWSMAP.get(CoinEnums.BUY_CNT.name());
+            buyCnt = String.valueOf(new BigDecimal(buyCntTime).multiply(new BigDecimal(buyCntStr)));
+        }else if (OrderParamEnums.BUY.getValue().equals(side)){
+            log.info("当前状态为加仓");
+            String buyCntTime = OrderInfoWs.ORDERINFOWSMAP.get("buyCntTime");
+            String buyCntStr = InstrumentsWs.INSTRUMENTSWSMAP.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.POSITIONSWSMAP.get("pos"));
+        }else{
+            log.warn("交易状态异常,取消发送");
             return;
         }
 
@@ -52,7 +67,7 @@
         }
 
         try {
-            String clOrdId = MallUtils.getOrderNum(side);
+            String clOrdId = WsParamBuild.getOrderNum(side);
             JSONArray argsArray = new JSONArray();
             JSONObject args = new JSONObject();
             args.put("instId", CoinEnums.HE_YUE.getCode());
@@ -64,33 +79,54 @@
             args.put("sz", buyCnt);
             argsArray.add(args);
 
-            String connId = MallUtils.getOrderNum(ORDERWS_CHANNEL);
+            String connId = WsParamBuild.getOrderNum(ORDERWS_CHANNEL);
             JSONObject jsonObject = WsParamBuild.buildJsonObject(connId, ORDERWS_CHANNEL, argsArray);
             webSocketClient.send(jsonObject.toJSONString());
             log.info("发送下单频道:{},数量:{}", side, buyCnt);
-            boolean setResult =
-                    redisUtils.set(ORDERWS_CHANNEL + ":" + CoinEnums.HE_YUE.getCode() + ":clOrdId", clOrdId, 0)
-                    && redisUtils.set(ORDERWS_CHANNEL + ":" + CoinEnums.HE_YUE.getCode() + ":state", CoinEnums.ORDER_FILLED.getCode(), 0)
-                    && redisUtils.set(InstrumentsWs.INSTRUMENTSWS_CHANNEL + ":" + CoinEnums.HE_YUE.getCode() + ":state", OrderParamEnums.STATE_4.getValue(), 0);
-            if (!setResult) {
-                log.warn("Redis set operation failed for key: order:{}", CoinEnums.HE_YUE.getCode());
+
+            WsMapBuild.saveStringToMap(TRADEORDERWSMAP, "clOrdId", clOrdId);
+            WsMapBuild.saveStringToMap(TRADEORDERWSMAP, "state", CoinEnums.ORDER_FILLED.getCode());
+
+            if (OrderParamEnums.SELL.getValue().equals(side)){
+                WsMapBuild.saveBigDecimalToMap(PositionsWs.POSITIONSWSMAP, "pos", BigDecimal.ZERO);
             }
+
+            if (OrderParamEnums.BUY.getValue().equals(side)){
+                WsMapBuild.saveBigDecimalToMap(PositionsWs.POSITIONSWSMAP, "pos", new BigDecimal(buyCnt));
+            }
+
+
         } catch (Exception e) {
             log.error("下单构建失败", e);
         }
     }
 
+
+
     /**
-     * 统一封装 Redis Key 构建逻辑
+     * 计算盈亏金额。
      *
-     * @param redisUtils Redis 工具类实例
-     * @param prefix     渠道前缀
-     * @param suffix     字段后缀
-     * @return Redis 中存储的值
+     * @param faceValue 面值
+     * @param position 持仓数量
+     * @param markPrice 标记价格
+     * @param openPrice 开仓价格
+     * @param isLong 是否为多头仓位
+     * @param minTickSz 最小变动单位精度
+     * @return 盈亏金额,保留指定精度的小数位
      */
-    private static String getRedisValue(RedisUtils redisUtils, String prefix, String suffix) {
-        String key = prefix + ":" + CoinEnums.HE_YUE.getCode() + suffix;
-        Object valueObj = redisUtils.get(key);
-        return valueObj == null ? null : String.valueOf(valueObj);
+    public BigDecimal profit(BigDecimal faceValue, BigDecimal position,
+                             BigDecimal markPrice, BigDecimal openPrice, boolean isLong, int minTickSz) {
+        BigDecimal profit = BigDecimal.ZERO;
+        if (isLong) {
+            profit = markPrice.subtract(openPrice)
+                    .multiply(faceValue)
+                    .multiply(position);
+        } else {
+            profit = openPrice.subtract(markPrice)
+                    .multiply(faceValue)
+                    .multiply(position);
+        }
+        return profit.setScale(minTickSz, BigDecimal.ROUND_DOWN);
     }
-}
+
+}
\ No newline at end of file

--
Gitblit v1.9.1