Administrator
4 days ago 04063bcb7b9e9d8e0242c1313f54ccc1b71f0b6e
src/main/java/com/xcong/excoin/modules/okxApi/wsHandler/handler/PositionsOkxChannelHandler.java
@@ -2,17 +2,17 @@
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xcong.excoin.modules.okxApi.Direction;
import com.xcong.excoin.modules.okxApi.IOkxStrategy;
import com.xcong.excoin.modules.okxApi.OkxConfig;
import com.xcong.excoin.modules.okxApi.OkxGridTradeService;
import com.xcong.excoin.modules.okxApi.wsHandler.AbstractOkxPrivateChannelHandler;
import com.xcong.excoin.modules.okxApi.TraderParam;
import lombok.extern.slf4j.Slf4j;
import java.math.BigDecimal;
/**
 * OKX 仓位频道处理器(positions),接收仓位更新推送并回调
 * {@link OkxGridTradeService#onPositionUpdate(String, TraderParam.Direction, BigDecimal, BigDecimal)}。
 * {@link IOkxStrategy#onPositionUpdate(String, Direction, BigDecimal, BigDecimal)}。
 *
 * <h3>订阅格式</h3>
 * 私有频道,需要先登录认证。订阅 arg 使用 instType: "SWAP"(不指定具体 instId,
@@ -21,24 +21,10 @@
 * {"op":"subscribe","args":[{"channel":"positions","instType":"SWAP"}]}
 * </pre>
 *
 * <h3>数据推送格式</h3>
 * <pre>
 * {
 *   "arg": {"channel":"positions","instType":"SWAP"},
 *   "data": [{
 *     "instId": "ETH-USDT-SWAP",
 *     "posSide": "long",        // "long" 或 "short"
 *     "pos": "1",               // 持仓张数
 *     "avgPx": "3000",          // 开仓均价
 *     ...
 *   }]
 * }
 * </pre>
 *
 * <h3>数据映射</h3>
 * <ul>
 *   <li>posSide "long" → {@link TraderParam.Direction#LONG},映射为 DUAL_LONG</li>
 *   <li>posSide "short" → {@link TraderParam.Direction#SHORT},映射为 DUAL_SHORT</li>
 *   <li>posSide "long" → {@link Direction#LONG}</li>
 *   <li>posSide "short" → {@link Direction#SHORT}</li>
 *   <li>pos → 持仓张数(绝对值)</li>
 *   <li>avgPx → 开仓均价</li>
 * </ul>
@@ -57,14 +43,14 @@
    /**
     * 构造仓位频道处理器。
     *
     * @param config           OKX 配置实例(提供合约名称等)
     * @param gridTradeService OKX 网格交易策略服务实例
     * @param config   OKX 配置实例(提供合约名称等)
     * @param strategy OKX 交易策略服务实例
     */
    public PositionsOkxChannelHandler(OkxConfig config, OkxGridTradeService gridTradeService) {
    public PositionsOkxChannelHandler(OkxConfig config, IOkxStrategy strategy) {
        super(CHANNEL_NAME,
                config.getApiKey(), config.getApiSecret(), config.getPassphrase(),
                config.getContract(),
                gridTradeService);
                strategy);
        this.config = config;
    }
@@ -107,11 +93,11 @@
                // 解析持仓方向:OKX 的 posSide 可以是 "long" 或 "short"
                String posSide = posData.getString("posSide");
                TraderParam.Direction direction;
                Direction direction;
                if ("long".equals(posSide)) {
                    direction = TraderParam.Direction.LONG;
                    direction = Direction.LONG;
                } else if ("short".equals(posSide)) {
                    direction = TraderParam.Direction.SHORT;
                    direction = Direction.SHORT;
                } else {
                    log.debug("[OKX-WS] positions 忽略 net 方向: {}", posSide);
                    continue;
@@ -125,11 +111,11 @@
                BigDecimal entryPrice = (avgPxStr != null && !avgPxStr.isEmpty())
                        ? new BigDecimal(avgPxStr) : BigDecimal.ZERO;
                log.info("[OKX-WS] positions 持仓更新, instId:{}, posSide:{}, pos:{}, avgPx:{}",
                        dataInstId, posSide, size, entryPrice);
//                log.info("[OKX-WS] positions 持仓更新, instId:{}, posSide:{}, pos:{}, avgPx:{}",
//                        dataInstId, posSide, size, entryPrice);
                if (getGridTradeService() != null) {
                    getGridTradeService().onPositionUpdate(contract, direction, size, entryPrice);
                if (getStrategy() != null) {
                    getStrategy().onPositionUpdate(contract, direction, size, entryPrice);
                }
            }
        } catch (Exception e) {