package com.xcong.excoin.modules.okxNewPrice; import com.xcong.excoin.modules.okxNewPrice.gridWs.OkxAlgoOrdersChannelHandler; import com.xcong.excoin.modules.okxNewPrice.gridWs.OkxKlineChannelHandler; import com.xcong.excoin.modules.okxNewPrice.gridWs.OkxPositionsChannelHandler; import com.xcong.excoin.modules.okxNewPrice.okxpi.config.OKXAccount; import com.xcong.excoin.modules.okxNewPrice.okxpi.config.enums.DefaultUrls; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import java.math.BigDecimal; /** * OKX 网格交易系统 Spring 容器入口 — 组件组装 + 生命周期管理。 * *

组装顺序({@code @PostConstruct})

*
    *
  1. {@link OkxConfig} — 构建配置(API 密钥、合约、策略参数)
  2. *
  3. {@link OkxGridTradeService}.init() — 获取账户 → 清条件单 → 平仓 → 设杠杆
  4. *
  5. {@link OkxGridWsClient} — 注册 3 个频道处理器 → init():建立 WS 连接并登录订阅
  6. *
  7. {@code gridTradeService.startGrid()} — 状态重置,等待首根 K 线
  8. *
* *

3 个频道处理器

*
    *
  1. OkxKlineChannelHandler — candle1m,K线 → onKline()
  2. *
  3. OkxPositionsChannelHandler — positions,持仓 → onPositionUpdate()
  4. *
  5. OkxAlgoOrdersChannelHandler — orders-algo,条件单 → onOrderUpdate()
  6. *
* *

销毁顺序({@code @PreDestroy})

*
    *
  1. gridTradeService.stopGrid():取消所有条件单 → 关闭交易线程池
  2. *
  3. gridWsClient.destroy():取消订阅 → 断开 WS → 关闭线程池
  4. *
* * @author Administrator */ @Slf4j @Component @ConditionalOnProperty(prefix = "app", name = "quant", havingValue = "true") public class OkxWebSocketClientManager { /** 网格交易公共 WS 客户端(candle1m) */ private OkxGridWsClient gridWsClientPublic; /** 网格交易私有 WS 客户端(positions / orders-algo) */ private OkxGridWsClient gridWsClientPrivate; /** 网格交易策略服务 */ private OkxGridTradeService gridTradeService; /** 统一配置 */ private OkxConfig okxConfig; @PostConstruct public void init() { log.info("[OKX-Manager] 开始初始化..."); try { // 获取账户配置 ExchangeInfoEnum[] accounts = ExchangeInfoEnum.values(); if (accounts == null || accounts.length == 0) { log.error("[OKX-Manager] 无可用账户,初始化失败"); return; } // 使用第一个账户 ExchangeInfoEnum primaryAccount = accounts[0]; log.info("[OKX-Manager] 使用主账户: {}", primaryAccount.name()); // 1. 创建 OKXAccount(REST API 调用需要) String baseUrl = primaryAccount.isAccountType() ? DefaultUrls.USDM_PROD_URL : DefaultUrls.USDM_UAT_URL; OKXAccount okxAccount = new OKXAccount( baseUrl, primaryAccount.getApiKey(), primaryAccount.getSecretKey(), primaryAccount.getPassphrase(), !primaryAccount.isAccountType() ); // 2. 构建 OkxConfig // TODO: 参数可通过配置文件/数据库动态读取 okxConfig = OkxConfig.builder() .apiKey(primaryAccount.getApiKey()) .secretKey(primaryAccount.getSecretKey()) .passphrase(primaryAccount.getPassphrase()) .instId("BTC-USDT-SWAP") .leverage("100") .tdMode("cross") .gridRate(new BigDecimal("0.0025")) .expectedProfit(new BigDecimal("2")) .maxLoss(new BigDecimal("15")) .quantity("1") .baseQuantity("10") .priceScale(2) .ctVal(new BigDecimal("0.1")) .isSimulate(!primaryAccount.isAccountType()) .gridQueueSize(300) .marginRatioLimit(new BigDecimal("0.2")) .build(); // 3. 初始化交易服务:查账户 → 清条件单 → 平已有仓位 → 设杠杆 gridTradeService = new OkxGridTradeService(okxConfig, okxAccount); gridTradeService.init(); // 4. 创建 WS 客户端并注册频道处理器 // 公共 WS:candle1m(K线数据) gridWsClientPublic = new OkxGridWsClient(primaryAccount, true); gridWsClientPublic.addChannelHandler(new OkxKlineChannelHandler(okxConfig.getInstId(), gridTradeService)); gridWsClientPublic.init(); // 私有 WS:positions + orders-algo(持仓 + 条件单) gridWsClientPrivate = new OkxGridWsClient(primaryAccount, false); gridWsClientPrivate.addChannelHandler(new OkxPositionsChannelHandler(okxConfig.getInstId(), gridTradeService)); gridWsClientPrivate.addChannelHandler(new OkxAlgoOrdersChannelHandler(okxConfig.getInstId(), gridTradeService)); gridWsClientPrivate.init(); log.info("[OKX-Manager] WS已连接, 公共: candle1m, 私有: positions/orders-algo"); // 5. 激活策略,等待首根 K 线触发基底双开 gridTradeService.startGrid(); log.info("[OKX-Manager] 初始化完成"); } catch (Exception e) { log.error("[OKX-Manager] 初始化失败", e); } } /** * 销毁:停止策略 → 关闭交易线程池 → 取消 WS 订阅 → 断开连接 → 关闭 WS 线程池。 */ @PreDestroy public void destroy() { log.info("[OKX-Manager] 开始销毁..."); if (gridTradeService != null) { try { gridTradeService.stopGrid(); } catch (Exception e) { log.error("[OKX-Manager] 停止策略失败", e); } } if (gridWsClientPublic != null) { try { gridWsClientPublic.destroy(); } catch (Exception e) { log.error("[OKX-Manager] 销毁公共WS客户端失败", e); } } if (gridWsClientPrivate != null) { try { gridWsClientPrivate.destroy(); } catch (Exception e) { log.error("[OKX-Manager] 销毁私有WS客户端失败", e); } } log.info("[OKX-Manager] 销毁完成"); } /** @return 网格交易策略服务实例 */ public OkxGridTradeService getGridTradeService() { return gridTradeService; } /** @return 网格交易公共 WS 客户端实例 */ public OkxGridWsClient getGridWsClientPublic() { return gridWsClientPublic; } /** @return 网格交易私有 WS 客户端实例 */ public OkxGridWsClient getGridWsClientPrivate() { return gridWsClientPrivate; } public OkxConfig getOkxConfig() { return okxConfig; } }