Administrator
2025-12-09 7e213a5e5a233ba19eaa148cc65c9f3cfa96986e
src/main/java/com/xcong/excoin/modules/okxNewPrice/celue/CaoZuoServiceImpl.java
@@ -44,6 +44,9 @@
        final String positionsMarkPxKey = PositionsWs.POSITIONSWS_CHANNEL + ":" + coinCode + ":markPx";
        final String positionsAvgPxKey = PositionsWs.POSITIONSWS_CHANNEL + ":" + coinCode + ":avgPx";
        final String positionsOrderPriceKey = PositionsWs.POSITIONSWS_CHANNEL + ":" + coinCode + ":orderPrice";
        final String uplKey = PositionsWs.POSITIONSWS_CHANNEL + ":" + coinCode + ":upl";
        final String realizedPnlKey = PositionsWs.POSITIONSWS_CHANNEL + ":" + coinCode + ":realizedPnl";
        final String imrKey = PositionsWs.POSITIONSWS_CHANNEL + ":" + coinCode + ":imr";
        // 获取合约状态
        String state = (String) redisUtils.get(instrumentsKey);
@@ -84,7 +87,7 @@
            // 判断是加仓还是减仓
            if (avgPx.compareTo(markPx) > 0) {
                DescBigDecimal kaiCang = queueKaiCang.peek();
                if (kaiCang != null && kaiCang.getValue().compareTo(markPx) >= 0) {
                if (kaiCang != null && markPx.compareTo(kaiCang.getValue()) <= 0 && avgPx.compareTo(kaiCang.getValue()) >= 0) {
                    log.info("开始加仓...开仓队列价格大于当前价格{}>{}", kaiCang.getValue(), markPx);
                    side = OrderParamEnums.BUY.getValue();
                    redisUtils.set(positionsOrderPriceKey, String.valueOf(kaiCang.getValue()), 0);
@@ -93,10 +96,41 @@
                }
            } else if (avgPx.compareTo(markPx) < 0) {
                AscBigDecimal pingCang = queuePingCang.peek();
                if (pingCang != null && pingCang.getValue().compareTo(markPx) <= 0) {
                if (pingCang != null && markPx.compareTo(pingCang.getValue()) >= 0 && avgPx.compareTo(pingCang.getValue()) < 0) {
                    log.info("开始减仓...平仓队列价格小于当前价格{}<={}", pingCang.getValue(), markPx);
                    side = OrderParamEnums.SELL.getValue();
                    redisUtils.set(positionsOrderPriceKey, String.valueOf(pingCang.getValue()), 0);
                    //判断当前是否盈利
                    String upl = (String) redisUtils.get(uplKey);
                    String realizedPnl = (String) redisUtils.get(realizedPnlKey);
                    String imr = (String) redisUtils.get(imrKey);
                    if (upl != null && realizedPnl != null && imr != null) {
                        BigDecimal uplValue = new BigDecimal(upl);
                        BigDecimal realizedPnlValue = new BigDecimal(realizedPnl);
                        BigDecimal imrValue = new BigDecimal(imr).multiply(new BigDecimal(OrderParamEnums.PING_CANG_SHOUYI.getValue()));
                        if (realizedPnlValue.compareTo(BigDecimal.ZERO) <= 0) {
                            if (uplValue.compareTo(realizedPnlValue) < 0) {
                                log.info("当前未实现盈亏:{}没有大于已实现收益>{},等待中", uplValue, realizedPnlValue);
                                return OrderParamEnums.HOLDING.getValue();
                            }else if (uplValue.compareTo(realizedPnlValue) > 0 && uplValue.compareTo(imrValue)  >= 0) {
                                log.info("当前未实现盈亏:{}大于预计收益>{},赚钱咯", uplValue, imrValue);
                                redisUtils.set(positionsOrderPriceKey, String.valueOf(pingCang.getValue()), 0);
                                return OrderParamEnums.SELL.getValue();
                            }else{
                                log.info("当前未实现盈亏:{}没有大于预计收益>{},钱在路上了", uplValue, imrValue);
                                return OrderParamEnums.HOLDING.getValue();
                            }
                        }else {
                            if (uplValue.compareTo(imrValue)  >= 0) {
                                log.info("当前未实现盈亏:{}大于预计收益>{},赚钱咯", uplValue, imrValue);
                                redisUtils.set(positionsOrderPriceKey, String.valueOf(pingCang.getValue()), 0);
                                return OrderParamEnums.SELL.getValue();
                            }else{
                                log.info("当前未实现盈亏:{}没有大于预计收益>{},钱在路上了", uplValue, imrValue);
                                return OrderParamEnums.HOLDING.getValue();
                            }
                         }
                    }else {
                        return OrderParamEnums.HOLDING.getValue();
                    }
                } else {
                    log.info("未触发减仓......,等待");
                }
@@ -125,6 +159,7 @@
        if (orderPrice == null) {
            return;
        }
        log.info("需要移除的价格: {}", orderPrice);
        BigDecimal priceDecimal;
        try {
@@ -140,6 +175,8 @@
        } else {
            queueKaiCang.removeIf(item -> item.getValue().equals(priceDecimal));
        }
        // 打印开仓队列
        log.info("开仓队列: {}", queueKaiCang);
        boolean pingCangExists = queuePingCang.stream().anyMatch(item -> item.getValue().equals(priceDecimal));
        if (!pingCangExists) {
@@ -147,35 +184,8 @@
        } else {
            queuePingCang.removeIf(item -> item.getValue().equals(priceDecimal));
        }
    }
    /**
     * 计算盈亏金额。
     *
     * @param faceValue 面值
     * @param position 持仓数量
     * @param contractMultiplier 合约乘数
     * @param markPrice 标记价格
     * @param openPrice 开仓价格
     * @param isLong 是否为多头仓位
     * @param minTickSz 最小变动单位精度
     * @return 盈亏金额,保留指定精度的小数位
     */
    public BigDecimal profit(BigDecimal faceValue, BigDecimal position, BigDecimal contractMultiplier,
                             BigDecimal markPrice, BigDecimal openPrice, boolean isLong, int minTickSz) {
        BigDecimal profit = BigDecimal.ZERO;
        if (isLong) {
            profit = markPrice.subtract(openPrice)
                    .multiply(faceValue)
                    .multiply(contractMultiplier)
                    .multiply(position);
        } else {
            profit = openPrice.subtract(markPrice)
                    .multiply(faceValue)
                    .multiply(contractMultiplier)
                    .multiply(position);
        }
        return profit.setScale(minTickSz, BigDecimal.ROUND_DOWN);
        // 打印平仓队列
        log.info("平仓队列: {}", queuePingCang);
    }
}