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.OkxOrdersChannelHandler;
|
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 容器入口 — 组件组装 + 生命周期管理。
|
*
|
* <h3>组装顺序({@code @PostConstruct})</h3>
|
* <ol>
|
* <li>{@link OkxConfig} — 构建配置(API 密钥、合约、策略参数)</li>
|
* <li>{@link OkxGridTradeService}.init() — 获取账户 → 清条件单 → 平仓 → 设杠杆</li>
|
* <li>{@link OkxGridWsClient} — 注册 3 个频道处理器 → init():建立 WS 连接并登录订阅</li>
|
* <li>{@code gridTradeService.startGrid()} — 状态重置,等待首根 K 线</li>
|
* </ol>
|
*
|
* <h3>3 个频道处理器</h3>
|
* <ol>
|
* <li>OkxKlineChannelHandler — candle1m,K线 → onKline()</li>
|
* <li>OkxPositionsChannelHandler — positions,持仓 → onPositionUpdate()</li>
|
* <li>OkxAlgoOrdersChannelHandler — orders-algo,条件单 → onOrderUpdate()</li>
|
* </ol>
|
*
|
* <h3>销毁顺序({@code @PreDestroy})</h3>
|
* <ol>
|
* <li>gridTradeService.stopGrid():取消所有条件单 → 关闭交易线程池</li>
|
* <li>gridWsClient.destroy():取消订阅 → 断开 WS → 关闭线程池</li>
|
* </ol>
|
*
|
* @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.001"))
|
.expectedProfit(new BigDecimal("200"))
|
.maxLoss(new BigDecimal("30"))
|
.quantity("1")
|
.baseQuantity("10")
|
.priceScale(2)
|
.ctVal(new BigDecimal("0.01"))
|
.isSimulate(!primaryAccount.isAccountType())
|
.gridQueueSize(300)
|
.marginRatioLimit(new BigDecimal("0.2"))
|
.build();
|
|
// 3. 初始化交易服务:查账户 → 清条件单 → 平已有仓位 → 设杠杆
|
gridTradeService = new OkxGridTradeService(okxConfig, okxAccount);
|
gridTradeService.init();
|
|
// 4. 创建 WS 客户端并注册频道处理器
|
// 业务 WS(/v5/business):candle1m
|
gridWsClientPublic = new OkxGridWsClient(primaryAccount, true);
|
gridWsClientPublic.addChannelHandler(new OkxKlineChannelHandler(okxConfig.getInstId(), gridTradeService));
|
gridWsClientPublic.init();
|
|
// 私有 WS(/v5/private):positions + orders(algo触发后订单fill带algoId可匹配)
|
gridWsClientPrivate = new OkxGridWsClient(primaryAccount, false);
|
gridWsClientPrivate.addChannelHandler(new OkxPositionsChannelHandler(okxConfig.getInstId(), gridTradeService));
|
gridWsClientPrivate.addChannelHandler(new OkxOrdersChannelHandler(okxConfig.getInstId(), gridTradeService));
|
gridWsClientPrivate.init();
|
|
log.info("[OKX-Manager] WS已连接, business: candle1m, private: positions/orders");
|
|
// 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; }
|
}
|