Helius
2020-08-12 ca0aa2ef38321b2d522b9db7fbc25a1a5a7510ce
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package com.xcong.excoin.utils;
 
 
import com.xcong.excoin.common.exception.GlobalException;
import com.xcong.excoin.common.response.Result;
import com.xcong.excoin.modules.contract.dao.ContractHoldOrderDao;
import com.xcong.excoin.modules.contract.entity.ContractHoldOrderEntity;
import com.xcong.excoin.modules.member.dao.MemberWalletContractDao;
import com.xcong.excoin.modules.member.entity.MemberEntity;
import com.xcong.excoin.modules.platform.entity.PlatformTradeSettingEntity;
import lombok.extern.slf4j.Slf4j;
 
import java.math.BigDecimal;
 
/**
 * @author helius
 */
@Slf4j
public class CalculateUtil {
 
    /**
     * 计算预估强平价
     *
     * @param bondAmount      保证金
     * @param openPrice       开仓价
     * @param symbolSkuNumber 张数
     * @param lotNumber       规格
     * @param type            1:买多2:卖空
     * @return
     */
    public static BigDecimal getForceSetPrice(BigDecimal bondAmount, BigDecimal openPrice, int symbolSkuNumber, BigDecimal lotNumber,
                                              int type, MemberEntity member) {
        CacheSettingUtils cacheSettingUtils = SpringContextHolder.getBean(CacheSettingUtils.class);
        BigDecimal forcePrice = BigDecimal.ZERO;
        BigDecimal money = bondAmount.divide(new BigDecimal(symbolSkuNumber).multiply(lotNumber), 8, BigDecimal.ROUND_DOWN);
        //卖空
        if (type == 2) {
            forcePrice = money.add(openPrice);
            if (member.getIsForce() == 1) {
                //预估强平价 = 预估强平价-预估强平价*系数
                forcePrice = forcePrice.subtract(forcePrice.multiply(member.getForceParam() == null ? BigDecimal.ZERO : member.getForceParam()));
            }
        } else {//开多
            forcePrice = openPrice.subtract(money);
            if (member.getIsForce() == 1) {
                //预估强平价 = 预估强平价-预估强平价*系数
                forcePrice = forcePrice.add(forcePrice.multiply(member.getForceParam() == null ? BigDecimal.ZERO : member.getForceParam()));
            }
        }
        if (forcePrice.compareTo(BigDecimal.ZERO) < 0) {
            forcePrice = BigDecimal.ZERO;
        }
        return forcePrice;
    }
 
    /**
     * 计算保证金 -- 建仓价*规格*手数*(1/杠杆倍率)
     *
     * @param openingPrice 开仓价
     * @param lotNumber    规格
     * @param symbolCnt    张数
     * @param leverRatio   杠杆倍率
     * @return
     */
    public static BigDecimal getBondAmount(BigDecimal openingPrice, BigDecimal lotNumber, Integer symbolCnt, Integer leverRatio) {
        return openingPrice.multiply(lotNumber).multiply(new BigDecimal(symbolCnt))
                .multiply(BigDecimal.ONE.divide(new BigDecimal(leverRatio)))
                .setScale(8, BigDecimal.ROUND_DOWN);
    }
 
    /**
     * 全仓模式 -- 预估强平价
     * 面值*(多单张数*多单开仓价-空单张数*空单开仓价)-余额-已实现盈亏 / 面值*(多单张数-空单张数)-(维持保证金率+TAKER手续费)*面值*(开多张数+开空张数)
     *
     * @return
     */
    public static BigDecimal getForceSetPriceForWhole(MemberEntity memberEntity) {
        ContractHoldOrderDao holdOrderDao = SpringContextHolder.getBean(ContractHoldOrderDao.class);
        MemberWalletContractDao walletContractDao = SpringContextHolder.getBean(MemberWalletContractDao.class);
        CacheSettingUtils cacheSettingUtils = SpringContextHolder.getBean(CacheSettingUtils.class);
        return null;
    }
 
    /**
     * 计算开仓价
     *
     * @param orderType 订单类型
     * @param newPrice  当前价
     * @param spread    划点
     * @return
     */
    public static BigDecimal getOpeningPrice(int orderType, BigDecimal newPrice, BigDecimal spread) {
        BigDecimal openingPrice = BigDecimal.ZERO;
        if (orderType == ContractHoldOrderEntity.OPENING_TYPE_MORE) {
            // 市场价*(1 + (点差/10000))
            openingPrice = newPrice.multiply(BigDecimal.ONE.add(spread.divide(new BigDecimal(10000)))).setScale(8, BigDecimal.ROUND_DOWN);
 
            // 开空
        } else if (orderType == ContractHoldOrderEntity.OPENING_TYPE_LESS) {
            // 市场价*(1 - (点差/10000))
            openingPrice = newPrice.multiply(BigDecimal.ONE.subtract(spread.divide(new BigDecimal(10000)))).setScale(8, BigDecimal.ROUND_DOWN);
        } else {
            throw new GlobalException(MessageSourceUtils.getString("unknown_type"));
        }
        return openingPrice;
    }
 
    /**
     * 计算开仓手续费
     *
     * @param openingPrice 开仓价
     * @param lotNumber    规格
     * @param count        张数
     * @param feeRatio     手续费率
     * @return
     */
    public static BigDecimal getOpenFeePrice(BigDecimal openingPrice, BigDecimal lotNumber, int count, BigDecimal feeRatio) {
        return openingPrice.multiply(lotNumber)
                .multiply(new BigDecimal(count))
                .multiply(feeRatio.divide(new BigDecimal(100)))
                .setScale(8, BigDecimal.ROUND_DOWN);
    }
}