From 0c389d73cc79a0027cf779721c6bf184b12f5d86 Mon Sep 17 00:00:00 2001
From: zj <1772600164@qq.com>
Date: Tue, 30 Sep 2025 18:53:21 +0800
Subject: [PATCH] 1

---
 trading-order-service/src/main/java/com/yami/trading/service/exchange/impl/ExchangeApplyOrderServiceImpl.java |  131 +++++++++++++++++++++++++++----------------
 1 files changed, 82 insertions(+), 49 deletions(-)

diff --git a/trading-order-service/src/main/java/com/yami/trading/service/exchange/impl/ExchangeApplyOrderServiceImpl.java b/trading-order-service/src/main/java/com/yami/trading/service/exchange/impl/ExchangeApplyOrderServiceImpl.java
index 635ba0d..3b355fa 100644
--- a/trading-order-service/src/main/java/com/yami/trading/service/exchange/impl/ExchangeApplyOrderServiceImpl.java
+++ b/trading-order-service/src/main/java/com/yami/trading/service/exchange/impl/ExchangeApplyOrderServiceImpl.java
@@ -7,6 +7,7 @@
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.google.gson.Gson;
+import com.yami.trading.bean.data.domain.Kline;
 import com.yami.trading.bean.data.domain.Realtime;
 import com.yami.trading.bean.exchange.ExchangeApplyOrder;
 import com.yami.trading.bean.exchange.dto.ExchangeApplyOrderDto;
@@ -40,6 +41,7 @@
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.text.DecimalFormat;
+import java.time.ZoneId;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -169,16 +171,12 @@
 
     @Override
     public List<ExchangeSymbolDto> getETFListByUserId(String userId, String type) {
-
         List<String> symbols = itemService.findByType(type).stream().map(Item::getSymbol).collect(Collectors.toList());
         symbols.add("-1");
-        log.info(JSONUtil.toJsonStr(symbols));
         LambdaQueryWrapper<ExchangeApplyOrder> lambdaQueryWrapper = Wrappers.<ExchangeApplyOrder>query().lambda();
         lambdaQueryWrapper.eq(ExchangeApplyOrder::getPartyId, userId);
         lambdaQueryWrapper.in(ExchangeApplyOrder::getSymbol, symbols);
-        lambdaQueryWrapper.notIn(ExchangeApplyOrder::getOffset, ExchangeApplyOrder.OFFSET_CLOSE);
-//        lambdaQueryWrapper.notIn(ExchangeApplyOrder::getOrderPriceType, "opponent");
-        lambdaQueryWrapper.eq(ExchangeApplyOrder::getState, ExchangeApplyOrder.STATE_CREATED);
+        lambdaQueryWrapper.eq(ExchangeApplyOrder::getState, ExchangeApplyOrder.STATE_SUBMITTED);
         lambdaQueryWrapper.orderByDesc(ExchangeApplyOrder::getCreateTime);
         List<ExchangeApplyOrder> list = list(lambdaQueryWrapper);
         return getDataList(list);
@@ -203,7 +201,6 @@
     }
 
     public List<ExchangeSymbolDto> getDataList(List<ExchangeApplyOrder> dbList) {
-
         List<ExchangeSymbolDto> result = new ArrayList<>();
         Map<String, List<ExchangeSymbolDto>> map = new HashMap<>();
         for (ExchangeApplyOrder order : dbList) {
@@ -211,70 +208,106 @@
             if (exchangeSymbolDtos == null) {
                 exchangeSymbolDtos = new ArrayList<>();
             }
-//            Realtime realtime = new Realtime();
-//            realtime.setClose(new BigDecimal(99));
-//            realtime.setOpen(new BigDecimal(100));
-//            ExchangeSymbolDto exchangeSymbolDto = new ExchangeSymbolDto();
-//            exchangeSymbolDto.setVolume(order.getVolume());
-//            exchangeSymbolDto.setName("test");
-//            exchangeSymbolDto.setOpenPrice(realtime.getOpen().doubleValue());
-//            exchangeSymbolDto.setCurrentPrice(realtime.getClose().doubleValue());
-//            exchangeSymbolDto.setPrice(order.getClosePrice());
-//            exchangeSymbolDtos.add(exchangeSymbolDto);
-//            map.put(order.getSymbol(), exchangeSymbolDtos);
             List<Realtime> symbolList = dataService.realtime(order.getSymbol());
             if (!CollectionUtil.isEmpty(symbolList)) {
                 Realtime realtime = symbolList.get(0);
                 ExchangeSymbolDto exchangeSymbolDto = new ExchangeSymbolDto();
-                exchangeSymbolDto.setVolume(order.getVolume());
+                exchangeSymbolDto.setVolume(order.getVolume() != 0 ? order.getVolume() : order.getSymbolValue());
                 exchangeSymbolDto.setName(realtime.getName());
-                exchangeSymbolDto.setOpenPrice(realtime.getOpen().doubleValue());
+                exchangeSymbolDto.setOpenPrice(order.getPrice());
                 exchangeSymbolDto.setCurrentPrice(realtime.getClose().doubleValue());
                 exchangeSymbolDto.setPrice(order.getClosePrice());
+                exchangeSymbolDto.setOffset(order.getOffset());
+                exchangeSymbolDto.setState(order.getState());
+                exchangeSymbolDto.setCloseTimeTs(order.getCreateTimeTs());
                 exchangeSymbolDtos.add(exchangeSymbolDto);
                 map.put(order.getSymbol(), exchangeSymbolDtos);
             }
         }
         for (String key : map.keySet()) {
             List<ExchangeSymbolDto> list = map.get(key);
+            Item item = itemService.findBySymbol(key);
             double volume = 0; //可用
-            double cost = 0.0;
+            double costValue = 0.0;//总价值
             double marketValue = 0; //市值
             double currentPrice = 0; //当前价格
-            double profitLoss = 0; //总盈亏
-            double toDayProfitLoss = 0; //今日总盈亏
-            double openPrice = 0;
+            double profitLoss = 0; //浮盈
+            double toDayProfitLoss = 0; //今日盈亏(浮动)
+            double todayProfit = 0; //今日盈亏(结算)
+            double profitTotal = 0; //累计盈亏
+            double openPrice = 0;//开仓价格
             String name = "";
-            for (ExchangeSymbolDto dto : list) {
-                volume += dto.getVolume();
+            BigDecimal price = BigDecimal.ZERO;//成本价
+            List<ExchangeSymbolDto> sort = list.stream().sorted(Comparator.comparing(ExchangeSymbolDto::getCloseTimeTs)).collect(Collectors.toList());
+            for (ExchangeSymbolDto dto : sort) {
                 name = dto.getName();
-                cost += (dto.getVolume() * dto.getPrice());
                 currentPrice = dto.getCurrentPrice();
-                openPrice = dto.getOpenPrice();
-                marketValue += (dto.getCurrentPrice() * dto.getVolume());
+                openPrice = dto.getPrice();
+                //成本价值
+                double cost = dto.getVolume() * dto.getPrice();
+
+                if (dto.getOffset().equals(ExchangeApplyOrder.OFFSET_CLOSE)) {
+                    volume -= dto.getVolume();
+
+                    if (ExchangeApplyOrder.STATE_CREATED.equalsIgnoreCase(dto.getState())) {
+                        profitTotal += dto.getVolume() * (dto.getPrice() - price.doubleValue());
+                        if (dto.getCloseTimeTs() != null && UTCDateUtils.isTimestampFromToday(dto.getCloseTimeTs(), ZoneId.systemDefault())) {
+                            todayProfit += dto.getVolume() * (dto.getPrice() - price.doubleValue());
+                        }
+                        costValue -= (dto.getVolume() * dto.getPrice());
+                        marketValue -= (dto.getCurrentPrice() * dto.getVolume());
+                    }
+                    if (volume == 0) {
+                        price = BigDecimal.ZERO;
+                    }
+                } else {
+                    volume += dto.getVolume();
+                    if (volume != 0) {
+                        price = price.multiply(BigDecimal.valueOf(volume - dto.getVolume()));
+                        price = price.add(BigDecimal.valueOf(cost));
+                        price = price.divide(BigDecimal.valueOf(volume), item.getDecimals(), RoundingMode.FLOOR);
+                    } else {
+                        price = BigDecimal.ZERO;
+                    }
+                    costValue += (dto.getVolume() * dto.getPrice());
+                    marketValue += (dto.getCurrentPrice() * dto.getVolume());
+                    //当日浮动盈亏
+                    List<Kline> kline = dataService.kline(key, Kline.PERIOD_1DAY);
+                    kline = kline.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
+                    double diff = 0.0;
+                    if (CollectionUtil.isNotEmpty(kline)) {
+                        Kline day = kline.get(0);
+                        Long ts = day.getTs() / 1000;
+                        Long timeTs = dto.getCloseTimeTs();
+                        if (timeTs > ts) {
+                            diff = currentPrice - openPrice;
+                        } else {
+                            diff = currentPrice - day.getClose().doubleValue();
+                        }
+                    }
+                    toDayProfitLoss += diff * dto.getVolume();
+                }
             }
-            double price = 0;
-            if (volume == 0) {
-                price = 0;
-            } else {
-                price = cost / volume;
+            if (volume > 0) {
+                //总浮动盈亏
+                profitLoss = marketValue - costValue;
+                ExchangeSymbolDto exchangeSymbolDto = new ExchangeSymbolDto();
+                exchangeSymbolDto.setVolume(new BigDecimal(volume).setScale(4, RoundingMode.HALF_UP).doubleValue());
+                exchangeSymbolDto.setPositionVolume(new BigDecimal(volume).setScale(4, RoundingMode.HALF_UP).doubleValue());
+                exchangeSymbolDto.setPrice(price.setScale(4, RoundingMode.HALF_UP).doubleValue());
+                exchangeSymbolDto.setName(name);
+                exchangeSymbolDto.setSymbol(key);
+                exchangeSymbolDto.setToDayProfitLoss(new BigDecimal(toDayProfitLoss).setScale(4, RoundingMode.HALF_UP).doubleValue());
+                exchangeSymbolDto.setToDayProfitLossPercentage(calculateProfitPercentage(openPrice, currentPrice));
+                exchangeSymbolDto.setCurrentPrice(new BigDecimal(currentPrice).setScale(4, RoundingMode.HALF_UP).doubleValue());
+                exchangeSymbolDto.setOpenPrice(new BigDecimal(openPrice).setScale(4, RoundingMode.HALF_UP).doubleValue());
+                exchangeSymbolDto.setMarketValue(new BigDecimal(marketValue).setScale(4, RoundingMode.HALF_UP).doubleValue());
+                exchangeSymbolDto.setProfitLoss(new BigDecimal(profitLoss).setScale(4, RoundingMode.HALF_UP).doubleValue());
+                exchangeSymbolDto.setProfitLossPercentage(calculateProfitPercentage(price.doubleValue(), currentPrice));
+                exchangeSymbolDto.setProfitTotal(new BigDecimal(profitTotal).setScale(4, RoundingMode.HALF_UP).doubleValue());
+                exchangeSymbolDto.setTodayProfit(todayProfit);
+                result.add(exchangeSymbolDto);
             }
-            toDayProfitLoss = (marketValue - (openPrice * volume));
-            profitLoss = marketValue - cost;
-            ExchangeSymbolDto exchangeSymbolDto = new ExchangeSymbolDto();
-            exchangeSymbolDto.setVolume(new BigDecimal(volume).setScale(2, RoundingMode.HALF_UP).doubleValue());
-            exchangeSymbolDto.setPositionVolume(new BigDecimal(volume).setScale(2, RoundingMode.HALF_UP).doubleValue());
-            exchangeSymbolDto.setPrice(new BigDecimal(price).setScale(2, RoundingMode.HALF_UP).doubleValue());
-            exchangeSymbolDto.setName(name);
-            exchangeSymbolDto.setSymbol(key);
-            exchangeSymbolDto.setToDayProfitLoss(new BigDecimal(toDayProfitLoss).setScale(2, RoundingMode.HALF_UP).doubleValue());
-            exchangeSymbolDto.setToDayProfitLossPercentage(calculateProfitPercentage(openPrice, currentPrice));
-            exchangeSymbolDto.setCurrentPrice(new BigDecimal(currentPrice).setScale(2, RoundingMode.HALF_UP).doubleValue());
-            exchangeSymbolDto.setOpenPrice(new BigDecimal(openPrice).setScale(2, RoundingMode.HALF_UP).doubleValue());
-            exchangeSymbolDto.setMarketValue(new BigDecimal(marketValue).setScale(2, RoundingMode.HALF_UP).doubleValue());
-            exchangeSymbolDto.setProfitLoss(new BigDecimal(profitLoss).setScale(2, RoundingMode.HALF_UP).doubleValue());
-            exchangeSymbolDto.setProfitLossPercentage(calculateProfitPercentage(price, currentPrice));
-            result.add(exchangeSymbolDto);
         }
         return result;
     }

--
Gitblit v1.9.3