From 030e1d50c1f643137220f1ecf1d90ce39174204a Mon Sep 17 00:00:00 2001
From: dd <gitluke@outlook.com>
Date: Sat, 30 May 2026 01:58:54 +0800
Subject: [PATCH] 1
---
trading-order-service/src/main/java/com/yami/trading/service/contract/ContractApplyOrderService.java | 48 +++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 45 insertions(+), 3 deletions(-)
diff --git a/trading-order-service/src/main/java/com/yami/trading/service/contract/ContractApplyOrderService.java b/trading-order-service/src/main/java/com/yami/trading/service/contract/ContractApplyOrderService.java
index 03b1e32..2d12389 100644
--- a/trading-order-service/src/main/java/com/yami/trading/service/contract/ContractApplyOrderService.java
+++ b/trading-order-service/src/main/java/com/yami/trading/service/contract/ContractApplyOrderService.java
@@ -237,10 +237,10 @@
}
Wallet wallet = this.walletService.findByUserId(order.getPartyId());
- BigDecimal amountBefore = wallet.getMoney();
- BigDecimal totalAmountCost = order.getDeposit().add(order.getFee());
+ BigDecimal totalAmountCost = order.getDeposit().add(order.getFee() != null ? order.getFee() : BigDecimal.ZERO);
+ BigDecimal available = getAvailableOpenMargin(order.getPartyId(), null);
- if (amountBefore.compareTo(totalAmountCost) < 0) {
+ if (available.compareTo(totalAmountCost) < 0) {
throw new YamiShopBindException("not sufficient funds");
}
@@ -255,6 +255,48 @@
);
}
save(order);
+
+ // 市价单同步成交,避免异步撮合失败时长期挂单
+ if (ContractApplyOrder.ORDER_PRICE_TYPE_OPPONENT.equals(order.getOrderPriceType())) {
+ executeOpenImmediately(order);
+ }
+ }
+
+ /**
+ * 市价开仓立即撮合;失败则向上抛出,由事务回滚委托单。
+ */
+ private void executeOpenImmediately(ContractApplyOrder order) {
+ List<Realtime> realtimes = dataService.realtime(order.getSymbol());
+ if (CollectionUtil.isEmpty(realtimes)) {
+ return;
+ }
+ contractOrderService.saveOpen(order, realtimes.get(0));
+ }
+
+ /**
+ * 可用于新开仓的余额(双向持仓下多空各自占用保证金,需扣除未成交市价委托预留额)。
+ *
+ * @param excludeOrderNo 正在成交的委托单号,不计入预留
+ */
+ public BigDecimal getAvailableOpenMargin(String partyId, String excludeOrderNo) {
+ Wallet wallet = walletService.findByUserId(partyId);
+ if (wallet == null || wallet.getMoney() == null) {
+ return BigDecimal.ZERO;
+ }
+ BigDecimal available = wallet.getMoney();
+ List<ContractApplyOrder> pendingOpens = findSubmitted(partyId, null, ContractApplyOrder.OFFSET_OPEN, null);
+ for (ContractApplyOrder pending : pendingOpens) {
+ if (excludeOrderNo != null && excludeOrderNo.equals(pending.getOrderNo())) {
+ continue;
+ }
+ if (!ContractApplyOrder.ORDER_PRICE_TYPE_OPPONENT.equals(pending.getOrderPriceType())) {
+ continue;
+ }
+ BigDecimal deposit = pending.getDeposit() != null ? pending.getDeposit() : BigDecimal.ZERO;
+ BigDecimal fee = pending.getFee() != null ? pending.getFee() : BigDecimal.ZERO;
+ available = available.subtract(deposit).subtract(fee);
+ }
+ return available.max(BigDecimal.ZERO);
}
/**
--
Gitblit v1.9.3