新版仿ok交易所-后端
1
zj
2025-09-30 0c389d73cc79a0027cf779721c6bf184b12f5d86
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;
    }