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