From 60d1f642052ad8c7bd8a11f02f965b122bebf9a4 Mon Sep 17 00:00:00 2001
From: zj <1772600164@qq.com>
Date: Thu, 09 Apr 2026 18:43:37 +0800
Subject: [PATCH] 1

---
 trading-order-service/src/main/java/com/yami/trading/service/contract/ContractOrderCalculationServiceImpl.java |  109 +++++++++++++++++++++++-------------------------------
 1 files changed, 47 insertions(+), 62 deletions(-)

diff --git a/trading-order-service/src/main/java/com/yami/trading/service/contract/ContractOrderCalculationServiceImpl.java b/trading-order-service/src/main/java/com/yami/trading/service/contract/ContractOrderCalculationServiceImpl.java
index 43d9b73..16af431 100644
--- a/trading-order-service/src/main/java/com/yami/trading/service/contract/ContractOrderCalculationServiceImpl.java
+++ b/trading-order-service/src/main/java/com/yami/trading/service/contract/ContractOrderCalculationServiceImpl.java
@@ -1,17 +1,16 @@
 package com.yami.trading.service.contract;
 
 import com.yami.trading.bean.contract.domain.ContractOrder;
+import com.yami.trading.bean.contract.domain.ContractOrderProfit;
 import com.yami.trading.bean.data.domain.Realtime;
 import com.yami.trading.bean.item.domain.Item;
 import com.yami.trading.bean.model.Wallet;
-import com.yami.trading.bean.syspara.domain.Syspara;
 import com.yami.trading.common.constants.ContractRedisKeys;
 import com.yami.trading.common.util.RedisUtil;
 import com.yami.trading.common.util.ThreadUtils;
 import com.yami.trading.service.WalletService;
 import com.yami.trading.service.data.DataService;
 import com.yami.trading.service.item.ItemService;
-import com.yami.trading.service.syspara.SysparaService;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.ObjectUtils;
 import org.apache.logging.log4j.LogManager;
@@ -21,13 +20,12 @@
 import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
 
-import javax.annotation.Resource;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
-import java.time.Duration;
 import java.time.Instant;
 import java.time.LocalDate;
 import java.time.ZoneId;
+import java.util.Date;
 import java.util.List;
 
 @Slf4j
@@ -51,31 +49,10 @@
     private DataService dataService;
     @Autowired
     private WalletService walletService;
-    @Resource
-    private SysparaService sysparaService;
     private Logger logger = LogManager.getLogger(ContractOrderCalculationServiceImpl.class);
 
     private BigDecimal defaultZero(BigDecimal value) {
         return value == null ? BigDecimal.ZERO : value;
-    }
-
-    private BigDecimal estimateAccruedFundingFee(ContractOrder order) {
-        if (order == null || order.getCreateTime() == null) {
-            return BigDecimal.ZERO;
-        }
-        BigDecimal borrowedAmount = defaultZero(order.getBorrowedAmount());
-        if (borrowedAmount.compareTo(BigDecimal.ZERO) <= 0) {
-            return BigDecimal.ZERO;
-        }
-        long holdHours = Duration.between(order.getCreateTime().toInstant(), Instant.now()).toHours();
-        long settlementPeriods = holdHours / 4;
-        if (settlementPeriods <= 0) {
-            return BigDecimal.ZERO;
-        }
-        BigDecimal conservativeRate = new BigDecimal("0.001");
-        return borrowedAmount.multiply(conservativeRate)
-                .multiply(BigDecimal.valueOf(settlementPeriods))
-                .setScale(8, RoundingMode.HALF_UP);
     }
 
     private BigDecimal calculateType1ForceClosePrice(ContractOrder order, Wallet wallet) {
@@ -97,11 +74,9 @@
             otherEquity = otherEquity.add(defaultZero(contractOrder.getProfit()).add(defaultZero(contractOrder.getDeposit())));
         }
 
-        BigDecimal accruedFundingFee = estimateAccruedFundingFee(order);
         BigDecimal baseEquity = defaultZero(wallet.getMoney())
                 .add(otherEquity)
-                .add(defaultZero(order.getDeposit()))
-                .subtract(accruedFundingFee);
+                .add(defaultZero(order.getDeposit()));
         BigDecimal priceOffset = baseEquity.divide(volume, 10, RoundingMode.HALF_UP);
         if (ContractOrder.DIRECTION_BUY.equalsIgnoreCase(order.getDirection())) {
             return tradeAvgPrice.subtract(priceOffset);
@@ -119,7 +94,7 @@
         if (thresholdRatio.compareTo(BigDecimal.ZERO) <= 0) {
             return tradeAvgPrice;
         }
-        BigDecimal availableDeposit = defaultZero(order.getDeposit()).subtract(estimateAccruedFundingFee(order));
+        BigDecimal availableDeposit = defaultZero(order.getDeposit());
         if (availableDeposit.compareTo(BigDecimal.ZERO) <= 0) {
             return tradeAvgPrice;
         }
@@ -195,11 +170,10 @@
         BigDecimal point = close.subtract(order.getTradeAvgPrice()).abs().divide(order.getPips(), 10, RoundingMode.HALF_UP);
         // 根据偏 差点数和手数算出盈亏金额
         BigDecimal amount = order.getPipsAmount().multiply(point).multiply(order.getVolume());
-        if (order.getDirection().equalsIgnoreCase(ContractOrder.DIRECTION_BUY)) {
-            return amount;
-        } else {
-            return amount.negate();
-        }
+        BigDecimal pricePnl = order.getDirection().equalsIgnoreCase(ContractOrder.DIRECTION_BUY)
+                ? amount : amount.negate();
+        BigDecimal funding = contractOrderService.calculateAccruedFundingPnl(order, close, new Date());
+        return pricePnl.add(funding);
 
     }
 
@@ -230,11 +204,10 @@
          * 根据偏 差点数和手数算出盈亏金额
          */
         BigDecimal amount = order.getPipsAmount().multiply(point).multiply(order.getVolume());
-        if (order.getDirection().equalsIgnoreCase(ContractOrder.DIRECTION_BUY)) {
-            return amount;
-        } else {
-            return amount.negate();
-        }
+        BigDecimal pricePnl = order.getDirection().equalsIgnoreCase(ContractOrder.DIRECTION_BUY)
+                ? amount : amount.negate();
+        BigDecimal funding = contractOrderService.calculateAccruedFundingPnl(order, close, new Date());
+        return pricePnl.add(funding);
 
     }
 
@@ -262,28 +235,7 @@
             pips = new BigDecimal("0.01");
         }
 
-        /**
-         * 根据价格变化百分比和保证金计算盈亏金额
-         */
-        BigDecimal priceChangeRatio = currentPrice.subtract(order.getTradeAvgPrice())
-            .divide(order.getTradeAvgPrice(), 6, RoundingMode.DOWN);
-
-        BigDecimal margin = order.getTradeAvgPrice().multiply(order.getVolume()); // 这是用户当前持仓对应的投资金额
-
-        BigDecimal profitAmount = margin.multiply(priceChangeRatio);
-
-        if (ContractOrder.DIRECTION_BUY.equals(order.getDirection())) {
-            order.setProfit(profitAmount.setScale(6,RoundingMode.DOWN));
-        } else{
-            order.setProfit(profitAmount.setScale(6,RoundingMode.DOWN).negate());
-        }
-
-
-        /**
-         * 多次平仓价格不对,后续修
-         */
-        order.setCloseAvgPrice(currentPrice);
-        this.contractOrderService.updateByIdBuffer(order);
+        applyMarkPriceToOrder(order, currentPrice);
 
         /**
          * 止盈价
@@ -332,7 +284,8 @@
                 return;
             }
         }
-        BigDecimal profit1 = contractOrderService.getCacheProfit(order.getUuid()).getProfit();
+        ContractOrderProfit cp = contractOrderService.getCacheProfit(order.getUuid());
+        BigDecimal profit1 = cp != null ? cp.getProfit() : defaultZero(order.getProfit());
         if (order_close_line_type == 1) {
             Wallet wallet = this.walletService.findByUserId(order.getPartyId().toString());
             Integer decimal = itemService.getDecimal(order.getSymbol());
@@ -389,4 +342,36 @@
         this.order_close_line_type = order_close_line_type;
     }
 
+    private void applyMarkPriceToOrder(ContractOrder order, BigDecimal currentPrice) {
+        BigDecimal priceChangeRatio = currentPrice.subtract(order.getTradeAvgPrice())
+                .divide(order.getTradeAvgPrice(), 6, RoundingMode.DOWN);
+        BigDecimal margin = order.getTradeAvgPrice().multiply(order.getVolume());
+        BigDecimal profitAmount = margin.multiply(priceChangeRatio);
+        BigDecimal priceProfit;
+        if (ContractOrder.DIRECTION_BUY.equals(order.getDirection())) {
+            priceProfit = profitAmount.setScale(6, RoundingMode.DOWN);
+        } else {
+            priceProfit = profitAmount.setScale(6, RoundingMode.DOWN).negate();
+        }
+        BigDecimal fundingPnl = contractOrderService.calculateAccruedFundingPnl(order, currentPrice, new Date());
+        order.setProfit(priceProfit.add(fundingPnl));
+        order.setCloseAvgPrice(currentPrice);
+        this.contractOrderService.updateByIdBuffer(order);
+    }
+
+    @Override
+    public void refreshMarkPriceProfit(ContractOrder order) {
+        if (order == null || !ContractOrder.STATE_SUBMITTED.equals(order.getState())) {
+            return;
+        }
+        if (defaultZero(order.getVolume()).compareTo(BigDecimal.ZERO) <= 0) {
+            return;
+        }
+        List<Realtime> list = this.dataService.realtime(order.getSymbol());
+        if (list.isEmpty()) {
+            return;
+        }
+        applyMarkPriceToOrder(order, BigDecimal.valueOf(list.get(0).getClose()));
+    }
+
 }

--
Gitblit v1.9.3