Helius
2021-01-29 d6d2e8a040131ea89044f25c47408c9bfa766764
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
package com.xcong.excoin.rabbit.pricequeue;
 
import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONObject;
import com.xcong.excoin.common.contants.AppContants;
import com.xcong.excoin.common.enumerates.CoinTypeEnum;
import com.xcong.excoin.modules.contract.dao.ContractEntrustOrderDao;
import com.xcong.excoin.modules.contract.dao.ContractHoldOrderDao;
import com.xcong.excoin.modules.contract.entity.ContractEntrustOrderEntity;
import com.xcong.excoin.modules.contract.entity.ContractHoldOrderEntity;
import com.xcong.excoin.modules.contract.mapper.ContractHoldOrderEntityMapper;
import com.xcong.excoin.modules.member.dao.MemberWalletContractDao;
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.utils.RedisUtils;
import com.xcong.excoin.utils.SpringContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
 
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.PriorityBlockingQueue;
 
/**
 * 处理消费者的订单止盈等价格信息
 */
@Slf4j
public class OrderOperatePriceService {
 
    /**
     * 处理用户提交的止盈止损价格 爆仓 限价委托
     *
     * @param orderModel
     */
    public static void dealWithNewMq(OrderModel orderModel) {
        // 根据不同的类型将价格信息加入到对应队列和MAP
        // 【1:买入委托2:开多3:开空4:平多5:平空6:爆仓平多7:爆仓平空8:撤单9:止盈平多10:止盈平空11:止损平多12:止损平空】
        int type = orderModel.getType();
        Map<String, List<OrderModel>> orderMap = PricePriorityQueue.getOrderMap(orderModel.getSymbol(), type);
        if (type == 12 || type == 9 || type == 7 || type == 3 || type == 4) {
            // 需要价格涨的
            PriorityBlockingQueue<AscBigDecimal> queue = PricePriorityQueue.getQueueAsc(orderModel.getSymbol());
            dealPriceAsc(orderModel, orderMap, queue);
        } else {
            // 需要价格跌的
            PriorityBlockingQueue<DescBigDecimal> queue = PricePriorityQueue.getQueueDesc(orderModel.getSymbol());
            dealPriceDesc(orderModel, orderMap, queue);
        }
 
    }
 
    /**
     * 倒叙的添加价格和订单
     *
     * @param orderMap
     * @param queue
     */
    public static void dealPriceDesc(OrderModel order, Map<String, List<OrderModel>> orderMap, PriorityBlockingQueue<DescBigDecimal> queue) {
        // 添加币种的价格和价格订单信息
        String price = order.getPrice();
        int type = order.getType();
        Long orderId = order.getOrderId();
        queue.add(new DescBigDecimal(price));
 
//        log.info("原有:{}", JSONObject.toJSONString(orderMap));
        removeExistOrder(type, orderId, orderMap);
//        log.info("删除后:{}", JSONObject.toJSONString(orderMap));
        if (orderMap.containsKey(price)) {
            // 有这个价的key
            List<OrderModel> list = orderMap.get(price);
            // 判断这个单的这个类型是否有
//            if (CollectionUtils.isNotEmpty(list)) {
                // 新增
                OrderModel orderModel = new OrderModel(orderId, type, price, null,order.getOperateNo(), order.getMemberId());
                list.add(orderModel);
//            }
        } else {
            List<OrderModel> list = new ArrayList<OrderModel>();
            OrderModel orderModel = new OrderModel(orderId, type, price, null,order.getOperateNo(), order.getMemberId());
            list.add(orderModel);
            orderMap.put(price, list);
        }
//        log.info("调整后:{}", JSONObject.toJSONString(orderMap));
    }
 
 
    /**
     * 正序的添加价格和订单
     *
     * @param orderMap
     * @param queue
     */
    public static void dealPriceAsc(OrderModel order, Map<String, List<OrderModel>> orderMap, PriorityBlockingQueue<AscBigDecimal> queue) {
        // 添加币种的价格和价格订单信息
        String price = order.getPrice();
        int type = order.getType();
        Long orderId = order.getOrderId();
        queue.add(new AscBigDecimal(price));
//        log.info("原有:{}", JSONObject.toJSONString(orderMap));
        // 需要找到这个订单的原始的单进行处理
        removeExistOrder(type, orderId, orderMap);
//        log.info("删除后:{}", JSONObject.toJSONString(orderMap));
        if (orderMap.containsKey(price)) {
            // 有这个价的key
            List<OrderModel> list = orderMap.get(price);
            // 判断这个单的这个类型是否有
//            if (CollectionUtils.isNotEmpty(list)) {
                // 新增
                OrderModel orderModel = new OrderModel(orderId, type, price, null,order.getOperateNo(), order.getMemberId());
                list.add(orderModel);
//            }
        } else {
            List<OrderModel> list = new ArrayList<OrderModel>();
            OrderModel orderModel = new OrderModel(orderId, type, price, null,order.getOperateNo(), order.getMemberId());
            list.add(orderModel);
            orderMap.put(price, list);
        }
//        log.info("调整后:{}", JSONObject.toJSONString(orderMap));
    }
 
    private static void removeExistOrder(Integer type, Long orderId, Map<String, List<OrderModel>> orderMap) {
        // 需要找到这个订单的原始的单进行处理
        boolean breakFlag = false;
        for (Map.Entry<String, List<OrderModel>> entry : orderMap.entrySet()) {
            List<OrderModel> value = entry.getValue();
            if (CollectionUtils.isNotEmpty(value)) {
                Iterator<OrderModel> iterator = value.iterator();
                if (iterator.hasNext()) {
                    OrderModel next = iterator.next();
                    if (next.getType().equals(type)  && orderId.equals(next.getOrderId())) {
                        // 移除这个
                        System.out.println("存在相同的平仓类型,删除原来的:"+next.getOrderId()+",价格:"+next.getPrice());
                        iterator.remove();
                        break;
 
                    }
                }
 
            }
        }
    }
 
    /**
     * 全仓价格处理
     *
     * @param memberId
     */
    public static void wholePriceDataOperation(Long memberId) {
        Map<String, WholePriceDataModel> dataModelMap = WholeDataQueue.MAP;
        log.info("操作前:{}", dataModelMap);
        RedisUtils redisUtils = SpringContextHolder.getBean(RedisUtils.class);
 
        ContractHoldOrderDao contractHoldOrderDao = SpringContextHolder.getBean(ContractHoldOrderDao.class);
        ContractEntrustOrderDao contractEntrustOrderDao = SpringContextHolder.getBean(ContractEntrustOrderDao.class);
 
        MemberWalletContractDao memberWalletContractDao = SpringContextHolder.getBean(MemberWalletContractDao.class);
 
        List<ContractHoldOrderEntity> holdOrders = contractHoldOrderDao.selectHoldOrderListByMemberId(memberId);
        log.info("持仓数量:{}", holdOrders.size());
        if (CollUtil.isEmpty(holdOrders)) {
            if (dataModelMap.get(memberId.toString()) != null) {
                dataModelMap.remove(memberId.toString());
 
                redisUtils.set(AppContants.WHOLE_BOMB_MAP, JSONObject.toJSONString(dataModelMap));
            }
            return;
        }
 
        MemberWalletContractEntity wallet = memberWalletContractDao.findWalletContractByMemberIdAndSymbol(memberId, CoinTypeEnum.USDT.name());
 
        WholePriceDataModel wholePriceData = new WholePriceDataModel();
        List<HoldOrderDataModel> holdOrderDataModels = ContractHoldOrderEntityMapper.INSTANCE.entitiesToDataModels(holdOrders);
        wholePriceData.setList(holdOrderDataModels);
 
        BigDecimal totalHoldBond = BigDecimal.ZERO;
        for (ContractHoldOrderEntity holdOrder : holdOrders) {
            totalHoldBond = totalHoldBond.add(holdOrder.getHoldBond() == null ? BigDecimal.ZERO : holdOrder.getHoldBond());
        }
 
        wholePriceData.setHoldBond(totalHoldBond);
 
        List<ContractEntrustOrderEntity> entrustOrder = contractEntrustOrderDao.selectEntrustOrderListByMemberId(wholePriceData.getMemberId());
        BigDecimal totalAmount = BigDecimal.ZERO;
        if (CollUtil.isNotEmpty(entrustOrder)) {
            for (ContractEntrustOrderEntity contractEntrustOrderEntity : entrustOrder) {
                totalAmount.add(contractEntrustOrderEntity.getEntrustAmount());
            }
        }
 
        wholePriceData.setBalance(wallet.getTotalBalance().subtract(totalAmount));
        wholePriceData.setMemberId(memberId);
 
        dataModelMap.put(wholePriceData.getMemberId().toString(), wholePriceData);
        redisUtils.set(AppContants.WHOLE_BOMB_MAP, JSONObject.toJSONString(dataModelMap));
        log.info("dataModelMap为:{}", dataModelMap);
    }
 
}