From 4b844113469b203adc40f1e540de98612321f26e Mon Sep 17 00:00:00 2001
From: Helius <wangdoubleone@gmail.com>
Date: Mon, 01 Jun 2020 20:49:07 +0800
Subject: [PATCH] finish contrach closing order and fix rabbit some question

---
 src/main/java/com/xcong/excoin/modules/contract/service/impl/ContractHoldOrderServiceImpl.java |  130 ++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 122 insertions(+), 8 deletions(-)

diff --git a/src/main/java/com/xcong/excoin/modules/contract/service/impl/ContractHoldOrderServiceImpl.java b/src/main/java/com/xcong/excoin/modules/contract/service/impl/ContractHoldOrderServiceImpl.java
index cfa7f95..f911e60 100644
--- a/src/main/java/com/xcong/excoin/modules/contract/service/impl/ContractHoldOrderServiceImpl.java
+++ b/src/main/java/com/xcong/excoin/modules/contract/service/impl/ContractHoldOrderServiceImpl.java
@@ -1,5 +1,7 @@
 package com.xcong.excoin.modules.contract.service.impl;
 
+import cn.hutool.core.collection.CollUtil;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.xcong.excoin.common.LoginUserUtils;
 import com.xcong.excoin.common.enumerates.CoinTypeEnum;
@@ -11,25 +13,29 @@
 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.parameter.dto.HoldOrderListDto;
 import com.xcong.excoin.modules.contract.parameter.dto.SubmitOrderDto;
 import com.xcong.excoin.modules.contract.service.ContractHoldOrderService;
 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.dao.TradeSettingDao;
 import com.xcong.excoin.modules.platform.entity.PlatformTradeSettingEntity;
-import com.xcong.excoin.utils.CacheSettingUtils;
-import com.xcong.excoin.utils.CalculateUtil;
+import com.xcong.excoin.rabbit.producer.OrderProducer;
+import com.xcong.excoin.utils.*;
 import com.xcong.excoin.rabbit.pricequeue.OrderModel;
-import com.xcong.excoin.utils.CoinTypeConvert;
-import com.xcong.excoin.utils.RedisUtils;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
+import sun.rmi.runtime.Log;
 
 import javax.annotation.Resource;
 import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 /**
  * @author wzy
@@ -56,6 +62,9 @@
 
     @Resource
     private RedisUtils redisUtils;
+
+    @Resource
+    private OrderProducer producer;
 
     @Transactional(rollbackFor = Exception.class)
     @Override
@@ -130,15 +139,18 @@
         holdOrderEntity.setMarkPrice(newPrice);
         holdOrderEntity.setIsCanClosing(ContractHoldOrderEntity.ORDER_CAN_CLOSING_Y);
         holdOrderEntity.setPrePaymentAmount(prePaymentAmount);
-        holdOrderEntity.setBondAmount(bondAmount);
+        holdOrderEntity.setBondAmount(bondAmount.add(openFeePrice));
 
         ContractOrderEntity contractOrderEntity = ContractHoldOrderEntityMapper.INSTANCE.holdOrderToOrder(holdOrderEntity);
 
         contractHoldOrderDao.insert(holdOrderEntity);
         int i = contractOrderDao.insert(contractOrderEntity);
         walletContract.setAvailableBalance(walletContract.getAvailableBalance().subtract(prePaymentAmount));
-        walletContract.setFrozenBalance(walletContract.getFrozenBalance().add(prePaymentAmount));
+        walletContract.setFrozenBalance(walletContract.getFrozenBalance().add(bondAmount.add(openFeePrice)));
         memberWalletContractDao.updateById(walletContract);
+
+        // 计算佣金
+        ThreadPoolUtils.calReturnMoney(memberEntity.getId(), contractOrderEntity.getOpeningFeeAmount(), contractOrderEntity, AgentReturnEntity.ORDER_TYPE_OPEN);
         if (i > 0) {
             return Result.ok("success");
         }
@@ -146,8 +158,8 @@
     }
 
     @Override
-    public int updateContractHoldOrderCanNotClosingByIds(List<OrderModel> list, String batchNo){
-        return contractHoldOrderDao.updateContractHoldOrderCanNotClosingByIds(list,batchNo);
+    public int updateContractHoldOrderCanNotClosingByIds(List<OrderModel> list, String batchNo) {
+        return contractHoldOrderDao.updateContractHoldOrderCanNotClosingByIds(list, batchNo);
     }
 
     @Override
@@ -160,5 +172,107 @@
         contractHoldOrderDao.updateOrderIsCanClosingAndBatchNoById(id);
     }
 
+    @Override
+    public Result findHoldOrderList() {
+        MemberEntity memberEntity = LoginUserUtils.getAppLoginUser();
 
+        List<ContractHoldOrderEntity> list = contractHoldOrderDao.selectHoldOrderListByMemberId(memberEntity.getId());
+        if (CollUtil.isNotEmpty(list)) {
+            BigDecimal totalProfitOrLoss = BigDecimal.ZERO;
+            List<HoldOrderListDto> resultList = new ArrayList<>();
+            for (ContractHoldOrderEntity holdOrderEntity : list) {
+                HoldOrderListDto holdOrderListDto = ContractHoldOrderEntityMapper.INSTANCE.holdOrderToDto(holdOrderEntity);
+                String symbol = holdOrderEntity.getSymbol();
+                // 获取最新价
+                BigDecimal newPrice = new BigDecimal(redisUtils.getString(CoinTypeConvert.convertToKey(symbol)));
+                BigDecimal lotNumber = cacheSettingUtils.getSymbolSku(symbol);
+                // 盈亏
+                BigDecimal rewardRatio = BigDecimal.ZERO;
+                // 开多
+                if (ContractHoldOrderEntity.OPENING_TYPE_MORE == holdOrderEntity.getOpeningType()) {
+                    // (最新价-开仓价)*规格*张数
+                    rewardRatio = newPrice.subtract(holdOrderEntity.getOpeningPrice()).multiply(lotNumber).multiply(new BigDecimal(holdOrderEntity.getSymbolCnt()));
+                    // 开空
+                } else {
+                    // (开仓价-最新价)*规格*张数
+                    rewardRatio = holdOrderEntity.getOpeningPrice().subtract(newPrice).multiply(lotNumber).multiply(new BigDecimal(holdOrderEntity.getSymbolCnt()));
+                }
+
+                if (memberEntity.getIsProfit() == MemberEntity.IS_PROFIT_Y) {
+                    PlatformTradeSettingEntity tradeSettingEntity = cacheSettingUtils.getTradeSetting();
+                    if (rewardRatio.compareTo(BigDecimal.ZERO) > -1) {
+                        rewardRatio = rewardRatio.multiply(BigDecimal.ONE.subtract(tradeSettingEntity.getProfitParam()));
+                    } else {
+                        rewardRatio = rewardRatio.multiply(BigDecimal.ONE.add(tradeSettingEntity.getProfitParam()));
+                    }
+                }
+
+                // 回报率
+                BigDecimal returnRate = rewardRatio.divide(holdOrderEntity.getBondAmount().subtract(holdOrderEntity.getOpeningFeeAmount()), 8, BigDecimal.ROUND_DOWN);
+
+                // 成本价格
+                BigDecimal costPrice = holdOrderEntity.getOpeningPrice()
+                        .multiply(lotNumber)
+                        .multiply(new BigDecimal(holdOrderEntity.getSymbolCnt()))
+                        .divide(new BigDecimal(holdOrderEntity.getLeverRatio()), 8, BigDecimal.ROUND_DOWN);
+
+                // 可增加最大保证金
+                BigDecimal canAddMaxBond = holdOrderEntity.getBondAmount().subtract(holdOrderEntity.getOpeningFeeAmount()).subtract(costPrice);
+                if (canAddMaxBond.compareTo(BigDecimal.ZERO) < 0) {
+                    canAddMaxBond = BigDecimal.ZERO;
+                }
+
+                holdOrderListDto.setCanAddMaxBond(canAddMaxBond);
+                holdOrderListDto.setReturnRate(returnRate);
+                holdOrderListDto.setProfitOrLoss(rewardRatio);
+                resultList.add(holdOrderListDto);
+                totalProfitOrLoss = totalProfitOrLoss.add(rewardRatio);
+            }
+
+            Map<String, Object> result = new HashMap<>();
+            result.put("hold", resultList);
+            result.put("totalProfitOrLoss", totalProfitOrLoss);
+            return Result.ok(result);
+        }
+        return Result.ok("success");
+    }
+
+    @Override
+    public Result cancelHoldOrder(Long id) {
+        MemberEntity memberEntity = LoginUserUtils.getAppLoginUser();
+        ContractHoldOrderEntity holdOrderEntity = contractHoldOrderDao.selectHoldOrderByMemberIdAndId(memberEntity.getId(), id);
+        if (holdOrderEntity == null) {
+            return Result.fail("订单不存在");
+        }
+
+        if (ContractHoldOrderEntity.ORDER_CAN_CLOSING_N == holdOrderEntity.getIsCanClosing()) {
+            return Result.fail("订单暂不可平仓");
+        }
+
+        contractHoldOrderDao.updateHoldOrderIsCanClosingById(ContractHoldOrderEntity.ORDER_CAN_CLOSING_N, id);
+        // 发送平仓消息
+        List<Long> ids = new ArrayList<>();
+        ids.add(id);
+        producer.sendCloseTrade(JSONObject.toJSONString(ids));
+
+        return Result.ok("平仓成功");
+    }
+
+    @Override
+    public Result cancelHoldOrderBatch() {
+        MemberEntity memberEntity = LoginUserUtils.getAppLoginUser();
+        List<ContractHoldOrderEntity> holdOrderEntities = contractHoldOrderDao.selectHoldOrderListByMemberId(memberEntity.getId());
+        if (CollUtil.isEmpty(holdOrderEntities)) {
+            return Result.fail("订单不存在");
+        }
+
+        List<Long> ids = new ArrayList<>();
+        for (ContractHoldOrderEntity holdOrderEntity : holdOrderEntities) {
+            contractHoldOrderDao.updateHoldOrderIsCanClosingById(ContractHoldOrderEntity.ORDER_CAN_CLOSING_N, holdOrderEntity.getId());
+            ids.add(holdOrderEntity.getId());
+        }
+        ;
+        producer.sendCloseTrade(JSONObject.toJSONString(ids));
+        return Result.ok("平仓成功");
+    }
 }

--
Gitblit v1.9.1