From 04063bcb7b9e9d8e0242c1313f54ccc1b71f0b6e Mon Sep 17 00:00:00 2001
From: Administrator <15274802129@163.com>
Date: Thu, 25 Jun 2026 22:46:56 +0800
Subject: [PATCH] fix(gateApi): 调整网格交易参数配置

---
 src/main/java/com/xcong/excoin/modules/okxApi/OkxWebSocketClientManager.java |  204 +++++++++++++++++++++++++++++++++-----------------
 1 files changed, 135 insertions(+), 69 deletions(-)

diff --git a/src/main/java/com/xcong/excoin/modules/okxApi/OkxWebSocketClientManager.java b/src/main/java/com/xcong/excoin/modules/okxApi/OkxWebSocketClientManager.java
index 0ea9325..8959797 100644
--- a/src/main/java/com/xcong/excoin/modules/okxApi/OkxWebSocketClientManager.java
+++ b/src/main/java/com/xcong/excoin/modules/okxApi/OkxWebSocketClientManager.java
@@ -11,28 +11,55 @@
 import java.math.BigDecimal;
 
 /**
- * OKX 模块 Spring 容器入口 — 组件组装 + 生命周期管理。
+ * OKX 盈利回收策略 — 唯一入口,所有参数集中在此。
  *
- * <h3>组装顺序({@code @PostConstruct})</h3>
- * <ol>
- *   <li>{@link OkxConfig} — 构建配置(API 密钥、合约、策略参数)</li>
- *   <li>{@link OkxGridTradeService} — init():切双向持仓 → 清旧条件单 → 平仓 → 设杠杆</li>
- *   <li>{@link OkxKlineWebSocketClient} — 注册 3 个频道处理器 → init():建立 WS 连接并订阅</li>
- *   <li>{@code gridTradeService.startGrid()} — 状态重置,等待首根 K 线</li>
- * </ol>
+ * <pre>
+ * ┌─────────────────────────────────────────────────────────────────┐
+ * │                     🔧 全部参数在此修改                          │
+ * ├──────────────────┬──────────────────────────────────────────────┤
+ * │ 参数名            │ 值                                  │ 说明    │
+ * ├──────────────────┼──────────────────────────────────────┼────────┤
+ * │ apiKey           │ ac76252d-...                         │ API密钥 │
+ * │ apiSecret        │ A8168543...                          │ 签名密钥│
+ * │ passphrase       │ Aa12345678@                          │ 口令密码│
+ * ├──────────────────┼──────────────────────────────────────┼────────┤
+ * │ contract         │ BTC-USDT-SWAP                        │ 交易合约│
+ * │ leverage         │ 50                                   │ 杠杆倍数│
+ * │ baseQuantity     │ 10                                   │ 底仓张数│
+ * ├──────────────────┼──────────────────────────────────────┼────────┤
+ * │ profitTriggerRatio│ 0.5                                 │ 触发ROI │
+ * │ reinvestRatio    │ 0.5                                  │ 补仓比例│
+ * ├──────────────────┼──────────────────────────────────────┼────────┤
+ * │ maxPositionMult  │ 10  (= base×10 = 100张上限)          │ 风控1   │
+ * │ maxLoss          │ 15 USDT                              │ 风控2   │
+ * │ equityRestartRatio│ 0.05 (= 5%)                         │ 风控3   │
+ * ├──────────────────┼──────────────────────────────────────┼────────┤
+ * │ contractMult     │ 0.01        (BTC 每张0.01个币)        │ 合约乘数│
+ * │ priceScale       │ 2           (价格精度0.01)            │ 价格精度│
+ * │ pnlPriceMode     │ LAST_PRICE                           │ 盈亏计价│
+ * │ isProduction     │ false       (false=模拟盘)            │ 交易环境│
+ * └──────────────────┴──────────────────────────────────────────────┘
+ * </pre>
  *
- * <h3>3 个频道处理器</h3>
- * <ol>
- *   <li>MarkPriceOkxChannelHandler — 公开频道,标记价格 → onKline() + setMarkPrice()</li>
- *   <li>PositionsOkxChannelHandler — 私有频道,仓位 → onPositionUpdate()</li>
- *   <li>OrdersOkxChannelHandler — 私有频道,订单成交(含algoId) → onAutoOrder()</li>
- * </ol>
+ * <h3>策略核心公式</h3>
+ * <ul>
+ *   <li>保证金 = 张数 × 合约乘数 × 开仓均价 / 杠杆</li>
+ *   <li>ROI = 未实现盈亏 / 该方向保证金</li>
+ *   <li>触发条件:ROI ≥ profitTriggerRatio</li>
+ *   <li>平仓:floor(盈利仓位张数 / 2)</li>
+ *   <li>补仓保证金 B = 已实现利润 × reinvestRatio</li>
+ *   <li>单张保证金 = 合约乘数 × 开仓均价 / 杠杆</li>
+ *   <li>补仓张数 = max(baseQuantity, floor(B / 单张保证金))</li>
+ * </ul>
  *
- * <h3>销毁顺序({@code @PreDestroy})</h3>
- * <ol>
- *   <li>gridTradeService.stopGrid():取消所有条件单 → 关闭交易线程池</li>
- *   <li>wsClient.destroy():取消订阅 → 断开 WS → 关闭线程池</li>
- * </ol>
+ * <h3>仓位演化示例 (BTC-USDT-SWAP, 50x, base10)</h3>
+ * <pre>
+ *   初始: LONG=10  SHORT=10
+ *   多盈: LONG=5   SHORT=12
+ *   多盈: LONG=3   SHORT=15
+ *   多盈: LONG=2   SHORT=18
+ *   → 权益达+5% → 全平重置 → LONG=10 SHORT=10
+ * </pre>
  *
  * @author Administrator
  */
@@ -40,78 +67,117 @@
 @Component
 public class OkxWebSocketClientManager {
 
+    // ╔══════════════════════════════════════════════════════════════╗
+    // ║                  🔐 OKX API 认证信息                         ║
+    // ╚══════════════════════════════════════════════════════════════╝
+    private static final String OKX_API_KEY       = "ac76252d-e717-4459-a6f9-80512aed5ea0";
+    private static final String OKX_API_SECRET    = "A8168543EF4F08A6DBFE27AB23956898";
+    private static final String OKX_PASSPHRASE    = "Aa12345678@";
+
+    // ╔══════════════════════════════════════════════════════════════╗
+    // ║                    📊 交易标的参数                            ║
+    // ╚══════════════════════════════════════════════════════════════╝
+    private static final String CONTRACT          = "BTC-USDT-SWAP";    // 合约名称
+    private static final String LEVERAGE          = "50";               // 杠杆倍数
+    private static final String MARGIN_MODE       = "cross";            // 全仓 cross / 逐仓 isolated
+    private static final String POSITION_MODE     = "long_short_mode";  // 双向持仓
+
+    // ╔══════════════════════════════════════════════════════════════╗
+    // ║                  🎯 策略核心参数                              ║
+    // ╚══════════════════════════════════════════════════════════════╝
+    /** 基础仓位张数 — 初始化时多空各开此张数,也是最小开仓单位 */
+    private static final String BASE_QUANTITY     = "10";
+    /** 盈利触发比例 — ROI=未实现盈亏/保证金 达到此值时触发平仓 */
+    private static final BigDecimal PROFIT_TRIGGER_RATIO = new BigDecimal("0.5");  // 50%
+    /** 再投资比例 — 已实现利润中用于补反向仓的比例 */
+    private static final BigDecimal REINVEST_RATIO = new BigDecimal("0.5");  // 50%
+
+    // ╔══════════════════════════════════════════════════════════════╗
+    // ║                   🛡 风控参数                                ║
+    // ╚══════════════════════════════════════════════════════════════╝
+    /** 风控1: 反向仓位倍数上限 — 反向最大持仓 = baseQuantity × 此值 (10×10=100张) */
+    private static final int MAX_POSITION_MULTIPLIER = 10;
+    /** 风控2: 最大亏损阈值(USDT) — 全局盈亏≤-此值时停止策略 */
+    private static final BigDecimal MAX_LOSS = new BigDecimal("15");
+    /** 风控3: 权益重置比例 — 账户权益 ≥ 初始权益 × (1+此值) 时全平重新双开 */
+    private static final BigDecimal EQUITY_RESTART_RATIO = new BigDecimal("0.05");  // 5%
+
+    // ╔══════════════════════════════════════════════════════════════╗
+    // ║                  ⚙ 技术与环境参数                            ║
+    // ╚══════════════════════════════════════════════════════════════╝
+    /** 合约乘数 — BTC-USDT-SWAP 每张=0.01 BTC */
+    private static final BigDecimal CONTRACT_MULTIPLIER = new BigDecimal("0.01");
+    /** 价格精度 — OKX 价格小数位数 (BTC=2, ETH=2) */
+    private static final int PRICE_SCALE = 2;
+    /** 盈亏计价模式 — LAST_PRICE(最新价) / MARK_PRICE(标记价) */
+    private static final OkxConfig.PnLPriceMode PNL_PRICE_MODE = OkxConfig.PnLPriceMode.LAST_PRICE;
+    /** false=模拟盘 (wspap.okx.com) / true=实盘 (ws.okx.com) */
+    private static final boolean IS_PRODUCTION = false;
+
+    // ==================== 以下为启动代码,通常无需修改 ====================
+
     private OkxKlineWebSocketClient wsClient;
-    private OkxGridTradeService gridTradeService;
+    private OkxProfitRecycleStrategy strategy;
     private OkxConfig config;
 
     @PostConstruct
     public void init() {
-        log.info("[OKX管理器] 开始初始化...");
+        log.info("[OKX] 正在初始化盈利回收策略...");
 
         try {
-            // TODO: 替换为实际 API 密钥
             config = OkxConfig.builder()
-                    .apiKey("ac76252d-e717-4459-a6f9-80512aed5ea0")
-                    .apiSecret("A8168543EF4F08A6DBFE27AB23956898")
-                    .passphrase("Aa12345678@")
-                    .contract("ETH-USDT-SWAP")
-                    .leverage("100")
-                    .marginMode("cross")
-                    .positionMode("long_short_mode")
-                    .gridRate(new BigDecimal("0.0025"))
-                    .expectedProfit(new BigDecimal("25"))
-                    .maxLoss(new BigDecimal("15"))
-                    .baseQuantity("1")
-                    .quantity("1")
-                    .restartGridSpan(6)
-                    .maxPositionSize(2)
-                    .priceScale(2)
-                    .contractMultiplier(new BigDecimal("0.01"))
-                    .unrealizedPnlPriceMode(OkxConfig.PnLPriceMode.LAST_PRICE)
-                    .isProduction(false)
-                    .reopenMaxRetries(3)
+                    .apiKey(OKX_API_KEY)
+                    .apiSecret(OKX_API_SECRET)
+                    .passphrase(OKX_PASSPHRASE)
+                    .contract(CONTRACT)
+                    .leverage(LEVERAGE)
+                    .marginMode(MARGIN_MODE)
+                    .positionMode(POSITION_MODE)
+                    .baseQuantity(BASE_QUANTITY)
+                    .maxLoss(MAX_LOSS)
+                    .priceScale(PRICE_SCALE)
+                    .contractMultiplier(CONTRACT_MULTIPLIER)
+                    .unrealizedPnlPriceMode(PNL_PRICE_MODE)
+                    .isProduction(IS_PRODUCTION)
+                    .profitTriggerRatio(PROFIT_TRIGGER_RATIO)
+                    .reinvestRatio(REINVEST_RATIO)
+                    .maxPositionMultiplier(MAX_POSITION_MULTIPLIER)
+                    .equityRestartRatio(EQUITY_RESTART_RATIO)
                     .build();
 
-            // 1. 初始化交易服务
-            gridTradeService = new OkxGridTradeService(config);
-            gridTradeService.init();
+            strategy = new OkxProfitRecycleStrategy(config);
+            strategy.init();
 
-            // 2. 创建 WS 客户端并注册频道处理器
             wsClient = new OkxKlineWebSocketClient(config);
+            wsClient.addPublicHandler(new MarkPriceOkxChannelHandler(config.getContract(), strategy));
+            wsClient.addPrivateHandler(new PositionsOkxChannelHandler(config, strategy));
+            wsClient.addPrivateHandler(new OrdersOkxChannelHandler(config, strategy));
 
-            // 公开频道:标记价格(替代 K 线,同时驱动策略 onKline 和 PnL 计算)
-            wsClient.addPublicHandler(new MarkPriceOkxChannelHandler(
-                    config.getContract(), gridTradeService));
-            // 私有频道:仓位
-            wsClient.addPrivateHandler(new PositionsOkxChannelHandler(
-                    config, gridTradeService));
-            // 私有频道:条件单(orders 频道含 algoId,可追溯到源条件单)
-            wsClient.addPrivateHandler(new OrdersOkxChannelHandler(
-                    config, gridTradeService));
-
-            gridTradeService.setWsClient(wsClient);
+            strategy.setWsClient(wsClient);
             wsClient.init();
-            log.info("[OKX管理器] WS已连接, 已注册 3 个频道处理器");
+            log.info("[OKX] WS已连接 | 合约: {} | 杠杆: {}x | 基础张数: {} | "
+                            + "触发ROI: {}% | 补仓比例: {}% | 仓位上限: {}x | 重置阈值: {}%",
+                    CONTRACT, LEVERAGE, BASE_QUANTITY,
+                    PROFIT_TRIGGER_RATIO.multiply(new BigDecimal("100")),
+                    REINVEST_RATIO.multiply(new BigDecimal("100")),
+                    MAX_POSITION_MULTIPLIER,
+                    EQUITY_RESTART_RATIO.multiply(new BigDecimal("100")));
 
-            // 3. 激活策略
-            gridTradeService.startGrid();
+            strategy.startStrategy();
         } catch (Exception e) {
-            log.error("[OKX管理器] 初始化失败", e);
+            log.error("[OKX] 初始化失败", e);
         }
     }
 
     @PreDestroy
     public void destroy() {
-        log.info("[OKX管理器] 开始销毁...");
-        if (gridTradeService != null) {
-            gridTradeService.stopGrid();
-        }
-        if (wsClient != null) {
-            wsClient.destroy();
-        }
-        log.info("[OKX管理器] 销毁完成");
+        log.info("[OKX] 正在销毁...");
+        if (strategy != null) strategy.stopStrategy();
+        if (wsClient != null) wsClient.destroy();
+        log.info("[OKX] 销毁完成");
     }
 
     public OkxKlineWebSocketClient getKlineWebSocketClient() { return wsClient; }
-    public OkxGridTradeService getGridTradeService() { return gridTradeService; }
+    public OkxProfitRecycleStrategy getStrategy() { return strategy; }
+    public IOkxStrategy getActiveStrategy() { return strategy; }
 }

--
Gitblit v1.9.1