1
zj
2 days ago 5e57de9b12ee136e45ce5754c7fe2e7eb12af05a
trading-order-service/src/main/java/com/yami/trading/service/future/FuturesOrderService.java
@@ -208,6 +208,87 @@
     * @param operaName
     * @return
     */
    public String saveOrderManualProfitPercent(String orderNo, Double manualProfitPercent, String profitLoss, String operaName) {
        if (manualProfitPercent == null) {
            return "盈亏百分比不能为空";
        }
        double absPercent = Math.abs(manualProfitPercent);
        if (absPercent <= 0) {
            return "盈亏百分比必须大于0";
        }
        double signedPercent;
        String resolvedProfitLoss;
        if (StrUtil.isNotBlank(profitLoss)) {
            resolvedProfitLoss = profitLoss.trim().toLowerCase();
            if ("loss".equals(resolvedProfitLoss)) {
                signedPercent = -absPercent;
                resolvedProfitLoss = "loss";
            } else if ("profit".equals(resolvedProfitLoss)) {
                signedPercent = absPercent;
                resolvedProfitLoss = "profit";
            } else {
                return "场控方向无效";
            }
        } else {
            signedPercent = manualProfitPercent;
            resolvedProfitLoss = signedPercent >= 0 ? "profit" : "loss";
        }
        String message = "";
        boolean lock = false;
        while (true) {
            try {
                if (!FuturesLock.add(orderNo)) {
                    continue;
                }
                lock = true;
                FuturesOrder futuresOrder = (FuturesOrder) RedisUtil.get(FuturesRedisKeys.FUTURES_SUBMITTED_ORDERNO + orderNo);
                if (futuresOrder == null) {
                    futuresOrder = cache.get(orderNo);
                }
                if (futuresOrder == null || FuturesOrder.STATE_CREATED.equals(futuresOrder.getState())) {
                    message = "订单已结算或不存在";
                    break;
                }
                Double oldPercent = futuresOrder.getManualProfitPercent();
                String oldProfitLoss = futuresOrder.getProfitLoss();
                futuresOrder.setProfitLoss(resolvedProfitLoss);
                futuresOrder.setManualProfitPercent(signedPercent);
                applyManualProfitPercentToOrder(futuresOrder);
                Double close = futuresOrder.getCloseAvgPrice();
                if (close == null) {
                    close = futuresOrder.getTradeAvgPrice();
                }
                refreshCache(futuresOrder, close);
                RedisUtil.set(FuturesRedisKeys.FUTURES_SUBMITTED_ORDERNO + futuresOrder.getOrderNo(), futuresOrder);
                cache.put(futuresOrder.getOrderNo(), futuresOrder);
                updateById(futuresOrder);
                User party = userService.getById(futuresOrder.getPartyId());
                Log log = new Log();
                log.setCategory(Constants.LOG_CATEGORY_OPERATION);
                log.setOperator(operaName);
                log.setUsername(party.getUserName());
                log.setUserId(party.getUserId());
                log.setCreateTime(new Date());
                log.setLog("设定交割订单场控与盈亏比例。订单号[" + futuresOrder.getOrderNo() + "],场控["
                        + Constants.PROFIT_LOSS_TYPE.get(oldProfitLoss) + "→"
                        + Constants.PROFIT_LOSS_TYPE.get(resolvedProfitLoss) + "],比例["
                        + oldPercent + "→" + signedPercent + "%].");
                this.logService.save(log);
                ThreadUtils.sleep(100);
            } catch (Throwable e) {
                log.error("error:", e);
                message = "修改错误";
            } finally {
                if (lock) {
                    FuturesLock.remove(orderNo);
                    break;
                }
            }
        }
        return message;
    }
    public String saveOrderPorfitOrLoss(String orderNo, String porfitOrLoss, String operaName) {
        String message = "";
        boolean lock = false;
@@ -229,6 +310,7 @@
                Map<String, Double> futuresAssetsOld = this.walletService.getMoneyFuturesByOrder(futuresOrder);
                String oldProfitLoss = futuresOrder.getProfitLoss();
                futuresOrder.setManualProfitPercent(null);
                futuresOrder.setProfitLoss(porfitOrLoss);
                RedisUtil.set(FuturesRedisKeys.FUTURES_SUBMITTED_ORDERNO + futuresOrder.getOrderNo(), futuresOrder);
@@ -330,7 +412,7 @@
            realtime = realtime_list.get(0);
        }
        if (null == realtime) {
            throw new BusinessException(1, "请稍后再试");
            throw new BusinessException(1, "行情获取失败,请稍后再试");
        }
        Double volume = futuresOrder.getVolume();
@@ -454,41 +536,45 @@
        order.setRemainTime(fomatTime(remain_time));
        order.setCloseAvgPrice(close);
        double futures_loss_part = Double.valueOf(this.sysparaService.find("futures_loss_part").getSvalue());
        double closeAvgPrice = order.getCloseAvgPrice().doubleValue();
        double tradeAvgPrice = order.getTradeAvgPrice().doubleValue();
        if (FuturesOrder.DIRECTION_BUY.equals(order.getDirection())) {
            /*
             * 0 买涨
             */
            if (closeAvgPrice >= tradeAvgPrice) {
                DecimalFormat df = new DecimalFormat("#.##");
                order.setProfit(Double.valueOf(df.format(Arith.mul(order.getVolume(), order.getProfitRatio()))));
            }
            if (closeAvgPrice <= tradeAvgPrice) {
                if (futures_loss_part == 2) {
                    DecimalFormat df = new DecimalFormat("#.##");
                    order.setProfit(Arith.sub(0, Double.valueOf(df.format(Arith.mul(order.getVolume(), order.getProfitRatio())))));
                } else {
                    order.setProfit(Arith.sub(0, order.getVolume()));
                }
            }
        if (order.getManualProfitPercent() != null) {
            applyManualProfitPercentToOrder(order);
        } else {
            /*
             * 1 买跌
             */
            if (closeAvgPrice <= tradeAvgPrice) {
                DecimalFormat df = new DecimalFormat("#.##");
                order.setProfit(Double.valueOf(df.format(Arith.mul(order.getVolume(), order.getProfitRatio()))));
            }
            if (closeAvgPrice >= tradeAvgPrice) {
                if (futures_loss_part == 2) {
            double futures_loss_part = Double.valueOf(this.sysparaService.find("futures_loss_part").getSvalue());
            double closeAvgPrice = order.getCloseAvgPrice().doubleValue();
            double tradeAvgPrice = order.getTradeAvgPrice().doubleValue();
            if (FuturesOrder.DIRECTION_BUY.equals(order.getDirection())) {
                /*
                 * 0 买涨
                 */
                if (closeAvgPrice >= tradeAvgPrice) {
                    DecimalFormat df = new DecimalFormat("#.##");
                    order.setProfit(Arith.sub(0, Double.valueOf(df.format(Arith.mul(order.getVolume(), order.getProfitRatio())))));
                } else {
                    order.setProfit(Arith.sub(0, order.getVolume()));
                    order.setProfit(Double.valueOf(df.format(Arith.mul(order.getVolume(), order.getProfitRatio()))));
                }
                if (closeAvgPrice <= tradeAvgPrice) {
                    if (futures_loss_part == 2) {
                        DecimalFormat df = new DecimalFormat("#.##");
                        order.setProfit(Arith.sub(0, Double.valueOf(df.format(Arith.mul(order.getVolume(), order.getProfitRatio())))));
                    } else {
                        order.setProfit(Arith.sub(0, order.getVolume()));
                    }
                }
            } else {
                /*
                 * 1 买跌
                 */
                if (closeAvgPrice <= tradeAvgPrice) {
                    DecimalFormat df = new DecimalFormat("#.##");
                    order.setProfit(Double.valueOf(df.format(Arith.mul(order.getVolume(), order.getProfitRatio()))));
                }
                if (closeAvgPrice >= tradeAvgPrice) {
                    if (futures_loss_part == 2) {
                        DecimalFormat df = new DecimalFormat("#.##");
                        order.setProfit(Arith.sub(0, Double.valueOf(df.format(Arith.mul(order.getVolume(), order.getProfitRatio())))));
                    } else {
                        order.setProfit(Arith.sub(0, order.getVolume()));
                    }
                }
            }
        }
@@ -641,6 +727,11 @@
        order.setCloseTime(System.currentTimeMillis() / 1000);
        order.setState(FuturesOrder.STATE_CREATED);
        if (order.getManualProfitPercent() != null) {
            settleByManualProfitPercent(order);
            return;
        }
        String ProfitLoss = null;
        /**
@@ -883,6 +974,59 @@
         tipService.deleteTip(order.getUuid());
    }
    private void settleByManualProfitPercent(FuturesOrder order) {
        applyManualProfitPercentToOrder(order);
        if (order.getProfit() >= 0) {
            order.setProfitLoss("profit");
        } else {
            order.setProfitLoss("loss");
        }
        double profit = order.getProfit();
        logger.warn("---> FuturesOrderService.settleByManualProfitPercent 订单:{} 使用手动盈亏百分比:{}%, profit:{}",
                order.getOrderNo(), order.getManualProfitPercent(), profit);
        if (profit > 0) {
            BigDecimal amount = BigDecimal.valueOf(order.getProfit()).add(BigDecimal.valueOf(order.getVolume()));
            walletService.updateMoney(order.getSymbol(), order.getPartyId(), amount, BigDecimal.ZERO,
                    Constants.MONEYLOG_CATEGORY_CONTRACT, Constants.WALLET, Constants.DELIVERY_MONEYLOG_CONTENT_CONTRACT_CLOSE,
                    "交割合约盈利(手动盈亏%),订单号[" + order.getOrderNo() + "]");
            String future_profit_bonus_parameters = sysparaService.find("future_profit_bonus_parameters").getSvalue();
            if (StringUtils.isNotEmpty(future_profit_bonus_parameters)) {
                saveParentFeeProfit(order, future_profit_bonus_parameters);
            }
        } else {
            BigDecimal amount = BigDecimal.valueOf(order.getVolume()).add(BigDecimal.valueOf(order.getProfit()));
            walletService.updateMoney(order.getSymbol(), order.getPartyId(), amount, BigDecimal.ZERO,
                    Constants.MONEYLOG_CATEGORY_CONTRACT, Constants.WALLET, Constants.DELIVERY_MONEYLOG_CONTENT_CONTRACT_CLOSE,
                    "交割合约亏损退还(手动盈亏%),订单号[" + order.getOrderNo() + "]");
        }
        updateById(order);
        cache.remove(order.getOrderNo());
        FuturesOrder futuresOld = (FuturesOrder) RedisUtil.get(FuturesRedisKeys.FUTURES_SUBMITTED_ORDERNO + order.getOrderNo());
        RedisUtil.del(FuturesRedisKeys.FUTURES_SUBMITTED_ORDERNO + order.getOrderNo());
        Double futuresAssets = (Double) RedisUtil.get(FuturesRedisKeys.FUTURES_ASSETS_PARTY_ID + order.getPartyId().toString());
        Double futuresAssetsProfit = (Double) RedisUtil.get(FuturesRedisKeys.FUTURES_ASSETS_PROFIT_PARTY_ID + order.getPartyId().toString());
        if (null != futuresOld) {
            Map<String, Double> futuresAssetsOld = this.walletService.getMoneyFuturesByOrder(futuresOld);
            RedisUtil.set(FuturesRedisKeys.FUTURES_ASSETS_PARTY_ID + order.getPartyId().toString(),
                    Arith.add(null == futuresAssets ? 0.000D : futuresAssets, 0 - futuresAssetsOld.get("money_futures")));
            RedisUtil.set(FuturesRedisKeys.FUTURES_ASSETS_PROFIT_PARTY_ID + order.getPartyId().toString(),
                    Arith.add(null == futuresAssetsProfit ? 0.000D : futuresAssetsProfit, 0 - futuresAssetsOld.get("money_futures_profit")));
        }
        this.userDataService.saveFuturesClose(order);
        User party = userService.getById(order.getPartyId());
        party.setWithdrawLimitNowAmount(new BigDecimal(Arith.add(party.getWithdrawLimitNowAmount().doubleValue(), order.getVolume())));
        userService.updateById(party);
        tipService.deleteTip(order.getUuid());
    }
    /** 按后台设定的 manualProfitPercent 计算盈亏,与买卖方向、现价无关 */
    private void applyManualProfitPercentToOrder(FuturesOrder order) {
        double profit = Arith.mul(order.getVolume(), Arith.div(order.getManualProfitPercent(), 100.0));
        DecimalFormat df = new DecimalFormat("#.##");
        order.setProfit(Double.valueOf(df.format(profit)));
    }
    public List<FuturesOrder> findByHourAndSate(String state, String rolename) {
        return baseMapper.findByHourAndSate(state, rolename, new Date());