From c5faaa1111091280365100c95e7e06930b98ee4b Mon Sep 17 00:00:00 2001
From: Administrator <15274802129@163.com>
Date: Tue, 23 Dec 2025 16:21:44 +0800
Subject: [PATCH] feat(indicator): 添加15分钟交易策略和指标详细说明

---
 src/main/java/com/xcong/excoin/modules/okxNewPrice/celue/CaoZuoServiceImpl.java |   76 ++++++++++++++++++++++++++++++++++++++
 1 files changed, 76 insertions(+), 0 deletions(-)

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 a912b74..304ad4c 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
@@ -40,6 +40,82 @@
     private final RedisUtils redisUtils;
     private final TechnicalIndicatorStrategy technicalIndicatorStrategy;
 
+    @Override
+    public TradeRequestParam caoZuoStrategy(String accountName, String markPx, String posSide) {
+        TradeRequestParam tradeRequestParam = new TradeRequestParam();
+        tradeRequestParam.setAccountName(accountName);
+        tradeRequestParam.setInstId(CoinEnums.HE_YUE.getCode());
+        tradeRequestParam.setTdMode(CoinEnums.CROSS.getCode());
+        tradeRequestParam.setPosSide(posSide);
+        tradeRequestParam.setOrdType(CoinEnums.ORDTYPE_MARKET.getCode());
+
+        log.info("操作账户:{},当前价格: {},仓位方向: {}", accountName,markPx,posSide);
+        /**
+         * 准备工作
+         * 1、准备好下单的基本信息
+         */
+        // 系统设置的开关,等于冷静中,则代表不开仓
+        String outStr = InstrumentsWs.getAccountMap(accountName).get(CoinEnums.OUT.name());
+        if (OrderParamEnums.OUT_YES.getValue().equals(outStr)){
+            log.error("冷静中,不允许下单......");
+            tradeRequestParam.setTradeType(OrderParamEnums.TRADE_NO.getValue());
+            return tradeRequestParam;
+        }
+        BigDecimal cashBal = WsMapBuild.parseBigDecimalSafe(AccountWs.getAccountMap(accountName).get("cashBal"));
+        /**
+         * 判断止损抗压
+         */
+        BigDecimal realKuiSunAmount = WsMapBuild.parseBigDecimalSafe(AccountWs.getAccountMap(accountName).get("upl"));
+        log.info("实际盈亏金额: {}", realKuiSunAmount);
+        String zhiSunPercent = InstrumentsWs.getAccountMap(accountName).get(CoinEnums.ZHI_SUN.name());
+        BigDecimal zhiSunAmount = cashBal.multiply(new BigDecimal(zhiSunPercent));
+        log.info("预期亏损金额: {}", zhiSunAmount);
+        String kangYaPercent = InstrumentsWs.getAccountMap(accountName).get(CoinEnums.KANG_CANG.name());
+        BigDecimal  kangYaAmount = cashBal.multiply(new BigDecimal(kangYaPercent));
+        log.info("预期抗仓金额: {}", kangYaAmount);
+
+        if (realKuiSunAmount.compareTo(BigDecimal.ZERO) < 0){
+            realKuiSunAmount = realKuiSunAmount.multiply(new BigDecimal("-1"));
+            // 账户预期亏损金额比这个还小时,立即止损
+            if (realKuiSunAmount.compareTo(zhiSunAmount) > 0){
+                log.error("账户冷静止损......");
+                WsMapBuild.saveStringToMap(InstrumentsWs.getAccountMap(accountName), CoinEnums.OUT.name(),  OrderParamEnums.OUT_YES.getValue());
+                tradeRequestParam.setTradeType(OrderParamEnums.TRADE_YES.getValue());
+                return caoZuoZhiSunEvent(accountName, markPx, posSide);
+            }
+            // 判断抗压
+            if (realKuiSunAmount.compareTo(kangYaAmount) > 0 && realKuiSunAmount.compareTo(zhiSunAmount) <= 0){
+                log.error("账户紧张扛仓......");
+                tradeRequestParam.setTradeType(OrderParamEnums.TRADE_NO.getValue());
+                return tradeRequestParam;
+            }
+        }
+
+        String positionAccountName = PositionsWs.initAccountName(accountName, posSide);
+        // 判断是否保证金超标
+        if (PositionsWs.getAccountMap(positionAccountName).get("imr") == null){
+            log.error("没有获取到持仓信息,等待初始化......");
+            tradeRequestParam.setTradeType(OrderParamEnums.TRADE_NO.getValue());
+            return tradeRequestParam;
+        }
+        BigDecimal ordFrozImr = PositionsWs.getAccountMap(positionAccountName).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){
+            log.error("已满仓......");
+            tradeRequestParam.setTradeType(OrderParamEnums.TRADE_NO.getValue());
+            return tradeRequestParam;
+        }
+
+        if (PositionsWs.getAccountMap(positionAccountName).get("pos") == null){
+            log.error("没有获取到持仓信息,等待初始化......");
+            tradeRequestParam.setTradeType(OrderParamEnums.TRADE_NO.getValue());
+            return tradeRequestParam;
+        }
+        tradeRequestParam.setTradeType(OrderParamEnums.TRADE_YES.getValue());
+        return chooseEvent(tradeRequestParam);
+    }
+
     /**
      * 执行主要的操作逻辑,包括读取合约状态、获取市场价格信息,
      * 并根据当前持仓均价和标记价格决定是否执行买卖操作。

--
Gitblit v1.9.1