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