package com.xcong.excoin.modules.contract.service.impl; import cn.hutool.core.collection.CollUtil; import com.xcong.excoin.common.enumerates.CoinTypeEnum; import com.xcong.excoin.common.enumerates.OrderClosingTypeEnum; import com.xcong.excoin.common.system.service.CommonService; import com.xcong.excoin.modules.contract.dao.ContractHoldOrderDao; import com.xcong.excoin.modules.contract.dao.ContractOrderDao; import com.xcong.excoin.modules.contract.entity.ContractHoldOrderEntity; import com.xcong.excoin.modules.contract.entity.ContractOrderEntity; import com.xcong.excoin.modules.contract.mapper.ContractHoldOrderEntityMapper; import com.xcong.excoin.modules.contract.service.RabbitOrderService; import com.xcong.excoin.modules.member.dao.MemberDao; import com.xcong.excoin.modules.member.dao.MemberWalletContractDao; import com.xcong.excoin.modules.member.entity.AgentReturnEntity; import com.xcong.excoin.modules.member.entity.MemberEntity; import com.xcong.excoin.modules.member.entity.MemberWalletContractEntity; import com.xcong.excoin.modules.platform.entity.PlatformTradeSettingEntity; import com.xcong.excoin.utils.CacheSettingUtils; import com.xcong.excoin.utils.CoinTypeConvert; import com.xcong.excoin.utils.RedisUtils; import com.xcong.excoin.utils.ThreadPoolUtils; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import java.math.BigDecimal; import java.util.Date; import java.util.List; /** * @author wzy * @date 2020-06-01 **/ @Slf4j @Service public class RabbitOrderServiceImpl implements RabbitOrderService { @Resource private MemberDao memberDao; @Resource private OrderWebsocketServiceImpl orderWebsocketService; @Resource private ContractHoldOrderDao contractHoldOrderDao; @Resource private ContractOrderDao contractOrderDao; @Resource private CommonService commonService; @Resource private MemberWalletContractDao memberWalletContractDao; @Resource private CacheSettingUtils cacheSettingUtils; @Resource private RedisUtils redisUtils; @Transactional(rollbackFor = Exception.class) @Override public void cancelHoldOrder(List ids) { if (CollUtil.isNotEmpty(ids)) { if (ids.size() == 1) { ContractHoldOrderEntity holdOrderEntity = contractHoldOrderDao.selectById(ids.get(0)); cancelHoldOrderMethod(holdOrderEntity); } else { List holdOrderEntities = contractHoldOrderDao.selectBatchIds(ids); if (CollUtil.isNotEmpty(holdOrderEntities)) { for (ContractHoldOrderEntity holdOrder : holdOrderEntities) { cancelHoldOrderMethod(holdOrder); } } } } } public void cancelHoldOrderMethod(ContractHoldOrderEntity holdOrderEntity) { String symbol = holdOrderEntity.getSymbol(); // 获取最新价 BigDecimal newPrice = new BigDecimal(redisUtils.getString(CoinTypeConvert.convertToKey(symbol))); MemberEntity memberEntity = memberDao.selectById(holdOrderEntity.getMemberId()); MemberWalletContractEntity walletContract = memberWalletContractDao.findWalletContractByMemberIdAndSymbol(holdOrderEntity.getMemberId(), CoinTypeEnum.USDT.name()); if (walletContract != null) { // 删除持仓表订单 contractHoldOrderDao.deleteById(holdOrderEntity.getId()); BigDecimal lotNumber = cacheSettingUtils.getSymbolSku(symbol); // 盈亏 BigDecimal profitOrLoss = BigDecimal.ZERO; Integer orderType = null; Integer closingType = null; // 开多 if (ContractHoldOrderEntity.OPENING_TYPE_MORE == holdOrderEntity.getOpeningType()) { // (最新价-开仓价)*规格*张数 profitOrLoss = newPrice.subtract(holdOrderEntity.getOpeningPrice()).multiply(lotNumber).multiply(new BigDecimal(holdOrderEntity.getSymbolCnt())); orderType = ContractOrderEntity.ORDER_TYPE_CLOSE_MORE; closingType = OrderClosingTypeEnum.CLOSE_MORE.getValue(); // 开空 } else { // (开仓价-最新价)*规格*张数 profitOrLoss = holdOrderEntity.getOpeningPrice().subtract(newPrice).multiply(lotNumber).multiply(new BigDecimal(holdOrderEntity.getSymbolCnt())); orderType = ContractOrderEntity.ORDER_TYPE_CLOSE_LESS; closingType = OrderClosingTypeEnum.CLOSE_LESS.getValue(); } if (memberEntity.getIsProfit() == MemberEntity.IS_PROFIT_Y) { PlatformTradeSettingEntity tradeSettingEntity = cacheSettingUtils.getTradeSetting(); if (profitOrLoss.compareTo(BigDecimal.ZERO) > -1) { profitOrLoss = profitOrLoss.multiply(BigDecimal.ONE.subtract(tradeSettingEntity.getProfitParam())); } else { profitOrLoss = profitOrLoss.multiply(BigDecimal.ONE.add(tradeSettingEntity.getProfitParam())); } } // 盈亏比例(回报率) BigDecimal rewardRatio = profitOrLoss.divide(holdOrderEntity.getBondAmount().subtract(holdOrderEntity.getOpeningFeeAmount()), 8, BigDecimal.ROUND_DOWN); ContractOrderEntity contractOrderEntity = ContractHoldOrderEntityMapper.INSTANCE.holdOrderToOrder(holdOrderEntity); contractOrderEntity.setId(null); contractOrderEntity.setOrderType(orderType); contractOrderEntity.setClosingPrice(newPrice); contractOrderEntity.setClosingFeeAmount(holdOrderEntity.getOpeningFeeAmount()); contractOrderEntity.setClosingTime(new Date()); contractOrderEntity.setClosingType(closingType); contractOrderEntity.setRewardAmount(profitOrLoss); contractOrderEntity.setRewardRatio(rewardRatio); contractOrderDao.insert(contractOrderEntity); // 计算盈利或亏损后可用金额和总金额应该增加或减少的 BigDecimal addMoney = holdOrderEntity.getBondAmount().subtract(holdOrderEntity.getOpeningPrice()).add(profitOrLoss); log.info("平仓增加金额:{}", addMoney); walletContract.setFrozenBalance(walletContract.getFrozenBalance().subtract(holdOrderEntity.getBondAmount())); walletContract.setAvailableBalance(walletContract.getAvailableBalance().add(addMoney)); walletContract.setTotalBalance(walletContract.getTotalBalance().add(addMoney)); // 计算佣金 ThreadPoolUtils.calReturnMoney(memberEntity.getId(), contractOrderEntity.getClosingFeeAmount(), contractOrderEntity, AgentReturnEntity.ORDER_TYPE_CLOSE); } } }