From 1b4be6ae8557ba25bc2fc5b97972c4ff2611a1b1 Mon Sep 17 00:00:00 2001
From: Helius <wangdoubleone@gmail.com>
Date: Thu, 13 Aug 2020 18:11:34 +0800
Subject: [PATCH] modify force_closing_price for whole

---
 src/main/java/com/xcong/excoin/utils/CalculateUtil.java |   90 ++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 89 insertions(+), 1 deletions(-)

diff --git a/src/main/java/com/xcong/excoin/utils/CalculateUtil.java b/src/main/java/com/xcong/excoin/utils/CalculateUtil.java
index a25ac4f..258355a 100644
--- a/src/main/java/com/xcong/excoin/utils/CalculateUtil.java
+++ b/src/main/java/com/xcong/excoin/utils/CalculateUtil.java
@@ -1,6 +1,9 @@
 package com.xcong.excoin.utils;
 
 
+import cn.hutool.core.collection.CollUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.xcong.excoin.common.enumerates.RabbitPriceTypeEnum;
 import com.xcong.excoin.common.exception.GlobalException;
 import com.xcong.excoin.common.response.Result;
 import com.xcong.excoin.modules.contract.dao.ContractHoldOrderDao;
@@ -9,10 +12,17 @@
 import com.xcong.excoin.modules.member.dao.MemberSettingDao;
 import com.xcong.excoin.modules.member.entity.MemberEntity;
 import com.xcong.excoin.modules.member.entity.MemberSettingEntity;
+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.producer.OrderProducer;
 import lombok.extern.slf4j.Slf4j;
 
+import javax.validation.constraints.NotNull;
 import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * @author helius
@@ -78,13 +88,91 @@
      *
      * @return
      */
-    public static BigDecimal getForceSetPriceForWhole(MemberEntity memberEntity) {
+    public static BigDecimal getForceSetPriceForWhole(@NotNull String symbol, @NotNull MemberEntity memberEntity) {
         ContractHoldOrderDao holdOrderDao = SpringContextHolder.getBean(ContractHoldOrderDao.class);
         MemberWalletContractDao walletContractDao = SpringContextHolder.getBean(MemberWalletContractDao.class);
         CacheSettingUtils cacheSettingUtils = SpringContextHolder.getBean(CacheSettingUtils.class);
+
+        Long memberId = memberEntity.getId();
+        BigDecimal lotNumber = cacheSettingUtils.getSymbolSku(symbol);
+        PlatformTradeSettingEntity tradeSettingEntity = cacheSettingUtils.getTradeSetting();
+        MemberWalletContractEntity walletContract = walletContractDao.findWalletContractByMemberIdAndSymbol(memberId, symbol);
+        List<ContractHoldOrderEntity> holdOrderEntities = holdOrderDao.selectHoldOrderListByMemberIdAndSymbol(memberId, symbol, 2);
+        if (CollUtil.isNotEmpty(holdOrderEntities)) {
+            // 多单开仓价
+            BigDecimal moreOpenPrice = BigDecimal.ZERO;
+            // 多单张数
+            int moreCnt = 0;
+            // 空单开仓价
+            BigDecimal lessOpenPrice = BigDecimal.ZERO;
+            // 空单张数
+            int lessCnt = 0;
+            // 已实现盈亏
+            BigDecimal rewardAmount = BigDecimal.ZERO;
+            List<ContractHoldOrderEntity> updateHoldOrders = new ArrayList<>();
+            for (ContractHoldOrderEntity holdOrderEntity : holdOrderEntities) {
+                if (holdOrderEntity.getOpeningType() == ContractHoldOrderEntity.OPENING_TYPE_MORE) {
+                    moreOpenPrice = holdOrderEntity.getOpeningPrice();
+                    moreCnt = holdOrderEntity.getSymbolCntSale();
+                } else {
+                    lessOpenPrice = holdOrderEntity.getOpeningPrice();
+                    lessCnt = holdOrderEntity.getSymbolCntSale();
+                }
+                ContractHoldOrderEntity updateHoldOrder = new ContractHoldOrderEntity();
+                updateHoldOrder.setOperateNo(holdOrderEntity.getOperateNo() + 1);
+                updateHoldOrder.setId(holdOrderEntity.getId());
+                updateHoldOrder.setOpeningType(holdOrderEntity.getOpeningType());
+                updateHoldOrder.setSymbol(holdOrderEntity.getSymbol());
+                updateHoldOrders.add(updateHoldOrder);
+
+                rewardAmount = rewardAmount.add(holdOrderEntity.getRewardAmount());
+                log.info("rewardAmount : {}", rewardAmount);
+            }
+
+            // 多单张数*多单开仓价-空单张数*空单开仓价
+            BigDecimal allOrderPrice = moreOpenPrice.multiply(BigDecimal.valueOf(moreCnt)).subtract(lessOpenPrice.multiply(BigDecimal.valueOf(lessCnt)));
+            log.info("allOrderPrice : {}", allOrderPrice);
+            // 除数 -- 面值*(多单张数*多单开仓价-空单张数*空单开仓价)-余额-已实现盈亏
+            BigDecimal divisor = lotNumber.multiply(allOrderPrice).subtract(walletContract.getAvailableBalance()).subtract(rewardAmount);
+            log.info("divisor : {}", divisor);
+
+            // 面值*(多单张数-空单张数)
+            BigDecimal dividendOne = lotNumber.multiply(BigDecimal.valueOf(moreCnt + lessCnt));
+            log.info("dividendOne : {}", dividendOne);
+            // (维持保证金率+TAKER手续费)*面值*(开多张数+开空张数)
+            BigDecimal dividendTwo = tradeSettingEntity.getFeeRatio().multiply(lotNumber).multiply(BigDecimal.valueOf(moreCnt + lessCnt));
+            log.info("dividendTwo : {}", dividendTwo);
+
+            BigDecimal forceSetPrice = divisor.divide(dividendOne.subtract(dividendTwo), 8, BigDecimal.ROUND_DOWN);
+            log.info("forceSetPrice : {}", forceSetPrice);
+
+            for (ContractHoldOrderEntity updateHoldOrder : updateHoldOrders) {
+                updateHoldOrder.setForceClosingPrice(forceSetPrice);
+                holdOrderDao.updateById(updateHoldOrder);
+
+                sendOrderBombMsg(updateHoldOrder.getId(), updateHoldOrder.getOpeningType(), forceSetPrice, updateHoldOrder.getSymbol(), updateHoldOrder.getOperateNo());
+            }
+
+        } else {
+            throw new GlobalException("强平价异常");
+        }
+
         return null;
     }
 
+    private static void sendOrderBombMsg(Long id, int type, BigDecimal forceClosingPrice, String symbol, int operateNo) {
+        OrderModel model = null;
+        // 开多
+        if (ContractHoldOrderEntity.OPENING_TYPE_MORE == type) {
+            model = new OrderModel(id, RabbitPriceTypeEnum.CLOSE_MORE_BOMB.getValue(), forceClosingPrice.setScale(8, RoundingMode.HALF_UP).toPlainString(), symbol, operateNo);
+            // 开空
+        } else {
+            model = new OrderModel(id, RabbitPriceTypeEnum.CLOSE_LESS_BOMB.getValue(), forceClosingPrice.setScale(8, RoundingMode.HALF_UP).toPlainString(), symbol, operateNo);
+        }
+        SpringContextHolder.getBean(OrderProducer.class).sendPriceOperate(JSONObject.toJSONString(model));
+    }
+
+
     /**
      * 计算开仓价
      *

--
Gitblit v1.9.1