src/main/java/com/xcong/excoin/common/system/controller/CommonController.java
@@ -93,7 +93,7 @@ } @ApiOperation(value = "文件上次接口", notes = "文件上传") @GetMapping(value = "/uploadFile") @PostMapping(value = "/uploadFileBase64") public Result uploadFileBase64(@RequestBody @Validated Base64UploadDto uploadDto) { String imageName = "uploadeFile/image/" + System.currentTimeMillis() + IdUtil.simpleUUID() + AppContants.UPLOAD_IMAGE_SUFFIX; src/main/java/com/xcong/excoin/configurations/RabbitMqConfig.java
@@ -27,6 +27,52 @@ public static final String ROUTING_KEY_TEST = "test-routingKey"; public static final String EXCHANGE_A = "biyi-exchange-A"; // 开多止盈队列 public static final String QUEUE_MOREPRO = "QUEUE_MOREPRO"; // 开空止盈队列 public static final String QUEUE_LESSPRO = "QUEUE_LESSPRO"; // 开多止损队列 public static final String QUEUE_MORELOSS = "QUEUE_MORELOSS"; // 开空止损队列 public static final String QUEUE_LESSLOSS = "QUEUE_LESSLOSS"; // 限价委托 public static final String QUEUE_LIMIT = "QUEUE_LIMIT"; // 爆仓队列 public static final String QUEUE_COINOUT = "QUEUE_COINOUT"; //价格操作 public static final String QUEUE_PRICEOPERATE = "QUEUE_PRICEOPERATE"; // 平仓队列 public static final String QUEUE_CLOSETRADE = "QUEUE_CLOSETRADE"; // 开多止盈路由键 public static final String ROUTINGKEY_MOREPRO = "ROUTINGKEY_MOREPRO"; // 开空止盈路由 public static final String ROUTINGKEY_LESSPRO = "ROUTINGKEY_LESSPRO"; // 开多止损路由 public static final String ROUTINGKEY_MORELOSS = "ROUTINGKEY_MORELOSS"; // 开空止损路由 public static final String ROUTINGKEY_LESSLOSS = "ROUTINGKEY_LESSLOSS"; // 限价委托 public static final String ROUTINGKEY_LIMIT = "ROUTINGKEY_LIMIT"; // 爆仓路由 public static final String ROUTINGKEY_COINOUT = "ROUTINGKEY_COINOUT"; // 价格操作 public static final String ROUTINGKEY_PRICEOPERATE = "ROUTINGKEY_PRICEOPERATE"; // 平仓路由 public static final String ROUTINGKEY_CLOSETRADE = "ROUTINGKEY_CLOSETRADE"; @Resource private ConnectionFactory connectionFactory; @@ -60,4 +106,171 @@ return BindingBuilder.bind(testQueue()).to(defaultExchange()).with(ROUTING_KEY_TEST); } /** * 交换器A 可以继续添加交换器B C * * @return */ @Bean public DirectExchange orderExchange() { return new DirectExchange(EXCHANGE_A); } /** * 开多止盈队列 * @return */ @Bean public Queue queueMorePro() { // 定义一个名称为QUEUE_A,持久化的队列 return new Queue(QUEUE_MOREPRO, true); } /** * 开空止盈队列 * @return */ @Bean public Queue queueLessPro() { // 定义一个名称为QUEUE_A,持久化的队列 return new Queue(QUEUE_LESSPRO, true); } /** * 开多止损 * @return */ @Bean public Queue queueMoreLoss() { // 定义一个名称为QUEUE_A,持久化的队列 return new Queue(QUEUE_MORELOSS, true); } /** * 开空止损 * @return */ @Bean public Queue queueLessLoss() { // 定义一个名称为QUEUE_A,持久化的队列 return new Queue(QUEUE_LESSLOSS, true); } /** * 限价委托 * @return */ @Bean public Queue queueLimit() { return new Queue(QUEUE_LIMIT, true); } /** * 爆仓 * @return */ @Bean public Queue queueCoinout() { return new Queue(QUEUE_COINOUT, true); } /** * 价格操作 * @return */ @Bean public Queue queuePriceoperate() { return new Queue(QUEUE_PRICEOPERATE, true); } /** * 价格操作 * @return */ @Bean public Queue queueCloseTrade() { return new Queue(QUEUE_CLOSETRADE, true); } /** * 开多止盈 * @return */ @Bean public Binding bindingMroPro() { return BindingBuilder.bind(queueMorePro()).to(orderExchange()).with(RabbitMqConfig.ROUTINGKEY_MOREPRO); } /** * 开空止盈 * @return */ @Bean public Binding bindingLessPro() { return BindingBuilder.bind(queueLessPro()).to(orderExchange()).with(RabbitMqConfig.ROUTINGKEY_LESSPRO); } /** * 开多止损 * @return */ @Bean public Binding bindingMroLoss() { return BindingBuilder.bind(queueMoreLoss()).to(orderExchange()).with(RabbitMqConfig.ROUTINGKEY_MORELOSS); } /** * 开空止损 * @return */ @Bean public Binding bindingLessLoss() { return BindingBuilder.bind(queueLessLoss()).to(orderExchange()).with(RabbitMqConfig.ROUTINGKEY_LESSLOSS); } /** * 委托 * @return */ @Bean public Binding bindingLimit() { return BindingBuilder.bind(queueLimit()).to(orderExchange()).with(RabbitMqConfig.ROUTINGKEY_LIMIT); } /** * 爆仓 * @return */ @Bean public Binding bindingCoinout() { return BindingBuilder.bind(queueCoinout()).to(orderExchange()).with(RabbitMqConfig.ROUTINGKEY_COINOUT); } /** * 价格操作 * @return */ @Bean public Binding bindingPriceoperate() { return BindingBuilder.bind(queuePriceoperate()).to(orderExchange()).with(RabbitMqConfig.ROUTINGKEY_PRICEOPERATE); } /** * 平仓绑定 * @return */ @Bean public Binding bindingCloseTrade() { return BindingBuilder.bind(queueCloseTrade()).to(orderExchange()).with(RabbitMqConfig.ROUTINGKEY_CLOSETRADE); } } src/main/java/com/xcong/excoin/modules/contract/controller/ContractOrderController.java
@@ -2,10 +2,13 @@ import com.xcong.excoin.common.response.Result; import com.xcong.excoin.modules.contract.parameter.dto.SubmitOrderDto; import com.xcong.excoin.modules.contract.service.ContractHoldOrderService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; /** * @author wzy @@ -17,10 +20,13 @@ @RequestMapping(value = "/api/contractOrder") public class ContractOrderController { @Resource private ContractHoldOrderService contractHoldOrderService; @ApiOperation(value = "市价提交合约订单") @PostMapping(value = "/submitOrder") public Result submitOrder(@RequestBody SubmitOrderDto submitOrderDto) { return null; return contractHoldOrderService.submitOrder(submitOrderDto); } @ApiOperation(value = "查询当前持仓订单列表") src/main/java/com/xcong/excoin/modules/contract/dao/ContractEntrustOrderDao.java
@@ -14,4 +14,6 @@ public ContractEntrustOrderEntity selectEntrustOrderByIdAndMemberId(@Param("id") Long id, @Param("memberId") Long memberId); public List<ContractEntrustOrderEntity> selectEntrustOrderListByMemberId(@Param("memberId") Long memberId); public List<ContractEntrustOrderEntity> selectEntrustOrderListByIds(@Param("list") List<Long> list); } src/main/java/com/xcong/excoin/modules/contract/dao/ContractHoldOrderDao.java
@@ -2,9 +2,33 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.xcong.excoin.modules.contract.entity.ContractHoldOrderEntity; import com.xcong.excoin.rabbit.pricequeue.OrderModel; import org.apache.ibatis.annotations.Param; import java.util.List; /** * @author helius */ public interface ContractHoldOrderDao extends BaseMapper<ContractHoldOrderEntity> { /** * 根据ids更新所有订单的平仓状态 * @param list * @return */ int updateContractHoldOrderCanNotClosingByIds(@Param("list") List<OrderModel> list, @Param("batchNo") String batchNo); /** * 根据批次号查询次仓订单 * @param batchNo * @return */ List<ContractHoldOrderEntity> selectContractHoldOrderByBatchNo(@Param("batchNo") String batchNo); /** * 更新该订单为可平仓状态 * @param id */ public void updateOrderIsCanClosingAndBatchNoById(@Param("id")Long id); } src/main/java/com/xcong/excoin/modules/contract/entity/ContractEntrustOrderEntity.java
@@ -82,7 +82,7 @@ /** * 杠杆倍率 */ private BigDecimal leverRatio; private int leverRatio; /** * 保证金 src/main/java/com/xcong/excoin/modules/contract/entity/ContractHoldOrderEntity.java
@@ -26,6 +26,26 @@ public static final int ORDER_CAN_CLOSING_N = 0; /** * 开多 */ public static final int OPENING_TYPE_MORE = 1; /** * 开空 */ public static final int OPENING_TYPE_LESS = 2; /** * 交易类型 市价 */ public static final int TRADE_TYPE_MARK = 1; /** * 交易类型 限价 */ public static final int TRADE_TYPE_LIMIT = 2; /** * 会员Id */ private Long memberId; @@ -38,7 +58,7 @@ /** * 仓位类型 1-逐仓 2-全仓 */ private int potionType; private int positionType; /** * 交易类型 1-市价 2-限价 @@ -63,7 +83,7 @@ /** * 币种规格 */ private Long symbolSku; private BigDecimal symbolSku; /** * 开仓价 @@ -71,7 +91,7 @@ private BigDecimal openingPrice; /** * 开仓类型 1-开多 2-开多 * 开仓类型 1-开多 2-开空 */ private int openingType; @@ -83,7 +103,7 @@ /** * 保证金 */ private BigDecimal bondPrice; private BigDecimal bondAmount; /** * 杠杆倍率 src/main/java/com/xcong/excoin/modules/contract/entity/ContractOrderEntity.java
@@ -47,7 +47,7 @@ /** * 仓位类型 1-逐仓 2-全仓 */ private int potionType; private int positionType; /** * 交易类型 1-市价 2-限价 @@ -100,6 +100,11 @@ private Date closingTime; /** * 平仓类型 2平多3平空4爆仓平多5爆仓平空6止盈平多7止盈平空8止损平多9止损平空 */ private int closingType; /** * 杠杆倍率 */ private int leverRatio; src/main/java/com/xcong/excoin/modules/contract/mapper/ContractEntrustOrderEntityMapper.java
@@ -1,6 +1,7 @@ package com.xcong.excoin.modules.contract.mapper; import com.xcong.excoin.modules.contract.entity.ContractEntrustOrderEntity; import com.xcong.excoin.modules.contract.entity.ContractHoldOrderEntity; import com.xcong.excoin.modules.contract.entity.ContractOrderEntity; import com.xcong.excoin.modules.contract.parameter.dto.SubmitEntrustDto; import com.xcong.excoin.modules.contract.parameter.vo.ContractEntrustVo; @@ -30,4 +31,6 @@ public abstract List<ContractEntrustVo> entityListToVoList(List<ContractEntrustOrderEntity> list); public abstract ContractHoldOrderEntity entrustOrderToHoldOrder(ContractEntrustOrderEntity entrustOrderEntity); } src/main/java/com/xcong/excoin/modules/contract/mapper/ContractHoldOrderEntityMapper.java
New file @@ -0,0 +1,19 @@ package com.xcong.excoin.modules.contract.mapper; import com.xcong.excoin.modules.contract.entity.ContractHoldOrderEntity; import com.xcong.excoin.modules.contract.entity.ContractOrderEntity; import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.factory.Mappers; /** * @author wzy * @date 2020-05-31 **/ @Mapper public abstract class ContractHoldOrderEntityMapper { public static final ContractHoldOrderEntityMapper INSTANCE = Mappers.getMapper(ContractHoldOrderEntityMapper.class); @Mapping(target = "orderType", source = "openingType") public abstract ContractOrderEntity holdOrderToOrder(ContractHoldOrderEntity holdOrderEntity); } src/main/java/com/xcong/excoin/modules/contract/service/ContractEntrustOrderService.java
@@ -5,6 +5,8 @@ import com.xcong.excoin.modules.contract.entity.ContractEntrustOrderEntity; import com.xcong.excoin.modules.contract.parameter.dto.SubmitEntrustDto; import java.util.List; /** * @author helius */ @@ -15,4 +17,7 @@ public Result findEntrustOrderList(); public Result cancelEntrustOrder(Long id); public List<ContractEntrustOrderEntity> selectEntrustOrderListByIds( List<Long> list); } src/main/java/com/xcong/excoin/modules/contract/service/ContractHoldOrderService.java
@@ -4,6 +4,10 @@ import com.xcong.excoin.common.response.Result; import com.xcong.excoin.modules.contract.entity.ContractHoldOrderEntity; import com.xcong.excoin.modules.contract.parameter.dto.SubmitOrderDto; import com.xcong.excoin.rabbit.pricequeue.OrderModel; import org.apache.ibatis.annotations.Param; import java.util.List; /** * @author helius @@ -11,4 +15,11 @@ public interface ContractHoldOrderService extends IService<ContractHoldOrderEntity> { public Result submitOrder(SubmitOrderDto submitOrderDto); public int updateContractHoldOrderCanNotClosingByIds(List<OrderModel> list, String batchNo); public List<ContractHoldOrderEntity> selectContractHoldOrderByBatchNo(String batchNo); public void updateOrderIsCanClosingAndBatchNoById(Long id); } src/main/java/com/xcong/excoin/modules/contract/service/impl/ContractEntrustOrderServiceImpl.java
@@ -157,4 +157,9 @@ } return Result.fail("撤销失败"); } @Override public List<ContractEntrustOrderEntity> selectEntrustOrderListByIds(List<Long> list) { return contractEntrustOrderDao.selectEntrustOrderListByIds(list); } } src/main/java/com/xcong/excoin/modules/contract/service/impl/ContractHoldOrderServiceImpl.java
@@ -2,23 +2,41 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.xcong.excoin.common.LoginUserUtils; import com.xcong.excoin.common.enumerates.CoinTypeEnum; import com.xcong.excoin.common.response.Result; import com.xcong.excoin.common.system.service.CommonService; import com.xcong.excoin.modules.contract.dao.ContractHoldOrderDao; import com.xcong.excoin.modules.contract.dao.ContractOrderDao; import com.xcong.excoin.modules.contract.entity.ContractEntrustOrderEntity; 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.SubmitOrderDto; import com.xcong.excoin.modules.contract.service.ContractHoldOrderService; import com.xcong.excoin.modules.member.dao.MemberWalletContractDao; 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.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 javax.annotation.Resource; import java.math.BigDecimal; import java.util.List; /** * @author wzy * @date 2020-05-27 **/ @Slf4j @Service public class ContractHoldOrderServiceImpl extends ServiceImpl<ContractHoldOrderDao, ContractHoldOrderEntity> implements ContractHoldOrderService { @Resource @@ -28,14 +46,119 @@ private ContractOrderDao contractOrderDao; @Resource private CommonService commonService; @Resource private MemberWalletContractDao memberWalletContractDao; @Resource private CacheSettingUtils cacheSettingUtils; @Resource private RedisUtils redisUtils; @Transactional(rollbackFor = Exception.class) @Override public Result submitOrder(SubmitOrderDto submitOrderDto) { MemberEntity memberEntity = LoginUserUtils.getAppLoginUser(); // 获取最新价 BigDecimal newPrice = new BigDecimal(redisUtils.getString(CoinTypeConvert.convertToKey(submitOrderDto.getSymbol()))); return null; MemberWalletContractEntity walletContract = memberWalletContractDao.findWalletContractByMemberIdAndSymbol(memberEntity.getId(), CoinTypeEnum.USDT.name()); PlatformTradeSettingEntity tradeSettingEntity = cacheSettingUtils.getTradeSetting(); // 规格 BigDecimal lotNumber = cacheSettingUtils.getSymbolSku(submitOrderDto.getSymbol()); // 开仓价 BigDecimal openingPrice = BigDecimal.ZERO; // 开多 if (submitOrderDto.getOrderType() == ContractHoldOrderEntity.OPENING_TYPE_MORE) { // 市场价*(1 + (点差/10000)) openingPrice = newPrice.multiply(BigDecimal.ONE.add(tradeSettingEntity.getSpread().divide(new BigDecimal(10000)))).setScale(8, BigDecimal.ROUND_DOWN); // 开空 } else if (submitOrderDto.getOrderType() == ContractHoldOrderEntity.OPENING_TYPE_LESS) { // 市场价*(1 - (点差/10000)) openingPrice = newPrice.multiply(BigDecimal.ONE.subtract(tradeSettingEntity.getSpread().divide(new BigDecimal(10000)))).setScale(8, BigDecimal.ROUND_DOWN); } else { return Result.fail("未知类型"); } log.info("开仓价:{}", openingPrice); // 开仓手续费 建仓价*规格*手数*手续费率 BigDecimal openFeePrice = openingPrice.multiply(lotNumber) .multiply(new BigDecimal(submitOrderDto.getSymbolCnt())) .multiply(tradeSettingEntity.getFeeRatio().divide(new BigDecimal(100))) .setScale(8, BigDecimal.ROUND_DOWN); log.info("开仓手续费:{}", openFeePrice); // 保证金 建仓价*规格*手数*(1/杠杆倍率) BigDecimal bondAmount = openingPrice.multiply(lotNumber).multiply(new BigDecimal(submitOrderDto.getSymbolCnt())) .multiply(BigDecimal.ONE.divide(new BigDecimal(submitOrderDto.getLeverRatio()))) .setScale(8, BigDecimal.ROUND_DOWN); log.info("保证金:{}", bondAmount); // 预付款为 --> 保证金+开仓手续费+平仓手续费 (开仓平仓手续费相同) BigDecimal prePaymentAmount = bondAmount.add(openFeePrice).add(openFeePrice); log.info("预付款:{}", prePaymentAmount); if (prePaymentAmount.compareTo(walletContract.getAvailableBalance()) > -1) { return Result.fail("可用金额不足"); } // 预估强平价 BigDecimal forceClosingPrice = CalculateUtil.getForceSetPrice(bondAmount, openingPrice, submitOrderDto.getSymbolCnt(), lotNumber, submitOrderDto.getOrderType(), memberEntity); log.info("强平价:{}", forceClosingPrice); ContractHoldOrderEntity holdOrderEntity = new ContractHoldOrderEntity(); holdOrderEntity.setMemberId(memberEntity.getId()); holdOrderEntity.setOrderNo(commonService.generateOrderNo(memberEntity.getId())); holdOrderEntity.setPositionType(ContractEntrustOrderEntity.POSITION_TYPE_ADD); holdOrderEntity.setTradeType(ContractHoldOrderEntity.TRADE_TYPE_MARK); holdOrderEntity.setSymbol(submitOrderDto.getSymbol()); holdOrderEntity.setSymbolCnt(submitOrderDto.getSymbolCnt()); holdOrderEntity.setSymbolSku(lotNumber); holdOrderEntity.setLeverRatio(submitOrderDto.getLeverRatio()); holdOrderEntity.setForceClosingPrice(forceClosingPrice); holdOrderEntity.setOpeningFeeAmount(openFeePrice); holdOrderEntity.setOpeningPrice(openingPrice); holdOrderEntity.setOpeningType(submitOrderDto.getOrderType()); holdOrderEntity.setMarkPrice(newPrice); holdOrderEntity.setIsCanClosing(ContractHoldOrderEntity.ORDER_CAN_CLOSING_Y); holdOrderEntity.setPrePaymentAmount(prePaymentAmount); holdOrderEntity.setBondAmount(bondAmount); 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)); memberWalletContractDao.updateById(walletContract); if (i > 0) { return Result.ok("success"); } return Result.fail("fail"); } @Override public int updateContractHoldOrderCanNotClosingByIds(List<OrderModel> list, String batchNo){ return contractHoldOrderDao.updateContractHoldOrderCanNotClosingByIds(list,batchNo); } @Override public List<ContractHoldOrderEntity> selectContractHoldOrderByBatchNo(String batchNo) { return contractHoldOrderDao.selectContractHoldOrderByBatchNo(batchNo); } @Override public void updateOrderIsCanClosingAndBatchNoById(Long id) { contractHoldOrderDao.updateOrderIsCanClosingAndBatchNoById(id); } } src/main/java/com/xcong/excoin/modules/contract/service/impl/OrderWebsocketServiceImpl.java
New file @@ -0,0 +1,842 @@ //package com.xcong.excoin.modules.contract.service.impl; // //import cn.hutool.core.bean.BeanUtil; //import com.alibaba.fastjson.JSONObject; //import com.kebex.app.dao.member.AgentReturnMapper; //import com.kebex.app.dao.member.MemberMapper; //import com.kebex.app.dao.member.WalletDao; //import com.kebex.app.dao.order.OrderMapper; //import com.kebex.app.dao.trade.TradeMapper; //import com.kebex.app.entity.member.*; //import com.kebex.app.entity.order.CoinsCoinsOrder; //import com.kebex.app.entity.trade.TradeSetting; //import com.kebex.app.entity.trade.TradeSymbolSku; //import com.kebex.app.service.member.MemberService; //import com.kebex.common.cache.TradeSettingCache; //import com.kebex.pricequeue.OrderModel; //import com.kebex.rabbit.producer.ExampleProducer; //import com.xcong.excoin.modules.contract.entity.ContractEntrustOrderEntity; //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.service.ContractEntrustOrderService; //import com.xcong.excoin.modules.contract.service.ContractHoldOrderService; //import com.xcong.excoin.modules.contract.service.ContractOrderService; //import com.xcong.excoin.modules.member.entity.MemberEntity; //import com.xcong.excoin.modules.member.entity.MemberWalletContractEntity; //import com.xcong.excoin.modules.member.service.MemberService; //import com.xcong.excoin.modules.member.service.MemberWalletContractService; //import com.xcong.excoin.modules.platform.entity.PlatformTradeSettingEntity; //import com.xcong.excoin.rabbit.pricequeue.OrderModel; //import com.xcong.excoin.rabbit.producer.OrderProducer; //import com.xcong.excoin.utils.CacheSettingUtils; //import com.xcong.excoin.utils.CalculateUtil; //import org.apache.commons.collections.CollectionUtils; //import org.springframework.beans.factory.annotation.Autowired; //import org.springframework.stereotype.Component; //import org.springframework.stereotype.Service; // //import javax.annotation.Resource; //import java.math.BigDecimal; //import java.math.RoundingMode; //import java.util.*; // //@Service //public class OrderWebsocketServiceImpl { // // @Resource // ContractHoldOrderService contractHoldOrderService; // // // @Resource // ContractOrderService contractOrderService; // // @Resource // ContractEntrustOrderService contractEntrustOrderService; // // // @Resource // MemberWalletContractService memberWalletContractService; // // // @Resource // CacheSettingUtils cacheSettingUtils; // // @Resource // OrderProducer producer; // // @Resource // MemberService memberService; // // // // public void dealOrderFromMq(List<OrderModel> list, Integer type) { // if (CollectionUtils.isNotEmpty(list)) { // String batchno = UUID.randomUUID().toString(); // // 更新订单状态 // // 更新为不可平仓状态 // int count = contractHoldOrderService.updateContractHoldOrderCanNotClosingByIds(list, batchno); // // 查询 // if (count > 0) { // // 查询 // List<ContractHoldOrderEntity> coinsCoinsOrders = contractHoldOrderService.selectContractHoldOrderByBatchNo(batchno); // // 根据状态调用不同的方法 // // 1:买入委托2:开多3:开空4:平多5:平空6:爆仓平多7:爆仓平空8:撤单9:止盈平多10:止盈平空11:止损平多12:止损平空 // // 6在这里是爆仓 包括爆空和暴多 // switch (type) { // case 6: // this.dealCoinOut(coinsCoinsOrders,list); // break; // case 9: // this.dealForMoreStopPro(coinsCoinsOrders,list); // break; // case 10: // this.dealForLessStopPro(coinsCoinsOrders,list); // break; // case 11: // this.dealForMoreLoss(coinsCoinsOrders,list); // break; // case 12: // this.dealForLessLoss(coinsCoinsOrders,list); // break; // } // // } // // // } // } // // public void dealForLimitMq(List<OrderModel> list){ // if(CollectionUtils.isNotEmpty(list)){ // //查询限价委托的单 // String batchno =UUID.randomUUID().toString(); // List<Long> ids = new ArrayList<>(); // list.forEach(model->ids.add(model.getOrderId())); // List<ContractEntrustOrderEntity> contractEntrustOrderEntities = contractEntrustOrderService.selectEntrustOrderListByIds(ids); // // if(CollectionUtils.isNotEmpty(contractEntrustOrderEntities)){ // this.dealLimitBuyOrder(contractEntrustOrderEntities); // } // // } // } // // /** // * 开多止盈 // */ // public void dealForMoreStopPro(List<ContractHoldOrderEntity> orderList,List<OrderModel> list) { // if (CollectionUtils.isNotEmpty(orderList)) { // Map<Long,BigDecimal> modelMap = new HashMap<Long,BigDecimal>(); // for(OrderModel model : list){ // modelMap.put(model.getOrderId(),new BigDecimal(model.getPrice())); // } // for (ContractHoldOrderEntity order : orderList) { // Long orderId = order.getId(); // System.out.println("开多止盈订单号:" + order.getOrderNo()); // System.out.println("传来的止盈价格:"+modelMap.get(order.getId())); // if (null != order.getStopProfitPrice()) { // BigDecimal closePrice = order.getStopProfitPrice(); // BigDecimal queuePrice = modelMap.get(order.getId()); // System.out.println("订单的止盈价格:"+closePrice); // // 判断 保留七位是为了忽略以为小数 防止不精确导致的不相等 // if(queuePrice.compareTo(closePrice)!=0){ // // // 不能止盈 // System.out.println("数据库价格:"+queuePrice.toPlainString()+"--价格不能止盈:"+closePrice); // //更新数据 // contractHoldOrderService.updateOrderIsCanClosingAndBatchNoById(orderId); // continue; // } // System.out.println("执行操作"); // // 止盈价 // String symbol = order.getSymbol(); // // 本次需要退回的预付款 // BigDecimal prePrice = order.getPrePaymentAmount(); // Long memberId = order.getMemberId(); // MemberWalletContractEntity wallet = memberWalletContractService.findWalletContractByMemberIdAndSymbol(memberId, "USDT"); // if (wallet != null) { // // 历史订单 // ContractOrderEntity contractOrderEntity = ContractHoldOrderEntityMapper.INSTANCE.holdOrderToOrder(order); // contractOrderEntity.setClosingType(6); // contractOrderEntity.setClosingTime(new Date()); // contractOrderEntity.setId(null); // // // 本次平仓数量 // int currentFlat = order.getSymbolCnt(); // BigDecimal symbolSku = cacheSettingUtils.getSymbolSku(order.getSymbol()); // // 盈亏额度= (当前的币种的平仓价-下单时的建仓价)*购买的手数/规格*倍率 // BigDecimal profitLossPrice = (closePrice // .subtract(order.getOpeningPrice())) // .multiply(new BigDecimal(currentFlat+"")) // .multiply(symbolSku).setScale(8, BigDecimal.ROUND_DOWN); // MemberEntity memberEntity = memberService.getById(memberId); // // if(memberEntity.getIsProfit() == 1) { // PlatformTradeSettingEntity tradeSetting = cacheSettingUtils.getTradeSetting(); // if(profitLossPrice.compareTo(BigDecimal.ZERO)>0) { // profitLossPrice = profitLossPrice.multiply(BigDecimal.ONE.subtract(tradeSetting.getProfitParam())); // }else { // profitLossPrice = profitLossPrice.multiply(BigDecimal.ONE.add(tradeSetting.getProfitParam())); // } // } // //回报率 // BigDecimal returnRate = profitLossPrice.divide((order.getPrePaymentAmount().subtract(contractOrderEntity.getClosingFeeAmount())), 8, BigDecimal.ROUND_DOWN); // contractOrderEntity.setRewardAmount(profitLossPrice); // contractOrderEntity.setRewardRatio(returnRate); // contractOrderEntity.setClosingFeeAmount(order.getOpeningFeeAmount()); // contractOrderEntity.setClosingPrice(closePrice); // contractOrderEntity.setClosingType(9); // BigDecimal totalReturn = BigDecimal.ZERO; // contractOrderService.save(contractOrderEntity); // // 将需要退回的减去手续费 // BigDecimal needReturn = prePrice.add(profitLossPrice); // //总退回金额=保证金+收益-手续费 // totalReturn = needReturn.subtract(contractOrderEntity.getClosingFeeAmount()); // // 更新钱包 // // 总的是收益-平仓手续费 // BigDecimal totalBalance = profitLossPrice.subtract(contractOrderEntity.getClosingFeeAmount()); // memberWalletContractService.increaseWalletContractBalanceById(totalBalance,totalReturn,null,wallet.getId()); // // // 流水记录 TODO 531 //// MemberAccountFlowRecord record = new MemberAccountFlowRecord(); //// record.setCreateTime(new Date()); //// record.setDirectionSource("止盈平仓"); //// record.setRemark("止盈平仓"); //// record.setMemberBalance(wallet.getAvailableBalance()); //// record.setMemberid(order.getMemberId()); //// record.setSymbolName(order.getSymbol()); //// record.setMemberName(wallet.getMemberName()); //// record.setMemberPhone(order.getMemberPhone()); //// record.setPrice(profitLossPrice + order.getPrePrice()); //// memberService.addFlowRecord(record); //// //// //返佣 TODO 531 //// calYj(order.getMemberId(), new BigDecimal(order.getClosingPrice()), order, 2); // } // } // } // } // // } // // /** // * 开空止盈 // */ // public void dealForLessStopPro(List<ContractHoldOrderEntity> orderList,List<OrderModel> list) { // //List<CoinsCoinsOrder> orderList = orderMapper.selectOrderByBatchNo(batchno); // //System.out.println("开空止盈订单batchno:" + batchno); // if (CollectionUtils.isNotEmpty(orderList)) { // Map<Long,BigDecimal> modelMap = new HashMap<Long,BigDecimal>(); // for(OrderModel model : list){ // modelMap.put(model.getOrderId(),new BigDecimal(model.getPrice())); // } // for (ContractHoldOrderEntity order : orderList) { // System.out.println("开空止盈订单号:" + order.getOrderNo()); // System.out.println("传来的止盈价格:"+modelMap.get(order.getId()).toPlainString()); // BigDecimal closePrice = order.getStopProfitPrice(); // if (null != closePrice) { // // // 止盈价 // BigDecimal closePrice = new BigDecimal(order.getStopProfitPrice()).setScale(7, RoundingMode.HALF_UP); // System.out.println("订单的止盈价格:"+closePrice); // System.out.println(closePrice.compareTo(modelMap.get(order.getId()))); // BigDecimal queuePrice = modelMap.get(order.getId()).setScale(7, RoundingMode.HALF_UP); // if(closePrice.compareTo(queuePrice)!=0){ // System.out.println("数据库价格:"+queuePrice.toPlainString()+"--价格不能开空止盈:"+closePrice); // orderMapper.updateOrderIsExitAndBatchno(order.getId()); // continue; // } // System.out.println("执行操作"); // String symbol = order.getSymbol(); // // 本次需要退回的预付款 // BigDecimal prePrice = new BigDecimal(order.getPrePrice()); // Wallet wallet = memberService.findWalletByMemberIdAndSymbol(order.getMemberId(), "USDT"); // // if (wallet != null) { // // 更新订单 // order.setIsEixt(0); // orderMapper.updateOrder(order); // order.setExitPrice(order.getStopProfitPrice());// 平仓价格 // order.setExitType(2);// 平仓类型,1:表示手动平仓,2:止盈平仓,3:止损平仓,4:爆仓 // order.setExitTime(new Date());// 平仓时间 // order.setEntrustStatus(7);// 平仓状态 // // 本次平仓数量 // Long currentFlat = order.getSymbolSkuNumber(); // TradeSymbolSku symbolSku = tradeMapper.findSymbolSkubySymbol(symbol); // // 盈亏额度= (当前的币种的平仓价-下单时的建仓价)*购买的手数/规格*倍率 // Double profitLossPrice = (new BigDecimal(order.getTradePrice()).subtract(closePrice)) // .multiply(new BigDecimal(currentFlat)) // .multiply(symbolSku.getLotNumber()) // .setScale(8, BigDecimal.ROUND_DOWN).doubleValue(); // // Member member = memberService.selectMemberById(order.getMemberId()); // if(member.getIsProfit() == 1) { // TradeSetting tradeSetting = tradeSettingCache.getTradeSetting(); // if(profitLossPrice>0) { // profitLossPrice = profitLossPrice*(1-tradeSetting.getProfitParam()); // }else { // profitLossPrice = profitLossPrice*(1+tradeSetting.getProfitParam());; // } // } // //回报率 // double returnRate = new BigDecimal(profitLossPrice).divide((new BigDecimal(order.getPrePrice()).subtract(new BigDecimal(order.getClosingPrice()))), 8, BigDecimal.ROUND_DOWN) // .doubleValue(); // order.setRewardRatio(profitLossPrice);// 盈亏 // order.setReturnRate(returnRate); // // BigDecimal totalReturn = BigDecimal.ZERO; // // 查询交易设置 // //TradeSetting tradeSetting = tradeMapper.findTradeSetting(); // // 计算手续费 //// Double closingPrice = closePrice //// .multiply(new BigDecimal(tradeSetting.getClosingRatio()).divide(new BigDecimal(100), 8, BigDecimal.ROUND_DOWN)) //// .multiply(symbolSku.getLotNumber())// 规格 //// .multiply(new BigDecimal(currentFlat)).setScale(8, BigDecimal.ROUND_DOWN) //// .doubleValue(); // order.setSellClosingPrice(order.getClosingPrice()); // // //添加止盈订单 // order.setId(null); // //10:止盈平空 // order.setStatus(10); // orderMapper.addCoinsCoinsOrder(order); // // 将需要退回的减去手续费 // BigDecimal needReturn = prePrice.add(new BigDecimal(profitLossPrice)); // //总退回金额=保证金+收益-手续费 // totalReturn = needReturn.subtract(new BigDecimal(order.getClosingPrice())); // // 更新钱包 // // Double availableBalance = totalReturn.add(new BigDecimal(wallet.getAvailableBalance())) // // .doubleValue(); // // Double availableBalance = totalReturn.doubleValue(); // // Double totalBalance = - order.getClosingPrice() + profitLossPrice; //// wallet.setAvailableBalance(availableBalance); //// wallet.setTotalBalance(totalBalance); //// int i = memberService.updateWallet(wallet); // walletDao.updateWallet(wallet.getId(),totalBalance,availableBalance,null); // // 流水记录 // MemberAccountFlowRecord record = new MemberAccountFlowRecord(); // record.setCreateTime(new Date()); // record.setDirectionSource("止盈平仓"); // record.setRemark("止盈平仓"); // record.setMemberBalance(wallet.getAvailableBalance()); // record.setMemberid(order.getMemberId()); // record.setSymbolName(order.getSymbol()); // record.setMemberName(wallet.getMemberName()); // record.setMemberPhone(order.getMemberPhone()); // record.setPrice(profitLossPrice + order.getPrePrice()); // memberService.addFlowRecord(record); // // //返佣 TODO // calYj(order.getMemberId(), new BigDecimal(order.getClosingPrice()), order, 2); // } // } // } // } // // } // // /** // * 开多止损 // * // * @param // */ // public void dealForMoreLoss(List<CoinsCoinsOrder> orderList,List<OrderModel> list) { // //List<CoinsCoinsOrder> orderList = orderMapper.selectOrderByBatchNo(batchno); // //System.out.println("开多止损批次号batchno:" + batchno); // if (CollectionUtils.isNotEmpty(orderList)) { // Map<Long,BigDecimal> modelMap = new HashMap<Long,BigDecimal>(); // for(OrderModel model : list){ // modelMap.put(model.getOrderId(),new BigDecimal(model.getPrice())); // } // for (CoinsCoinsOrder order : orderList) { // System.out.println("开多止损订单号:" + order.getSerialno()); // System.out.println("传来的止损价格:"+modelMap.get(order.getId())); // // if (null != order.getStopLossPrice()) { // // 止损价 // BigDecimal closePrice = new BigDecimal(order.getStopLossPrice()).setScale(7,RoundingMode.HALF_UP); // System.out.println("订单止损价格:"+closePrice.toPlainString()); // BigDecimal queuePrice = modelMap.get(order.getId()).setScale(7, RoundingMode.HALF_UP); // if(closePrice.compareTo(queuePrice)!=0){ // System.out.println("数据库价格:"+queuePrice.toPlainString()+"--价格不能开多止损:"+closePrice); // orderMapper.updateOrderIsExitAndBatchno(order.getId()); // continue; // } // System.out.println("执行操作"); // String symbol = order.getSymbol(); // // 本次需要退回的预付款 // BigDecimal prePrice = new BigDecimal(order.getPrePrice()); // Wallet wallet = memberService.findWalletByMemberIdAndSymbol(order.getMemberId(), "USDT"); // // if (wallet != null) { // // 更新订单 // order.setIsEixt(0); // orderMapper.updateOrder(order); // order.setExitPrice(order.getStopLossPrice());// 平仓价格 // order.setExitType(3);// 平仓类型,1:表示手动平仓,2:止盈平仓,3:止损平仓,4:爆仓 // order.setExitTime(new Date());// 平仓时间 // order.setEntrustStatus(8);// 平仓状态 // // TradeSymbolSku symbolSku = tradeMapper.findSymbolSkubySymbol(symbol); // // Double profitLossPrice = (closePrice // .subtract(new BigDecimal(order.getTradePrice()))) // .multiply(new BigDecimal(order.getSymbolSkuNumber())) // .multiply(symbolSku.getLotNumber()) // .setScale(8, BigDecimal.ROUND_DOWN).doubleValue(); // // Member member = memberService.selectMemberById(order.getMemberId()); // if(member.getIsProfit() == 1) { // TradeSetting tradeSetting = tradeSettingCache.getTradeSetting(); // if(profitLossPrice>0) { // profitLossPrice = profitLossPrice*(1-tradeSetting.getProfitParam()); // }else { // profitLossPrice = profitLossPrice*(1+tradeSetting.getProfitParam());; // } // } // //回报率 // double returnRate = new BigDecimal(profitLossPrice).divide((new BigDecimal(order.getPrePrice()).subtract(new BigDecimal(order.getClosingPrice()))), 8, BigDecimal.ROUND_DOWN) // .doubleValue(); // // 查询交易设置 // TradeSetting tradeSetting = tradeSettingCache.getTradeSetting(); // // 计算手续费 //// Double closingPrice = closePrice //// .multiply(new BigDecimal(tradeSetting.getClosingRatio()).divide(new BigDecimal(100), 8, BigDecimal.ROUND_DOWN)) //// .multiply(symbolSku.getLotNumber())// 规格 //// .multiply(new BigDecimal(currentFlat)).setScale(8, BigDecimal.ROUND_DOWN) //// .doubleValue(); // order.setRewardRatio(profitLossPrice);// 盈亏 // order.setReturnRate(returnRate); // order.setSellClosingPrice(order.getClosingPrice()); // // //添加止损 // order.setId(null); // order.setStatus(11); // orderMapper.addCoinsCoinsOrder(order); // BigDecimal totalReturn = BigDecimal.ZERO; // // 将需要退回的减去手续费 // BigDecimal needReturn = prePrice.add(new BigDecimal(profitLossPrice)); // //总退回金额=保证金+收益-手续费 // totalReturn = needReturn.subtract(new BigDecimal(order.getClosingPrice())); // // 更新钱包 // // Double availableBalance = totalReturn.add(new BigDecimal(wallet.getAvailableBalance())) // // .doubleValue(); // Double availableBalance = totalReturn.doubleValue(); // // //Double totalBalance = wallet.getTotalBalance() - order.getClosingPrice() + profitLossPrice; // Double totalBalance = -order.getClosingPrice() + profitLossPrice; // //// wallet.setAvailableBalance(availableBalance); //// wallet.setTotalBalance(totalBalance); //// int i = memberService.updateWallet(wallet); // walletDao.updateWallet(wallet.getId(),totalBalance,availableBalance,null); // // 流水记录 // MemberAccountFlowRecord record = new MemberAccountFlowRecord(); // record.setCreateTime(new Date()); // record.setDirectionSource("开多止损平仓"); // record.setRemark("开多止损平仓"); // record.setMemberBalance(wallet.getAvailableBalance()); // record.setMemberid(order.getMemberId()); // record.setSymbolName(order.getSymbol()); // record.setMemberName(wallet.getMemberName()); // record.setMemberPhone(order.getMemberPhone()); // record.setPrice(profitLossPrice + order.getPrePrice()); // memberService.addFlowRecord(record); // // //返佣 TODO // calYj(order.getMemberId(), new BigDecimal(order.getClosingPrice()), order, 2); // } // } // } // } // } // // /** // * 开空止损 // * // * @param // */ // public void dealForLessLoss(List<CoinsCoinsOrder> orderList,List<OrderModel> list) { // // List<CoinsCoinsOrder> orderList = orderMapper.selectOrderByBatchNo(batchno); // //System.out.println("开空止损批次号batchno:" + batchno); // if (CollectionUtils.isNotEmpty(orderList)) { // Map<Long,BigDecimal> modelMap = new HashMap<Long,BigDecimal>(); // for(OrderModel model : list){ // modelMap.put(model.getOrderId(),new BigDecimal(model.getPrice())); // } // for (CoinsCoinsOrder order : orderList) { // System.out.println("传来的止损价格:"+modelMap.get(order.getId()).toPlainString()); // System.out.println("开空止损订单号:" + order.getSerialno()); // if (null != order.getStopLossPrice()) { // // 止损价 // BigDecimal closePrice = new BigDecimal(order.getStopLossPrice()).setScale(7,RoundingMode.HALF_UP); // // System.out.println("订单止损价格:"+closePrice.toPlainString()); // BigDecimal queuePrice = modelMap.get(order.getId()).setScale(7, RoundingMode.HALF_UP); // if(closePrice.compareTo(queuePrice)!=0){ // System.out.println("数据库价格:"+queuePrice.toPlainString()+"--价格不能开空止损:"+closePrice); // // orderMapper.updateOrderIsExitAndBatchno(order.getId()); // continue; // } // System.out.println("执行操作"); // String symbol = order.getSymbol(); // // 本次需要退回的预付款 // BigDecimal prePrice = new BigDecimal(order.getPrePrice()); // Wallet wallet = memberService.findWalletByMemberIdAndSymbol(order.getMemberId(), "USDT"); // // if (wallet != null) { // // 更新订单 // order.setIsEixt(0); // orderMapper.updateOrder(order); // order.setExitPrice(order.getStopLossPrice());// 平仓价格 // order.setExitType(3);// 平仓类型,1:表示手动平仓,2:止盈平仓,3:止损平仓,4:爆仓 // order.setExitTime(new Date());// 平仓时间 // order.setEntrustStatus(8);// 平仓状态 // // TradeSymbolSku symbolSku = tradeMapper.findSymbolSkubySymbol(symbol); // // 盈亏额度= (当前的币种的平仓价-下单时的建仓价)*购买的手数 // Double profitLossPrice = (new BigDecimal(order.getTradePrice())) // .subtract(closePrice) // .multiply(new BigDecimal(order.getSymbolSkuNumber())) // .multiply(symbolSku.getLotNumber()) // .setScale(8, BigDecimal.ROUND_DOWN).doubleValue(); // Member member = memberService.selectMemberById(order.getMemberId()); // if(member.getIsProfit() == 1) { // TradeSetting tradeSetting=tradeSettingCache.getTradeSetting(); // if(profitLossPrice>0) { // profitLossPrice = profitLossPrice*(1-tradeSetting.getProfitParam()); // }else { // profitLossPrice = profitLossPrice*(1+tradeSetting.getProfitParam());; // } // } // //回报率 // double returnRate = new BigDecimal(profitLossPrice).divide((new BigDecimal(order.getPrePrice()).subtract(new BigDecimal(order.getClosingPrice()))), 8, BigDecimal.ROUND_DOWN) // .doubleValue(); // order.setRewardRatio(profitLossPrice);// 盈亏 // order.setReturnRate(returnRate); // // BigDecimal totalReturn = BigDecimal.ZERO; //// TradeSymbolSku symbolSku = tradeMapper.findSymbolSkubySymbol(symbol); // // 本次平仓数量 // // Long currentFlat = order.getSymbolSkuNumber(); // // 查询交易设置 // // TradeSetting tradeSetting = tradeMapper.findTradeSetting(); // // 计算手续费 //// Double closingPrice = new BigDecimal(order.getStopLossPrice()) //// .multiply(new BigDecimal(tradeSetting.getClosingRatio()).divide(new BigDecimal(100), 8, BigDecimal.ROUND_DOWN)) //// .multiply(symbolSku.getLotNumber())// 规格 //// .multiply(new BigDecimal(currentFlat)).setScale(8, BigDecimal.ROUND_DOWN) //// .doubleValue(); // order.setSellClosingPrice(order.getClosingPrice()); // // //添加止盈订单 // order.setId(null); // order.setStatus(12); // orderMapper.addCoinsCoinsOrder(order); // // 将需要退回的减去手续费 // BigDecimal needReturn = prePrice.add(new BigDecimal(profitLossPrice)); // //总退回金额=保证金+收益-手续费 // totalReturn = needReturn.subtract(new BigDecimal(order.getClosingPrice())); // // 更新钱包 // // Double availableBalance = totalReturn.add(new BigDecimal(wallet.getAvailableBalance())) // // .doubleValue(); // // Double availableBalance = totalReturn.doubleValue(); // // //Double totalBalance = wallet.getTotalBalance() - order.getClosingPrice() + profitLossPrice; // Double totalBalance = profitLossPrice- order.getClosingPrice() ; // //// wallet.setAvailableBalance(availableBalance); //// wallet.setTotalBalance(totalBalance); //// int i = memberService.updateWallet(wallet); // walletDao.updateWallet(wallet.getId(),totalBalance,availableBalance,null); // // // 流水记录 // MemberAccountFlowRecord record = new MemberAccountFlowRecord(); // record.setCreateTime(new Date()); // record.setDirectionSource("开空止损平仓"); // record.setRemark("开空止损平仓"); // record.setMemberBalance(wallet.getAvailableBalance()); // record.setMemberid(order.getMemberId()); // record.setSymbolName(order.getSymbol()); // record.setMemberName(wallet.getMemberName()); // record.setMemberPhone(order.getMemberPhone()); // record.setPrice(profitLossPrice + order.getPrePrice()); // memberService.addFlowRecord(record); // // //返佣 TODO // calYj(order.getMemberId(), new BigDecimal(order.getClosingPrice()), order, 2); // } // } // } // } // } // // // /** // * 限价委托 // * // * @param // */ // public void dealLimitBuyOrder(List<ContractEntrustOrderEntity> orderList) { // // //List<CoinsCoinsOrder> orderList = orderMapper.selectOrderByBatchNo(batchno); // if (CollectionUtils.isNotEmpty(orderList)) { // ContractHoldOrderEntity contractHoldOrderEntity=null; // for (ContractEntrustOrderEntity coinsCoinsOrder : orderList) { // MemberWalletContractEntity wallet = memberWalletContractService.findWalletContractByMemberIdAndSymbol(coinsCoinsOrder.getMemberId(), "USDT"); // if (wallet == null) { // continue; // } // // contractHoldOrderEntity = new ContractHoldOrderEntity(); // Long memId = coinsCoinsOrder.getMemberId(); // MemberEntity memberEntity = memberService.getById(memId); // BigDecimal entrustPrice = coinsCoinsOrder.getEntrustPrice(); // int symbolCnt = coinsCoinsOrder.getSymbolCnt(); // int type = coinsCoinsOrder.getEntrustType(); // //开仓价 // // Double openPrice = coinsCoinsOrder.getOpenPrice().doubleValue(); // //委托价 // // Double markPrice = coinsCoinsOrder.getMarkPrice(); // if (type == 1) { // // 开多 // contractHoldOrderEntity.setOpeningType(ContractHoldOrderEntity.ORDER_OPENING_TYPE_MORE); // } else { // // 开空 // contractHoldOrderEntity.setOpeningType(ContractHoldOrderEntity.ORDER_OPENING_TYPE_LESS); // // } // // //持仓单赋值 // contractHoldOrderEntity.setMemberId(memId); // contractHoldOrderEntity.setIsCanClosing(ContractHoldOrderEntity.ORDER_CAN_CLOSING_Y); // contractHoldOrderEntity.setMarkPrice(coinsCoinsOrder.getEntrustPrice()); // contractHoldOrderEntity.setBondPrice(coinsCoinsOrder.getBondAmount()); // // 开仓手续费 建仓价*规格*手数*手续费率 // BigDecimal lotNumber = cacheSettingUtils.getSymbolSku(coinsCoinsOrder.getSymbol()); // PlatformTradeSettingEntity tradeSettingEntity = cacheSettingUtils.getTradeSetting(); // BigDecimal openFeePrice = coinsCoinsOrder.getEntrustPrice().multiply(lotNumber) // .multiply(new BigDecimal(coinsCoinsOrder.getSymbolCnt())) // .multiply(tradeSettingEntity.getFeeRatio().divide(new BigDecimal(100))) // .setScale(8, BigDecimal.ROUND_DOWN); // contractHoldOrderEntity.setOpeningFeeAmount(openFeePrice); // contractHoldOrderEntity.setVersion(1); // BigDecimal forceSetPrice = CalculateUtil.getForceSetPrice(coinsCoinsOrder.getBondAmount(), entrustPrice, symbolCnt, lotNumber, type, memberEntity); // // contractHoldOrderEntity.setForceClosingPrice(forceSetPrice); // contractHoldOrderEntity.setLeverRatio(coinsCoinsOrder.getLeverRatio()); // contractHoldOrderEntity.setOpeningPrice(entrustPrice); // contractHoldOrderService.save(contractHoldOrderEntity); // // // 需要一个历史插入 // ContractOrderEntity contractOrderEntity = ContractHoldOrderEntityMapper.INSTANCE.holdOrderToOrder(contractHoldOrderEntity); // contractOrderEntity.setId(null); // contractOrderService.save(contractOrderEntity); // // 发送爆仓的队列 // // 市价 // if (coinsCoinsOrder.getEntrustType() == 1) { // // 开多 // OrderModel model = new OrderModel(contractHoldOrderEntity.getId(), 6, contractHoldOrderEntity.getForceClosingPrice().toPlainString(), coinsCoinsOrder.getSymbol(),1); // producer.sendPriceOperate(JSONObject.toJSONString(model)); // } else { // // 开空 // OrderModel model = new OrderModel(contractHoldOrderEntity.getId(), 7, contractHoldOrderEntity.getForceClosingPrice().toPlainString(), coinsCoinsOrder.getSymbol(),1); // producer.sendPriceOperate(JSONObject.toJSONString(model)); // } // // 扣除手续费 // //double totalBalance = wallet.getTotalBalance() - coinsCoinsOrder.getClosingPrice(); // BigDecimal totalBalance = openFeePrice.negate(); // // /** TradeSetting tradeSetting = tradeSettingCache.getTradeSetting(); // // Double totalPayPrice = new BigDecimal(coinsCoinsOrder.getPrePrice()).add(new BigDecimal(coinsCoinsOrder.getClosingPrice())).add(new BigDecimal(coinsCoinsOrder.getClosingPrice())) // .setScale(8, BigDecimal.ROUND_HALF_UP).doubleValue(); // totalBalance = totalBalance+(-totalPayPrice*(Double.valueOf(tradeSetting.getSpread())/10000));*/ // // memberWalletContractService.increaseWalletContractBalanceById(null,totalBalance,null,wallet.getId()); // // TODO 531 待写 // //calYj(memId, new BigDecimal(coinsCoinsOrder.getClosingPrice()), coinsCoinsOrder, 1); // } // } // } // // /** // * 爆仓 // * // * @param // */ // public void dealCoinOut(List<ContractHoldOrderEntity> orderList,List<OrderModel> orderModels) { // // 需要比较查询到的和消息发来的单的爆仓操作次序号是否相同 // // 构建map // // if (CollectionUtils.isNotEmpty(orderList)) { // Map<Long,Integer> modelMap = new HashMap<Long,Integer>(); // for(OrderModel model : orderModels){ // modelMap.put(model.getOrderId(),model.getOperateNo()); // } // // TradeSetting tradeSetting = tradeMapper.findTradeSetting(); // for (ContractHoldOrderEntity coinsOrder : orderList) { // Long orderId = coinsOrder.getId(); // Integer operateNo = coinsOrder.getOperateNo(); // //判断当前订单是否是最新的爆仓价 不相等时直接进入下一个订单 // if(!modelMap.get(orderId).equals(operateNo)){ // // 将订单更新为可平仓并删除批次号 // contractHoldOrderService.updateOrderIsCanClosingAndBatchNoById(orderId); // continue; // } // boolean isDone = false; // Long memId = coinsOrder.getMemberId(); // MemberEntity byId = memberService.getById(memId); // String symbol = coinsOrder.getSymbol(); // //TradeSymbolSku symbolSku = tradeMapper.findSymbolSkubySymbol(symbol); // BigDecimal nowPrice = coinsOrder.getForceClosingPrice(); // // 创建订单(加入历史表的订单) // ContractOrderEntity contractOrderEntity = ContractHoldOrderEntityMapper.INSTANCE.holdOrderToOrder(coinsOrder); // // //查询是否满足爆仓条件 // if (coinsOrder.getOpeningType() == ContractHoldOrderEntity.ORDER_OPENING_TYPE_MORE) { // //如果是开多,当前价小于预估强平价即为爆仓 // // 设置平仓类型 // 爆仓平多 // contractOrderEntity.setClosingType(4); // //更新用户钱包数据 // isDone = true; // } else { // //如果是开空,当前价大于预估强平价即为爆仓 // contractOrderEntity.setClosingType(5); // //更新主表订单状态位为“已平仓” // isDone = true; // // } // if (isDone) { // //删除次仓订单 // contractHoldOrderService.removeById(orderId); // // //系统自动平仓(爆仓) //// Double closingPrice = nowPrice //// .multiply(new BigDecimal(tradeSetting.getClosingRatio()).divide(new BigDecimal(100), 8, BigDecimal.ROUND_DOWN)) //// .multiply(symbolSku.getLotNumber())// 规格 //// .multiply(new BigDecimal(coinsOrder.getSymbolSkuNumber())) //// .setScale(8, BigDecimal.ROUND_DOWN).doubleValue(); // //更新主表订单状态位为“已平仓” // contractOrderEntity.setId(null); // contractOrderEntity.setClosingPrice(BigDecimal.ZERO); // //order.setPayTotalPrice(coinsOrder.getPrePrice()+coinsOrder.getClosingPrice());// 总支付金额(预付款) // // contractOrderEntity.setClosingPrice(nowPrice); // contractOrderEntity.setClosingTime(new Date()); // contractOrderEntity.setRewardAmount((coinsOrder.getOpeningFeeAmount().multiply(new BigDecimal("2")).subtract(coinsOrder.getPrePaymentAmount()))); // //order.setRewardRatio(-(coinsOrder.getPrePrice() - (2*coinsOrder.getClosingPrice()))); // contractOrderService.save(contractOrderEntity); // // //更新用户钱包数据 // MemberWalletContractEntity usdt = memberWalletContractService.findWalletContractByMemberIdAndSymbol(memId, "USDT"); // // // Double totalPrice = wallet.getTotalBalance() - coinsOrder.getPrePrice(); // // 减去的时候用负数 // BigDecimal totalPrice = coinsOrder.getPrePaymentAmount().negate(); // //Double totalPrice = - coinsOrder.getPrePrice(); // memberWalletContractService.increaseWalletContractBalanceById(null,totalPrice,null,usdt.getId()); // // // 流水记录 TODO //// MemberAccountFlowRecord record = new MemberAccountFlowRecord(); //// record.setCreateTime(new Date()); //// record.setDirectionSource("系统自动平仓"); //// record.setRemark("系统自动平仓"); //// record.setMemberBalance(coinsOrder.getPrePrice()); //// record.setMemberid(memId); //// record.setSymbolName(null); //// record.setMemberName(null); //// record.setMemberPhone(null); //// record.setPrice(coinsOrder.getPrePrice()); //// memberService.addFlowRecord(record); // // } // } // } // } // // // public void calYj(Long mid, BigDecimal money, CoinsCoinsOrder order, int type) { // if(money!=null) { // money = money.multiply(new BigDecimal(0.7868)); // } // Member member = memberService.selectMemberById(mid); // String[] referenceIds = member.getReferenceIds().split(","); // List<String> ids = Arrays.asList(referenceIds); // // // 判断该用户是否为代理商 // NeedMoneyMember needMoneyMember = memberMapper.selectFriendRelationUserByMid(mid); // // // 查询该用户下所有需要返佣的代理商 // List<NeedMoneyMember> list = memberMapper.selectAllNeedMoneyMember(ids); // TreeMap<String, NeedMoneyMember> treeMap = new TreeMap<>(new Comparator<String>() { // @Override // public int compare(String o1, String o2) { // return o2.compareTo(o1); // } // }); // // 建立层级关系 // for (int i = 0; i < list.size(); i++) { // treeMap.put(list.get(i).getLevelId(), list.get(i)); // } // // // 该用户为代理商则判断is_self字段,判断是否保留其手续费 // // 该用户为代理商则判断is_self字段,判断是否保留其手续费 // if (needMoneyMember != null && needMoneyMember.getIsSelf() == 1) { // treeMap.put(needMoneyMember.getLevelId(), needMoneyMember); // } // // // // 存放uid以及对应uid用户的佣金 // Map<String, BigDecimal> map = new HashMap<>(); // Iterator<Map.Entry<String, NeedMoneyMember>> it = treeMap.entrySet().iterator(); // BigDecimal lastRate = BigDecimal.ZERO; // BigDecimal lastYj = BigDecimal.ZERO; // while (it.hasNext()) { // Map.Entry<String, NeedMoneyMember> entry = it.next(); // NeedMoneyMember member1 = entry.getValue(); // // 上下级佣金比率相减后乘以手续费 -- 即用户所得佣金 // lastYj = (member1.getReturnRate().subtract(lastRate)).multiply(money); // lastRate = member1.getReturnRate(); // map.put(member1.getUid(), lastYj); // } // // // 输出对应佣金是否正确 // Iterator<Map.Entry<String, BigDecimal>> it1 = map.entrySet().iterator(); // List<AgentReturn> agentList = new ArrayList<AgentReturn>(); // while (it1.hasNext()) { // Map.Entry<String, BigDecimal> entry = it1.next(); // // System.out.println(entry.getKey() + "-----" + entry.getValue()); // Member agentMember = memberMapper.findMemberByUID(entry.getKey()); // AgentReturn agent = new AgentReturn(); // agent.setMemId(mid); // agent.setOrderId(order.getId()); // agent.setOrderNo(order.getSerialno()); // agent.setAgentId(agentMember.getmId()); // agent.setReturnType(order.getStatus()); // agent.setReturnTime(new Date()); // agent.setReturnSymbol(order.getSymbol()); // agent.setIsReturn(0); // agent.setReturnMoney(entry.getValue()); // if (type == 1) {//开仓 // agent.setOpenPrice(new BigDecimal(order.getClosingPrice())); // } else if (type == 2) {//平仓 // agent.setClosePrice(new BigDecimal(order.getClosingPrice())); // } else {//持仓费 // agent.setDoingPrice(order.getDoingPrice()); // } // agent.setReturnMenId(agentMember.getmId()); // agent.setUid(entry.getKey()); // agent.setOrderType(order.getStatus()); // agentReturnMapper.insert(agent); // } // // // } // //} src/main/java/com/xcong/excoin/modules/member/dao/MemberWalletContractDao.java
@@ -5,8 +5,18 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.xcong.excoin.modules.member.entity.MemberWalletContractEntity; import java.math.BigDecimal; public interface MemberWalletContractDao extends BaseMapper<MemberWalletContractEntity> { MemberWalletContractEntity findWalletContractByMemberIdAndSymbol(@Param("memberId")Long memberId, @Param("symbol")String symbol); /** * 增减合约钱包(负数为减) * @param availableBalance * @param totalBalance * @param frozenBalance * @param id */ void increaseWalletContractBalanceById(@Param("availableBalance") BigDecimal availableBalance,@Param("totalBalance") BigDecimal totalBalance,@Param("frozenBalance") BigDecimal frozenBalance,@Param("id") Long id); } src/main/java/com/xcong/excoin/modules/member/entity/AgentReturnEntity.java
New file @@ -0,0 +1,41 @@ package com.xcong.excoin.modules.member.entity; import com.baomidou.mybatisplus.annotation.TableName; import com.xcong.excoin.common.system.base.BaseEntity; import lombok.Data; import java.math.BigDecimal; /** * @author wzy * @date 2020-05-31 **/ @Data @TableName("agent_return") public class AgentReturnEntity extends BaseEntity { private Long memberId; private Long id; private String orderNo; private int orderType; private BigDecimal closingFeeAmount; private BigDecimal holdingFeeAmount; private BigDecimal openingFeeAmount; private BigDecimal returnAmount; private String refererId; private String inviteId; private BigDecimal returnRatio; private BigDecimal childReturnRatio; } src/main/java/com/xcong/excoin/modules/member/service/MemberWalletContractService.java
New file @@ -0,0 +1,23 @@ package com.xcong.excoin.modules.member.service; import com.baomidou.mybatisplus.extension.service.IService; import com.xcong.excoin.modules.member.entity.MemberEntity; import com.xcong.excoin.modules.member.entity.MemberWalletContractEntity; import org.apache.ibatis.annotations.Param; import java.math.BigDecimal; public interface MemberWalletContractService extends IService<MemberWalletContractEntity> { MemberWalletContractEntity findWalletContractByMemberIdAndSymbol(Long memberId, String symbol); /** * 增减合约钱包(负数为减) * @param availableBalance * @param totalBalance * @param frozenBalance * @param id */ void increaseWalletContractBalanceById(BigDecimal availableBalance, BigDecimal totalBalance, BigDecimal frozenBalance, Long id); } src/main/java/com/xcong/excoin/modules/member/service/impl/MemberWalletContractServiceImpl.java
New file @@ -0,0 +1,33 @@ package com.xcong.excoin.modules.member.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.xcong.excoin.modules.member.dao.MemberWalletContractDao; import com.xcong.excoin.modules.member.entity.MemberWalletContractEntity; import com.xcong.excoin.modules.member.service.MemberWalletContractService; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.math.BigDecimal; /** * 会员合约钱包 */ @Slf4j @Service public class MemberWalletContractServiceImpl extends ServiceImpl<MemberWalletContractDao, MemberWalletContractEntity> implements MemberWalletContractService { @Resource private MemberWalletContractDao memberWalletContractDao; @Override public MemberWalletContractEntity findWalletContractByMemberIdAndSymbol(Long memberId, String symbol){ return memberWalletContractDao.findWalletContractByMemberIdAndSymbol(memberId,symbol); } @Override public void increaseWalletContractBalanceById(BigDecimal availableBalance, BigDecimal totalBalance, BigDecimal frozenBalance, Long id) { memberWalletContractDao.increaseWalletContractBalanceById(availableBalance,totalBalance,frozenBalance,id); } } src/main/java/com/xcong/excoin/modules/platform/dao/PlatformSymbolsSkuDao.java
New file @@ -0,0 +1,15 @@ package com.xcong.excoin.modules.platform.dao; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.xcong.excoin.modules.member.parameter.vo.MemberCoinAddressCountVo; import com.xcong.excoin.modules.platform.entity.PlatformSymbolsCoinEntity; import com.xcong.excoin.modules.platform.entity.PlatformSymbolsSkuEntity; import org.apache.ibatis.annotations.Param; import java.util.List; public interface PlatformSymbolsSkuDao extends BaseMapper<PlatformSymbolsSkuEntity> { PlatformSymbolsSkuEntity findSymbolSkuByName(@Param("name") String name); } src/main/java/com/xcong/excoin/modules/platform/service/PlatformSymbolsSkuService.java
New file @@ -0,0 +1,12 @@ package com.xcong.excoin.modules.platform.service; import com.baomidou.mybatisplus.extension.service.IService; import com.xcong.excoin.common.response.Result; import com.xcong.excoin.modules.platform.entity.PlatformBannerEntity; import com.xcong.excoin.modules.platform.entity.PlatformSymbolsSkuEntity; public interface PlatformSymbolsSkuService extends IService<PlatformSymbolsSkuEntity> { public PlatformSymbolsSkuEntity findSymbolSkuByName(String name); } src/main/java/com/xcong/excoin/modules/platform/service/impl/PlatformSymbolsSkuServiceImpl.java
New file @@ -0,0 +1,24 @@ package com.xcong.excoin.modules.platform.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.xcong.excoin.modules.platform.dao.PlatformSymbolsSkuDao; import com.xcong.excoin.modules.platform.entity.PlatformSymbolsSkuEntity; import com.xcong.excoin.modules.platform.service.PlatformSymbolsSkuService; import org.springframework.stereotype.Service; import javax.annotation.Resource; /** * 币种规格服务类 */ @Service public class PlatformSymbolsSkuServiceImpl extends ServiceImpl<PlatformSymbolsSkuDao, PlatformSymbolsSkuEntity> implements PlatformSymbolsSkuService { @Resource private PlatformSymbolsSkuDao platformSymbolsSkuDao; @Override public PlatformSymbolsSkuEntity findSymbolSkuByName(String name) { return platformSymbolsSkuDao.findSymbolSkuByName(name); } } src/main/java/com/xcong/excoin/modules/symbols/controller/SymbolsController.java
@@ -1,10 +1,12 @@ package com.xcong.excoin.modules.symbols.controller; import com.huobi.client.model.Candlestick; import com.xcong.excoin.common.response.Result; import com.xcong.excoin.modules.symbols.parameter.dto.KlineDetailDto; import com.xcong.excoin.modules.symbols.parameter.vo.HomeSymbolsVo; import com.xcong.excoin.modules.symbols.parameter.vo.KlineDataVo; import com.xcong.excoin.modules.symbols.service.SymbolsService; import com.xcong.excoin.utils.RedisUtils; import com.xcong.excoin.utils.TypeJudgeUtils; import io.swagger.annotations.*; import lombok.extern.slf4j.Slf4j; @@ -25,6 +27,9 @@ @Resource private SymbolsService symbolsService; @Resource private RedisUtils redisUtils; @ApiOperation(value = "轮询获取app首页币种交易信息", notes = "轮询获取app首页币种交易信息") @ApiResponses({ @@ -56,4 +61,11 @@ return symbolsService.findKlineDetails(klineDetailDto); } @ApiOperation(value = "查询当日最高最低价") @GetMapping(value = "/getDayHighAndLow") public Result getDayHighAndLow(@ApiParam(name = "symbol", value = "币种", required = true, example = "BTC/USDT") @RequestParam(value = "symbol") String symbol) { Candlestick object = (Candlestick) redisUtils.get(symbol); return Result.ok(object); } } src/main/java/com/xcong/excoin/quartz/job/NewestPriceUpdateJob.java
@@ -5,9 +5,11 @@ import com.huobi.client.model.Candlestick; import com.huobi.client.model.enums.CandlestickInterval; import com.xcong.excoin.modules.symbols.service.SymbolsService; import com.xcong.excoin.rabbit.pricequeue.WebsocketPriceService; import com.xcong.excoin.utils.CoinTypeConvert; import com.xcong.excoin.utils.RedisUtils; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.stereotype.Component; @@ -31,6 +33,9 @@ @Resource private SymbolsService symbolsService; @Resource private WebsocketPriceService websocketPriceService; @PostConstruct public void initNewestPrice() { log.info("#=======价格更新开启=======#"); @@ -47,8 +52,8 @@ // TODO 测试环境关闭这个插入redis redisUtils.set(CoinTypeConvert.convertToKey(symbol), price); // 比较 // websocketPriceService.comparePriceAsc(symbol, price); // websocketPriceService.comparePriceDesc(symbol, price); websocketPriceService.comparePriceAsc(symbol, price); websocketPriceService.comparePriceDesc(symbol, price); //System.out.println("比较完毕:"+symbol+"-"+price); } src/main/java/com/xcong/excoin/rabbit/consumer/OperateOrderPriceConsumer.java
New file @@ -0,0 +1,45 @@ package com.xcong.excoin.rabbit.consumer; import com.alibaba.fastjson.JSONObject; import com.rabbitmq.client.Channel; import com.xcong.excoin.configurations.RabbitMqConfig; import com.xcong.excoin.rabbit.pricequeue.OrderModel; import com.xcong.excoin.rabbit.pricequeue.OrderOperatePriceService; import org.springframework.amqp.core.Message; import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.stereotype.Component; /** * 用户修改止损止盈价格、提价限价委托、下单爆仓价等消息 * 后台打包开启 APP 不开启 */ @Component @ConditionalOnProperty(prefix="app",name="newest-price-update-job",havingValue="true") public class OperateOrderPriceConsumer { /** * 用户修改止损止盈价格、提价限价委托、下单爆仓价等消息 * @date 2019年4月19日 * @param message 消息体 * @param channel 信道 */ @RabbitListener(queues = RabbitMqConfig.QUEUE_PRICEOPERATE) public void onMessageMorePro(Message message, Channel channel) { String content = new String(message.getBody()); System.out.println("我收到了用户的订单操作消息:"+content); // 操作前的map // 转为model OrderModel orderModel = JSONObject.parseObject(content, OrderModel.class); // 向优先队列添加 OrderOperatePriceService.dealWithNewMq(orderModel); } } src/main/java/com/xcong/excoin/rabbit/consumer/WebsocketPriceConsumer.java
New file @@ -0,0 +1,135 @@ package com.xcong.excoin.rabbit.consumer; import com.alibaba.fastjson.JSONArray; import com.rabbitmq.client.Channel; import com.xcong.excoin.configurations.RabbitMqConfig; import com.xcong.excoin.rabbit.pricequeue.OrderModel; import org.springframework.amqp.core.Message; import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.stereotype.Component; import java.util.List; /** * APP和后台打包都开启 * */ @Component @ConditionalOnProperty(name="useRabbit",havingValue="true") public class WebsocketPriceConsumer { //@Autowired //OrderWebsocketService orderWebsocketService; //@Autowired //OrderService orderService; /** * 开多止盈 * @param message 消息体 * @param channel 信道 */ @RabbitListener(queues = RabbitMqConfig.QUEUE_MOREPRO) public void onMessageMorePro(Message message, Channel channel) { String content = new String(message.getBody()); System.out.println("我收到消息了开多止盈:"+content); List<OrderModel> list = JSONArray.parseArray(content,OrderModel.class); // 开始处理 TODO //orderWebsocketService.dealOrderFromMq(list,9); } // 1:买入委托2:开多3:开空4:平多5:平空6:爆仓平多7:爆仓平空8:撤单9:止盈平多10:止盈平空11:止损平多12:止损平空 /** * 开空止盈 * @param message * @param channel */ @RabbitListener(queues = RabbitMqConfig.QUEUE_LESSPRO) public void onMessageLessPro(Message message, Channel channel) { String content = new String(message.getBody()); System.out.println("我收到消息了开空止盈:"+content); // 开始处理 List<OrderModel> list = JSONArray.parseArray(content,OrderModel.class); // 开始处理 //orderWebsocketService.dealOrderFromMq(list,10); } /** * 开多止损 * @param message * @param channel */ @RabbitListener(queues = RabbitMqConfig.QUEUE_MORELOSS) public void onMessageMoreLoss(Message message, Channel channel) { String content = new String(message.getBody()); System.out.println("我收到消息了开多止损:"+content); // 开始处理 List<OrderModel> list = JSONArray.parseArray(content,OrderModel.class); // 开始处理 //orderWebsocketService.dealOrderFromMq(list,11); } /** * 开空止损 * @param message * @param channel */ @RabbitListener(queues = RabbitMqConfig.QUEUE_LESSLOSS) public void onMessageLessLoss(Message message, Channel channel) { String content = new String(message.getBody()); System.out.println("我收到消息了开空止损:"+content); // 开始处理 List<OrderModel> list = JSONArray.parseArray(content,OrderModel.class); // 开始处理 //orderWebsocketService.dealOrderFromMq(list,12); } /** * 限价委托 * @param message * @param channel */ @RabbitListener(queues = RabbitMqConfig.QUEUE_LIMIT) public void onMessageLimit(Message message, Channel channel) { String content = new String(message.getBody()); System.out.println("我收到消息了限价委托:"+content); // 开始处理 List<OrderModel> list = JSONArray.parseArray(content,OrderModel.class); // 开始处理 //orderWebsocketService.dealForLimitMq(list); } /** * 爆仓消费者 * @param message * @param channel */ @RabbitListener(queues = RabbitMqConfig.QUEUE_COINOUT) public void onMessageCoinout(Message message, Channel channel) { String content = new String(message.getBody()); System.out.println("我收到消息了爆仓:"+content); // 开始处理 List<OrderModel> list = JSONArray.parseArray(content,OrderModel.class); // 开始处理 //orderWebsocketService.dealOrderFromMq(list,6); } /** * 平仓 * @param message * @param channel */ @RabbitListener(queues = RabbitMqConfig.QUEUE_CLOSETRADE) public void onMessageCloseTrade(Message message, Channel channel) { String content = new String(message.getBody()); System.out.println("我收到消息了平仓:"+content); // 订单 List<Long> ids = JSONArray.parseArray(content, Long.class); //orderService.closeTradeForMq(ids); } } src/main/java/com/xcong/excoin/rabbit/pricequeue/AscBigDecimal.java
New file @@ -0,0 +1,43 @@ package com.xcong.excoin.rabbit.pricequeue; import java.math.BigDecimal; import java.math.RoundingMode; /** * 正序的 从小到大 头元素最小 */ public class AscBigDecimal implements Comparable{ private BigDecimal value; public AscBigDecimal(String val) { this.value = new BigDecimal(val).setScale(8, RoundingMode.HALF_UP); } public AscBigDecimal(double val){ this.value = new BigDecimal(val).setScale(8, RoundingMode.HALF_UP); } public BigDecimal getValue() { return value; } public void setValue(BigDecimal value) { this.value = value; } @Override public int compareTo(Object o) { if(o==null){ return -1; } AscBigDecimal val = (AscBigDecimal)o; if(this.value.compareTo(val.getValue())>0){ return 1; }else if(this.value.compareTo(val.getValue())<0){ return -1; }else { return 0; } } } src/main/java/com/xcong/excoin/rabbit/pricequeue/DescBigDecimal.java
New file @@ -0,0 +1,45 @@ package com.xcong.excoin.rabbit.pricequeue; import java.math.BigDecimal; import java.math.RoundingMode; /** * 倒叙序的 从大到小 头元素最大 */ public class DescBigDecimal implements Comparable{ private BigDecimal value; public DescBigDecimal(String val) { this.value = new BigDecimal(val).setScale(8, RoundingMode.HALF_UP); } public DescBigDecimal(double val){ this.value = new BigDecimal(val).setScale(8, RoundingMode.HALF_UP); } public BigDecimal getValue() { return value; } public void setValue(BigDecimal value) { this.value = value; } @Override public int compareTo(Object o) { if(o==null){ return -1; } DescBigDecimal val = (DescBigDecimal)o; if(this.value.compareTo(val.getValue())>0){ return -1; }else if(this.value.compareTo(val.getValue())<0){ return 1; }else { return 0; } } } src/main/java/com/xcong/excoin/rabbit/pricequeue/OrderModel.java
New file @@ -0,0 +1,83 @@ package com.xcong.excoin.rabbit.pricequeue; public class OrderModel { /** * 订单ID */ private Long orderId; /** * 类型 */ private Integer type; /** * 触发价格 */ private String price; /** * 币种 */ private String symbol; /** * 爆仓价位设置次数 */ private Integer operateNo; public OrderModel(Long orderId, Integer type, String price, String symbol){ this.orderId= orderId; this.type= type; this.price= price; this.symbol= symbol; } public OrderModel(Long orderId,Integer type,String price, String symbol,Integer operateNo){ this.orderId= orderId; this.type= type; this.price= price; this.symbol= symbol; this.operateNo= operateNo; } public Integer getOperateNo() { return operateNo; } public void setOperateNo(Integer operateNo) { this.operateNo = operateNo; } public Long getOrderId() { return orderId; } public void setOrderId(Long orderId) { this.orderId = orderId; } public Integer getType() { return type; } public void setType(Integer type) { this.type = type; } public String getPrice() { return price; } public void setPrice(String price) { this.price = price; } public String getSymbol() { return symbol; } public void setSymbol(String symbol) { this.symbol = symbol; } } src/main/java/com/xcong/excoin/rabbit/pricequeue/OrderOperatePriceService.java
New file @@ -0,0 +1,124 @@ package com.xcong.excoin.rabbit.pricequeue; import org.apache.commons.collections.CollectionUtils; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.concurrent.PriorityBlockingQueue; /** * 处理消费者的订单止盈等价格信息 */ 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) { // 需要价格涨的 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)); removeExistOrder(type, orderId, 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()); list.add(orderModel); } } else { List<OrderModel> list = new ArrayList<OrderModel>(); OrderModel orderModel = new OrderModel(orderId, type, price, null,order.getOperateNo()); list.add(orderModel); orderMap.put(price, list); } } /** * 正序的添加价格和订单 * * @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)); // 需要找到这个订单的原始的单进行处理 removeExistOrder(type, orderId, 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()); list.add(orderModel); } } else { List<OrderModel> list = new ArrayList<OrderModel>(); OrderModel orderModel = new OrderModel(orderId, type, price, null,order.getOperateNo()); list.add(orderModel); orderMap.put(price, list); } } 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; } } } } } } src/main/java/com/xcong/excoin/rabbit/pricequeue/PricePriorityQueue.java
New file @@ -0,0 +1,300 @@ package com.xcong.excoin.rabbit.pricequeue; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.PriorityBlockingQueue; /** * 止盈止损的价格队列 */ public class PricePriorityQueue { /** * BTC 正序队列 头元素最小 开多止损 开空止盈 开多爆仓 限价开多 */ public static PriorityBlockingQueue<AscBigDecimal> BTC_QUEUE_ASC = null; private static Map<String, List<OrderModel>> BTC_MAP_ASC = null; /** * BTC 倒序队列 头元素最大 开多止盈 开空止损 开空爆仓 限价开空 */ public static PriorityBlockingQueue<DescBigDecimal> BTC_QUEUE_DESC = null; private static Map<String, List<OrderModel>> BTC_MAP_DESC = null; /** * ETH 正序队列 头元素最小 开多止损 开空止盈 开多爆仓 限价开多 */ private static PriorityBlockingQueue<AscBigDecimal> ETH_QUEUE_ASC = null; private static Map<String, List<OrderModel>> ETH_MAP_ASC = null; /** * ETH 倒序队列 头元素最大 开多止盈 开空止损 开空爆仓 限价开空 */ private static PriorityBlockingQueue<DescBigDecimal> ETH_QUEUE_DESC = null; private static Map<String, List<OrderModel>> ETH_MAP_DESC = null; /** * XRP 正序队列 头元素最小 开多止损 开空止盈 开多爆仓 限价开多 */ private static PriorityBlockingQueue<AscBigDecimal> XRP_QUEUE_ASC = null; private static Map<String, List<OrderModel>> XRP_MAP_ASC = null; /** * XRP 倒序队列 头元素最大 开多止盈 开空止损 开空爆仓 限价开空 */ private static PriorityBlockingQueue<DescBigDecimal> XRP_QUEUE_DESC = null; private static Map<String, List<OrderModel>> XRP_MAP_DESC = null; /** * LTC 正序队列 头元素最小 开多止损 开空止盈 开多爆仓 限价开多 */ private static PriorityBlockingQueue<AscBigDecimal> LTC_QUEUE_ASC = null; private static Map<String, List<OrderModel>> LTC_MAP_ASC = null; /** * LTC 倒序队列 头元素最大 开多止盈 开空止损 开空爆仓 限价开空 */ private static PriorityBlockingQueue<DescBigDecimal> LTC_QUEUE_DESC = null; private static Map<String, List<OrderModel>> LTC_MAP_DESC = null; /** * BCH 正序队列 头元素最小 开多止损 开空止盈 开多爆仓 限价开多 */ private static PriorityBlockingQueue<AscBigDecimal> BCH_QUEUE_ASC = null; private static Map<String, List<OrderModel>> BCH_MAP_ASC = null; /** * BCH 倒序队列 头元素最大 开多止盈 开空止损 开空爆仓 限价开空 */ private static PriorityBlockingQueue<DescBigDecimal> BCH_QUEUE_DESC = null; private static Map<String, List<OrderModel>> BCH_MAP_DESC = null; /** * EOS 正序队列 头元素最小 开多止损 开空止盈 开多爆仓 限价开多 */ private static PriorityBlockingQueue<AscBigDecimal> EOS_QUEUE_ASC = null; private static Map<String, List<OrderModel>> EOS_MAP_ASC = null; /** * EOS 倒序队列 头元素最大 开多止盈 开空止损 开空爆仓 限价开空 */ private static PriorityBlockingQueue<DescBigDecimal> EOS_QUEUE_DESC = null; private static Map<String, List<OrderModel>> EOS_MAP_DESC = null; /** * ETC 正序队列 头元素最小 开多止损 开空止盈 开多爆仓 限价开多 */ private static PriorityBlockingQueue<AscBigDecimal> ETC_QUEUE_ASC = null; private static Map<String, List<OrderModel>> ETC_MAP_ASC = null; /** * ETC 倒序队列 头元素最大 开多止盈 开空止损 开空爆仓 限价开空 */ private static PriorityBlockingQueue<DescBigDecimal> ETC_QUEUE_DESC = null; private static Map<String, List<OrderModel>> ETC_MAP_DESC = null; // 收到消息队列的方法 即收取到新的止盈止损等 // 【1:买入委托2:开多3:开空4:平多5:平空6:爆仓平多7:爆仓平空8:撤单9:止盈平多10:止盈平空11:止损平多12:止损平空】 public static PriorityBlockingQueue<AscBigDecimal> getQueueAsc(String symbol) { switch (symbol) { case "BTC/USDT": // 开多止损 开空止盈 开多爆仓 限价开多 if (BTC_QUEUE_ASC == null) { BTC_QUEUE_ASC = new PriorityBlockingQueue<AscBigDecimal>(); } return BTC_QUEUE_ASC; case "ETH/USDT": // 开多止损 开空止盈 开多爆仓 限价开多 if (ETH_QUEUE_ASC == null) { ETH_QUEUE_ASC = new PriorityBlockingQueue<AscBigDecimal>(); } return ETH_QUEUE_ASC; case "XRP/USDT": // 开多止损 开空止盈 开多爆仓 限价开多 if (XRP_QUEUE_ASC == null) { XRP_QUEUE_ASC = new PriorityBlockingQueue<AscBigDecimal>(); } return XRP_QUEUE_ASC; case "LTC/USDT": // 开多止损 开空止盈 开多爆仓 限价开多 if (LTC_QUEUE_ASC == null) { LTC_QUEUE_ASC = new PriorityBlockingQueue<AscBigDecimal>(); } return LTC_QUEUE_ASC; case "BCH/USDT": // 开多止损 开空止盈 开多爆仓 限价开多 if (BCH_QUEUE_ASC == null) { BCH_QUEUE_ASC = new PriorityBlockingQueue<AscBigDecimal>(); } return BCH_QUEUE_ASC; case "EOS/USDT": // 开多止损 开空止盈 开多爆仓 限价开多 if (EOS_QUEUE_ASC == null) { EOS_QUEUE_ASC = new PriorityBlockingQueue<AscBigDecimal>(); } return EOS_QUEUE_ASC; case "ETC/USDT": // 开多止损 开空止盈 开多爆仓 限价开多 if (ETC_QUEUE_ASC == null) { ETC_QUEUE_ASC = new PriorityBlockingQueue<AscBigDecimal>(); } return ETC_QUEUE_ASC; default: break; } return null; } public static PriorityBlockingQueue<DescBigDecimal> getQueueDesc(String symbol) { switch (symbol) { case "BTC/USDT": // 开多止损 开空止盈 开多爆仓 限价开多 //if (type == 11 || type == 10 || type == 7 || type == 6 || type == 2) { if (BTC_QUEUE_DESC == null) { BTC_QUEUE_DESC = new PriorityBlockingQueue<DescBigDecimal>(); } return BTC_QUEUE_DESC; case "ETH/USDT": // 开多止损 开空止盈 开多爆仓 限价开多 if (ETH_QUEUE_DESC == null) { ETH_QUEUE_DESC = new PriorityBlockingQueue<DescBigDecimal>(); } return ETH_QUEUE_DESC; case "XRP/USDT": // 开多止损 开空止盈 开多爆仓 限价开多 if (XRP_QUEUE_DESC == null) { XRP_QUEUE_DESC = new PriorityBlockingQueue<DescBigDecimal>(); } return XRP_QUEUE_DESC; case "LTC/USDT": // 开多止损 开空止盈 开多爆仓 限价开多 if (LTC_QUEUE_DESC == null) { LTC_QUEUE_DESC = new PriorityBlockingQueue<DescBigDecimal>(); } return LTC_QUEUE_DESC; case "BCH/USDT": // 开多止损 开空止盈 开多爆仓 限价开多 if (BCH_QUEUE_DESC == null) { BCH_QUEUE_DESC = new PriorityBlockingQueue<DescBigDecimal>(); } return BCH_QUEUE_DESC; case "EOS/USDT": // 开多止损 开空止盈 开多爆仓 限价开多 if (EOS_QUEUE_DESC == null) { EOS_QUEUE_DESC = new PriorityBlockingQueue<DescBigDecimal>(); } return EOS_QUEUE_DESC; case "ETC/USDT": // 开多止损 开空止盈 开多爆仓 限价开多 if (ETC_QUEUE_DESC == null) { ETC_QUEUE_DESC = new PriorityBlockingQueue<DescBigDecimal>(); } return ETC_QUEUE_DESC; default: break; } return null; } /** * 获得币种价格订单map * @param symbol * @param type * @return */ public static Map<String,List<OrderModel>> getOrderMap(String symbol, int type) { switch (symbol) { case "BTC/USDT": // 开空止损 开多止盈 开空爆仓 限价开空 if (type == 12 || type == 9 || type == 7 || type == 3) { if (BTC_MAP_ASC == null) { BTC_MAP_ASC = new ConcurrentHashMap<String,List<OrderModel>>(); } return BTC_MAP_ASC; } else { if (BTC_MAP_DESC == null) { BTC_MAP_DESC = new ConcurrentHashMap<String,List<OrderModel>>(); } return BTC_MAP_DESC; } case "ETH/USDT": // 开多止损 开空止盈 开多爆仓 限价开多 if (type == 12 || type == 9 || type == 7 || type == 3) { if (ETH_MAP_ASC == null) { ETH_MAP_ASC = new ConcurrentHashMap<String,List<OrderModel>>(); } return ETH_MAP_ASC; } else { if (ETH_MAP_DESC == null) { ETH_MAP_DESC = new ConcurrentHashMap<String,List<OrderModel>>(); } return ETH_MAP_DESC; } case "XRP/USDT": // 开多止损 开空止盈 开多爆仓 限价开多 if (type == 12 || type == 9 || type == 7 || type == 3) { if (XRP_MAP_ASC == null) { XRP_MAP_ASC = new ConcurrentHashMap<String,List<OrderModel>>(); } return XRP_MAP_ASC; } else { if (XRP_MAP_DESC == null) { XRP_MAP_DESC = new ConcurrentHashMap<String,List<OrderModel>>(); } return XRP_MAP_DESC; } case "LTC/USDT": // 开多止损 开空止盈 开多爆仓 限价开多 if (type == 12 || type == 9 || type == 7 || type == 3) { if (LTC_MAP_ASC == null) { LTC_MAP_ASC = new ConcurrentHashMap<String,List<OrderModel>>(); } return LTC_MAP_ASC; } else { if (LTC_MAP_DESC == null) { LTC_MAP_DESC =new ConcurrentHashMap<String,List<OrderModel>>(); } return LTC_MAP_DESC; } case "BCH/USDT": // 开多止损 开空止盈 开多爆仓 限价开多 if (type == 12 || type == 9 || type == 7 || type == 3) { if (BCH_MAP_ASC == null) { BCH_MAP_ASC = new ConcurrentHashMap<String,List<OrderModel>>(); } return BCH_MAP_ASC; } else { if (BCH_MAP_DESC == null) { BCH_MAP_DESC = new ConcurrentHashMap<String,List<OrderModel>>(); } return BCH_MAP_DESC; } case "EOS/USDT": // 开多止损 开空止盈 开多爆仓 限价开多 if (type == 12 || type == 9 || type == 7 || type == 3) { if (EOS_MAP_ASC == null) { EOS_MAP_ASC = new ConcurrentHashMap<String,List<OrderModel>>(); } return EOS_MAP_ASC; } else { if (EOS_MAP_DESC == null) { EOS_MAP_DESC = new ConcurrentHashMap<String,List<OrderModel>>(); } return EOS_MAP_DESC; } case "ETC/USDT": // 开多止损 开空止盈 开多爆仓 限价开多 if (type == 12 || type == 9 || type == 7 || type == 3) { if (ETC_MAP_ASC == null) { ETC_MAP_ASC = new ConcurrentHashMap<String,List<OrderModel>>(); } return ETC_MAP_ASC; } else { if (ETC_MAP_DESC == null) { ETC_MAP_DESC = new ConcurrentHashMap<String,List<OrderModel>>(); } return ETC_MAP_DESC; } default: break; } return null; } } src/main/java/com/xcong/excoin/rabbit/pricequeue/WebsocketPriceService.java
New file @@ -0,0 +1,229 @@ package com.xcong.excoin.rabbit.pricequeue; import com.alibaba.fastjson.JSONObject; import com.xcong.excoin.rabbit.producer.OrderProducer; import org.apache.commons.collections.CollectionUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; import java.util.concurrent.PriorityBlockingQueue; @Component public class WebsocketPriceService { @Autowired OrderProducer orderProducer; /** * @param symbol * @param price */ public void comparePriceAsc(String symbol, String price) { // 比较价格 正序的 最小元素在头部 开多止盈 开空止损等 PriorityBlockingQueue<AscBigDecimal> queue = PricePriorityQueue.getQueueAsc(symbol); // 最小的 AscBigDecimal b = queue.peek(); // 当前价 AscBigDecimal now = new AscBigDecimal(price); List<AscBigDecimal> list = new ArrayList<AscBigDecimal>(); // 找到所有比当前价格大的 是需要操作的 if (b != null && b.compareTo(now) <= 0) { // 可以操作 System.out.println("当前价格:" + price + "---正序---" + "队列价格:" + b.getValue().toPlainString()+" time:"+new Date()); while (queue.peek() != null && queue.peek().compareTo(now) <= 0) { // 可以发送消息操作 list.add(queue.remove()); } } if(CollectionUtils.isNotEmpty(list)){ dealAscPriceOrderAndSenMq(list,symbol); } } public void comparePriceDesc(String symbol, String price) { // 比较价格 倒叙的 开多止损 开空止盈 PriorityBlockingQueue<DescBigDecimal> queue = PricePriorityQueue.getQueueDesc(symbol); // 最大价格 DescBigDecimal b = queue.peek(); // 当前价格 DescBigDecimal now = new DescBigDecimal(price); List<DescBigDecimal> list = new ArrayList<DescBigDecimal>(); // 找到比当前价格还大的就是需要操作的 开多止损 // 即最大的币当前价大 那么需要开多止损 if (b != null && b.compareTo(now) <= 0) { // 可以操作 System.out.println("当前价格:" + price + "---倒序操作---" + "队列:" + b.getValue().toPlainString()+" time:"+new Date()); while (queue.peek() != null && queue.peek().compareTo(now) <= 0) { // 可以发送消息操作 list.add(queue.remove()); } } if(CollectionUtils.isNotEmpty(list)){ dealDescPriceOrderAndSenMq(list,symbol); } } // 处理消息 正序的 包括 // 1:买入委托2:开多3:开空4:平多5:平空6:爆仓平多7:爆仓平空8:撤单9:止盈平多10:止盈平空11:止损平多12:止损平空 public void dealAscPriceOrderAndSenMq(List<AscBigDecimal> list, String symbol) { if (CollectionUtils.isNotEmpty(list)) { // 根据不同类型发送不同消息 1 倒序 2 正序 List<OrderModel> orderModelList = new ArrayList<OrderModel>(); // 3 正序 Map<String, List<OrderModel>> orderMap = PricePriorityQueue.getOrderMap(symbol, 3); // 根据价格查询到对应的订单 for (AscBigDecimal asc : list) { String key = asc.getValue().toPlainString(); if(orderMap.containsKey(key)){ orderModelList.addAll(orderMap.get(key)); orderMap.remove(key); } } if(CollectionUtils.isEmpty(orderModelList)){ return; } System.out.println("本次执行的列表ASC"); System.out.println(JSONObject.toJSONString(orderModelList)); // 根据订单的类型发送消息 // 3:开空 7:爆仓平空 // 9:止盈平多 12:止损平空 for (OrderModel model : orderModelList) { List<OrderModel> kkzsList = null; List<OrderModel> kdzyList = null; List<OrderModel> bcList = null; List<OrderModel> wtkkList = null; switch (model.getType()) { case 3: if (wtkkList == null) { wtkkList = new ArrayList<OrderModel>(); } wtkkList.add(model); break; case 7: if (bcList == null) { bcList = new ArrayList<OrderModel>(); } bcList.add(model); break; case 9: if (kdzyList == null) { kdzyList = new ArrayList<OrderModel>(); } kdzyList.add(model); break; case 12: if (kkzsList == null) { kkzsList = new ArrayList<OrderModel>(); } kkzsList.add(model); break; } // 发送消息 if(CollectionUtils.isNotEmpty(kkzsList)){ String kkzs= JSONObject.toJSONString(kkzsList); orderProducer.sendLessLoss(kkzs); } if(CollectionUtils.isNotEmpty(kdzyList)){ String kdzy = JSONObject.toJSONString(kdzyList); orderProducer.sendMorePro(kdzy); } if(CollectionUtils.isNotEmpty(bcList)){ orderProducer.sendCoinout(JSONObject.toJSONString(bcList)); } if(CollectionUtils.isNotEmpty(wtkkList)){ orderProducer.sendLimit(JSONObject.toJSONString(wtkkList)); } } } } // 处理消息 正序的 包括 // 1:买入委托2:开多3:开空4:平多5:平空6:爆仓平多7:爆仓平空8:撤单9:止盈平多10:止盈平空11:止损平多12:止损平空 public void dealDescPriceOrderAndSenMq(List<DescBigDecimal> list, String symbol) { if (CollectionUtils.isNotEmpty(list)) { // 根据不同类型发送不同消息 1 倒序 2 正序 List<OrderModel> orderModelList = new ArrayList<OrderModel>(); Map<String, List<OrderModel>> orderMap = PricePriorityQueue.getOrderMap(symbol, 2); // 根据价格查询到对应的订单 for (DescBigDecimal desc : list) { String key = desc.getValue().toPlainString(); if(orderMap.containsKey(key)){ orderModelList.addAll(orderMap.get(key)); orderMap.remove(key); } } if(CollectionUtils.isEmpty(orderModelList)){ return; } System.out.println("本次执行的列表Desc"); System.out.println(JSONObject.toJSONString(orderModelList)); // 根据订单的类型发送消息 // 2:开多6:爆仓平多 // 10:止盈平空11:止损平多 for (OrderModel model : orderModelList) { List<OrderModel> kkzyList = null; List<OrderModel> kdzsList = null; List<OrderModel> bcList = null; List<OrderModel> wtkdList = null; switch (model.getType()) { case 2: if (wtkdList == null) { wtkdList = new ArrayList<OrderModel>(); } wtkdList.add(model); break; case 6: if (bcList == null) { bcList = new ArrayList<OrderModel>(); } bcList.add(model); break; case 10: if (kkzyList == null) { kkzyList = new ArrayList<OrderModel>(); } kkzyList.add(model); break; case 11: if (kdzsList == null) { kdzsList = new ArrayList<OrderModel>(); } kdzsList.add(model); break; } // 发送消息 if(CollectionUtils.isNotEmpty(kkzyList)){ String kkzy= JSONObject.toJSONString(kkzyList); orderProducer.sendLessPro(kkzy); } if(CollectionUtils.isNotEmpty(kdzsList)){ String kdzs = JSONObject.toJSONString(kdzsList); orderProducer.sendMoreLoss(kdzs); } if(CollectionUtils.isNotEmpty(bcList)){ orderProducer.sendCoinout(JSONObject.toJSONString(bcList)); } if(CollectionUtils.isNotEmpty(wtkdList)){ orderProducer.sendLimit(JSONObject.toJSONString(wtkdList)); } } } } } src/main/java/com/xcong/excoin/rabbit/producer/OrderProducer.java
New file @@ -0,0 +1,132 @@ package com.xcong.excoin.rabbit.producer; import com.xcong.excoin.configurations.RabbitMqConfig; import org.springframework.amqp.rabbit.connection.CorrelationData; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.amqp.rabbit.core.RabbitTemplate.ConfirmCallback; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.UUID; /** * rabbitMq示例生产者 */ @Component public class OrderProducer implements ConfirmCallback { /** * 配置中配置的RabbitTemplate的是prototype类型,不能直接注入 */ private RabbitTemplate rabbitTemplate; /** * 在构造方法上注入RabbitTemplate * * @param */ @Autowired public OrderProducer(RabbitTemplate rabbitTemplate) { this.rabbitTemplate = rabbitTemplate; rabbitTemplate.setConfirmCallback(this); } /** * P发送消息方法 开多止盈 */ public void sendMorePro(String content) { CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString()); System.out.println("发送开多止盈:"+content+"==pid:"+correlationData.getId()); rabbitTemplate.convertAndSend(RabbitMqConfig.EXCHANGE_A, RabbitMqConfig.ROUTINGKEY_MOREPRO, content, correlationData); } /** * 开空止盈 * @param content */ public void sendLessPro(String content) { CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString()); System.out.println("发送开空止盈:"+content+"==pid:"+correlationData.getId()); rabbitTemplate.convertAndSend(RabbitMqConfig.EXCHANGE_A, RabbitMqConfig.ROUTINGKEY_LESSPRO, content, correlationData); } /** * 开多止损 * @param content */ public void sendMoreLoss(String content) { CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString()); System.out.println("发送开多止损:"+content+"==pid:"+correlationData.getId()); rabbitTemplate.convertAndSend(RabbitMqConfig.EXCHANGE_A, RabbitMqConfig.ROUTINGKEY_MORELOSS, content, correlationData); } /** * 开空止损 * @param content */ public void sendLessLoss(String content) { CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString()); System.out.println("发送开空止损:"+content+"==pid:"+correlationData.getId()); rabbitTemplate.convertAndSend(RabbitMqConfig.EXCHANGE_A, RabbitMqConfig.ROUTINGKEY_LESSLOSS, content, correlationData); } /** * 发送委托交易消息 * @param content */ public void sendLimit(String content){ CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString()); System.out.println("发送限价委托:"+content+"==pid:"+correlationData.getId()); rabbitTemplate.convertAndSend(RabbitMqConfig.EXCHANGE_A, RabbitMqConfig.ROUTINGKEY_LIMIT, content, correlationData); } /** * 发送爆仓消息 * @param content */ public void sendCoinout(String content){ CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString()); System.out.println("发送爆仓:"+content+"==pid:"+correlationData.getId()); rabbitTemplate.convertAndSend(RabbitMqConfig.EXCHANGE_A, RabbitMqConfig.ROUTINGKEY_COINOUT, content, correlationData); } /** * 发送价格操作消息 * @param content */ public void sendPriceOperate(String content){ CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString()); System.out.println("发送价格操作:"+content+"==pid:"+correlationData.getId()); rabbitTemplate.convertAndSend(RabbitMqConfig.EXCHANGE_A, RabbitMqConfig.ROUTINGKEY_PRICEOPERATE, content, correlationData); } /** * 发送平仓 * @param content */ public void sendCloseTrade(String content){ CorrelationData correlationData = new CorrelationData(UUID.randomUUID().toString()); System.out.println("发送平仓消息:"+content+"==pid:"+correlationData.getId()); rabbitTemplate.convertAndSend(RabbitMqConfig.EXCHANGE_A, RabbitMqConfig.ROUTINGKEY_CLOSETRADE, content, correlationData); } /** * 用于确认消息是否成功发送到队列 */ @Override public void confirm(CorrelationData correlationData, boolean ack, String cause) { if (ack) { //System.out.println("消息发送成功"+correlationData.getId()); //LogUtil.info("消息发送成功,correlationId={}", correlationData.getId()); } else { System.out.println("消息发送失败"+correlationData.getId()); //LogUtil.info("消息发送失败,correlationId={}", correlationData.getId()); } } } src/main/java/com/xcong/excoin/utils/CalculateUtil.java
New file @@ -0,0 +1,49 @@ package com.xcong.excoin.utils; import com.xcong.excoin.modules.member.entity.MemberEntity; import com.xcong.excoin.modules.platform.entity.PlatformTradeSettingEntity; import java.math.BigDecimal; /** * @author helius */ 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); PlatformTradeSettingEntity tradeSetting = cacheSettingUtils.getTradeSetting(); 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.getIsProfit() == 1) { //预估强平价 = 预估强平价-预估强平价*系数 forcePrice = forcePrice.subtract(forcePrice.multiply(tradeSetting.getForceParam())); } } else {//开多 forcePrice = openPrice.subtract(money); if (member.getIsProfit() == 1) { //预估强平价 = 预估强平价-预估强平价*系数 forcePrice = forcePrice.add(forcePrice.multiply(tradeSetting.getForceParam())); } } if (forcePrice.compareTo(BigDecimal.ZERO) < 0) { forcePrice = BigDecimal.ZERO; } return forcePrice; } } src/main/resources/mapper/contract/ContractEntrustOrderDao.xml
@@ -11,4 +11,11 @@ select * from contract_entrust_order where member_id=#{memberId} </select> <select id="selectEntrustOrderListByIds" resultType="com.xcong.excoin.modules.contract.entity.ContractEntrustOrderEntity"> select * from contract_entrust_order where id in <foreach collection="list" separator="," open="(" close=")" item="item"> #{item} </foreach> </select> </mapper> src/main/resources/mapper/contract/ContractHoldOrderDao.xml
@@ -2,4 +2,21 @@ <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.xcong.excoin.modules.contract.dao.ContractHoldOrderDao"> <select id="updateContractHoldOrderCanNotClosingByIds" parameterType="map" resultType="int"> UPDATE contract_hold_order set is_can_closing = 0,batch_no=#{batchNo} where is_can_closing=1 and id in <foreach collection="list" close=")" item="item" open="(" separator=","> #{item.orderId} </foreach> </select> <select id="selectContractHoldOrderByBatchNo" parameterType="string" resultType="com.xcong.excoin.modules.contract.entity.ContractHoldOrderEntity"> select * from contract_hold_order where batch_no=#{batchNo} </select> <update id="updateOrderIsCanClosingAndBatchNoById" parameterType="long"> update contract_hold_order set is_can_closing = 1 ,batch_no=null where id=#{id} </update> </mapper> src/main/resources/mapper/member/MemberWalletContractDao.xml
@@ -9,5 +9,21 @@ and wallet_code = #{symbol} </if> </select> <update id="increaseWalletContractBalanceById" parameterType="map" > update member_wallet_contract <set> <if test="availableBalance!=null"> available_balance = #{availableBalance}, </if> <if test="totalBalance!=null"> total_balance = #{totalBalance}, </if> <if test="frozenBalance!=null"> frozen_balance = #{frozenBalance}, </if> </set> where id =#{id} </update> </mapper> src/main/resources/mapper/platform/PlatformSymbolsSkuDao.xml
New file @@ -0,0 +1,8 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="com.xcong.excoin.modules.platform.dao.PlatformSymbolsSkuDao"> <select id="findSymbolSkuByName" parameterType="string" resultType="com.xcong.excoin.modules.platform.entity.PlatformSymbolsSkuEntity"> SELECT * FROM platform_symbols_sku where name = #{name} </select> </mapper>