| | |
| | | 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; |
| | |
| | | import java.math.BigDecimal; |
| | | import java.math.RoundingMode; |
| | | import java.text.DecimalFormat; |
| | | import java.time.ZoneId; |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | |
| | | |
| | | @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); |
| | |
| | | } |
| | | |
| | | public List<ExchangeSymbolDto> getDataList(List<ExchangeApplyOrder> dbList) { |
| | | |
| | | List<ExchangeSymbolDto> result = new ArrayList<>(); |
| | | Map<String, List<ExchangeSymbolDto>> map = new HashMap<>(); |
| | | for (ExchangeApplyOrder order : dbList) { |
| | |
| | | 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; |
| | | } |