新版仿ok交易所-后端
1
zj
3 days ago 43d1131549c5ee6128f0ad4160df9cfce43db067
1
3 files modified
169 ■■■■■ changed files
trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiContractApplyOrderController.java 6 ●●●●● patch | view | raw | blame | history
trading-order-service/src/main/java/com/yami/trading/service/contract/ContractOrderCalculationServiceImpl.java 14 ●●●● patch | view | raw | blame | history
trading-order-service/src/main/java/com/yami/trading/service/contract/ContractOrderService.java 149 ●●●●● patch | view | raw | blame | history
trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiContractApplyOrderController.java
@@ -28,7 +28,6 @@
import com.yami.trading.service.contract.ContractApplyOrderService;
import com.yami.trading.service.contract.ContractLockService;
import com.yami.trading.service.contract.ContractOrderService;
import com.yami.trading.service.contract.ContractPositionModeService;
import com.yami.trading.service.data.DataService;
import com.yami.trading.service.item.ItemLeverageService;
import com.yami.trading.service.item.ItemService;
@@ -95,9 +94,6 @@
    private ContractOrderService contractOrderService;
    @Autowired
    private ContractPositionModeService contractPositionModeService;
    @Autowired
    private ContractLockService contractLockService;
    @Autowired
    private SessionTokenService sessionTokenService;
@@ -132,8 +128,6 @@
        data.put("contract_open_limit_min", contractOpenLimitMin);
        BigDecimal contractOpenLimitMax = new BigDecimal(sysparaService.find("contract_open_limit_max").getSvalue());
        data.put("contract_open_limit_max", contractOpenLimitMax);
        data.put("contract_position_mode", contractPositionModeService.getMode());
        return Result.succeed(data);
trading-order-service/src/main/java/com/yami/trading/service/contract/ContractOrderCalculationServiceImpl.java
@@ -19,7 +19,6 @@
import java.math.RoundingMode;
import java.util.Date;
import java.util.List;
import java.util.Objects;
@Slf4j
@Service
@@ -197,11 +196,7 @@
        BigDecimal forceClose;
        if (order_close_line_type == 1) {
            Wallet wallet = this.walletService.findByUserId(order.getPartyId().toString());
            if (wallet == null) {
                forceClose = calculateType2ForceClosePrice(order);
            } else {
                forceClose = calculateType1ForceClosePrice(order, wallet);
            }
            forceClose = calculateType1ForceClosePrice(order, wallet);
        } else {
            forceClose = calculateType2ForceClosePrice(order);
        }
@@ -244,19 +239,16 @@
        List<ContractOrder> list = contractOrderService.findSubmitted(order.getPartyId(), null, null, null, null, null);
        BigDecimal otherEquity = BigDecimal.ZERO;
        for (ContractOrder contractOrder : list) {
            if (contractOrder == null) {
                continue;
            }
            if (ContractOrder.STATE_SUBMITTED.equals(contractOrder.getState())) {
                contractOrderService.wrapProfit(contractOrder);
            }
            if (Objects.equals(order.getUuid(), contractOrder.getUuid())) {
            if (order.getUuid().equals(contractOrder.getUuid())) {
                continue;
            }
            otherEquity = otherEquity.add(defaultZero(contractOrder.getProfit()).add(defaultZero(contractOrder.getDeposit())));
        }
        BigDecimal baseEquity = defaultZero(wallet != null ? wallet.getMoney() : null)
        BigDecimal baseEquity = defaultZero(wallet.getMoney())
                .add(otherEquity)
                .add(defaultZero(order.getDeposit()));
        BigDecimal priceOffset = baseEquity.divide(volumeFactor, 10, RoundingMode.HALF_UP);
trading-order-service/src/main/java/com/yami/trading/service/contract/ContractOrderService.java
@@ -123,9 +123,6 @@
    @Autowired
    private SysparaService sysparaService;
    @Autowired
    private ContractPositionModeService contractPositionModeService;
    public IPage<ContractOrderDTO> listRecord(Page page, ContractOrderQuery query) {
        return baseMapper.listRecord(page, query);
    }
@@ -740,123 +737,6 @@
        return rentalProfit;
    }
    /**
     * 单向持仓:反向开仓前先按张数平掉对向持仓,释放保证金后再开剩余仓位。
     *
     * @return 对冲后仍需新开仓的张数
     */
    private BigDecimal netOppositePositions(ContractApplyOrder applyOrder, Realtime realtime, BigDecimal openVolume) {
        if (openVolume == null || openVolume.compareTo(BigDecimal.ZERO) <= 0) {
            return BigDecimal.ZERO;
        }
        String oppositeDirection = ContractOrder.DIRECTION_BUY.equals(applyOrder.getDirection())
                ? ContractOrder.DIRECTION_SELL
                : ContractOrder.DIRECTION_BUY;
        List<ContractOrder> oppositeList = findSubmitted(
                applyOrder.getPartyId(), applyOrder.getSymbol(), oppositeDirection);
        if (CollectionUtil.isEmpty(oppositeList)) {
            return openVolume;
        }
        BigDecimal remainingOpenVolume = openVolume;
        for (ContractOrder opposite : oppositeList) {
            if (remainingOpenVolume.compareTo(BigDecimal.ZERO) <= 0) {
                break;
            }
            if (opposite.getVolume() == null || opposite.getVolume().compareTo(BigDecimal.ZERO) <= 0) {
                continue;
            }
            if (!ContractLock.add(opposite.getOrderNo())) {
                continue;
            }
            try {
                BigDecimal closeVolume = remainingOpenVolume.min(opposite.getVolume());
                contractOrderCalculationService.refreshMarkPriceProfit(opposite);
                BigDecimal profit = settle(opposite, closeVolume);
                update(opposite);
                Wallet wallet = walletService.findByUserId(applyOrder.getPartyId());
                if (wallet.getMoney().add(profit).compareTo(BigDecimal.ZERO) < 0) {
                    profit = wallet.getMoney().negate();
                }
                walletService.updateMoney(opposite.getSymbol(), applyOrder.getPartyId(), profit, BigDecimal.ZERO,
                        Constants.MONEYLOG_CATEGORY_CONTRACT, Constants.WALLET_USDT,
                        Constants.MONEYLOG_CONTENT_CONTRACT_CLOSE,
                        "反手对冲平仓,平仓合约数[" + closeVolume + "],订单号[" + opposite.getOrderNo() + "]");
                if (ContractOrder.STATE_CREATED.equals(opposite.getState())) {
                    User party = userService.getById(opposite.getPartyId());
                    if (party != null) {
                        if (party.getWithdrawLimitNowAmount() == null) {
                            party.setWithdrawLimitNowAmount(BigDecimal.ZERO);
                        }
                        party.setWithdrawLimitNowAmount(party.getWithdrawLimitNowAmount().add(opposite.getDepositOpen()));
                        userService.updateById(party);
                    }
                    userDataService.saveClose(opposite);
                    User partyUser = userService.getById(opposite.getPartyId());
                    if (partyUser != null && Constants.SECURITY_ROLE_MEMBER.equals(partyUser.getRoleName())) {
                        tipService.deleteTip(opposite.getUuid().toString());
                    }
                }
                remainingOpenVolume = remainingOpenVolume.subtract(closeVolume);
            } finally {
                ContractLock.remove(opposite.getOrderNo());
            }
        }
        return remainingOpenVolume;
    }
    /**
     * 反向开仓完全被对向持仓对冲,无需再开新仓。
     */
    private void completeNettedApplyOrder(ContractApplyOrder applyOrder,
                                          BigDecimal originalDeposit, BigDecimal originalFee) {
        applyOrder.setVolume(BigDecimal.ZERO);
        applyOrder.setState(ContractApplyOrder.STATE_CREATED);
        contractApplyOrderService.updateById(applyOrder);
        if (ContractApplyOrder.ORDER_PRICE_TYPE_LIMIT.equals(applyOrder.getOrderPriceType())) {
            BigDecimal refund = defaultZero(originalDeposit).add(defaultZero(originalFee));
            if (refund.compareTo(BigDecimal.ZERO) > 0) {
                walletService.updateMoney(applyOrder.getSymbol(), applyOrder.getPartyId(), refund, BigDecimal.ZERO,
                        Constants.MONEYLOG_CATEGORY_CONTRACT, Constants.WALLET_USDT,
                        Constants.MONEYLOG_CONTENT_CONTRACT_CONCEL,
                        "反手完全对冲,退回保证金,订单号[" + applyOrder.getOrderNo() + "]");
            }
        }
    }
    /**
     * 部分对冲后,按剩余比例调整委托单保证金/手续费;限价单退回多扣部分。
     */
    private void adjustApplyOrderAfterPartialNet(ContractApplyOrder applyOrder,
                                                 BigDecimal originalVolume,
                                                 BigDecimal remainingVolume,
                                                 BigDecimal originalMoney,
                                                 BigDecimal originalDeposit,
                                                 BigDecimal originalFee) {
        BigDecimal ratio = remainingVolume.divide(originalVolume, 10, RoundingMode.HALF_UP);
        BigDecimal remainingMoney = originalMoney.multiply(ratio).setScale(4, RoundingMode.DOWN);
        BigDecimal remainingDeposit = defaultZero(originalDeposit).multiply(ratio).setScale(4, RoundingMode.DOWN);
        BigDecimal remainingFee = defaultZero(originalFee).multiply(ratio).setScale(4, RoundingMode.DOWN);
        if (ContractApplyOrder.ORDER_PRICE_TYPE_LIMIT.equals(applyOrder.getOrderPriceType())) {
            BigDecimal refund = defaultZero(originalDeposit).subtract(remainingDeposit)
                    .add(defaultZero(originalFee).subtract(remainingFee));
            if (refund.compareTo(BigDecimal.ZERO) > 0) {
                walletService.updateMoney(applyOrder.getSymbol(), applyOrder.getPartyId(), refund, BigDecimal.ZERO,
                        Constants.MONEYLOG_CATEGORY_CONTRACT, Constants.WALLET_USDT,
                        Constants.MONEYLOG_CONTENT_CONTRACT_CONCEL,
                        "反手部分对冲,退回多余保证金,订单号[" + applyOrder.getOrderNo() + "]");
            }
        }
        applyOrder.setVolume(remainingVolume);
        applyOrder.setVolumeOpen(remainingVolume);
        applyOrder.setMoney(remainingMoney);
        applyOrder.setDeposit(remainingDeposit);
        applyOrder.setFee(remainingFee);
    }
    private void applyLimitOpenToOrder(ContractOrder order, ContractApplyOrder applyOrder) {
        order.setUnitAmount(applyOrder.getUnitAmount());
        order.setDepositOpen(applyOrder.getDeposit());
@@ -897,31 +777,6 @@
    public void saveOpen(ContractApplyOrder applyOrder, Realtime realtime) {
        Item item = this.itemService.findBySymbol(applyOrder.getSymbol());
        if (item == null) {
            throw new YamiShopBindException("Parameter Error3");
        }
        // 单向持仓:反向开仓前先平掉对向仓位;双向持仓(默认)允许同币种多空并存
        if (contractPositionModeService.isOneWayMode()) {
            BigDecimal originalVolume = applyOrder.getVolume();
            BigDecimal originalMoney = applyOrder.getMoney();
            BigDecimal originalDeposit = applyOrder.getDeposit();
            BigDecimal originalFee = applyOrder.getFee();
            BigDecimal remainingVolume = netOppositePositions(applyOrder, realtime, originalVolume);
            if (remainingVolume.compareTo(BigDecimal.ZERO) <= 0) {
                completeNettedApplyOrder(applyOrder, originalDeposit, originalFee);
                return;
            }
            if (remainingVolume.compareTo(originalVolume) < 0) {
                adjustApplyOrderAfterPartialNet(applyOrder, originalVolume, remainingVolume,
                        originalMoney, originalDeposit, originalFee);
            }
        }
        if (ContractApplyOrder.ORDER_PRICE_TYPE_OPPONENT.equals(applyOrder.getOrderPriceType())) {
            ensureOpponentOpenMargin(applyOrder);
        }
        ContractOrder f = getOne(new LambdaQueryWrapper<>(ContractOrder.class)
                .eq(ContractOrder::getPartyId, applyOrder.getPartyId())
@@ -1000,9 +855,9 @@
            } else {
                applyLimitOpenToOrder(order, applyOrder);
            }
            save(order);
            //计算强平价格
            getStrongPrice(order);
            update(order);
            save(order);
            refreshOrder(applyOrder, order);
        }
    }