src/main/java/com/xcong/excoin/modules/contract/dao/ContractHoldOrderDao.java
@@ -53,7 +53,7 @@ public List<ContractHoldOrderEntity> selectHoldOrderListForWholeByMemberIdAndSymbol(@Param("memberId") Long memberId, @Param("symbol") String symbol); public List<HashMap<String, Object>> selectAllWholeOrderMemberIdAndSymbol(); public List<Long> selectAllWholeOrderMemberId(); public List<String> selectWholeHoldOrderSymbolsByMemberId(@Param("memberId") Long memberId); src/main/java/com/xcong/excoin/modules/contract/mapper/ContractHoldOrderEntityMapper.java
@@ -4,9 +4,12 @@ import com.xcong.excoin.modules.contract.entity.ContractOrderEntity; import com.xcong.excoin.modules.contract.parameter.vo.HoldOrderDetailVo; import com.xcong.excoin.modules.contract.parameter.vo.HoldOrderListVo; import com.xcong.excoin.rabbit.pricequeue.whole.HoldOrderDataModel; import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.factory.Mappers; import java.util.List; /** * @author wzy @@ -24,4 +27,8 @@ @Mapping(target = "openingTime", source = "createTime") public abstract HoldOrderDetailVo holdOrderToOrderDetailVo(ContractHoldOrderEntity holdOrderEntity); public abstract HoldOrderDataModel entityToDataModel(ContractHoldOrderEntity holdOrderEntity); public abstract List<HoldOrderDataModel> entitiesToDataModels(List<ContractHoldOrderEntity> holdOrderEntities); } src/main/java/com/xcong/excoin/modules/contract/service/impl/RabbitOrderServiceImpl.java
@@ -35,6 +35,7 @@ import com.xcong.excoin.modules.member.entity.MemberWalletContractEntity; import com.xcong.excoin.modules.platform.entity.PlatformTradeSettingEntity; import com.xcong.excoin.rabbit.pricequeue.OrderModel; import com.xcong.excoin.rabbit.pricequeue.whole.HoldOrderDataModel; import com.xcong.excoin.rabbit.pricequeue.whole.WholePriceDataModel; import com.xcong.excoin.utils.*; import lombok.extern.slf4j.Slf4j; @@ -472,9 +473,54 @@ ThreadPoolUtils.calReturnMoney(memberEntity.getId(), fee, contractOrderEntity, AgentReturnEntity.ORDER_TYPE_CLOSE); } @Transactional(rollbackFor = Exception.class) @Override public void wholeBombOrder(WholePriceDataModel wholePriceData) { MemberWalletContractEntity wallet = memberWalletContractDao.findWalletContractByMemberIdAndSymbol(wholePriceData.getMemberId(), CoinTypeEnum.USDT.name()); List<HoldOrderDataModel> list = wholePriceData.getList(); if (CollUtil.isNotEmpty(list)) { for (HoldOrderDataModel holdOrderDataModel : list) { ContractHoldOrderEntity holdOrderEntity = contractHoldOrderDao.selectById(holdOrderDataModel.getId()); contractHoldOrderDao.deleteById(holdOrderDataModel.getId()); ContractOrderEntity contractOrderEntity = ContractHoldOrderEntityMapper.INSTANCE.holdOrderToOrder(holdOrderEntity); if (holdOrderEntity.getOpeningType() == ContractHoldOrderEntity.OPENING_TYPE_MORE) { contractOrderEntity.setClosingType(4); } else { contractOrderEntity.setClosingType(5); } BigDecimal rewardRatio = holdOrderDataModel.getRewardAmount().divide(holdOrderEntity.getBondAmount().subtract(holdOrderEntity.getOpeningFeeAmount()), 8, BigDecimal.ROUND_DOWN); contractOrderEntity.setRewardRatio(rewardRatio); contractOrderEntity.setRewardAmount(holdOrderDataModel.getRewardAmount()); contractOrderEntity.setClosingPrice(holdOrderDataModel.getClosingPrice()); contractOrderEntity.setForceClosingPrice(holdOrderDataModel.getClosingPrice()); // 订单状态转换 if (ContractOrderEntity.ORDER_TYPE_OPEN_MORE == contractOrderEntity.getOrderType()) { contractOrderEntity.setOrderType(ContractOrderEntity.ORDER_TYPE_CLOSE_MORE); } else { contractOrderEntity.setOrderType(ContractOrderEntity.ORDER_TYPE_CLOSE_LESS); } contractOrderEntity.setClosingTime(new Date()); contractOrderEntity.setClosingFeeAmount(holdOrderEntity.getOpeningFeeAmount()); contractOrderDao.insert(contractOrderEntity); } List<ContractEntrustOrderEntity> entrustOrder = contractEntrustOrderDao.selectEntrustOrderListByMemberId(wholePriceData.getMemberId()); BigDecimal totalAmount = BigDecimal.ZERO; if (CollUtil.isNotEmpty(entrustOrder)) { for (ContractEntrustOrderEntity contractEntrustOrderEntity : entrustOrder) { totalAmount.add(contractEntrustOrderEntity.getEntrustAmount()); } } memberWalletContractDao.increaseWalletContractBalanceById(wallet.getAvailableBalance().negate(), wallet.getTotalBalance().subtract(totalAmount).negate(), null, wallet.getId()); } } @Transactional(rollbackFor = Exception.class) src/main/java/com/xcong/excoin/rabbit/consumer/OperateOrderPriceConsumer.java
@@ -45,11 +45,10 @@ @RabbitListener(queues = RabbitMqConfig.QUEUE_WHOLE_PRICE) public void onMessageWholePrice(Message message, Channel channel) { log.info("我收到了用户的全仓价格消息"); String content = new String(message.getBody()); WholePriceDataModel wholePriceData = JSONObject.parseObject(content, WholePriceDataModel.class); log.info("我收到了用户的全仓价格消息 : {}", content); OrderOperatePriceService.wholePriceDataOperation(wholePriceData); } src/main/java/com/xcong/excoin/rabbit/init/OrderProducerInit.java
@@ -129,18 +129,10 @@ } // 全仓持仓 List<HashMap<String, Object>> wholeHoldOrders = contractHoldOrderDao.selectAllWholeOrderMemberIdAndSymbol(); List<Long> wholeHoldOrders = contractHoldOrderDao.selectAllWholeOrderMemberId(); if (CollUtil.isNotEmpty(wholeHoldOrders)) { MemberEntity memberEntity = null; for (HashMap<String, Object> wholeHoldOrder : wholeHoldOrders) { Long memberId = (Long) wholeHoldOrder.get("member_id"); String symbol = (String) wholeHoldOrder.get("symbol"); if (memberEntity == null || !memberId.equals(memberEntity.getId())) { memberEntity = memberDao.selectById(memberId); } // ThreadPoolUtils.sendWholeForceClosingPrice(symbol, memberEntity); CalculateUtil.getForceSetPriceForWhole(null, memberEntity); for (Long memberId : wholeHoldOrders) { ThreadPoolUtils.sendWholePrice(memberId); } } src/main/java/com/xcong/excoin/rabbit/pricequeue/WebsocketPriceService.java
@@ -12,6 +12,7 @@ import com.xcong.excoin.modules.member.dao.MemberWalletContractDao; import com.xcong.excoin.modules.member.entity.MemberEntity; import com.xcong.excoin.modules.member.entity.MemberWalletContractEntity; import com.xcong.excoin.rabbit.pricequeue.whole.HoldOrderDataModel; import com.xcong.excoin.rabbit.pricequeue.whole.WholeDataQueue; import com.xcong.excoin.rabbit.pricequeue.whole.WholePriceDataModel; import com.xcong.excoin.rabbit.producer.OrderProducer; @@ -289,25 +290,30 @@ for (Map.Entry<String, WholePriceDataModel> entry : dataModelMap.entrySet()) { WholePriceDataModel wholePriceData = entry.getValue(); List<ContractHoldOrderEntity> list = wholePriceData.getList(); List<HoldOrderDataModel> list = wholePriceData.getList(); if (CollUtil.isNotEmpty(list)) { BigDecimal totalProfitOrLoss = BigDecimal.ZERO; Map<String, BigDecimal> prices = new HashMap<>(); for (ContractHoldOrderEntity holdOrderEntity : list) { BigDecimal newPrice = (BigDecimal) redisUtils.get(CoinTypeConvert.convertToKey(holdOrderEntity.getSymbol())); for (HoldOrderDataModel holdOrderData : list) { String price = redisUtils.getString(CoinTypeConvert.convertToKey(holdOrderData.getSymbol())); // BigDecimal newPrice = new BigDecimal(price); BigDecimal newPrice = new BigDecimal("29958.46627789"); BigDecimal rewardRatio = null; if (ContractHoldOrderEntity.OPENING_TYPE_MORE == holdOrderEntity.getOpeningType()) { if (ContractHoldOrderEntity.OPENING_TYPE_MORE == holdOrderData.getOpeningType()) { // (最新价-开仓价)*规格*张数 rewardRatio = newPrice.subtract(holdOrderEntity.getOpeningPrice()).multiply(holdOrderEntity.getSymbolSku()).multiply(new BigDecimal(holdOrderEntity.getSymbolCntSale())); rewardRatio = newPrice.subtract(holdOrderData.getOpeningPrice()).multiply(holdOrderData.getSymbolSku()).multiply(new BigDecimal(holdOrderData.getSymbolCntSale())); // 开空 } else { // (开仓价-最新价)*规格*张数 rewardRatio = holdOrderEntity.getOpeningPrice().subtract(newPrice).multiply(holdOrderEntity.getSymbolSku()).multiply(new BigDecimal(holdOrderEntity.getSymbolCntSale())); rewardRatio = holdOrderData.getOpeningPrice().subtract(newPrice).multiply(holdOrderData.getSymbolSku()).multiply(new BigDecimal(holdOrderData.getSymbolCntSale())); } totalProfitOrLoss = totalProfitOrLoss.add(rewardRatio); prices.put(holdOrderEntity.getSymbol(), newPrice); holdOrderData.setRewardAmount(rewardRatio); holdOrderData.setClosingPrice(newPrice); totalProfitOrLoss = totalProfitOrLoss.add(rewardRatio).setScale(8, BigDecimal.ROUND_DOWN); prices.put(holdOrderData.getSymbol(), newPrice); } BigDecimal holdBond = wholePriceData.getHoldBond(); @@ -316,7 +322,10 @@ continue; } dataModelMap.remove(entry.getKey()); System.out.println("触发"); wholePriceData.setPrices(prices); contractHoldOrderDao.updateMemberAllHoldOrderClosingStatus(wholePriceData.getMemberId()); orderProducer.sendWholeBomb(JSONObject.toJSONString(wholePriceData)); } } src/main/java/com/xcong/excoin/rabbit/pricequeue/whole/HoldOrderDataModel.java
New file @@ -0,0 +1,29 @@ package com.xcong.excoin.rabbit.pricequeue.whole; import lombok.Data; import java.math.BigDecimal; /** * @author wzy * @date 2021-01-28 **/ @Data public class HoldOrderDataModel { private Long id; private String symbol; private BigDecimal openingPrice; private BigDecimal symbolSku; private Integer symbolCntSale; private BigDecimal rewardAmount; private BigDecimal closingPrice; private int openingType; } src/main/java/com/xcong/excoin/rabbit/pricequeue/whole/WholePriceDataModel.java
@@ -25,7 +25,7 @@ /** * 当前持仓列表 */ private List<ContractHoldOrderEntity> list; private List<HoldOrderDataModel> list; /** * 维持保证金 src/main/java/com/xcong/excoin/utils/ThreadPoolUtils.java
@@ -7,11 +7,13 @@ 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.impl.OrderWebsocketServiceImpl; import com.xcong.excoin.modules.documentary.service.FollowOrderOperationService; import com.xcong.excoin.modules.member.dao.MemberWalletContractDao; import com.xcong.excoin.modules.member.entity.MemberEntity; import com.xcong.excoin.modules.member.entity.MemberWalletContractEntity; import com.xcong.excoin.rabbit.pricequeue.whole.HoldOrderDataModel; import com.xcong.excoin.rabbit.pricequeue.whole.WholePriceDataModel; import com.xcong.excoin.rabbit.producer.OrderProducer; import com.xcong.excoin.utils.dingtalk.DingTalkUtils; @@ -117,7 +119,8 @@ MemberWalletContractEntity wallet = memberWalletContractDao.findWalletContractByMemberIdAndSymbol(memberId, CoinTypeEnum.USDT.name()); WholePriceDataModel wholePriceData = new WholePriceDataModel(); wholePriceData.setList(holdOrders); List<HoldOrderDataModel> holdOrderDataModels = ContractHoldOrderEntityMapper.INSTANCE.entitiesToDataModels(holdOrders); wholePriceData.setList(holdOrderDataModels); BigDecimal totalHoldBond = BigDecimal.ZERO; for (ContractHoldOrderEntity holdOrder : holdOrders) { src/main/resources/mapper/contract/ContractHoldOrderDao.xml
@@ -68,13 +68,12 @@ order by create_time desc </select> <select id="selectAllWholeOrderMemberIdAndSymbol" resultType="java.util.HashMap"> <select id="selectAllWholeOrderMemberId" resultType="java.lang.Long"> select member_id, symbol member_id from contract_hold_order where position_type=2 group by member_id, symbol where position_type=2 and is_can_closing=1 group by member_id </select> <select id="selectWholeHoldOrderSymbolsByMemberId" resultType="java.lang.String"> src/test/java/com/xcong/excoin/WholeTest.java
@@ -18,6 +18,7 @@ import com.xcong.excoin.utils.CalculateUtil; import com.xcong.excoin.utils.RedisUtils; import com.xcong.excoin.utils.ThreadPoolUtils; import lombok.SneakyThrows; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @@ -28,6 +29,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * @author wzy @@ -116,22 +118,6 @@ CalculateUtil.getForceSetPriceForWhole("BTC/USDT", memberEntity); } @Test public void initOrderTest() { List<HashMap<String, Object>> wholeHoldOrders = contractHoldOrderDao.selectAllWholeOrderMemberIdAndSymbol(); if (CollUtil.isNotEmpty(wholeHoldOrders)) { MemberEntity memberEntity = null; for (HashMap<String, Object> wholeHoldOrder : wholeHoldOrders) { Long memberId = (Long) wholeHoldOrder.get("member_id"); String symbol = (String) wholeHoldOrder.get("symbol"); if (memberEntity == null || !memberId.equals(memberEntity.getId())) { memberEntity = memberDao.selectById(memberId); } System.out.println(memberId + "-----" + symbol); } } } @Resource private RedisUtils redisUtils; @@ -156,6 +142,36 @@ CalculateUtil.getForceSetPriceForWhole(null, memberEntity); } public static void main(String[] args) { Map<String, String> map = new ConcurrentHashMap<>(); map.put("1", "1"); map.put("2", "2"); map.put("3", "3"); map.put("4", "4"); map.put("5", "5"); new Thread(new Runnable() { @SneakyThrows @Override public void run() { for (Map.Entry<String, String> entry : map.entrySet()) { System.out.println(entry.getKey() + " - " + entry.getValue()); if (entry.getKey().equals("3")) { System.out.println(11); map.remove("3"); } Thread.sleep(1000); } System.out.println(map.get("3")); } }).start(); } @Test public void mapTest() { websocketPriceService.wholeBomb(); } }